Compute! Publications, Inc.
Part of ABC Consumer Magazines, Inc.
One of the ABC Publishing Companies
Greensboro, North Carolina
“SpeedScript 3.0: All Machine Language Word Processor for Atari” was originally published in COMPUTE! magazine, May 1985, copyright 1985, COMPUTE! Publications, Inc.
Copyright 1985, COMPUTE! Publications, Inc. All rights reserved.
Reproduction or translation of any part of this work beyond that permitted by Sections 107 and 108 of the United States Copyright Act without the permission of the copyright owner is unlawful.
Printed in the United States of America
10 9 8 7 6 5 4 3 2 1
ISBN 0-87455-003-3
The author and publisher have made every effort in the preparation of this book to insure the accuracy of the programs and information. However, the information and programs in this book are sold without warranty, either express or implied. Neither the author nor COMPUTE! Publications, Inc. will be liable for any damages caused or alleged to be caused directly, indirectly, incidentally, or consequentially by the programs or information in this book.
The opinions expressed in this book are solely those of the author and are not necessarily those of COMPUTE! publications, Inc.
COMPUTE! Publications, Inc., Post Office Box 5406, Greensboro, NC 27403, (919) 275-9809, is one of the ABC Publishing Companies and is not associated with any manufacturer of personal computers. Atari 400, 800, 600XL, 800XL, 1200XL, and XE are trademarks of Atari, Inc.
SpeedScript is the most popular program ever published by COMPUTE! Publications. Ever since it first appeared in the January 1984 issue of COMPUTE!’s Gazette, the letters have been pouring in. People wanted to know more about the program and word processing, and they had countless suggestions about how to make SpeedScript better.
The result is SpeedScript 3.0, an even more powerful word processor for all eight-bit Ataris (including the 400/800, 600XL/800XL, 1200XL, and new XE series). Enhanced with additional commands and features, this all machine language word processor gives you all the things you expect from a commercial software package. You can write, edit, format, and print anything from memos to novels on your Atari. With a few keystrokes you can change the color of the screen and its text to whatever combination best suits you.
It’s easy to add or delete words, letters, even whole paragraphs. You can search through an entire document and find every occurrence of a particular word or phrase, then replace it with something new. Of course, when you finish writing, you can save your work to tape or disk.
The ability to quickly change the appearance of a printed document is one of the things that make word processing so efficient. SpeedScript lets you alter the margins, page length, spacing, page numbers, page width, as well as set up headers and footers at the top and bottom of the paper.
And once you’ve formatted your document, you’ll find enough print features to make even the most demanding writer happy. With SpeedScript, you can start printing at any page, force the printer to create a new page at any time, even make it wait while you put in another sheet of paper. Underlining and centering are simple. If you want to get fancy, you can use your printer’s codes to create graphics symbols or logos. And if you’re writing something really long—perhaps a novel or term paper—SpeedScript lets you link any number of files so that they print out as one continuous document.
In addition to the SpeedScript program for the Atari, you’ll find complete documentation and a keyboard map in this book. SpeedScript’s source code has also been included for your examination. By studying it, you’ll see exactly how the program is put together.
“The Machine Language Editor: MLX” makes typing in the program easier. MLX almost guarantees that you’ll have an error-free copy of the program the first time you type it in. If you prefer to purchase a copy of SpeedScript on disk rather than type it in, just use the convenient coupon in the back, or call toll-free 1-800-334-0868.
SpeedScript is an exceptionally easy-to-use and powerful word processor that will meet all your writing needs.
SpeedScript has become one of the most popular word processors for the Commodore 64, VIC-20, and Apple computers. And now SpeedScript has been translated to run on all eight-bit Ataris with at least 24K, with either disk or cassette (including the 400, 800, 600XL with memory expansion, 800XL, 1200XL, and new XE series). SpeedScript compares favorably with commercial word processors and has some features never seen before in an Atari word processor. It represents unique value in a type-in program.
SpeedScript 3.0, though compact in size (8K), has many features found on commercial word processors. SpeedScript is also very easy to learn and use. You type in everything first; preview and make corrections on the screen; insert and delete words, sentences, and paragraphs; then print out an error-free draft, letting SpeedScript take care of things like margins, centering, headers, and footers.
Atari SpeedScript is the longest machine language program we’ve ever published, but COMPUTE!’s “MLX” entry system helps you type it right the first time. MLX can detect most errors people make when entering numbers. (See the instructions for using MLX in chapter 2.) MLX also lets you type SpeedScript in more than one sitting. Although the program listing is lengthy, we guarantee the effort will be worthwhile.
After you run the Atari version of MLX, answer the first two questions like this:
Next, you’ll be asked “Tape or Disk.” SpeedScript can be saved as either a binary file on disk or as a boot tape. Press T for use with a tape drive. If you press D for disk, you’ll be asked “Boot Disk or Binary File.” Press F to select the Binary File option. Although you could save SpeedScript as an autobooting disk, it makes no sense, because such a disk cannot contain DOS, which is necessary for file-oriented disk access.
The screen will then show the first prompt, the number 7936 followed by a colon (:). Type in each three-digit number shown in the listing. You do not need to type the comma shown in the listing. MLX inserts the comma automatically.
The last number you enter in each line is a checksum. It represents the values of the other numbers in the line summed together. If you type the line correctly, the checksum calculated by MLX and displayed on the screen should match the checksum number in the listing. If it doesn’t match, you will have to retype the line. MLX is not foolproof, though. It’s possible to fool the checksum by exchanging the positions of the three-digit numbers. Also, an error in one number can be offset by an error in another. MLX will help catch your errors, but you must still be careful.
If you want to stop typing the listing at some point and pick up later, press CTRL-S and follow the screen prompts. (For disk, MLX will ask you to specify a filename; do not use AUTORUN.SYS until the entire listing is typed in.) Remember to note the line number of the last line you entered. When you are ready to continue typing, load MLX, answer the prompts as you did before, then press CTRL-L. For a boot tape, be sure the cassette is in the tape drive and rewound. For a binary disk file, MLX asks for the filename you gave to the partially typed listing. After the LOAD is complete, press CTRL-N and tell MLX the line number where you stopped. Now continue typing as before.
When you finish all typing, MLX automatically prompts you to save the program. For disks with Atari DOS 2.0 or 3.0, save the completed program with the filename AUTORUN.SYS. This will allow SpeedScript to load and run automatically when the disk is booted.
At this point, MLX has saved either a boot tape or binary disk file. To load your boot tape, remove all cartridges, rewind the tape, and hold down the START button while turning on the power. (On the 600XL, 800XL, and XE series, disable BASIC by holding down both START and OPTION while turning on the power.) When the computer turns on, you’ll hear a single beep tone. (On the XL and XE series, make sure the volume is turned up on your TV or monitor.) Press PLAY on the tape drive, then press any key on the keyboard to start the load. SpeedScript will automatically run once the boot is successfully completed.
To use SpeedScript with an Atari DOS disk, you must save or copy it on a disk which also contains DOS.SYS and DUP.SYS. Since you’ve saved SpeedScript as AUTORUN.SYS, it will automatically load and run when you turn on your computer with this disk in the drive. (On the 600XL, 800XL, and XE series, disable BASIC by holding down OPTION when switching on the computer.) SpeedScript must always be named AUTORUN.SYS in order to load properly with Atari DOS. If you want to prevent it from automatically running for some reason, you can save it with another name, then rename it AUTORUN.SYS later.
If you’re using Optimized System Software’s OS/A+ DOS or a compatible successor, you can give SpeedScript any filename you like. Just use the LOAD command from DOS, and SpeedScript will automatically run. Or you can give it a filename with the extension .COM, such as SPEED.COM. Then you can start up by just typing SPEED at the DOS prompt. You can also write a simple batch file to boot up SpeedScript automatically. Some enhanced DOS packages like Optimized System Software’s DOS XL may use so much memory that they conflict with SpeedScript. In this case, you’ll need either to use Atari DOS instead on your SpeedScript disks or to reassemble the source code at a higher address to avoid conflicts.
Note: The AUTORUN.SYS file on your DOS master disk is responsible for booting up the 850 Interface Module for RS-232 communications. There is no easy way to combine the 850 boot program with SpeedScript, so you can’t access the R: device. We’ll show you later how to transfer files over a modem or print to a serial printer.
If you prefer, Atari SpeedScript is available for purchase on disk. To order the disk, use the coupon in the back of this book or call COMPUTE! Publications toll-free at 800-334-0868.
When you run SpeedScript, the screen colors change to black on white. The first line on the screen is black with white letters. SpeedScript presents all messages on this command line. The remaining 18 lines of the screen are used to enter, edit, and display your document. SpeedScript makes use of a special, but little-used, Atari character mode that permits larger, more readable characters with true lowercase descenders. The screen still shows up to 40 columns; only five rows are sacrificed. We think you’ll agree that this is the most readable text you’ve ever seen on an Atari—perfect for word processing. (Technical note: SpeedScript starts at $1F00, and the ANTIC 3 character set is embedded at $2000.)
The cursor, a blinking square, shows where the next character you type will appear on the screen. SpeedScript lets you move the cursor anywhere within your document, making it easy to find and correct errors.
To begin using SpeedScript, just start typing. When the cursor reaches the right edge of the screen, it automatically jumps to the beginning of the next line, just as in BASIC. But unlike BASIC, SpeedScript never splits words at the right edge of the screen. If a word you’re typing won’t fit at the end of one line, it’s instantly moved to the next line. This feature, called word-wrap, or parsing, also helps to make your text more readable.
When you finish typing on the last screen line, SpeedScript automatically scrolls the text upward to make room for a new line at the bottom. Imagine the screen as an 18-line window on a long, continuous document. If you’ve unplugged all cartridges or disabled BASIC as described above, there’s room in memory for 3328 characters of text with 24K RAM and up to 27,904 characters on a 48K machine. (Unfortunately, SpeedScript 3.0 cannot make use of the extra memory available in the XL and XE series.) An additional 2K of text memory is available if SpeedScript is loaded from a boot tape. To check at any time how much unused space is left, press CTRL-U (hold down the CTRL key while pressing the U key). The number appearing in the command line indicates how much unused room remains for characters of text.
If you’re used to a typewriter, you’ll have to unlearn some habits if this is your first experience with word processing. Since the screen is only 40 columns wide, and most printers have 80-column carriages, it doesn’t make sense to press RETURN at the end of each line as you do on a typewriter. SpeedScript’s word-wrap takes care of this automatically. Press RETURN only when you want to force a carriage return to end a paragraph or limit the length of a line. A return-mark appears on the screen as a crooked left-pointing arrow.
Most features are accessed with control key commands—you hold down CTRL while pressing another key. In this book, control key commands are abbreviated CTRL-x (where x is the key you press in combination with CTRL). An example is the CTRL-U mentioned above to check on unused memory. CTRL-E means hold down CTRL and press E. Sometimes you must also hold down the OPTION button to select a special option of a command, such as OPTION-CTRL-H. Other keys are referenced by name or function, such as DELETE/BACK S for the backspace key, CTRL-CLEAR for the clear-screen key, and cursor left or CTRL-+ for the cursor-left key. (See the “Keyboard Map,” for a summary of the keyboard commands.)
Some keys let you move the cursor to different places in the document to make corrections or scroll text into view. You can move the cursor by character, word, sentence, or paragraph. Here’s how to control the cursor:
For special applications, if you ever need to type the actual character represented by a command or cursor key, press ESC before typing the CTRL key. Press ESC twice to get the ESCape character, CHR$(27).
Sometimes you’ll have to insert some characters to make a correction. Use CTRL-INSERT to open up a single space, just as in BASIC. Merely position the cursor at the point where you want to insert a space, and press CTRL-INSERT.
It can be tedious to use CTRL-INSERT to open up enough space for a whole sentence or paragraph. For convenience, SpeedScript has an insert mode that automatically inserts space for each character you type. In this mode, you can’t type over characters; everything is inserted at the cursor position. To enter insert mode, press CTRL-I. To cancel insert mode, press CTRL-I again. To let you know you’re in insert mode, the black command line at the top of the screen turns blue.
Insert mode is the easiest way to insert text, but it can become too slow when inserting near the top of a very long document because it must move all the text following the cursor position. So SpeedScript has even more ways to insert blocks of text.
One way is to use the TAB key. It is programmed in SpeedScript to act as a five-space margin indent. To end a paragraph and start another, press RETURN twice and press TAB. TAB always inserts; you don’t need to be in insert mode. You can also use TAB to open up more space than CTRL-INSERT. (You cannot set or clear tab stops in SpeedScript as you can with the normal screen editor.) No matter how much space you want to insert, each insertion takes the same amount of time. So the TAB key can insert five spaces five times faster than pressing CTRL-INSERT five times.
There’s an even better way, though. Press SHIFT-INSERT to insert 255 spaces (it does not insert a line; use RETURN for that). You can press it several times to open up as much space as you need. And SHIFT-INSERT is fast. It inserts 255 spaces as fast as CTRL-INSERT opens up one space. Now just type the text you want to insert over the blank space. (You don’t want to be in CTRL-I insert mode when you use this trick; that would defeat its purpose.)
Since the DELETE/BACK S key (backspace) is also slow when working with large documents (it, too, must move all text following the cursor), you may prefer to use the cursor-left key to backspace when using this method.
After you’ve finished inserting, there may be some inserted spaces left over that you didn’t use. Just press SHIFT-DELETE/BACK S. This instantly deletes all extra spaces between the cursor and the start of following text. It’s also useful whenever you need to delete a block of spaces for some reason.
Press DELETE/BACK S by itself to erase the character to the left of the cursor. All the following text is pulled back to fill the vacant space.
Press CTRL-DELETE/BACK S to delete the character on which the cursor is sitting. Again, all the following text is moved toward the cursor to fill the empty space.
These keys are fine for minor deletions, but it could take all day to delete a whole paragraph this way. So SpeedScript has two commands that can delete an entire word, sentence, or paragraph at a time. CTRL-E erases text after (to the right of) the cursor position, and CTRL-D deletes text behind (to the left of) the cursor.
To use the CTRL-E erase mode, first place the cursor at the beginning of the word, sentence, or paragraph you want to erase. Then press CTRL-E. The command line shows the message “Erase (S,W,P): RETURN to exit.” Press S to erase a sentence, W for a word, or P for a paragraph. Each time you press one of these letters, the text is quickly erased. You can keep pressing S, W, or P until you’ve erased all the text you wish. Then press RETURN to exit the erase mode.
The CTRL-D delete mode works similarly, but deletes only one word, sentence, or paragraph at a time. First, place the cursor after the word, sentence, or paragraph you want to delete. Then press CTRL-D. Next, press S, W or P for sentence, word, or paragraph. The text is immediately deleted and you return to editing. You don’t need to Press RETURN to exit the CTRL-D delete mode unless you pressed this key by mistake. (In general, you can escape from any command in SpeedScript by simply pressing RETURN.) CTRL-D is most convenient when the cursor is already past what you’ve been typing.
When you erase or delete with CTRL-E or CTRL-D, the text isn’t lost forever. SpeedScript remembers what you’ve removed by storing deletions in a separate area of memory called a buffer. The buffer is a fail-safe device. If you erase too much or change your mind, just Press CTRL-R to restore the deletion. However, be aware that SpeedScript remembers only the last erase or delete you performed.
Another, more powerful use of this buffer is to move or copy sections of text. To move some text from one location in your document to another, first erase or delete it with CTRL-E or CTRL-D. Then move the cursor to where you want the text to appear and press CTRL-R. CTRL-R instantly inserts the contents of the buffer at the cursor position. If you want to copy some text from one part of your document to another, just erase or delete it with CTRL-E or CTRL-D, restore it at the original position with CTRL-R, then move the cursor elsewhere and press CTRL-R to restore it again. You can retrieve the buffer with CTRL-R as many times as you like. If there is no room left in memory for inserting the buffer, you’ll see the message “Memory Full.”
Important: The CTRL-E erase mode lets you erase up to the maximum size of the buffer (2K for disk, about 6K for tape), and CTRL-E also removes the previous contents of the buffer. Keep this in mind if there’s something in the buffer you’d rather keep. If you don’t want the buffer to be erased, hold down the OPTION key while you press CTRL-E. This preserves the buffer contents and adds newly erased text to the buffer.
If you ever need to erase the contents of the buffer, press CTRL-K (kill buffer).
If you want to start a new document or simply obliterate all your text, hold down OPTION while you press SHIFT-CLEAR (that’s not a combination you’re likely to press accidentally). SpeedScript asks, “ERASE ALL TEXT: Are you sure? (Y/N).” This is your last chance. If you don’t want to erase the entire document, press N or any other key. Press Y to perform the irreversible deed. There is no way to recover text wiped out with Erase All.
SpeedScript has a Find command that searches through your document to find a selected word or phrase. A Change option lets you automatically change one word to another throughout the document.
OPTION-CTRL-F (find) activates the search feature, OPTION-CTRL-C (change) lets you selectively search and replace, and CTRL-G (global) is for automatically searching and replacing.
Searching is a two-step process. First, you need to tell SpeedScript what to search for, then you trigger the actual search. Hold down OPTION and press CTRL-F. The command line prompts “Find:”. Type in what you’d like to search for, the search phrase. If you press RETURN alone without typing anything, the Find command is canceled.
When you are ready to search, press CTRL-F. SpeedScript looks for the next occurrence of the search phrase starting from the current cursor position. If you want to hunt through the entire document, press START twice to move the cursor to the very top before beginning the search. Each time you press CTRL-F, SpeedScript looks for the next occurrence of the search phrase and places the cursor at the start of the phrase. If the search fails, you’ll see the message “Not Found.”
CTRL-C works together with CTRL-F. After you’ve specified the search phrase with OPTION-CTRL-F, press OPTION-CTRL-C to select the replace phrase. (You can press RETURN alone at the “Change to:” prompt to select a null replace phrase. When you hunt and replace, this deletes the located phrase.) To search and replace manually, start by pressing CTRL-F. After SpeedScript finds the search phrase, press CTRL-C if you want to replace the phrase. If you don’t want to replace the phrase, don’t press CTRL-C. You are not in a special search and replace mode. You’re free to continue writing at any time.
CTRL-G links CTRL-F and CTRL-C together. It first asks “Find:”, then “Change to:”, then automatically searches and replaces throughout the document, starting at the cursor position.
There are a few things to watch out for when using search and replace. First, realize that if you search for the, SpeedScript finds the embedded the in words like therefore and heathen. If you changed all occurrences of the to cow, these words would become cowrefore and heacown. If you want to find a single word, include a space as the first character of the word, since almost all words are preceded by a space. Naturally, if you are replacing, you need to include the space in the replace phrase, too.
SpeedScript also distinguishes between uppercase and lowercase. The word Meldids does not match with meldids. SpeedScript will not find a capitalized word unless you capitalize it in the search phrase. To cover all bases, you will sometimes need to make two passes at replacing a word. Keep these things in mind when using CTRL-G, since you don’t have a chance to stop a global search and replace.
Just press CTRL-S to store a document. You’ll see the prompt “Save: (Device:Filename)>”. Type C: for cassette or D: plus a legal Atari filename for disk. If you use the same name as a file already on disk, that file will be replaced by the new one. CTRL-S always saves the entire document. The cursor position within the document is not important.
When the SAVE is complete, SpeedScript reports “No errors” if all is well or gives a message like “Error #144” if not. Check your DOS or BASIC manual for a list of error numbers and their causes.
To recall a previously saved document, press CTRL-L. Answer the “Load: (Device:Filename)>” prompt with the filename. Again, remember to include the C: for cassette or D: for disk. SpeedScript loads the file and should display “No errors.” Otherwise, SpeedScript reports the error number.
The position of the cursor is important before loading a file. Documents start loading at the cursor position, so be sure to press START twice or OPTION-SHIFT-CLEAR (Erase All) to move the cursor to the start of text, unless you want to merge two documents. When you press CTRL-L to load, the command line turns green to warn you if the cursor is not at the top of the document.
To merge two or more files, simply load the first file, press CTRL-Z to move the cursor to the end of the document, and then load the file you want to merge. Do not place the cursor somewhere in the middle of your document before loading. A load does not insert the text from tape or disk, but overwrites all text after the cursor position. The last character loaded becomes the new end-of-text pointer, and you cannot access any text that appears ahead of this pointer.
Since SpeedScript stores files in ASCII (American Standard Code for Information Interchange), you can load any ASCII file with SpeedScript. You could write a BASIC program with SpeedScript, save it on disk, then use ENTER to read the file from BASIC. In BASIC, you can store a program in ASCII form with LIST "D:filename" for disk or LIST "C:" for tape, ready to load with SpeedScript. You can even load files produced by most other word processors, and most other Atari word processors can read SpeedScript files. You can make full use of SpeedScript’s editing features to prepare ASCII files for the Atari Assembler/Editor, MAC/65, and most other Atari assemblers. And SpeedScript files can be transferred via modem with your favorite telecommunications program that handles ASCII.
Sometimes you forget the name of a file, or need to delete or rename a file. SpeedScript provides a unique mini-DOS for your convenience. Just press CTRL-M (menu). SpeedScript reads the entire disk directory and puts it on the screen in three columns. A large cursor shows you which file is currently selected. Use the cursor keys to move the cursor to the file you want to select. A menu at the bottom of the screen shows you what keys you need to press. Press CTRL-D to delete the selected file, R to rename, L to lock, U to unlock, or F to format the disk. You can load the selected file by pressing CTRL-L. The position of the cursor within your document is not important when loading a file from the menu—SpeedScript always erases anything you previously had in memory.
Any changes you make to the directory will not show up until you call up the directory again. Press either 1, 2, 3, or 4 to update the directory from drives 1-4. This also sets the default disk drive, the drive accessed for further changes. When you’re ready to return to writing, press either ESC or the RETURN key.
SpeedScript has a few commands that don’t do much, but are nice to have. CTRL-X exchanges the character under the cursor with the character to the right of the cursor. Thus, you can fix transposition errors with a single keystroke. CTRL-A changes the character under the cursor from uppercase to lowercase or vice versa.
Press CTRL-B to change the background and border colors. Each time you press CTRL-B, one of 128 different background colors appears. Press CTRL-T (text) to cycle between one of eight text luminances. The colors are preserved until you change them or reboot SpeedScript.
If your TV suffers from overscanning, some characters on the left or right margin may be chopped off. Atari SpeedScript lets you widen and narrow the width of the screen. Press OPTION-CTRL-+ (the cursor-left key) to decrease the width of the screen. Each time you press it, the text is reformatted, and the left and right screen margins are adjusted by one character. You can decrease the width all the way down to two characters (although if your screen overscans that much, it’s time to buy a new TV). To increase the width, to a maximum of 40 (the default width), press OPTION-CTRL-* (the cursor-right key).
One disadvantage of word-wrapping is that it’s hard to tell exactly how many spaces are at the end of a screen line. When a word too long to fit on a line is wrapped to the next line, the hole it left is filled with “false” spaces. That is, the spaces are not actually part of your text and won’t appear on paper. If you want to distinguish between true spaces and false spaces, press CTRL-O (on/of). The false spaces become tiny dots. You can write and edit in this mode if you wish, or turn off the feature by pressing CTRL-O again.
Atari SpeedScript disables the BREAK and inverse-video keys when you’re entering or editing text. The inverse-video key was disabled because it is frequently pressed by accident on the 800 and 800XL models. If you want to enter inverse-video characters, hold down SELECT while typing the keys.
Atari 400 and 800 owners will notice that the action of the CAPS/LOWR key has been changed in SpeedScript. It works like the CAPS key on the XL and XE models. Press it once to switch to uppercase, and again to switch to lowercase. In other words, the CAPS/LOWR key toggles between uppercase and lowercase. You can still use SHIFT-CAPS/LOWR to force entry to all uppercase. CTRL-CAPS/LOWR has no effect.
Pressing SYSTEM RESET returns you to SpeedScript without erasing your text when using Atari DOS. With OS/A+ DOS, SYSTEM RESET returns you to the DOS command prompt. You can get back to SpeedScript without losing any text if you type RUN at the prompt.
If you already think SpeedScript has plenty of commands, wait until you see what the printing package offers. SpeedScript supports an array of powerful formatting features. It automatically fits your text between left and right margins which you can specify. You can center a line or block it against the right margin. SpeedScript skips over the perforation on continuous-form paper, or it can wait for you to insert single-sheet paper. A line of text can be printed at the top of each page (a header) and/or at the bottom of each page (a footer), and can include automatic page numbering, starting with whatever number you like. (See page 19 for a summary of the formatting commands.)
SpeedScript can print on different lengths and widths of paper, and single-, double-, triple-, or any-spacing is easy. You can print a document as big as can fit on a tape or disk by linking several files together during printing. You can print to the screen or to a file instead of to a printer. Other features let you send special codes to the printer to control features like underlining, boldfacing, and double-width type (depending on the printer).
But with all this power comes the need to learn additional commands. Fortunately, SpeedScript sets most of these variables to a default state. If you don’t change these settings, SpeedScript assumes a left margin of 5, a right margin position of 75, no header or footer, single-spacing, and continuous-paper page feeding. You can change these default settings if you want (see below). Before printing, be sure the paper in your printer is adjusted to top-of-form (move the paper perforation just above the printing element). One additional note: Some printers incorporate an automatic skip-over-perforation feature. The printer skips to the next page when it reaches the bottom of a page. Since SpeedScript already controls paper feeding, you need to turn off this automatic skip-over-perf feature before running SpeedScript, or paging won’t work properly.
To begin printing, simply press CTRL-P. SpeedScript prompts “Print: (Device:Filename)>”. You can print to almost any device, even disk or cassette. If you enter E (for Editor), SpeedScript prints to the screen, letting you preview where lines and pages break. Enter P to Print for most printers. If your printer is attached, powered on, and selected (online), SpeedScript begins printing immediately. To cancel printing, hold down the BREAK key until printing stops. You can use CTRL-1 to pause printing. Press CTRL-1 again to continue.
If you need to print to an RS-232 printer, just print to a disk file, then boot up your DOS master disk and use the copy selection to copy the print file to the R: device. You can also write BASIC programs to read and process a printed disk file. Remember, a Print to disk is not the same as a Save to disk.
The print formatting commands must be distinguished from normal text, so they appear onscreen in inverse video with the text and background colors switched. As mentioned above, the regular inverse-video key is not used for entering inverse-video text. Instead, hold down the SELECT key while typing the format key. All lettered printer commands should be entered in lowercase (unSHIFTed). During printing, SpeedScript treats these characters as printing commands.
There are two kinds of printing commands, which we’ll call Stage 1 and Stage 2. Stage 1 commands usually control variables such as left margin and right margin. Most are followed by a number, with no space between the command and the number. Stage 1 commands are executed before a line is printed.
Stage 2 commands, like centering and underlining, are executed while the line is being printed. Usually, Stage 1 commands must be on a line of their own, although you can group several Stage 1 commands together on a line. Stage 2 commands are by nature embedded within a line of text. Again, remember to hold down SELECT to enter the boldface characters shown here.
l Left margin. Follow with a number from 0 to 255. Use 0 for no margin. Defaults to 5.
r Right margin position, a number from 1 to 255. Defaults to 75. Be sure the right margin value is greater than the left margin value, or SpeedScript will go bonkers.
t Top margin. The position at which the first line of text is printed, relative to the top of the page. Defaults to 5. The header (if any) is always printed on the first line of the page, before the first line of text.
b Bottom margin. The line at which printing stops before continuing to the next page. Standard 8-1/2 X 11 inch paper has 66 lines. Bottom margin defaults to line 58. Don’t make the bottom margin greater than the page length.
p Page length. Defaults to 66. If your printer does not print six lines per inch, multiply lines-per-inch by 11 to get the page length. European paper is usually longer than American paper—11-5/8 or 12 inches. Try a page length of 69 or 72.
s Spacing. Defaults to single-spacing. Follow with a number from 1 to 255. Use 1 for single-spacing, 2 for double-spacing, 3 for triple-spacing.
@ Start numbering at page number given. Page numbering normally starts with 1.
? Disables printing until selected page number is reached. For example, a value of 3 would start printing the third page of your document. Normally, SpeedScript starts printing with the first page.
x Sets the page width, in columns (think across). Defaults to 80. You need to change this for the sake of the centering command if you are printing in double-width or condensed type, or if you are using a 40-column or wide-carriage printer.
n Forced paging. Normally, SpeedScript prints the footer and moves on to the next page only when it has finished a page, but you can force it to continue to the next page by issuing this command. It requires no numbers.
m Margin release. Disables the left margin for the next printed line. Remember that this executes before the line is printed. It’s used for outdenting.
w Page wait. This command should be placed at the beginning of your document before any text. With page wait turned on, SpeedScript prompts you to “Insert next sheet, press RETURN” when each page is finished printing. Insert the next sheet, line it up with the printhead, then press RETURN to continue. Page wait is ignored during disk or screen output.
j Select automatic linefeeds after carriage return. Like w, this command must be placed before any text. Don’t use this command to achieve double-spacing, but only if all text prints on the same line.
i Information. This works like REM in BASIC. You follow the command with a line of text, up to 255 characters, ending in a return-mark. This line will be ignored during printing and is handy for making such notes to yourself as the filename of the document.
h Header define and enable. The header must be a single line of text (up to 254 characters) ending in a return-mark. The header prints on the first line of each page. You can include Stage 2 commands such as centering and page numbering in a header. You can use a header by itself without a footer. The header and footer should be defined at the top of your document, before any text. If you want to prevent the header from printing on the first page, put a return-mark by itself at the top of your document before the header definition.
f Footer define and enable. The footer must be a single line of text (up to 254 characters) ending in a return-mark. The footer prints two lines prior to the last line of each page. As with the header, you can include Stage 2 printing commands, and you don’t need to set the header to use a footer.
g Go to (link) next file. Put this command as the last line in your document. Follow the command with the filename, including D: for disk. After the text in memory is printed, the link command loads the next file into memory. You can continue linking in successive files, but don’t include a link in the last file. Before you start printing a linked file, make sure the first of the linked files is in memory. When printing is finished, the last file linked to will be in memory.
These commands either precede a line of text or are embedded within one.
c Centering. Put this at the beginning of a line you want to center. This will center only one line ending in a return-mark. Repeat this command at the beginning of every line you want centered. Centering uses the page-width setting (see above) to center the line properly. To center a double-width line, either set the page width to 40 or pad out the rest of the line with an equal number of spaces. If you use double-width, remember that the spaces preceding the centered text will be double-wide spaces.
e Edge right. This works in the same manner as centering, but it blocks the line flush with the right margin.
# When SpeedScript encounters this command, it prints the current page number. You usually embed this within a header or footer.
u A simple form of underlining. It works only on printers that recognize CHR$(8) as a backspace and CHR$(95) as an underline character. Underlining works on spaces, too. Use the first u to start underlining and another one to turn off underlining.
Command | Default |
---|---|
b bottom margin | 58 |
c centering | |
e edge right | |
f define footer | |
g goto linked file | |
h define header | |
i information | |
j select linefeeds | |
l left margin | 5 |
m margin release | |
n next page | |
p page length | 66 |
r right margin | 75 |
s spacing | 1 |
t top margin | 5 |
u underline toggle | |
w page wait | off |
x columns across | 80 |
# page number | |
@ starting page number | 1 |
? print starting with # | 1 |
Most dot-matrix printers are capable of more than just printing text at ten characters per inch. Some printers have several character sets, with italics and foreign language characters. Most can print in double-width (40 characters per line), condensed (132 characters per line), and in either pica or elite. Other features include programmable characters, programmable tab stops, and graphics modes. Many word processors customize themselves to a particular printer, but SpeedScript was purposely designed not to be printer-specific. Instead, SpeedScript lets you define your own Stage 2 printing commands.
You define a programmable printkey by choosing any character that is not already used for other printer commands. The entire uppercase alphabet is available for printkeys, and you can choose letters that are related to their function (like D for double-width). You enter these commands like printer commands, by holding down SELECT while you type them. The printkeys are like variables in BASIC.
To define a printkey, just hold down SELECT while you type the key you want to assign as the printkey, then an equal sign (=), and finally the ASCII value to be substituted for the printkey during printing. Now, whenever SpeedScript encounters the printkey embedded in text, it prints the character with the ASCII value you previously defined.
For example, to define the + key as the letter z, you first look up the ASCII value of z (in either your printer manual or in any Atari manual). The ASCII value of the letter z is 122, so the definition is
+=122
Gad+ooks! The +oo is +any!
Gadzooks! The zoo is zany!
More practically, here’s how you could program italics on an Epson MX-80-compatible printer. You switch on italics by sending an ESC (a character with an ASCII value of 27), then the character 4. You turn off italics by sending ESC 5. So define SHIFT-E as the escape code. Anywhere you want to print a word in italics, bracket it with printkey E, then 4, and printkey E, then 5:
The word E4italicE5 is in italics.
You can similarly define whatever codes your printer uses for features like double-width or emphasized mode. For your convenience, four of the printkeys are predefined, though you can change them. Keys 1-4 are defined as 27, 14, 15, and 18, common values for most printers. On most printers, CHR$(27) is the ESCape key, CHR$(14) starts double-width, CHR$(15) either stops double-width or starts condensed characters, and CHR$(18) usually cancels condensed characters.
SpeedScript actually lets you embed any character within text, so you may prefer to put in the actual printer codes as part of your text. To set italics, you could just press ESC twice, then 4. The ESC key appears in text as a mutant E. Double-width has a value of 14, the same value as CTRL-N. To start double-width, just embed a CTRL-N. Remember that you must press ESC before any CTRL key to get it to appear in text. CTRL keys appear as small “shadowed” capital letters. These characters, though, are counted as part of the length of a line, and excessive use within one line can result in a shorter than normal line. It can be more convenient to use the printkeys, since if you ever change printers, you have to change only the definitions of the keys.
Keep one thing in mind about printkeys: SpeedScript always assumes it is printing to a rather dumb, featureless printer, the least common denominator. SpeedScript doesn’t understand the intent of a printkey; it just sends out its value. So if you make one word within a line double-width, it may make the line overflow the specified right margin. There’s no way for SpeedScript to include built-in font and typestyle codes without being customized for a particular printer since no set of codes is universal to all printers.
It may take you awhile to fully master SpeedScript, but as you do, you’ll discover many ways to use the editing and formatting commands. For example, there is a simple way to simulate tab stops, say, for a columnar table. Just type a period at every tab stop position. Erase the line with CTRL-E, then restore it with CTRL-R multiple times. When you are filling in the table, just use word left/word right to jump quickly between the periods. Or you can use the programmable print-keys to embed your printer’s own commands for setting and jumping to tab stops.
You don’t have to change or define printer commands every time you write. Just save these definitions and load this file each time you write. You can create many custom definition files and have them ready to use on disk. You can create customized “fill-in-the-blank” letters. Just type the letter, and everywhere you’ll need to insert something, substitute a unique character, such as an * or a CTRL character. When you’re ready to customize the letter, use Find to locate each symbol and insert the specific information. Instead of typing an oft-used word or phrase, substitute a unique character, then use CTRL-G to globally change these characters into the actual word or phrase. You can even use SpeedScript as a simple filing program. Just type in all your data, flagging each field with a unique character. You can use Find to quickly locate any field.
Two program-entry aids written in BASIC are included here to make typing in SpeedScript as easy as possible. The first, “MLX,” is explained in this article. The second, “The Automatic Proofreader,” is a short program that will help you type in MLX without typing mistakes. Read the instructions for using the Automatic Proofreader later in this chapter before you type in the MLX program.
“MLX” is a new way to enter long machine language (ML) programs with a minimum of fuss. MLX lets you enter the numbers from a special list that looks similar to BASIC DATA statements. It checks your typing on a line-by-line basis. It won’t let you enter illegal characters when you should be typing numbers. It won’t let you enter numbers greater than 255 (forbidden in ML). And it won’t let you enter the wrong numbers on the wrong line. In addition, MLX creates a ready-to-use tape or disk file.
Type in and save MLX, Program 2-1 (you’ll want to use it in the future). When you’re ready to type in SpeedScript, run MLX. MLX asks you for three numbers: the starting address, the ending address, and the run/init address. These numbers for SpeedScript are
Next, you’ll be asked “Tape or Disk.” SpeedScript can be saved as either a binary file on disk or as a boot tape. Press T for use with a tape drive. If you press D for disk, you’ll be asked “Boot Disk or Binary File.” Press F to select the Binary File option. Although you could save SpeedScript as an auto-booting disk, it makes no sense, since such a disk cannot contain DOS, which is necessary for file-oriented disk access.
The screen will then show the first prompt, the number 7936 followed by a colon. Type in each three-digit number shown in the listing. You do not need to type the comma shown in the listing; MLX inserts the comma automatically. The prompt is the current line you are entering from the listing. It increases by six each time you enter a line. That’s because each line has seven numbers—six actual data numbers plus a checksum number. The checksum verifies that you typed the previous six numbers correctly. If you enter any of the six numbers wrong, or if you enter the checksum wrong, the computer rings a buzzer and prompts you to reenter the line. If you enter it correctly, a bell tone sounds and you continue to the next line.
MLX accepts only numbers as input. If you make a typing error, press the DELETE/BACK S key; the entire number is deleted. You can press it as many times as necessary back to the start of the line. If you enter three-digit numbers as listed, the computer automatically prints the comma and goes on to accept the next number. If you enter less than three digits, you can press the comma key, the space bar, or the RETURN key to advance to the next number. The checksum automatically appears in inverse video for emphasis.
When you finish typing an ML listing (assuming you type it all in one session), you can then save the completed program on tape or disk. Follow the screen instructions. If you get any errors while saving, you probably have a bad disk or the disk is full or you made a typo when entering the MLX program itself.
Fortunately, you don’t have to enter all of SpeedScript in one sitting. MLX lets you enter as much as you want, save it, and then reload the file from tape or disk later. MLX recognizes these commands:
To issue a command, hold down the CTRL key (CONTROL on the XL models) and press the indicated key. When you enter a command, MLX jumps out of the line you’ve been typing, so we recommend you do it at a new prompt. Use the Save command (CTRL-S) to save what you’ve been working on. It will save on tape or disk as if you’ve finished, but the tape or disk won’t work, of course, until you finish the typing. Remember to make a note of the address where you stop. The next time you run MLX, answer all the prompts as you did before—regardless of where you stopped typing—then insert the disk or tape. When you get to the line number prompt, press CTRL-L to reload the partly completed file into memory. Then use the New Address command to resume typing.
To use the New Address command, press CTRL-N and enter the address where you previously stopped. The prompt will change, and you can then continue typing. Always enter a New Address that matches up with one of the line numbers in the MLX-format listing, or the checksum won’t work. The Display command lets you display a section of your typing. After you press CTRL-D, enter two addresses within the line-number range of the listing. You can break out of the listing display and return to the prompt by pressing any key.
100 GRAPHICS 0:DL=PEEK(560)+256*PEEK(561)+4:POKE DL-1,71:POKE DL+2,6 110 POSITION 8,0:? "MLX":POSITION 23,0:? "failsafe entry":POKE 710,N:? 120 ? "Starting Address";:INPUT BEG:? " Ending Address";:INPUT FIN:? "Run/Init ADDRESS";:INPUT STARTADR 130 DIM A(6),BUFFER$(FIN-BEG+127),T$(20),F$(20),CIO$(7),SECTOR$(128),DSKINV$(6) 140 OPEN #1,4,0,"K:":? :? ,"Tape or Disk:"; 150 BUFFER$=CHR$(0):BUFFER$(FIN-BEG+30)=BUFFER$:BUFFER$(2)=BUFFER$:SECTOR$=BUFFER$ 160 ADDR=BEG:CIO$="hhh*LVd" 170 GET #1,MEDIA:IF MEDIA<>84 AND MEDIA<>68 THEN 170 180 ? CHR$(MEDIA):? :IF MEDIA<>ASC("T") THEN BUFFER$="":GOTO 250 190 BEG=BEG-24:BUFFER$=CHR$(0):BUFFER$(2)=CHR$(INT((FIN-BEG+127)/128)) 200 H=INT(BEG/256):L=BEG-H*256:BUFFER$(3)=CHR$(L):BUFFER$(4)=CHR$(H) 210 PINIT=BEG+8:H=INT(PINIT/256):L=PINIT-H*256:BUFFER$(5)=CHR$(L):BUFFER$(6)=CHR$(H) 220 FOR I=7 TO 24:READ A:BUFFER$(I)=CHR$(A):NEXT I:DATA 24,96,169,60,141,2,211,169,0,133,10,169,0,133,11,76,0,0 230 H=INT(STARTADR/256):L=STARTADR-H*256:BUFFER$(15)=CHR$(L):BUFFER$(19)=CHR$(H) 240 BUFFER$(23)=CHR$(L):BUFFER$(24)=CHR$(H) 250 IF MEDIA<>ASC("D") THEN 360 260 ? :? "Boot Disk or Binary File:"; 270 GET #1,DTYPE:IF DTYPE<>68 AND DTYPE<>70 THEN 270 280 ? CHR$(DTYPE):IF DTYPE=70 THEN 360 290 BEG=BEG-30:BUFFER$=CHR$(0):BUFFER$(2)=CHR$(INT((FIN-BEG+127)/128)) 300 H=INT(BEG/256):L=BEG-H*256:BUFFER$(3)=CHR$(L):BUFFER$(4)=CHR$(H) 310 PINIT=STARTADR:H=INT(PINIT/256):L=PINIT-H*256:BUFFER$(5)=CHR$(L):BUFFER$(6)=CHR$(H) 320 RESTORE 330:FOR I=7 TO 30:READ A:BUFFER$(I)=CHR$(A):NEXT I 330 DATA 169,0,141,231,2,133,14,169,0,141,232,2,133,15,169,0,133,10,169,0,133,11,24,96 340 H=INT(BEG/256):L=BEG-H*256:BUFFER$(8)=CHR$(L):BUFFER$(15)=CHR$(H) 350 H=INT(STARTADR/256):L=STARTADR-H*256:BUFFER$(22)=CHR$(L):BUFFER$(26)=CHR$(H) 360 GRAPHICS 0:POKE 712,10:POKE 710,10:POKE 709,2 370 ? ADDR;":";:FOR J=1 TO 6 380 GOSUB 570:IF N=-1 THEN J=J-1:GOTO 380 390 IF N=-19 THEN 720 400 IF N=-12 THEN LET READ=1:GOTO 720 410 TRAP 410:IF N=-14 THEN ? :? "New Address";:INPUT ADDR:? :GOTO 370 420 TRAP 32767:IF N<>-4 THEN 480 430 TRAP 430:? :? "Display:From";:INPUT F:? ,"To";:INPUT T:TRAP 32767 440 IF F<BEG OR F>FIN OR T<BEG OR T>FIN OR T<F THEN ? CHR$(253);"At least ";BEG;", Not More Than ";FIN:GOTO 430 450 FOR I=F TO T STEP 6:? :? I;":";:FOR K=0 TO 5:N=PEEK(ADR(BUFFER$)+I+K-BEG):T$="000":T$(4-LEN(STR$(N)))=STR$(N) 460 IF PEEK(764)<255 THEN GET #1,A:POP :POP :? :GOTO 370 470 ? T$;",";:NEXT K:? CHR$(126);:NEXT I:? :? :GOTO 370 480 IF N<0 THEN ? :GOTO 370 490 A(J)=N:NEXT J 500 CKSUM=ADDR-INT(ADDR/256)*256:FOR I=1 TO 6:CKSUM=CKSUM+A(I):CKSUM=CKSUM-256*(CKSUM>255):NEXT I 510 RF=128:SOUND 0,200,12,8:GOSUB 570:SOUND 0,0,0,0:RF=0:? CHR$(126) 520 IF N<>CKSUM THEN ? :? "Incorrect":GOTO 370 530 FOR W=15 TO 0 STEP -1:SOUND 0,50,10,W:NEXT W 540 FOR I=1 TO 6:POKE ADR(BUFFER$)+ADDR-BEG+I-1,A(I):NEXT I 550 ADDR=ADDR+6:IF ADDR<=FIN THEN 370 560 GOTO 710 570 N=0:Z=0 580 GET #1,A:IF A=155 OR A=44 OR A=32 THEN 670 590 IF A<32 THEN N=-A:RETURN 600 IF A<>126 THEN 630 610 GOSUB 690:IF I=1 AND T=44 THEN N=-1:? CHR$(126);:GOTO 690 620 GOTO 570 630 IF A<48 OR A>57 THEN 580 640 ? CHR$(A+RF);:N=N*10+A-48 650 IF N>255 THEN ? CHR$(253);:A=126:GOTO 600 660 Z=Z+1:IF Z<3 THEN 580 670 IF Z=0 THEN ? CHR$(253);:GOTO 570 680 ? ",";:RETURN 690 POKE 752,1:FOR I=1 TO 3:? CHR$(30);:GET #6,T:IF T<>44 AND T<>58 THEN ? CHR$(A);:NEXT I 700 POKE 752,0:? " ";CHR$(126);:RETURN 710 GRAPHICS 0:POKE 710,26:POKE 712,26:POKE 709,2 720 IF MEDIA=ASC("T") THEN 890 730 REM DISK 740 IF READ THEN ? :? "Load File":? 750 IF DTYPE<>70 THEN 1040 760 ? :? "Enter AUTORUN.SYS for automatic use":? :? "Enter filename":INPUT T$ 770 F$=T$:IF LEN(T$)>2 THEN IF T$(1,2)<>"D:" THEN F$="D:":F$(3)=T$ 780 TRAP 870:CLOSE #2:OPEN #2,8-4*READ,0,F$:? :? "Working..." 790 IF READ THEN FOR I=1 TO 6:GET #2,A:NEXT I:GOTO 820 800 PUT #2,255:PUT #2,255 810 H=INT(BEG/256):L=BEG-H*256:PUT #2,L:PUT #2,H:H=INT(FIN/256):L=FIN-H*256:PUT #2,L:PUT #2,H 820 GOSUB 970:IF PEEK(195)>1 THEN 870 830 IF STARTADR=0 OR READ THEN 850 840 PUT #2,224:PUT #2,2:PUT #2,225:PUT #2,2:H=INT(STARTADR/256):L=STARTADR-H*256:PUT #2,L:PUT #2,H 850 TRAP 32767:CLOSE #2:? "Finished.":IF READ THEN ? :? :LET READ=0:GOTO 360 860 END 870 ? "Error ";PEEK(195);" trying to access":? F$:CLOSE #2:? :GOTO 760 880 REM BOOT TAPE 890 IF READ THEN ? :? "Read Tape" 900 ? :? :? "Insert, Rewind Tape.":? "Press PLAY ";:IF NOT READ THEN ? "& RECORD" 910 ? :? "Press RETURN when ready:"; 920 TRAP 960:CLOSE #2:OPEN #2,8-4*READ,128,"C:":? :? "Working..." 930 GOSUB 970:IF PEEK(195)>1 THEN 960 940 CLOSE #2:TRAP 32767:? "Finished.":? :? :IF READ THEN LET READ=0:GOTO 360 950 END 960 ? :? "Error ";PEEK(195);" when reading/writing boot tape":? :CLOSE #2:GOTO 890 970 REM CIO Load/Save File#2 opened read=0 for write, read=1 for read 980 X=32:REM File#2,$20 990 ICCOM=834:ICBADR=836:ICBLEN=840:ICSTAT=835 1000 H=INT(ADR(BUFFER$)/256):L=ADR(BUFFER$)-H*256:POKE ICBADR+X,L:POKE ICBADR+X+1,H 1010 L=FIN-BEG+1:H=INT(L/256):L=L-H*256:POKE ICBLEN+X,L:POKE ICBLEN+X+1,H 1020 POKE ICCOM+X,11-4*READ:A=USR(ADR(CIO$),X) 1030 POKE 195,PEEK(ICSTAT):RETURN 1040 REM SECTOR I/O 1050 IF READ THEN 1100 1060 ? :? "Format Disk In Drive 1? (Y/N):"; 1070 GET #1,A:IF A<>78 AND A<>89 THEN 1070 1080 ? CHR$(A):IF A=78 THEN 1100 1090 ? :? "Formatting...":XIO 254,#2,0,0,"D:":? "Format Complete":? 1100 NR=INT((FIN-BEG+127)/128):BUFFER$(FIN-BEG+2)=CHR$(0):IF READ THEN ? "Reading...":GOTO 1120 1110 ? "Writing..." 1120 FOR I=1 TO NR:S=I 1130 IF READ THEN GOSUB 1220:BUFFER$(I*128-127)=SECTOR$:GOTO 1160 1140 SECTOR$=BUFFER$(I*128-127) 1150 GOSUB 1220 1160 IF PEEK(DSTATS)<>1 THEN 1200 1170 NEXT I 1180 IF NOT READ THEN END 1190 ? :? :LET READ=0:GOTO 360 1200 ? "Error on disk access.":? "May need formatting.":GOTO 1040 1210 REM 1220 REM SECTOR ACCESS SUBROUTINE 1230 REM Drive ONE 1240 REM Pass buffer in SECTOR$ 1250 REM sector #in variable S 1260 REM READ=1 for read, 1270 REM READ=0 for write 1280 BASE=3*256 1290 DUNIT=BASE+1:DCOMND=BASE+2:DSTATS=BASE+3 1300 DBUFLO=BASE+4:DBUFHI=BASE+5 1310 DBYTLO=BASE+8:DBYTHI=BASE+9 1320 DAUX1=BASE+10:DAUX2=BASE+11 1330 REM DIM DSKINV$(4) 1340 DSKINV$="hLS":DSKINV$(4)=CHR$(228) 1350 POKE DUNIT,1:A=ADR(SECTOR$):H=INT(A/256):L=A-256*H 1360 POKE DBUFHI,H 1370 POKE DBUFLO,L 1380 POKE DCOMND,87-5*READ 1390 POKE DAUX2,INT(S/256):POKE DAUX1,S-PEEK(DAUX2)*256 1400 A=USR(ADR(DSKINV$)) 1410 RETURN
At last there’s a way for your computer to help you check your typing. “The Automatic Proofreader” will make entering programs faster, easier, and more accurate.
The strong point of computers is that they excel at tedious, exacting tasks. So why not get your computer to check your typing for you?
“The Automatic Proofreader” will help you type in “MLX” program listings without typing mistakes. It is a short error-checking program that hides itself in memory. When activated, it lets you know immediately after typing a line from a program listing if you have made a mistake. Please read these instructions carefully before typing the MLX program.
The MLX program listing has a checksum found immediately to the left of each line number. Don’t enter the checksum when typing in a program. It is just for your information.
When you type in a line from the program listing and press RETURN, the Proofreader displays the checksum letters at the top of your screen. These checksum letters must match the checksum letters in the printed listing. If they don’t match, it means you typed the line differently from the way it is listed. Immediately recheck your typing. You can correct any mistakes you find.
The Proofreader is not picky with spaces. It will not notice extra spaces or missing ones. This is for your convenience since spacing is generally not important. But occasionally proper spacing is important, so be extra careful with spaces. The Proofreader will catch practically everything else that can go wrong. Characters in inverse video will appear like this:
INVERSE VIDEO
Due to the nature of a checksum, the Proofreader will not catch all errors. The Proofreader will not catch errors of transposition. In fact, you could type in a line in any order, and the Proofreader wouldn’t notice.
There’s another thing to watch out for: If you enter a line by using abbreviations for commands, the checksum will not match up. But there is a way to make the Proofreader check the line. After entering the line, LIST it. This eliminates the abbreviations. Then move the cursor up to the line and press RETURN. It should now match the checksum. You can check whole groups of lines this way. The only abbreviation that cannot be handled this way is when a question mark (?) is used instead of PRINT; they are not the same to the Proofreader.
100 GRAPHICS 0 110 FOR I=1536 TO 1700:READ A:POKE I,A:CK=CK+A:NEXT I 120 IF CK<>19072 THEN ? "ERROR IN DATA STATEMENTS. CHECK TYPING.":END 130 A=USR(1536) 140 ? :? "AUTOMATIC PROOFREADER NOW ACTIVATED." 150 END 1536 DATA 104,160,0,185,26,3 1542 DATA 201,69,240,7,200,200 1548 DATA 192,34,208,243,96,200 1554 DATA 169,74,153,26,3,200 1560 DATA 169,6,153,26,3,162 1566 DATA 0,189,0,228,157,74 1572 DATA 6,232,224,16,208,245 1578 DATA 169,93,141,78,6,169 1584 DATA 6,141,79,6,24,173 1590 DATA 4,228,105,1,141,95 1596 DATA 6,173,5,228,105,0 1602 DATA 141,96,6,169,0,133 1608 DATA 203,96,247,238,125,241 1614 DATA 93,6,244,241,115,241 1620 DATA 124,241,76,205,238,0 1626 DATA 0,0,0,0,32,62 1632 DATA 246,8,201,155,240,13 1638 DATA 201,32,240,7,72,24 1644 DATA 101,203,133,203,104,40 1650 DATA 96,72,152,72,138,72 1656 DATA 160,0,169,128,145,88 1662 DATA 200,192,40,208,249,165 1668 DATA 203,74,74,74,74,24 1674 DATA 105,161,160,3,145,88 1680 DATA 165,203,41,15,24,105 1686 DATA 161,200,145,88,169,0 1692 DATA 133,203,104,170,104,168 1698 DATA 104,40,96
Before you begin typing SpeedScript, you must load and run the “MLX” program. Answer the MLX prompts as follows:
7936:173,198,002,141,197,002,201 7942:032,137,037,169,203,205,021 7948:179,066,141,179,066,240,115 7954:033,032,031,037,032,080,007 7960:042,165,012,141,118,037,027 7966:165,013,141,119,037,169,162 7972:117,133,012,169,037,133,125 7978:013,169,000,141,068,002,179 7984:169,001,133,009,032,234,114 7990:037,076,072,038,000,000,021 7996:000,000,000,000,000,000,060 8002:000,000,000,000,000,000,066 8008:000,000,000,000,000,000,072 8014:000,000,000,000,000,000,078 8020:000,000,000,000,000,000,084 8026:000,000,000,000,000,000,090 8032:000,000,000,000,000,000,096 8038:000,000,000,000,000,000,102 8044:000,000,000,000,000,000,108 8050:000,000,000,000,000,000,114 8056:000,000,000,000,000,000,120 8062:000,000,000,000,000,000,126 8068:000,000,000,000,000,000,132 8074:000,000,000,000,000,000,138 8080:000,000,000,000,000,000,144 8086:000,000,000,000,000,000,150 8092:000,000,000,000,000,000,156 8098:000,000,000,000,000,000,162 8104:000,000,000,000,000,000,168 8110:000,000,000,000,000,000,174 8116:000,000,000,000,000,000,180 8122:000,000,000,000,000,000,186 8128:000,000,000,000,000,000,192 8134:000,000,000,000,000,000,198 8140:000,000,000,000,000,000,204 8146:000,000,000,000,000,000,210 8152:000,000,000,000,000,000,216 8158:000,000,000,000,000,000,222 8164:000,000,000,000,000,000,228 8170:000,000,000,000,000,000,234 8176:000,000,000,000,000,000,240 8182:000,000,000,000,000,000,246 8188:036,037,045,017,000,000,131 8194:000,000,000,000,000,000,002 8200:000,024,024,024,024,024,128 8206:000,024,000,102,102,102,088 8212:000,000,000,000,000,102,122 8218:255,102,102,255,102,000,074 8224:024,062,096,060,006,124,148 8230:024,000,000,204,216,048,018 8236:096,204,140,000,000,056,028 8242:108,056,112,222,204,118,102 8248:000,024,024,048,000,000,152 8254:000,000,000,024,048,096,230 8260:096,096,048,024,000,048,124 8266:024,012,012,012,024,048,206 8272:000,000,102,060,255,060,045 8278:102,000,000,000,024,024,236 8284:126,024,024,000,000,000,010 8290:000,000,000,048,048,096,034 8296:000,000,000,000,126,000,230 8302:000,000,000,000,000,000,110 8308:000,000,048,048,000,000,212 8314:006,012,024,048,096,192,244 8320:000,124,206,222,246,230,132 8326:198,124,000,024,056,024,048 8332:024,024,024,126,000,124,206 8338:198,012,024,048,096,254,010 8344:000,254,012,024,056,012,254 8350:198,124,000,028,060,108,164 8356:204,254,012,012,000,254,132 8362:192,252,006,006,198,124,180 8368:000,124,192,252,198,198,116 8374:198,124,000,126,006,012,136 8380:024,048,096,096,000,124,064 8386:198,198,124,198,198,124,210 8392:000,124,198,198,126,012,090 8398:024,048,000,000,048,048,118 8404:000,048,048,000,000,000,052 8410:048,048,000,048,048,096,250 8416:000,012,024,048,096,048,196 8422:024,012,000,000,000,126,136 8428:000,000,126,000,000,048,154 8434:024,012,006,012,024,048,112 8440:000,060,102,006,012,024,196 8446:000,024,000,124,198,222,054 8452:214,220,224,060,000,124,078 8458:198,198,198,254,198,198,230 8464:000,252,198,198,252,198,090 8470:198,252,000,124,198,192,218 8476:192,192,198,124,000,248,214 8482:204,198,198,198,204,248,004 8488:000,254,192,192,252,192,098 8494:192,254,000,254,192,192,106 8500:252,192,192,192,000,124,236 8506:198,192,222,198,198,124,166 8512:000,198,198,198,254,198,086 8518:198,198,000,126,024,024,128 8524:024,024,024,126,000,062,080 8530:012,012,012,012,204,120,198 8536:000,198,204,216,240,216,138 8542:204,198,000,192,192,192,048 8548:192,192,192,254,000,198,104 8554:238,254,214,198,198,198,126 8560:000,198,230,246,254,222,238 8566:206,198,000,124,198,198,018 8572:198,198,198,124,000,252,070 8578:198,198,198,252,192,192,080 8584:000,124,198,198,198,222,052 8590:124,014,000,252,198,198,160 8596:252,216,204,198,000,124,118 8602:198,192,124,006,198,124,228 8608:000,126,024,024,024,024,126 8614:024,024,000,198,198,198,040 8620:198,198,198,124,000,198,064 8626:198,198,198,198,108,056,110 8632:000,198,198,198,214,254,222 8638:238,198,000,198,198,108,106 8644:056,108,198,198,000,102,090 8650:102,102,060,024,024,024,026 8656:000,254,012,024,048,096,130 8662:192,254,000,030,024,024,226 8668:024,024,024,030,000,064,130 8674:096,048,024,012,006,000,156 8680:000,240,048,048,048,048,152 8686:048,240,000,008,028,054,104 8692:099,000,000,000,000,000,087 8698:000,000,000,000,000,255,249 8704:000,000,000,000,000,000,000 8710:000,000,124,194,153,153,118 8716:129,153,153,230,252,130,035 8722:153,130,153,153,131,252,222 8728:124,194,153,158,158,153,196 8734:194,124,252,130,153,153,012 8740:153,153,130,252,254,130,084 8746:158,132,156,158,130,254,006 8752:126,193,206,194,206,204,153 8758:204,120,124,194,153,158,239 8764:145,153,194,124,246,153,051 8770:153,129,153,153,153,246,029 8776:127,097,115,050,050,115,114 8782:097,127,062,050,050,050,002 8788:050,114,198,124,230,153,185 8794:146,132,146,153,153,230,026 8800:120,076,076,076,076,078,086 8806:066,124,230,153,129,129,165 8812:137,153,153,230,230,153,140 8818:137,129,145,153,153,230,037 8824:124,194,153,153,153,153,026 8830:194,124,254,195,201,201,015 8836:195,206,200,240,124,194,011 8842:153,153,153,146,201,118,038 8848:124,194,201,201,194,201,235 8854:201,247,126,195,158,194,247 8860:249,153,195,126,254,194,047 8866:102,100,100,100,100,124,020 8872:246,153,153,153,153,153,155 8878:194,124,230,153,153,153,157 8884:153,194,100,056,246,153,058 8890:153,153,137,129,153,246,133 8896:230,153,153,194,153,153,204 8902:153,230,230,153,153,195,032 8908:230,100,100,124,254,193,181 8914:249,050,228,206,193,254,110 8920:120,096,120,096,126,024,030 8926:030,000,000,024,060,126,206 8932:024,024,024,000,000,024,068 8938:024,024,126,060,024,000,236 8944:000,000,000,012,012,088,096 8950:112,120,000,024,012,126,128 8956:012,024,000,000,000,000,032 8962:024,060,126,126,060,024,166 8968:000,000,000,124,006,126,008 8974:198,126,000,000,192,252,014 8980:198,198,198,252,000,000,098 8986:000,124,198,192,198,124,094 8992:000,000,006,126,198,198,048 8998:198,126,000,000,000,124,230 9004:198,254,192,124,000,000,044 9010:062,096,252,096,096,096,236 9016:006,252,000,126,198,198,068 9022:198,126,000,000,192,192,002 9028:252,198,198,198,000,000,146 9034:024,000,056,024,024,060,006 9040:024,240,024,000,024,024,160 9046:024,024,000,000,192,204,018 9052:216,248,204,198,000,000,190 9058:056,024,024,024,024,060,054 9064:000,000,000,204,254,254,048 9070:214,198,000,000,000,252,006 9076:198,198,198,198,000,000,140 9082:000,124,198,198,198,124,196 9088:192,192,000,252,198,198,136 9094:198,252,006,006,000,126,210 9100:198,198,198,126,000,000,092 9106:000,252,198,192,192,192,148 9112:000,000,000,126,192,124,082 9118:006,252,000,000,048,254,206 9124:048,048,048,030,000,000,082 9130:000,198,198,198,198,126,064 9136:000,000,000,198,198,198,002 9142:108,056,000,000,000,198,032 9148:214,254,124,108,000,000,120 9154:000,198,108,056,108,198,094 9160:006,252,000,198,198,198,028 9166:198,126,000,000,000,254,016 9172:012,056,096,254,014,000,132 9178:014,024,024,056,024,024,128 9184:024,024,024,024,024,024,112 9190:024,024,112,000,112,024,014 9196:024,028,024,024,000,000,080 9202:000,008,024,056,024,008,106 9208:000,000,000,016,016,024,048 9214:028,024,000,000,000,000,050 9220:000,000,000,000,000,000,004 9226:000,000,000,000,000,000,010 9232:165,128,141,048,036,165,187 9238:129,141,049,036,165,130,160 9244:141,051,036,165,131,141,181 9250:052,036,166,133,240,032,181 9256:169,000,141,115,063,160,176 9262:000,185,255,255,153,255,125 9268:255,200,204,115,063,208,073 9274:244,238,049,036,238,052,147 9280:036,224,000,240,007,202,005 9286:208,224,165,132,208,222,205 9292:096,165,133,170,005,132,009 9298:208,001,096,024,138,101,138 9304:129,141,120,036,165,128,039 9310:141,119,036,024,138,101,141 9316:131,141,123,036,165,130,058 9322:141,122,036,232,164,132,165 9328:208,004,240,013,160,255,224 9334:185,255,255,153,255,255,196 9340:136,192,255,208,245,206,086 9346:120,036,206,123,036,202,085 9352:208,234,096,169,040,200,059 9358:024,109,108,068,024,101,064 9364:088,133,136,165,089,105,096 9370:000,133,137,024,173,111,220 9376:063,133,138,173,112,063,074 9382:133,139,162,001,173,114,120 9388:063,133,145,160,000,177,082 9394:138,153,123,063,200,041,128 9400:127,201,094,240,022,204,048 9406:107,068,208,239,136,177,101 9412:138,041,127,201,000,240,175 9418:007,136,208,245,172,107,053 9424:068,136,200,132,140,160,020 9430:000,185,123,063,145,136,098 9436:200,196,140,208,246,024,210 9442:152,101,138,133,138,165,029 9448:139,105,000,133,139,224,204 9454:001,208,003,140,110,063,251 9460:204,107,068,240,008,169,016 9466:064,145,136,200,076,244,091 9472:036,024,165,136,105,040,250 9478:133,136,144,002,230,137,020 9484:232,224,019,240,003,076,038 9490:175,036,165,138,141,121,026 9496:063,165,139,141,122,063,205 9502:096,173,102,063,133,138,223 9508:141,111,063,141,117,063,160 9514:133,134,173,103,063,133,013 9520:139,141,112,063,141,118,250 9526:063,133,135,056,173,105,207 9532:063,237,103,063,170,169,097 9538:000,160,255,198,139,145,195 9544:138,200,230,139,145,138,038 9550:200,208,251,230,139,202,028 9556:208,246,145,138,096,133,026 9562:140,132,141,169,001,141,046 9568:240,002,160,000,177,140,047 9574:240,006,032,127,047,200,242 9580:208,246,096,032,204,047,173 9586:240,251,096,032,064,021,050 9592:173,106,068,240,006,160,105 9598:000,165,144,145,134,032,234 9604:234,037,076,072,038,169,246 9610:125,032,127,047,169,000,126 9616:141,114,063,141,102,063,000 9622:141,104,063,141,106,063,000 9628:141,108,063,141,245,063,149 9634:141,020,064,141,182,067,009 9640:141,190,002,141,108,068,050 9646:169,040,141,107,068,169,100 9652:068,024,105,001,141,103,110 9658:063,173,049,002,056,233,250 9664:001,141,109,063,056,233,027 9670:008,141,107,063,056,233,038 9676:001,141,105,063,169,255,170 9682:141,243,063,165,075,240,113 9688:016,173,109,063,141,105,055 9694:063,169,007,141,107,063,004 9700:169,030,141,109,063,096,068 9706:032,173,045,173,102,063,054 9712:133,134,173,103,063,133,211 9718:135,032,139,036,032,010,118 9724:038,169,152,160,061,032,096 9730:089,037,238,113,063,076,106 9736:207,039,032,026,038,169,007 9742:136,160,061,032,089,037,017 9748:169,000,141,113,063,096,090 9754:160,039,169,000,145,088,115 9760:136,016,251,169,000,133,225 9766:082,133,085,133,084,096,139 9772:072,041,128,133,140,104,150 9778:041,127,201,096,176,013,192 9784:201,032,176,006,024,105,088 9790:064,076,069,038,056,233,086 9796:032,005,140,096,160,000,245 9802:140,106,068,177,134,133,064 9808:144,160,000,140,184,067,007 9814:177,134,073,128,145,134,109 9820:173,106,068,073,001,141,142 9826:106,068,032,139,036,032,255 9832:204,047,208,040,169,008,012 9838:141,031,208,173,031,208,134 9844:201,006,208,015,160,000,194 9850:140,106,068,165,144,145,122 9856:134,032,161,043,076,072,134 9862:038,165,020,041,016,240,142 9868:218,169,000,133,020,076,244 9874:081,038,170,169,008,141,241 9880:031,208,173,031,208,201,236 9886:005,208,005,169,128,141,046 9892:184,067,160,000,165,144,116 9898:145,134,173,113,063,240,014 9904:007,138,072,032,010,038,217 9910:104,170,138,201,155,208,134 9916:005,162,030,076,226,038,213 9922:138,044,182,067,048,026,187 9928:201,156,176,102,041,127,235 9934:201,032,144,096,201,123,235 9940:176,092,201,092,240,088,077 9946:201,094,240,084,201,095,109 9952:240,080,138,072,160,000,146 9958:140,182,067,177,134,201,107 9964:094,240,005,173,114,063,157 9970:240,003,032,124,044,104,021 9976:032,044,038,041,127,013,031 9982:184,067,160,000,145,134,176 9988:032,139,036,056,165,134,054 9994:237,117,063,133,140,165,097 10000:135,237,118,063,005,140,202 10006:144,014,165,134,105,000,072 10012:141,117,063,165,135,105,242 10018:000,141,118,063,230,134,208 10024:208,002,230,135,032,207,086 10030:039,076,072,038,174,083,016 10036:039,221,083,039,240,006,168 10042:202,208,248,076,072,038,134 10048:202,138,010,170,169,038,023 10054:072,169,071,072,189,120,251 10060:039,072,189,119,039,072,094 10066:096,035,031,030,092,094,204 10072:002,020,028,029,126,255,036 10078:004,009,125,124,095,005,200 10084:012,019,013,018,024,026,212 10090:016,254,001,011,006,021,159 10096:127,157,003,007,156,027,077 10102:015,132,040,183,040,236,252 10108:040,034,041,130,041,138,036 10114:041,154,041,000,042,049,201 10120:043,123,044,091,043,225,193 10126:044,001,045,048,045,081,150 10132:045,050,046,056,053,092,234 10138:052,186,049,124,054,016,123 10144:055,102,041,189,055,076,166 10150:043,032,055,079,042,132,037 10156:059,109,061,083,044,075,091 10162:044,047,060,099,059,216,191 10168:043,188,039,197,039,173,095 10174:182,067,073,128,141,182,195 10180:067,096,173,004,034,073,131 10186:016,141,004,034,096,032,013 10192:045,040,056,165,134,237,117 10198:111,063,165,135,237,112,013 10204:063,176,032,056,173,111,063 10210:063,237,102,063,133,140,196 10216:173,112,063,237,103,063,215 10222:005,140,240,013,165,134,167 10228:141,111,063,165,135,141,232 10234:112,063,032,139,036,056,176 10240:173,121,063,229,134,133,085 10246:138,173,122,063,229,135,098 10252:133,139,005,138,240,002,157 10258:176,024,024,173,111,063,077 10264:109,110,063,141,111,063,109 10270:173,112,063,105,000,141,112 10276:112,063,032,139,036,076,238 10282:255,039,096,056,173,117,010 10288:063,237,104,063,133,140,020 10294:173,118,063,237,105,063,045 10300:005,140,144,012,173,104,126 10306:063,141,117,063,173,105,216 10312:063,141,118,063,056,165,166 10318:134,237,102,063,133,140,119 10324:165,135,237,103,063,005,024 10330:140,176,011,173,102,063,243 10336:133,134,173,103,063,133,067 10342:135,096,056,165,134,237,157 10348:117,063,133,140,165,135,093 10354:237,118,063,005,140,176,085 10360:001,096,173,117,063,133,191 10366:134,173,118,063,133,135,114 10372:096,169,008,141,031,208,017 10378:173,031,208,201,003,208,194 10384:030,173,107,068,201,040,251 10390:240,020,238,107,068,238,037 10396:107,068,206,108,068,032,233 10402:139,036,032,207,039,169,016 10408:125,032,127,047,076,010,073 10414:038,230,134,208,002,230,248 10420:135,076,207,039,169,008,046 10426:141,031,208,173,031,208,210 10432:201,003,208,030,173,107,146 10438:068,201,002,240,020,206,167 10444:107,068,206,107,068,238,230 10450:108,068,032,139,036,032,113 10456:207,039,169,125,032,127,147 10462:047,076,010,038,165,134,180 10468:208,002,198,135,198,134,079 10474:076,207,039,165,134,133,220 10480:138,165,135,133,139,198,124 10486:139,160,255,177,138,201,036 10492:000,240,004,201,094,208,231 10498:003,136,208,243,177,138,139 10504:201,000,240,008,201,094,240 10510:240,004,136,208,243,096,173 10516:056,152,101,138,133,134,222 10522:165,139,105,000,133,135,191 10528:076,207,039,160,000,177,179 10534:134,201,000,240,008,201,054 10540:094,240,004,200,208,243,009 10546:096,200,208,011,230,135,162 10552:165,135,205,118,063,144,118 10558:002,208,025,177,134,201,041 10564:000,240,236,201,094,240,055 10570:232,024,152,101,134,133,082 10576:134,165,135,105,000,133,240 10582:135,076,207,039,173,117,065 10588:063,133,134,173,118,063,008 10594:133,135,076,207,039,169,089 10600:000,141,111,063,173,118,198 10606:063,056,233,004,205,103,006 10612:063,176,003,173,103,063,185 10618:141,112,063,032,139,036,133 10624:076,090,041,238,138,041,240 10630:238,138,041,096,008,238,125 10636:154,041,238,154,041,173,173 10642:154,041,041,015,141,154,180 10648:041,096,002,165,134,133,211 10654:138,165,135,133,139,198,042 10660:139,160,255,177,138,201,210 10666:014,240,012,201,001,240,110 10672:008,201,031,240,004,201,093 10678:094,208,004,136,208,235,043 10684:096,177,138,201,014,240,030 10690:027,201,001,240,023,201,119 10696:031,240,019,201,094,240,001 10702:015,136,208,235,198,139,113 10708:165,139,205,102,063,176,038 10714:226,076,244,041,132,140,053 10720:198,140,200,240,010,177,165 10726:138,201,000,240,247,136,168 10732:076,020,041,164,140,076,241 10738:189,041,173,102,063,133,175 10744:134,173,103,063,133,135,221 10750:076,207,039,160,000,177,145 10756:134,201,014,240,029,201,055 10762:001,240,025,201,031,240,236 10768:021,201,094,240,017,200,021 10774:208,235,230,135,165,135,106 10780:205,118,063,240,226,144,000 10786:224,076,090,041,200,208,105 10792:014,230,135,165,135,205,156 10798:118,063,144,005,240,003,107 10804:076,090,041,177,134,201,003 10810:000,240,233,201,014,240,218 10816:229,201,001,240,225,201,137 10822:031,240,221,201,094,240,073 10828:217,076,075,041,173,106,252 10834:063,141,209,063,173,107,070 10840:063,141,210,063,032,026,111 10846:038,169,172,160,061,032,214 10852:089,037,169,001,141,113,138 10858:063,096,056,165,134,237,089 10864:102,063,133,140,165,135,082 10870:237,103,063,005,140,208,106 10876:003,104,104,096,165,134,218 10882:133,128,165,135,133,129,185 10888:096,056,165,134,133,130,082 10894:073,255,101,128,141,213,029 10900:063,165,135,133,131,073,080 10906:255,101,129,141,214,063,033 10912:165,128,141,215,063,165,013 10918:129,141,216,063,165,130,242 10924:141,217,063,133,128,165,251 10930:131,141,218,063,133,129,225 10936:056,173,214,063,109,210,241 10942:063,205,109,063,144,016,022 10948:032,026,038,169,187,160,040 10954:061,032,089,037,169,001,079 10960:141,113,063,096,173,209,235 10966:063,133,130,173,210,063,218 10972:133,131,173,213,063,133,042 10978:132,024,109,209,063,141,136 10984:209,063,173,214,063,133,063 10990:133,109,210,063,141,210,080 10996:063,032,016,036,173,215,011 11002:063,133,128,173,216,063,002 11008:133,129,173,217,063,133,080 11014:130,173,218,063,133,131,086 11020:056,173,117,063,229,130,012 11026:133,132,173,118,063,229,098 11032:131,133,133,032,016,036,249 11038:056,173,117,063,237,213,121 11044:063,141,117,063,173,118,199 11050:063,237,214,063,141,118,110 11056:063,096,032,108,042,032,165 11062:184,040,032,137,042,056,033 11068:173,209,063,233,001,141,112 11074:209,063,173,210,063,233,249 11080:000,141,210,063,096,032,102 11086:133,040,032,108,042,032,209 11092:184,040,032,137,042,076,083 11098:059,043,032,080,042,169,003 11104:050,133,145,032,026,038,008 11110:169,199,160,061,032,089,044 11116:037,032,111,037,072,032,173 11122:010,038,104,041,095,009,155 11128:064,201,087,208,009,032,209 11134:108,042,032,237,040,076,149 11140:137,042,201,083,208,009,044 11146:032,108,042,032,155,041,036 11152:076,137,042,201,080,208,120 11158:009,032,108,042,032,082,199 11164:045,076,137,042,096,056,096 11170:165,134,237,111,063,133,237 11176:140,165,135,237,112,063,252 11182:005,140,240,026,173,111,101 11188:063,133,134,173,112,063,090 11194:133,135,169,000,133,020,008 11200:141,031,208,165,020,201,190 11206:030,208,250,076,207,039,240 11212:173,102,063,133,134,173,214 11218:103,063,133,135,076,188,140 11224:043,165,134,133,138,133,194 11230:130,165,135,133,139,133,033 11236:131,160,000,177,138,201,011 11242:000,208,030,200,208,247,103 11248:165,139,205,118,063,144,050 11254:015,173,117,063,133,138,117 11260:173,118,063,133,139,160,014 11266:000,076,011,044,230,139,246 11272:076,231,043,024,152,101,123 11278:138,133,128,169,000,101,171 11284:139,133,129,056,173,117,255 11290:063,229,130,133,132,173,118 11296:118,063,229,131,133,133,071 11302:056,165,128,229,130,141,119 11308:213,063,165,129,229,131,206 11314:141,214,063,032,016,036,040 11320:056,173,117,063,237,213,147 11326:063,141,117,063,173,118,225 11332:063,237,214,063,141,118,136 11338:063,096,169,255,141,238,012 11344:063,076,102,044,169,005,027 11350:141,238,063,032,102,044,194 11356:177,134,201,000,208,001,045 11362:200,076,075,041,169,000,147 11368:141,239,063,032,146,044,001 11374:169,000,174,238,063,160,146 11380:000,145,134,200,202,208,237 11386:250,096,169,001,141,238,249 11392:063,169,000,141,239,063,035 11398:032,146,044,169,000,160,173 11404:000,145,134,076,207,039,229 11410:024,173,117,063,109,238,102 11416:063,173,118,063,109,239,149 11422:063,205,105,063,144,005,231 11428:104,104,076,225,044,024,229 11434:165,134,133,128,109,238,053 11440:063,133,130,165,135,133,167 11446:129,109,239,063,133,131,218 11452:056,173,117,063,229,128,186 11458:133,132,173,118,063,229,018 11464:129,133,133,032,077,036,228 11470:024,173,117,063,109,238,162 11476:063,141,117,063,173,118,119 11482:063,109,239,063,141,118,183 11488:063,096,173,114,063,073,038 11494:116,141,114,063,096,169,161 11500:214,160,061,032,089,037,061 11506:032,204,047,041,127,240,165 11512:249,201,125,240,245,041,069 11518:223,201,089,096,169,008,016 11524:141,031,208,173,031,208,028 11530:201,003,240,001,096,169,208 11536:050,133,145,032,026,038,184 11542:169,237,160,061,032,089,002 11548:037,032,235,044,240,003,107 11554:076,010,038,162,250,154,212 11560:032,031,037,032,234,037,187 11566:076,072,038,160,000,177,057 11572:134,201,094,240,017,200,170 11578:208,247,230,135,165,135,154 11584:205,118,063,144,238,240,048 11590:236,076,090,041,200,208,153 11596:002,230,135,076,075,041,123 11602:165,134,133,138,165,135,184 11608:133,139,198,139,160,255,088 11614:177,138,201,094,240,017,193 11620:136,192,255,208,245,198,054 11626:139,165,139,205,103,063,152 11632:176,236,076,244,041,056,173 11638:152,101,138,133,138,169,181 11644:000,101,139,133,139,056,180 11650:165,138,229,134,133,140,045 11656:165,139,229,135,005,140,181 11662:208,018,132,140,024,165,061 11668:138,229,140,133,138,165,067 11674:139,233,000,133,139,076,106 11680:100,045,165,138,133,134,107 11686:165,139,133,135,076,207,253 11692:039,169,064,141,014,212,043 11698:169,010,141,000,002,169,157 11704:046,141,001,002,173,048,083 11710:002,133,140,173,049,002,177 11716:133,141,160,000,185,238,029 11722:045,145,140,200,192,028,184 11728:208,246,160,004,165,088,055 11734:145,140,165,089,200,145,074 11740:140,160,026,165,140,145,228 11746:140,165,141,200,145,140,133 11752:169,192,141,014,212,096,032 11758:112,112,112,195,000,000,001 11764:003,003,003,003,003,003,006 11770:003,003,003,003,003,003,012 11776:003,003,003,003,003,003,018 11782:016,065,000,000,072,173,076 11788:138,041,141,010,212,141,183 11794:024,208,141,200,002,173,254 11800:154,041,141,023,208,165,244 11806:145,141,198,002,169,010,183 11812:141,197,002,169,032,141,206 11818:244,002,169,000,141,182,012 11824:002,104,064,169,008,141,024 11830:031,208,173,031,208,201,138 11836:003,240,003,032,080,042,204 11842:032,026,038,169,252,160,231 11848:061,032,089,037,160,000,195 11854:177,134,073,128,145,134,101 11860:032,139,036,160,000,177,116 11866:134,073,128,145,134,169,105 11872:050,133,145,032,111,037,092 11878:041,095,009,064,201,087,087 11884:208,009,032,151,046,032,074 11890:035,041,076,166,046,201,167 11896:083,208,009,032,151,046,137 11902:032,001,042,076,166,046,233 11908:201,080,208,009,032,151,045 11914:046,032,049,045,076,166,040 11920:046,032,207,039,076,010,042 11926:038,165,134,133,130,141,123 11932:203,063,165,135,133,131,218 11938:141,204,063,096,056,165,119 11944:134,133,128,237,203,063,042 11950:141,213,063,165,135,133,000 11956:129,237,204,063,141,214,144 11962:063,032,160,042,173,203,091 11968:063,133,134,173,204,063,194 11974:133,135,032,139,036,076,237 11980:076,046,169,039,229,085,080 11986:141,119,063,160,000,140,065 11992:120,063,140,240,002,169,182 11998:032,032,127,047,169,126,243 12004:032,127,047,140,120,063,245 12010:032,111,037,172,120,063,001 12016:044,182,067,048,057,201,071 12022:027,208,011,169,128,141,162 12028:182,067,141,162,002,076,114 12034:231,046,201,155,240,069,176 12040:201,126,208,015,136,016,198 12046:004,200,076,231,046,169,228 12052:126,032,127,047,076,231,147 12058:046,133,140,041,127,201,202 12064:032,144,196,201,125,176,138 12070:192,204,119,063,240,187,019 12076:165,140,041,127,162,008,175 12082:142,031,208,174,031,208,076 12088:224,005,208,002,009,128,120 12094:153,163,063,032,127,047,135 12100:169,000,141,182,067,200,059 12106:076,231,046,162,001,142,220 12112:240,002,169,000,153,163,039 12118:063,152,096,162,000,169,216 12124:012,141,066,003,032,086,176 12130:228,162,000,169,153,141,183 12136:068,003,169,047,141,069,089 12142:003,169,002,141,072,003,244 12148:142,073,003,169,003,157,151 12154:066,003,076,086,228,140,209 12160:203,047,162,000,142,072,242 12166:003,142,073,003,142,255,240 12172:002,160,011,140,066,003,010 12178:032,086,228,172,203,047,146 12184:096,069,058,160,128,076,227 12190:162,047,160,000,140,104,003 12196:068,134,212,133,213,032,188 12202:170,217,032,230,216,160,171 12208:000,177,243,072,041,127,068 12214:044,104,068,048,006,032,228 12220:127,047,076,196,047,032,201 12226:098,055,104,048,003,200,190 12232:208,231,096,018,173,252,154 12238:002,201,255,208,003,169,020 12244:000,096,173,252,002,201,168 12250:255,240,249,141,109,068,000 12256:169,255,141,252,002,133,152 12262:017,032,041,048,173,109,138 12268:068,201,192,176,016,041,162 12274:063,201,060,208,024,173,203 12280:109,068,041,064,240,006,008 12286:141,190,002,169,000,096,084 12292:173,190,002,073,064,141,135 12298:190,002,169,000,096,174,129 12304:109,068,189,064,048,044,026 12310:190,002,080,010,201,097,090 12316:144,006,201,123,176,002,168 12322:041,223,201,128,240,217,060 12328:096,072,169,050,141,000,056 12334:210,162,175,142,001,210,178 12340:160,128,136,208,253,202,115 12346:224,159,208,243,104,096,068 12352:108,106,059,128,128,107,188 12358:043,042,111,128,112,117,111 12364:155,105,045,061,118,128,176 12370:099,128,128,098,120,122,009 12376:052,128,051,054,027,053,197 12382:050,049,044,032,046,110,169 12388:128,109,047,128,114,128,242 12394:101,121,127,116,119,113,035 12400:057,128,048,055,126,056,070 12406:060,062,102,104,100,128,162 12412:130,103,115,097,076,074,207 12418:058,128,128,075,092,094,193 12424:079,128,080,085,155,073,224 12430:095,124,086,128,067,128,002 12436:128,066,088,090,036,128,172 12442:035,038,027,037,034,033,102 12448:091,032,093,078,128,077,147 12454:063,128,082,128,069,089,213 12460:159,084,087,081,040,128,239 12466:041,039,156,064,125,157,248 12472:070,072,068,128,131,071,212 12478:083,065,012,010,123,128,099 12484:128,011,030,031,015,128,027 12490:016,021,155,009,028,029,204 12496:022,128,003,128,128,002,107 12502:024,026,128,128,133,128,013 12508:027,128,253,128,000,032,020 12514:096,014,128,013,128,128,221 12520:018,128,005,025,158,020,074 12526:023,017,128,128,128,128,022 12532:254,128,125,255,006,008,252 12538:004,128,132,007,019,001,029 12544:032,132,049,162,112,169,144 12550:122,157,068,003,169,062,075 12556:157,069,003,169,005,157,060 12562:072,003,169,000,157,073,236 12568:003,169,006,157,074,003,180 12574:169,003,157,066,003,032,204 12580:086,228,048,092,169,000,147 12586:141,103,068,174,103,068,187 12592:165,100,157,229,067,165,163 12598:101,157,230,067,238,103,182 12604:068,238,103,068,032,169,226 12610:049,048,063,201,043,176,134 12616:075,032,127,047,032,169,042 12622:049,048,051,169,000,141,024 12628:105,068,032,169,049,048,043 12634:041,032,127,047,238,105,168 12640:068,173,105,068,201,008,207 12646:208,008,169,046,032,127,180 12652:047,076,086,049,201,011,066 12658:208,226,169,005,133,140,227 12664:032,169,049,198,140,165,105 12670:140,208,247,076,045,049,123 12676:162,112,169,012,157,066,042 12682:003,032,086,228,162,112,249 12688:188,067,003,096,072,169,227 12694:155,032,127,047,104,032,135 12700:127,047,032,169,049,048,116 12706:225,032,127,047,076,158,059 12712:049,162,112,169,000,157,049 12718:072,003,157,073,003,169,139 12724:007,157,066,003,076,086,063 12730:228,032,255,053,032,089,107 12736:047,032,255,053,169,001,237 12742:141,240,002,133,082,169,197 12748:125,032,127,047,032,000,055 12754:049,032,239,051,173,229,215 12760:067,133,136,173,230,067,254 12766:133,137,169,000,141,228,006 12772:067,206,103,068,206,103,213 12778:068,032,227,051,032,111,243 12784:037,162,001,142,240,002,056 12790:174,025,050,201,097,144,169 12796:002,041,095,133,140,221,116 12802:025,050,240,006,202,208,221 12808:248,076,242,050,202,138,196 12814:010,170,189,042,050,072,035 12820:189,041,050,072,096,015,227 12826:030,031,028,029,004,082,230 12832:076,085,070,049,050,051,157 12838:052,027,012,070,050,083,076 12844:050,112,050,129,050,228,151 12850:050,007,051,247,050,255,198 12856:050,084,051,110,051,110,000 12862:051,110,051,110,051,152,075 12868:051,118,051,032,227,051,086 12874:174,228,067,240,031,202,248 12880:202,076,097,050,032,227,252 12886:051,174,228,067,232,232,046 12892:236,103,068,176,013,142,062 12898:228,067,189,229,067,133,243 12904:136,189,230,067,133,137,228 12910:076,235,049,032,227,051,012 12916:173,228,067,201,006,144,167 12922:243,056,233,006,170,076,138 12928:097,050,032,227,051,173,246 12934:228,067,024,105,006,205,001 12940:103,068,176,222,170,076,187 12946:097,050,162,000,189,122,254 12952:062,157,187,067,232,224,057 12958:003,208,245,160,001,177,184 12964:136,041,127,032,056,055,099 12970:201,032,240,004,157,187,223 12976:067,232,200,192,013,208,064 12982:236,189,186,067,201,046,083 12988:208,001,202,142,227,067,011 12994:169,000,157,187,067,096,102 13000:162,112,157,066,003,173,105 13006:227,067,157,072,003,169,133 13012:000,157,073,003,169,187,033 13018:157,068,003,169,067,157,071 13024:069,003,076,086,228,032,206 13030:148,050,169,033,032,200,094 13036:050,016,003,076,182,051,102 13042:032,227,051,076,235,049,144 13048:032,148,050,169,035,076,246 13054:234,050,032,148,050,169,169 13060:036,076,234,050,032,170,090 13066:051,169,079,160,063,032,052 13072:089,037,169,064,141,190,194 13078:002,032,206,046,169,000,221 13084:141,190,002,173,120,063,205 13090:240,043,032,148,050,162,197 13096:000,172,227,067,169,044,207 13102:153,187,067,200,189,163,237 13108:063,153,187,067,200,232,186 13114:236,120,063,208,243,140,044 13120:227,067,169,000,153,187,099 13126:067,032,239,051,169,032,148 13132:076,234,050,032,239,051,246 13138:076,242,050,032,170,051,191 13144:169,090,160,063,032,089,179 13150:037,032,235,044,208,235,117 13156:032,239,051,032,148,050,140 13162:169,254,076,234,050,165,030 13168:140,141,123,062,076,187,073 13174:049,162,112,142,185,067,067 13180:169,004,157,074,003,169,188 13186:000,133,142,133,143,032,201 13192:148,050,169,003,032,200,226 13198:050,048,037,032,031,037,121 13204:032,126,053,048,029,162,086 13210:250,154,169,125,032,127,243 13216:047,032,173,045,032,010,243 13222:038,076,072,038,169,022,069 13228:133,084,169,157,032,127,106 13234:047,076,127,047,140,236,083 13240:063,032,132,049,032,170,150 13246:051,169,050,160,062,032,202 13252:089,037,174,236,063,169,196 13258:000,032,160,047,169,253,095 13264:032,127,047,169,108,160,083 13270:062,032,089,037,032,111,065 13276:037,032,239,051,076,242,129 13282:050,160,012,177,136,073,066 13288:128,145,136,136,016,247,016 13294:096,032,170,051,169,000,244 13300:160,063,032,089,037,173,030 13306:123,062,076,127,047,169,086 13312:000,141,183,067,076,012,223 13318:052,169,128,141,183,067,234 13324:173,102,063,133,138,173,026 13330:103,063,133,139,076,038,058 13336:052,169,000,141,183,067,124 13342:165,134,133,138,165,135,132 13348:133,139,056,173,118,063,206 13354:229,139,170,232,160,000,204 13360:177,138,044,183,067,048,193 13366:015,201,155,208,005,169,039 13372:094,076,082,052,032,044,184 13378:038,076,082,052,201,094,097 13384:208,005,169,155,076,082,255 13390:052,032,056,055,145,138,044 13396:200,208,217,230,139,202,000 13402:208,212,096,032,026,038,190 13408:169,026,160,062,032,089,122 13414:037,169,008,032,235,052,123 13420:048,064,032,007,052,162,217 13426:112,173,102,063,157,068,021 13432:003,173,103,063,157,069,176 13438:003,056,173,117,063,237,007 13444:102,063,157,072,003,173,190 13450:118,063,237,103,063,157,111 13456:073,003,169,011,157,066,111 13462:003,032,086,228,048,011,046 13468:032,255,051,032,132,049,195 13474:048,010,076,232,053,152,221 13480:072,032,255,051,104,168,082 13486:192,128,240,033,152,072,223 13492:169,125,032,127,047,169,081 13498:050,160,062,032,089,037,104 13504:104,170,169,000,032,160,059 13510:047,032,224,052,032,173,246 13516:045,169,001,141,113,063,224 13522:096,032,026,038,169,058,117 13528:160,062,032,089,037,076,160 13534:199,052,174,185,067,169,044 13540:012,157,066,003,076,086,116 13546:228,162,112,142,185,067,106 13552:141,186,067,173,190,002,231 13558:072,169,064,141,190,002,116 13564:032,206,046,104,141,190,203 13570:002,173,120,063,208,008,064 13576:032,010,038,104,104,076,116 13582:173,045,032,224,052,174,202 13588:185,067,169,163,157,068,061 13594:003,169,063,157,069,003,234 13600:173,120,063,157,072,003,108 13606:169,000,157,073,003,173,101 13612:186,067,157,074,003,169,188 13618:003,157,066,003,076,086,185 13624:228,056,165,134,237,102,210 13630:063,133,138,133,142,165,068 13636:135,237,103,063,133,139,110 13642:133,143,005,138,240,004,225 13648:169,196,133,145,032,026,013 13654:038,169,084,160,062,032,119 13660:089,037,169,004,032,235,146 13666:052,016,003,076,174,052,215 13672:165,145,201,196,240,003,030 13678:032,031,037,032,126,053,165 13684:192,128,144,003,076,174,065 13690:052,076,232,053,174,185,126 13696:067,165,134,157,068,003,210 13702:165,135,157,069,003,056,207 13708:173,104,063,229,134,157,232 13714:072,003,173,105,063,229,023 13720:135,157,073,003,169,007,184 13726:157,066,003,032,086,228,218 13732:016,005,192,136,240,001,242 13738:096,174,185,067,024,189,137 13744:072,003,109,102,063,141,154 13750:117,063,189,073,003,109,224 13756:103,063,141,118,063,024,188 13762:173,117,063,101,142,141,163 13768:117,063,173,118,063,101,067 13774:143,141,118,063,032,025,216 13780:052,173,117,063,133,138,120 13786:173,118,063,133,139,169,245 13792:000,168,145,138,200,208,059 13798:251,096,032,224,052,016,133 13804:003,076,174,052,169,125,067 13810:032,127,047,169,074,160,083 13816:062,032,089,037,076,199,231 13822:052,169,064,141,014,212,138 13828:173,138,041,141,198,002,185 13834:141,200,002,173,154,041,209 13840:141,197,002,096,162,000,102 13846:142,205,063,142,206,063,075 13852:142,207,063,142,208,063,085 13858:056,177,138,233,016,144,030 13864:042,201,010,176,038,014,009 13870:205,063,046,206,063,014,131 13876:205,063,046,206,063,014,137 13882:205,063,046,206,063,014,143 13888:205,063,046,206,063,013,148 13894:205,063,141,205,063,200,179 13900:208,212,230,139,076,034,207 13906:054,248,173,205,063,013,070 13912:206,063,240,028,056,173,086 13918:205,063,233,001,141,205,174 13924:063,173,206,063,233,000,070 13930:141,206,063,238,207,063,000 13936:208,003,238,208,063,076,140 13942:084,054,173,207,063,216,147 13948:096,056,173,209,063,237,190 13954:106,063,141,211,063,173,119 13960:210,063,237,107,063,141,189 13966:212,063,013,211,063,208,144 13972:016,032,026,038,169,140,057 13978:160,062,032,089,037,169,191 13984:001,141,113,063,096,024,086 13990:165,134,133,128,109,211,022 13996:063,133,130,165,135,133,163 14002:129,109,212,063,133,131,187 14008:056,173,117,063,229,128,182 14014:133,132,173,118,063,229,014 14020:129,133,133,024,101,131,079 14026:205,105,063,144,016,032,255 14032:026,038,169,128,160,062,023 14038:032,089,037,169,001,141,171 14044:113,063,096,032,077,036,125 14050:024,173,211,063,133,132,194 14056:109,117,063,141,117,063,074 14062:173,212,063,133,133,109,037 14068:118,063,141,118,063,165,144 14074:134,133,130,165,135,133,056 14080:131,173,106,063,133,128,222 14086:173,107,063,133,129,032,131 14092:016,036,076,207,039,160,034 14098:000,177,134,170,200,177,108 14104:134,136,145,134,200,138,143 14110:145,134,096,160,000,177,230 14116:134,041,063,201,033,144,140 14122:010,201,059,176,006,177,159 14128:134,073,064,145,134,076,162 14134:133,040,072,041,128,133,089 14140:140,104,041,127,201,096,001 14146:176,011,201,064,144,005,155 14152:233,064,076,079,055,105,172 14158:032,005,140,096,005,075,175 14164:066,005,058,001,001,001,216 14170:000,001,000,080,027,014,212 14176:015,018,141,244,063,138,203 14182:072,152,072,056,173,228,087 14188:063,237,230,063,173,229,079 14194:063,237,231,063,144,049,133 14200:169,001,141,254,002,162,081 14206:112,169,000,157,072,003,127 14212:157,073,003,169,011,157,190 14218:066,003,173,244,063,032,207 14224:086,228,008,169,000,141,008 14230:254,002,040,016,009,032,247 14236:174,052,162,250,154,076,000 14242:072,038,173,255,002,208,142 14248:251,104,168,104,170,173,114 14254:244,063,096,032,026,038,161 14260:169,183,160,062,076,089,151 14266:037,076,215,056,032,026,116 14272:038,169,158,160,062,032,043 14278:089,037,032,255,053,169,065 14284:008,032,235,052,016,003,038 14290:076,215,056,032,255,053,129 14296:032,177,055,162,000,142,016 14302:220,063,142,219,063,142,047 14308:240,063,142,241,063,142,095 14314:181,067,189,082,055,157,197 14320:221,063,232,224,012,208,176 14326:245,169,255,141,235,063,074 14332:141,233,063,162,004,189,020 14338:093,055,157,067,064,202,128 14344:208,247,173,102,063,133,166 14350:138,173,103,063,133,139,251 14356:160,000,140,234,063,204,053 14362:233,063,240,006,173,221,194 14368:063,141,234,063,177,138,080 14374:016,003,076,166,057,201,045 14380:094,240,041,153,179,064,047 14386:200,238,234,063,173,234,168 14392:063,205,222,063,144,230,215 14398:140,116,063,177,138,201,129 14404:000,240,017,206,234,063,060 14410:136,208,244,172,116,063,245 14416:200,177,138,201,000,240,012 14422:001,136,140,116,063,152,182 14428:056,101,138,133,138,165,055 14434:139,105,000,133,139,160,006 14440:000,173,235,063,201,255,007 14446:208,003,032,077,057,173,148 14452:233,063,240,003,032,117,036 14458:057,056,046,233,063,173,238 14464:116,063,141,115,063,169,027 14470:179,133,142,169,064,133,186 14476:143,032,220,060,032,134,249 14482:057,173,235,063,205,225,080 14488:063,144,003,032,238,056,176 14494:056,165,138,237,117,063,166 14500:133,140,165,139,237,118,072 14506:063,005,140,240,060,144,054 14512:058,173,220,063,240,011,173 14518:169,000,141,219,063,141,147 14524:224,063,032,238,056,173,206 14530:163,063,201,069,208,015,145 14536:169,155,032,127,047,169,131 14542:108,160,062,032,089,037,182 14548:032,111,037,032,132,049,093 14554:162,250,154,032,173,045,010 14560:169,125,032,127,047,032,244 14566:010,038,076,072,038,076,028 14572:020,056,056,173,223,063,059 14578:237,235,063,168,136,136,193 14584:240,008,048,006,032,152,222 14590:057,136,208,250,173,220,018 14596:063,240,017,141,115,063,131 14602:169,180,133,142,169,066,101 14608:133,143,032,117,057,032,018 14614:220,060,032,152,057,032,063 14620:152,057,032,152,057,238,204 14626:228,063,208,003,238,229,235 14632:063,173,227,063,208,031,037 14638:056,173,228,063,237,230,009 14644:063,173,229,063,237,231,024 14650:063,144,016,032,026,038,121 14656:169,197,160,062,032,089,005 14662:037,032,111,037,032,177,240 14668:055,173,219,063,240,017,075 14674:141,115,063,169,179,133,114 14680:142,169,065,133,143,032,004 14686:117,057,032,220,060,172,240 14692:224,063,140,235,063,136,193 14698:240,008,048,006,032,152,080 14704:057,136,208,250,096,169,004 14710:032,172,221,063,140,234,212 14716:063,240,006,032,098,055,106 14722:136,208,250,096,172,226,194 14728:063,024,152,109,235,063,014 14734:141,235,063,032,152,057,054 14740:136,208,250,096,169,155,138 14746:032,098,055,173,181,067,248 14752:240,003,032,098,055,096,172 14758:141,237,063,041,127,032,039 14764:056,055,174,241,057,221,208 14770:241,057,240,009,202,208,111 14776:248,206,234,063,076,246,233 14782:058,202,138,010,170,140,140 14788:236,063,169,057,072,169,194 14794:212,072,189,004,058,072,041 14800:189,003,058,072,096,056,170 14806:173,236,063,101,138,133,034 14812:138,165,139,105,000,133,132 14818:139,076,020,056,177,138,064 14824:201,094,240,001,136,140,020 14830:236,063,096,017,119,108,109 14836:114,116,098,115,110,104,133 14842:102,064,112,063,120,109,052 14848:105,103,106,097,058,115,072 14854:058,125,058,135,058,145,073 14860:058,155,058,165,058,180,174 14866:058,214,058,071,058,087,052 14872:058,055,058,045,058,036,078 14878:058,239,058,024,059,106,062 14884:058,200,169,000,141,233,069 14890:063,076,230,057,200,032,188 14896:020,054,141,232,063,076,122 14902:230,057,200,032,020,054,135 14908:141,230,063,173,208,063,170 14914:141,231,063,076,230,057,096 14920:200,032,020,054,141,228,235 14926:063,173,208,063,141,229,187 14932:063,076,230,057,200,032,230 14938:020,054,141,223,063,076,155 14944:230,057,169,000,141,227,152 14950:063,200,076,230,057,169,129 14956:010,141,181,067,200,076,015 14962:230,057,200,032,020,054,195 14968:141,221,063,076,230,057,140 14974:200,032,020,054,141,222,027 14980:063,076,230,057,200,032,022 14986:020,054,141,224,063,076,204 14992:230,057,200,032,020,054,225 14998:141,225,063,076,230,057,174 15004:200,032,020,054,141,226,061 15010:063,076,230,057,172,236,228 15016:063,200,152,072,032,238,157 15022:056,104,168,140,236,063,173 15028:096,032,207,058,136,140,081 15034:219,063,160,001,177,138,176 15040:153,178,065,200,204,219,187 15046:063,144,245,240,243,200,053 15052:076,230,057,200,177,138,058 15058:201,094,208,249,096,032,066 15064:207,058,136,140,220,063,016 15070:160,001,177,138,153,179,006 15076:066,200,204,220,063,144,101 15082:245,240,243,076,230,057,045 15088:032,207,058,076,230,057,132 15094:200,177,138,201,029,240,207 15100:007,136,173,237,063,076,176 15106:047,056,200,032,020,054,155 15112:072,173,237,063,041,127,209 15118:170,104,157,051,064,032,080 15124:230,057,076,213,057,160,045 15130:001,162,000,177,138,201,193 15136:094,240,012,032,056,055,009 15142:157,163,063,200,232,224,053 15148:014,208,238,142,120,063,061 15154:169,000,157,163,063,162,252 15160:096,142,185,067,169,004,207 15166:141,186,067,032,016,053,045 15172:016,003,076,155,055,169,030 15178:000,133,142,133,143,032,145 15184:031,037,032,126,053,016,119 15190:003,076,155,055,104,104,071 15196:162,112,141,185,067,076,067 15202:010,056,032,145,059,173,061 15208:245,063,240,022,032,060,254 15214:060,032,183,059,173,243,092 15220:063,201,255,240,009,032,148 15226:095,060,032,139,036,076,048 15232:111,059,076,010,038,169,079 15238:008,141,031,208,173,031,214 15244:208,201,003,208,038,032,062 15250:026,038,169,229,160,062,062 15256:032,089,037,032,206,046,082 15262:141,245,063,208,003,076,126 15268:010,038,160,000,185,163,208 15274:063,153,246,063,200,204,075 15280:120,063,208,244,076,010,129 15286:038,165,134,133,138,165,187 15292:135,133,139,169,255,141,136 15298:243,063,160,001,162,000,055 15304:173,245,063,240,083,189,169 15310:246,063,032,044,038,209,070 15316:138,240,005,224,000,208,003 15322:235,202,200,208,011,230,024 15328:139,165,139,205,118,063,029 15334:240,002,176,054,232,236,146 15340:245,063,208,221,024,152,125 15346:101,138,133,140,165,139,034 15352:105,000,133,141,173,117,149 15358:063,197,140,173,118,063,240 15364:229,141,144,024,056,165,251 15370:140,237,245,063,133,134,194 15376:141,242,063,165,141,233,233 15382:000,133,135,141,243,063,225 15388:032,207,039,096,032,026,204 15394:038,169,235,160,062,032,218 15400:089,037,169,001,141,113,078 15406:063,096,169,008,141,031,042 15412:208,173,031,208,201,003,108 15418:208,035,032,026,038,169,054 15424:245,160,062,032,089,037,177 15430:032,206,046,141,020,064,067 15436:240,014,160,000,185,163,070 15442:063,153,021,064,200,204,019 15448:120,063,208,244,076,010,041 15454:038,056,165,134,133,130,238 15460:237,242,063,133,140,165,056 15466:135,133,131,237,243,063,024 15472:005,140,208,101,169,255,222 15478:141,243,063,024,173,245,239 15484:063,101,134,133,128,169,084 15490:000,101,135,133,129,056,172 15496:173,117,063,229,130,133,213 15502:132,173,118,063,229,131,220 15508:133,133,032,016,036,056,042 15514:173,117,063,237,245,063,028 15520:141,117,063,173,118,063,067 15526:233,000,141,118,063,173,126 15532:020,064,240,041,141,238,148 15538:063,169,000,141,239,063,085 15544:032,146,044,160,000,185,239 15550:021,064,032,044,038,145,022 15556:134,200,204,020,064,208,002 15562:242,024,165,134,109,020,128 15568:064,133,134,165,135,105,176 15574:000,133,135,076,207,039,036 15580:160,000,204,115,063,240,234 15586:029,177,142,048,026,032,168 15592:056,055,032,098,055,173,189 15598:241,063,240,010,169,008,201 15604:032,098,055,169,095,032,213 15610:098,055,200,076,222,060,193 15616:096,140,236,063,041,127,191 15622:141,237,063,032,056,055,078 15628:201,099,208,027,056,173,008 15634:232,063,237,115,063,074,034 15640:056,237,221,063,168,169,170 15646:032,032,098,055,136,208,079 15652:250,172,236,063,076,252,061 15658:060,201,101,208,017,056,173 15664:173,222,063,237,115,063,153 15670:056,237,221,063,168,169,200 15676:032,076,031,061,201,117,066 15682:208,008,173,241,063,073,064 15688:001,141,241,063,201,035,242 15694:208,018,140,236,063,174,149 15700:228,063,173,229,063,032,104 15706:155,047,172,236,063,076,071 15712:252,060,174,237,063,189,047 15718:051,064,032,098,055,076,222 15724:252,060,032,026,038,056,060 15730:173,104,063,237,117,063,103 15736:170,173,105,063,237,118,218 15742:063,032,160,047,169,001,086 15748:141,113,063,096,083,112,228 15754:101,101,100,083,099,114,224 15760:105,112,116,032,051,046,094 15766:048,000,032,098,121,032,225 15772:067,104,097,114,108,101,235 15778:115,032,066,114,097,110,184 15784:110,111,110,000,066,117,170 15790:102,102,101,114,032,067,180 15796:108,101,097,114,101,100,033 15802:000,066,117,102,102,101,162 15808:114,032,070,117,108,108,229 15814:000,068,101,108,101,116,180 15820:101,032,040,083,044,087,079 15826:044,080,041,000,058,032,209 15832:065,114,101,032,121,111,248 15838:117,032,115,117,114,101,050 15844:063,032,040,089,047,078,065 15850:041,058,000,069,082,065,037 15856:083,069,032,065,076,076,129 15862:032,084,069,088,084,000,091 15868:069,114,097,115,101,032,012 15874:040,083,044,087,044,080,124 15880:041,058,032,210,197,212,246 15886:213,210,206,032,116,111,134 15892:032,101,120,105,116,000,238 15898:083,097,118,101,032,040,241 15904:068,101,118,105,099,101,112 15910:058,070,105,108,101,110,078 15916:097,109,101,041,062,000,198 15922:069,114,114,111,114,032,092 15928:035,000,066,082,069,065,117 15934:075,032,075,101,121,032,242 15940:065,098,111,114,116,000,060 15946:078,111,032,069,114,114,080 15952:111,114,115,000,076,111,095 15958:097,100,032,040,068,101,012 15964:118,105,099,101,058,070,131 15970:105,108,101,110,097,109,216 15976:101,041,062,000,032,080,164 15982:114,101,115,115,032,210,029 15988:197,212,213,210,206,000,130 15994:068,049,058,042,046,042,171 16000:077,101,109,111,114,121,249 16006:032,070,117,108,108,000,057 16012:078,111,032,116,101,120,186 16018:116,032,105,110,032,098,127 16024:117,102,102,101,114,000,176 16030:080,114,105,110,116,032,203 16036:040,068,101,118,105,099,183 16042:101,058,070,105,108,101,201 16048:110,097,109,101,041,062,184 16054:000,080,114,105,110,116,195 16060:105,110,103,046,046,046,132 16066:155,155,000,073,110,115,034 16072:101,114,116,032,110,101,006 16078:120,116,032,115,104,101,026 16084:101,116,044,032,112,114,219 16090:101,115,115,032,210,197,220 16096:212,213,210,206,000,070,111 16102:105,110,100,058,000,078,169 16108:111,116,032,102,111,117,057 16114:110,100,000,067,104,097,208 16120:110,103,101,032,116,111,053 16126:058,000,027,028,027,029,167 16132:027,030,027,031,032,195,090 16138:212,210,204,045,196,101,210 16144:108,101,116,101,032,204,166 16150:111,099,107,032,213,110,182 16156:108,111,099,107,032,210,183 16162:101,110,097,109,101,032,072 16168:197,211,195,198,111,114,042 16174:109,097,116,032,195,212,039 16180:210,204,045,204,111,097,155 16186:100,032,032,068,114,105,253 16192:118,101,032,091,177,032,103 16198:178,032,179,032,180,093,252 16204:058,032,000,082,101,110,203 16210:097,109,101,032,116,111,136 16216:058,000,070,111,114,109,038 16222:097,116,032,100,105,115,147 16228:107,000,000,000,000,000,207
The source code for SpeedScript was originally developed using the MAC/65 assembler (from Optimized Systems Software, Inc.). The MAC/65 assembler uses the standard MOS source code format, so this source code can be assembled on a variety of Atari assemblers, including EASMD from OSS and the Atari Assembler/Editor cartridge. The source code was originally broken up into a number of modules, each SAVE#’d to disk. The .INCLUDE pseudo-op was used to link all the modules together. All files must be merged together to be assembled with the Atari Assembler/Editor cartridge. Line numbers are omitted.
Most pseudo-ops are in standard MOS 6502 notation: *= updates the program counter (some assemblers use .ORG instead); .BYTE assembles a list of numbers or an ATASCII character string; .WOR, or .WORD, assembles a list of addresses into low byte/high byte format; < extracts the low byte of a 16-bit expression; > extracts the high byte of a 16-bit expression (some assemblers reverse the use of < and > others, such as EASMD and the Assembler/Editor cartridge, use a suffix of &255 and /256 to achieve the same effect); and = is used to assign an expression to a label (some assemblers use .EQU).
Beginners should make sure they understand Indirect-Y addressing, as in LDA ($FB),Y or LDA (CURR),Y. This mode is used extensively in SpeedScript.
The Atari version of SpeedScript was developed by sending the Commodore 64 source code to the Atari via modem. References to Commodore 64 Kernal ROM routines were replaced with Atari CIO routines. Some routines built into the Commodore 64’s ROM had to be programmed into Atari SpeedScript, with resulting code expansion. References to location 1 (which maps banks of ROM in and out in the 64) were omitted. The REFRESH routine, TOPCLR, and a few other routines were changed to compensate for Atari’s floating screen memory. The raster interrupt used to highlight the command line in the 64 version became a display-list interrupt. A custom character set was added to take advantage of the Atari’s special nine-line character mode. The DOS package was written to support disk functions. But much of the source code did not need to be changed at all, since SpeedScript’s machine-specific code is segregated into distinct modules. These modules were rewritten. Approximately one week was required to get a primitive version running, followed by two months of testing, debugging, and refining to complete Atari SpeedScript. Because of the new character set, the DOS package, smoother input/output programming (such as Atari’s device-independent I/O), and more logical keyboard layout, the Atari version may be the best version of SpeedScript yet.
SpeedScript is written in small modules. Some people think that subroutines are useful only when a routine is called more than once. I strongly believe in breaking up a problem into a number of discrete tasks. These tasks can be written as subroutines, then tested individually. Once all the modules are working, just link them together with JSRs and you have a working program.
I’ve also tried to use meaningful labels, but sometimes one just runs out of imagination. Comments are added below as signposts to guide you through the source code (you needn’t type them in—if you do, precede each comment with a semicolon for the sake of your assembler). Modules are also set apart with blank lines. Notice that some modules are used in rather creative ways. For example, word left/word right is used both for moving the cursor and in delimiting a word to be erased in the erase mode. Also, note that memory locations are sometimes used instead of meaningful labels. In order to fit the complete source code into memory at once, I sometimes had to compromise readability for the sake of brevity.
Crucial to the understanding of SpeedScript is the REFRESH routine. Study it carefully. REFRESH is the only routine in SpeedScript that writes directly to the screen (CIO is used to print on the command line). It automatically takes care of word-wrap and carriage returns, and provides useful pointers so that the CHECK routine can easily scroll the screen. This frees the rest of SpeedScript to just move and modify contiguous memory. Carriage returns are not padded out in memory with spaces to fill the rest of a line; the REFRESH routine takes care of this transparently.
Filename: SPEED.0
Location $1F00 is safely above DOS 2.0S, DOS 3, and OS/A+ DOS. Some DOS’s may use more memory, so you may need to reassemble SpeedScript at a higher address, usually the address of LOMEM plus 256 bytes to be safe.
*= $1F00
Locations used by high-speed memory move routines.
FROML = $80 FROMH = $81 DESTL = $82 DESTH = $83 LLEN = $84 HLEN = $85
CURR: Position of cursor within text memory. SCR: used by the REFRESH routine.
CURR = $86 SCR = $88
TEX: An alternate location used in tandem with CURR. COLR is used by REFRESH. TEMP is used throughout as a scratehpad pointer. INDIR is also a reusable indirect pointer. UNDERCURS stores the value of the character highlighted by the cursor.
TEX = $8A TEMP = $8C INDIR = $8E UNDERCURS = $90
WTNDCOLOR: Color of command line window supported by HIGHLIGHT. RETCHAR is the screen-code value of the return-mark (a left-pointing arrow). SPACE is the screen-code value of the space character, RED and BLUE are used as command-line colors
WINDCOLR = $91 RETCHAR = 94 SPACE = 0 RED = $32 BLUE = $74
Input/Output Control System definitions for input/output control blocks (IOCBs). CIO is the entry point for all file-oriented input/output. SHFLOK is the SHiFtLOcK flag.
ICCOM = $0342 ICBADR = $0344 ICBLEN = $0348 ICAUX1 = $034A ICAUX2 = $034B ICSTAT = $0343 SHFLOK = $02BE CIO = $E456
Called only when run from DOS. It is assumed that the author’s initials (that conveniently work out in hex) are not normally present in memory. If they are, we know that SpeedScript has been run before, so we avoid the ERASE routine to preserve the text in memory.
BEGIN LDA 710 STA 709 JSR INIT LDA #$CB CMP FIRSTRUN STA FIRSTRUN BEQ SKIPERAS JSR ERASE JSR KILLBUFF
We save the DOS reset vector and change this vector to point to SpeedScript’s SYSTEM RESET routine. Since this routine is called at power-up, right after DOS.SYS runs, we need to disable the cold-start flag (location 580) and set location $09 to signify a successful disk boot.
LDA $0C STA JDOS+1 LDA $0D STA JDOS+2 LDA # <JDOS STA $0C LDA # >JDOS STA $0D LDA #0 STA 580 LDA #1 STA $09 SKIPERAS JSR INIT2 JMP MAIN
The character set for the ANTIC 3 nine-line character mode must be on an even 512-Syte boundary, so we force the assembler’s program counter to address $2000 and merge in the character set. We then link in each successive module of SpeedScript. Again, if your assembler cannot handle .INCLUDE, you’ll have to merge all these files together in the order indicated.
*= $2000 .INCLUDE #D:CHSET.SRC .INCLUDE #D:SPEED.1 .INCLUDE #D:SUPPORT .INCLUDE #D:DOSPAK .INCLUDE #D:SPEED.2 .INCLUDE #D:DATA .END
Filename: CHSET.SRC
The character set here is stored as eight bytes per line, so each line defines one character. Sheldon Leemon’s INSTEDIT character editor was used to create the character set, and I wrote a special program to convert the character set into .BYTE statements. In ANTIC mode 3, each character takes up ten scan lines of vertical screen space. The characters in the lowercase portion of the character set are displayed with a blank line at the top line, then the character data from bytes 1-7 of the character set. Byte 0 of the character’s definition is displayed at the ninth line of the character. The tenth line is always blank. This lets you define characters with true descenders. The forced blank line lets you use more of the character matrix for defining a character, so these characters are larger than normal Atari characters.
.BYTE 0,0,0,0,0,0,0,0 .BYTE 0,24,24,24,24,24,0,24 .BYTE 0,102,102,102,0,0,0,0 .BYTE 0,102,255,102,102,255,102,0 .BYTE 24,62,96,60,6,124,24,0 .BYTE 0,204,216,48,96,204,140,0 .BYTE 0,56,108,56,112,222,204,118 .BYTE 0,24,24,48,0,0,0,0 .BYTE 0,24,48,96,96,96,48,24 .BYTE 0,48,24,12,12,12,24,48 .BYTE 0,0,102,60,255,60,102,0 .BYTE 0,0,24,24,126,24,24,0 .BYTE 0,0,0,0,0,48,48,96 .BYTE 0,0,0,0,126,0,0,0 .BYTE 0,0,0,0,0,0,48,48 .BYTE 0,0,6,12,24,48,96,192 .BYTE 0,124,206,222,246,230,198,124 .BYTE 0,24,56,24,24,24,24,126 .BYTE 0,124,198,12,24,48,96,254 .BYTE 0,254,12,24,56,12,198,124 .BYTE 0,28,60,108,204,254,12,12 .BYTE 0,254,192,252,6,6,198,124 .BYTE 0,124,192,252,198,198,198,124 .BYTE 0,126,6,12,24,48,96,96 .BYTE 0,124,198,198,124,198,198,124 .BYTE 0,124,198,198,126,12,24,48 .BYTE 0,0,48,48,0,48,48,0 .BYTE 0,0,48,48,0,48,48,96 .BYTE 0,12,24,48,96,48,24,12 .BYTE 0,0,0,126,0,0,126,0 .BYTE 0,48,24,12,6,12,24,48 .BYTE 0,60,102,6,12,24,0,24 .BYTE 0,124,198,222,214,220,224,60 .BYTE 0,124,198,198,198,254,198,198 .BYTE 0,252,198,198,252,198,198,252 .BYTE 0,124,198,192,192,192,198,124 .BYTE 0,248,204,198,198,198,204,248 .BYTE 0,254,192,192,252,192,192,254 .BYTE 0,254,192,192,252,192,192,192 .BYTE 0,124,198,192,222,198,198,124 .BYTE 0,198,198,198,254,198,198,198 .BYTE 0,126,24,24,24,24,24,126 .BYTE 0,62,12,12,12,12,204,120 .BYTE 0,198,204,216,240,216,204,198 .BYTE 0,192,192,192,192,192,192,254 .BYTE 0,198,238,254,214,198,198,198 .BYTE 0,198,230,246,254,222,206,198 .BYTE 0,124,198,198,198,198,198,124 .BYTE 0,252,198,198,198,252,192,192 .BYTE 0,124,198,198,198,222,124,14 .BYTE 0,252,198,198,252,216,204,198 .BYTE 0,124,198,192,124,6,198,124 .BYTE 0,126,24,24,24,24,24,24 .BYTE 0,198,198,198,198,198,198,124 .BYTE 0,198,198,198,198,198,108,56 .BYTE 0,198,198,198,214,254,238,198 .BYTE 0,198,198,108,56,108,198,198 .BYTE 0,102,102,102,60,24,24,24 .BYTE 0,254,12,24,48,96,192,254 .BYTE 0,30,24,24,24,24,24,30 .BYTE 0,64,96,48,24,12,6,0 .BYTE 0,240,48,48,48,48,48,240 .BYTE 0,8,28,54,99,0,0,0 .BYTE 0,0,0,0,0,0,0,255 .BYTE 0,0,0,0,0,0,0,0 .BYTE 124,194,153,153,129,153,153,230 .BYTE 252,130,153,130,153,153,131,252 .BYTE 124,194,153,158,158,153,194,124 .BYTE 252,130,153,153,153,153,130,252 .BYTE 254,130,158,132,156,158,130,254 .BYTE 126,193,206,194,206,204,204,120 .BYTE 124,194,153,158,145,153,194,124 .BYTE 246,153,153,129,153,153,153,246 .BYTE 127,97,115,50,50,115,97,127 .BYTE 62,50,50,50,50,114,198,124 .BYTE 230,153,146,132,146,153,153,230 .BYTE 120,76,76,76,76,78,66,124 .BYTE 230,153,129,129,137,153,153,230 .BYTE 230,153,137,129,145,153,153,230 .BYTE 124,194,153,153,153,153,194,124 .BYTE 254,195,201,201,195,206,200,240 .BYTE 124,194,153,153,153,146,201,118 .BYTE 124,194,201,201,194,201,201,247 .BYTE 126,195,158,194,249,153,195,126 .BYTE 254,194,102,100,100,100,100,124 .BYTE 246,153,153,153,153,153,194,124 .BYTE 230,153,153,153,153,194,100,56 .BYTE 246,153,153,153,137,129,153,246 .BYTE 230,153,153,194,153,153,153,230 .BYTE 230,153,153,195,230,100,100,124 .BYTE 254,193,249,50,228,206,193,254 .BYTE 120,96,120,96,126,24,30,0 .BYTE 0,24,60,126,24,24,24,0 .BYTE 0,24,24,24,126,60,24,0 .BYTE 0,0,0,12,12,88,112,120 .BYTE 0,24,12,126,12,24,0,0 .BYTE 0,0,24,60,126,126,60,24 .BYTE 0,0,0,124,6,126,198,126 .BYTE 0,0,192,252,198,198,198,252 .BYTE 0,0,0,124,198,192,198,124 .BYTE 0,0,6,126,198,198,198,126 .BYTE 0,0,0,124,198,254,192,124 .BYTE 0,0,62,96,252,96,96,96 .BYTE 6,252,0,126,198,198,198,126 .BYTE 0,0,192,192,252,198,198,198 .BYTE 0,0,24,0,56,24,24,60 .BYTE 24,240,24,0,24,24,24,24 .BYTE 0,0,192,204,216,248,204,198 .BYTE 0,0,56,24,24,24,24,60 .BYTE 0,0,0,204,254,254,214,198 .BYTE 0,0,0,252,198,198,198,198 .BYTE 0,0,0,124,198,198,198,124 .BYTE 192,192,0,252,198,198,198,252 .BYTE 6,6,0,126,198,198,198,126 .BYTE 0,0,0,252,198,192,192,192 .BYTE 0,0,0,126,192,124,6,252 .BYTE 0,0,48,254,48,48,48,30 .BYTE 0,0,0,198,198,198,198,126 .BYTE 0,0,0,198,198,198,108,56 .BYTE 0,0,0,198,214,254,124,108 .BYTE 0,0,0,198,108,56,108,198 .BYTE 6,252,0,198,198,198,198,126 .BYTE 0,0,0,254,12,56,96,254 .BYTE 14,0,14,24,24,56,24,24 .BYTE 24,24,24,24,24,24,24,24 .BYTE 112,0,112,24,24,28,24,24 .BYTE 0,0,0,8,24,56,24,8 .BYTE 0,0,0,16,16,24,28,24 *= *+16 .END
Filename: SPEED.1
This module is chiefly concerned with the word processor editing functions. It contains many common subroutines, such as TOPCLR and PRMSG to clear the command line and print messages. It contains the initialization routines and takes care of memory moves (inserts and deletes). A second module, SPEED.2, is responsible for most input/output, including the printer routines. SPEED.1 is the largest file in the linked chain. UMOVE is a high-speed memory move routine. It gets its speed from self-modifying code (the $FFFFs at MOVLOOP are replaced by actual addresses when UMOVE is called). UMOVE is used to move an overlapping range of memory upward (toward location 0), so it is used to delete. Set FROML/FROMH to point to the source area of memory, DESTL/DESTH to point to the destination, and LLEN/HLEN to hold the length of the area being moved.
UMOVE LDA FROML STA MOVLOOP+1 LDA FROMH STA MOVLOOP+2 LDA DESTL STA MOVLOOP+4 LDA DESTH STA MOVLOOP+5 LDX HLEN BEQ SKIPMOV MOV1 LDA #0 MOV2 STA ENDPOS LDY #0 MOVLOOP LDA $FFFF,Y STA $FFFF,Y INY CPY ENDPOS BNE MOVLOOP INC MOVLOOP+2 INC MOVLOOP+5 CPX #0 BEQ OUT DEX BNE MOV1 SKIPMOV LDA LLEN BNE MOV2 OUT RTS
DMOVE uses the same variables as UMOVE, but it is used to move an overlapping block of memory downward (toward location $FFFF), so it is used to insert. If the block of memory to be moved does not overlap the destination area, then either routine can be used.
DMOVE LDA HLEN TAX ORA LLEN BNE NOTNULL RTS NOTNULL CLC TXA ADC FROMH STA DMOVLOOP+2 LDA FROML STA DMOVLOOP+1 CLC TXA ADC DESTH STA DMOVLOOP+5 LDA DESTL STA DMOVLOOP+4 INX LDY LLEN BNE DMOVLOOP BEQ SKIPDMOV DMOV1 LDY #255 DMOVLOOP LDA $FFFF,Y STA $FFFF,Y DEY CPY #255 BNE DMOVLOOP SKIPDMOV DEC DMOVLOOP+2 DEC DMOVLOOP+5 DEX BNE DMOV1 RTS
REFRESH copies a screenful of text from the area of memory pointed to by TOPLIN. It works like a printer routine, fitting a line of text between the screen margins, wrapping words, and restarts at the left margin after printing a carriage return. SpeedScript constantly calls this routine while the cursor is blinking, so it has to be very fast. To eliminate flicker, it clears out the end of each line instead of first clearing the screen. It stores the length of the first screen line for the sake of the CHECK routine (which scrolls up by adding that length to TOPLIN) and the last text location referenced (so CHECK can see if the cursor has moved off the visible screen). REFRESH can automatically handle different screen widths.
REFRESH LDA #40 INY CLC
RLM: Left margin. Location $58/$59 points to the address of screen memory.
ADC RLM CLC ADC $58 STA SCR LDA $59 ADC #0 STA SCR+1
TOPLIN points to the first character within text to be printed at the top-left comer of the screen.
CLC LDA TOPLIN STA TEX LDA TOPLIN+1 STA TEX+1 LDX #1 LDA INSMODE STA WINDCOLR PPAGE LDY #0 PLINE LDA (TEX),Y STA LBUFF,Y INY AND #127 CMP #RETCHAR BEQ BREAK CPY LINELEN BNE PLINE DEY SLOOP LDA (TEX),Y AND #127 NXCUR CMP #SPACE BEQ SBRK DEY BNE SLOOP LDY LINELEN DEY SBRK INY BREAK STY TEMP LDY #0 COPY LDA LBUFF,Y STA (SCR),Y INY CPY TEMP BNE COPY CLC TYA ADC TEX STA TEX LDA TEX+1 ADC #0 STA TEX+1 CPX #1 BNE CLRLN STY LENTABLE CLRLN CPY LINELEN BEQ CLEARED
Character #64 (ATASCII value of O) fills the gap when a line is broken. It can be redefined to show or not show these false spaces.
LDA #64 STA (SCR),Y INY JMP CLRLN CLEARED CLC LDA SCR ADC #40 STA SCR BCC INCNOT INC SCR+1 INCNOT INX CPX #19 BEQ PDONE JMP PPAGE PDONE LDA TEX STA BOTSCR LDA TEX+1 STA BOTSCR+1 RTS
The following routine fills the entire text area with space characters (screen code 0), effectively erasing all text. It is called when the program is first run and when an Erase All is performed. It also initializes the cursor position (CURR) and the end-of-text pointer (LASTLINE).
ERASE LDA TEXSTART STA TEX STA TOPLIN STA LASTLINE STA CURR LDA TEXSTART+1 STA TEX+1 STA TOPLIN+1 STA LASTLINE+1 STA CURR+1 SEC LDA TEXEND+1 SBC TEXSTART+1 TAX LDA #SPACE CLRLOOP LDY #255 DEC TEX+1 STA (TEX),Y INY INC TEX+1 CLR2 STA (TEX),Y INY BNE CLR2 INC TEX+1 DEX BNE CLR2 STA (TEX),Y RTS
PRMSG is used anytime we need to print something at the top of the screen (the command line). Pass it the address of the message to be printed by storing the low byte of the address in the accumulator and the high byte in the Y register. The message in memory must end with a zero byte. The routine does not add a carriage return. CHROUT (character out) prints the character in the accumulator to the screen. CHROUT is a subroutine in the SUPPORT package.
PRMSG STA TEMP STY TEMP+1 LDA #1 STA 752 LDY #0 PRLOOP LDA (TEMP),Y BEQ PREXIT JSR CHROUT INY BNE PRLOOP PREXIT RTS GETAKEY JSR GETIN BEQ GETAKEY RTS JDOS JSR PREXIT LDA BLINK BEQ NOBLINK LDY #0 LDA UNDERCURS STA (CURR),Y NOBLINK JSR INIT2 JMP MAIN
The initialization routine sets up the memory map, clears out certain flags, and enables the display-list interrupt.
INIT LDA #125 JSR CHROUT LDA #0 STA INSMODE STA TEXSTART STA TEXEND STA TEXBUF STA BUFEND STA HUNTLEN STA REPLEN STA ESCFLAG STA SHFLOK STA RLM LDA #40 STA LINELEN
Label END is at the end of the source code, so it points to the last address used by the object code. We use it to calculate the start-of-text memory.
LDA # >END CLC ADC #1 STA TEXSTART+1
Location 561 points to the display list, which holds screen information at the top of memory. We use it as the last address available for storing text or buffer text.
LDA 561 SEC SBC #1 STA BUFEND+1 SEC SBC #8 STA TEXBUF+1 SEC SBC #1 STA TEXEND+1 LDA #$FF STA FPOS+1
If location $4B is 0, then SpeedScript is booted from disk. if we booted from cassette, we free up the DOS area ($0700-$1E00) for use as the text buffer, and free up the text memory used by disk-based SpeedScript as the text buffer.
LDA $4B BEQ DISKBOOT LDA BUFEND+1 STA TEXEND+1 LDA #$07 STA TEXBUF+1 LDA #$1E STA BUFEND+1 DISKBOOT RTS
The second initialization routine turns on the display-list interrupt (HIGHLIGHT), homes the cursor, and prints the credit line.
INIT2 JSR HIGHLIGHT LDA TEXSTART STA CURR LDA TEXSTART+1 STA CURR+1 JSR REFRESH JSR SYSMSG LDA # <MSG2 LDY # >MSG2 JSR PRMSG INC MSGFLG JMP CHECK
SYSMSG displays “SpeedScript 3.0.” The message flag (MSGFLG) is set when a message is to be left on the screen only until the next keystroke. After that keystroke, SYSMSG is called. The INIT2 routine prints the credit line with the MSGFLG set so that you won’t have to stare at the author’s name while you’re writing—a modesty feature.
SYSMSG JSR TOPCLR LDA # <MSG1 LDY # >MSG1 JSR PRMSG LDA #0 STA MSGFLG RTS
TOPCLR keeps the command line clean. It is called before most messages. It’s like a one-line clear-screen. It also forces the left margin (82) to 0, and homes the cursor to the beginning of the command line by zeroing out the X and Y cursor positions (84 and 85).
TOPCLR LDY #39 LDA #SPACE TOPLOOP STA ($58),Y DEY BPL TOPLOOP LDA #0 STA 82 STA 85 STA 84 RTS
Convert ATASCII to screen codes
ASTOIN PHA AND #128 STA TEMP PLA AND #127 CMP #96 BCS LOWR CMP #32 BCS NOTCTRL CLC ADC #64 JMP LOWR NOTCTRL SEC SBC #32 LOWR ORA TEMP RTS
The MAIN loop blinks the cursor, checks for keystrokes, converts them from ATASCII to screen codes, puts them in text at the CURRent position, and increments the CURRent position and LASTLINE. It also checks for special cases like the RETURN key and passes control characters to the CONTROL routine. The INSMODE flag is checked to see if we should insert a space before a character.
MAIN LDY #0 STY BLINK LDA (CURR),Y STA UNDERCURS MAIN2 LDY #0 STY SELFLAG LDA (CURR),Y EOR #$80 STA (CURR),Y LDA BLINK EOR #1 STA BLINK JSR REFRESH WAIT JSR GETIN BNE KEYPRESS
We check for the START key, and if pressed, go to the HOME cursor routine.
LDA #8 STA 53279 LDA 53279 CMP #6 BNE FLIPIT LDY #0 STY BLINK LDA UNDERCURS STA (CURR),Y JSR HOME JMP MAIN
The realtime clock (location 20), which counts in 1/60 seconds, is checked for 16/60 seconds (about 1/5 second) to see if it’s time to blink the cursor.
FLIPIT LDA 20 AND #16 BEQ WAIT LDA #0 STA 20 JMP MAIN2
A key has been pressed. We check the SELECT key to see if the keystroke should be inverted.
KEYPRESS TAX LDA #8 STA 53279 LDA 53279 CMP #5 BNE NOTSEL LDA #128 STA SELFLAG NOTSEL LDY #0 LDA UNDERCURS STA (CURR),Y NOTBKS LDA MSGFLG BEQ NOMSG TXA PHA JSR SYSMSG PLA TAX NOMSG TXA CMP #155 BNE NOTCR
Change a carriage return into a back arrow.
LDX #30 JMP OVERCTRL NOTCR TXA BIT ESCFLAG BMI OVERCTRL CMP #156 BCS CONTROL AND #127 CMP #32 BCC CONTROL CMP #123 BCS CONTROL CMP #92 BEQ CONTROL CMP #94 BEQ CONTROL CMP #95 BEQ CONTROL OVERCTRL TXA PHA LDY #0 STY ESCFLAG LDA (CURR),Y CMP #RETCHAR BEQ DOINS LDA INSMODE BEQ NOINST DOINS JSR INSCHAR NOINST PLA JSR ASTOIN AND #127 ORA SELFLAG LDY #0
Put the character into memory.
STA (CURR),Y JSR REFRESH SEC LDA CURR SBC LASTLINE STA TEMP LDA CURR+1 SBC LASTLINE+1 ORA TEMP BCC INKURR LDA CURR ADC #0 STA LASTLINE LDA CURR+1 ADC #0 STA LASTLINE+1
Move the cursor forward.
INKURR INC CURR BNE NOINC2 INC CURR+1 NOINC2 JSR CHECK JMP MAIN
CONTROL looks up a keyboard command in the list of control codes at CTBL. The first byte of CTBL is the actual number of commands. Once the position is found, this position is doubled as an index to the two-byte address table at VECT. The address of MAIN-1 is put on the stack, simulating the return address; then the address of the command routine taken from VECT is pushed. We then perform an RTS. RTS pulls the bytes off the stack as if they were put there by a JSR. This powerful technique is used to simulate ON-GOTO in machine language.
CONTROL LDX CTBL SRCH CMP CTBL,X BEQ FOUND DEX BNE SRCH JMP MAIN FOUND DEX TXA ASL A TAX LDA # >MAIN-1 PHA LDA # <MAIN-1 PHA LDA VECT+1,X PHA LDA VECT,X PHA RTS CTBL .BYTE 35 .BYTE 31,30,92,94,2,20,28,29 .BYTE 126,255,4 .BYTE 9,125,124,95,5,12,19 .BYTE 13,18,24,26,16 .BYTE 254,1,11,6,21,127,157 .BYTE 3,7,156,27,15 VECT .WORD RIGHT-1,LEFT-1,WLEFT-1,WRIGHT-1,BORDER-1,LETTERS-1 .WORD SLEFT-1,SRIGHT-1,DELCHAR-1,INSCHAR-1,DELETE-1 .WORD INSTGL-1,CLEAR-1,PARIGHT-1,PARLEFT-1 .WORD ERAS-1,TLOAD-1,TSAVE-1 .WORD DOS-1,INSBUFFER-1,SWITCH-1 .WORD ENDTEX-1,PRINT-1 .WORD DELIN-1,ALPHA-1,KILLBUFF-1,HUNT-1,FREEMEM-1,TAB-1 .WORD LOTTASPACE-1,REPSTART-1,SANDR-1,EATSPACE-1,ESC-1,ONOFF-1
Toggle ESCape mode.
ESC LDA ESCFLAG EOR #128 STA ESCFLAG RTS
Change the character definition of the character used to fill in the end of a line. It alternates between being a blank space, and being a blank space with a tiny dot visible. This lets you see which spaces are actually part of your text and which are just used to parse the screen. Beware of the address $2204 if you reassemble at a different address (sorry, I didn’t use a label).
ONOFF LDA $2204 EOR #16 STA $2204 RTS
The CHECK routine first prevents the cursor from disappearing past the beginning or end-of-text memory and prevents us from cursoring past the end-of-text pointer. It also checks to see if the cursor has left the visible screen, scrolling with REFRESH to make the cursor visible. The double-byte SBCs are used as a 16-bit CMP macro, setting the Z and C flags just like CMP does.
CHECK JSR CHECK2 SEC LDA CURR SBC TOPLIN LDA CURR+1 SBC TOPLIN+1 BCS OK1 SEC LDA TOPLIN SBC TEXSTART STA TEMP LDA TOPLIN+1 SBC TEXSTART+1 ORA TEMP BEQ OK1 LDA CURR STA TOPLIN LDA CURR+1 STA TOPLIN+1 JSR REFRESH OK1 SEC LDA BOTSCR SBC CURR STA TEX LDA BOTSCR+1 SBC CURR+1 STA TEX+1 ORA TEX BEQ EQA BCS OK2 EQA CLC LDA TOPLIN ADC LENTABLE STA TOPLIN LDA TOPLIN+1 ADC #0 STA TOPLIN+1 REF JSR REFRESH JMP OK1 OK2 RTS CHECK2 SEC LDA LASTLINE SBC TEXEND STA TEMP LDA LASTLINE+1 SBC TEXEND+1 ORA TEMP BCC CK3 LDA TEXEND STA LASTLINE LDA TEXEND+1 STA LASTLINE+1 CK3 SEC LDA CURR SBC TEXSTART STA TEMP LDA CURR+1 SBC TEXSTART+1 ORA TEMP BCS INRANGE LDA TEXSTART STA CURR LDA TEXSTART+1 STA CURR+1 RTS INRANGE SEC LDA CURR SBC LASTLINE STA TEMP LDA CURR+1 SBC LASTLINE+1 ORA TEMP BCS OUTRANGE RTS OUTRANGE LDA LASTLINE STA CURR LDA LASTLINE+1 STA CURR+1 RTS
Move cursor right. If the OPTION key is held down, we instead increase the line length.
RIGHT LDA #8 STA 53279 LDA 53279 CMP #3 BNE CRIGHT LDA LINELEN CMP #40 BEQ NOBIGGER INC LINELEN INC LINELEN DEC RLM JSR REFRESH JSR CHECK LDA #125 JSR CHROUT NOBIGGER JMP SYSMSG CRIGHT INC CURR BNE NOINCR INC CURR+1 NOINCR JMP CHECK
Move cursor left. If the OPTION key is held down, we instead decrease the line length.
LEFT LDA #8 STA 53279 LDA 53279 CMP #3 BNE CLEFT LDA LINELEN CMP #2 BEQ TOOSMALL DEC LINELEN DEC LINELEN INC RLM JSR REFRESH JSR CHECK LDA #125 JSR CHROUT TOOSMALL JMP SYSMSG CLEFT LDA CURR BNE NODEC DEC CURR+1 NODEC DEC CURR JMP CHECK
Word left. We look backward for a space.
WLEFT LDA CURR STA TEX LDA CURR+1 STA TEX+1 DEC TEX+1 LDY #$FF STRIP LDA (TEX),Y CMP #SPACE BEQ STRLOOP CMP #RETCHAR BNE WLOOP STRLOOP DEY BNE STRIP WLOOP LDA (TEX),Y CMP #SPACE BEQ WROUT CMP #RETCHAR BEQ WROUT DEY BNE WLOOP RTS WROUT SEC TYA ADC TEX STA CURR LDA TEX+1 ADC #0 STA CURR+1 JMP CHECK
Word right. We scan forward for a space. OIDS is not a meaningful label.
WRIGHT LDY #0 RLOOP LDA (CURR),Y CMP #SPACE BEQ ROUT CMP #RETCHAR BEQ ROUT INY BNE RLOOP RTS ROUT INY BNE OIDS INC CURR+1 LDA CURR+1 CMP LASTLINE+1 BCC OIDS BNE LASTWORD OIDS LDA (CURR),Y CMP #SPACE BEQ ROUT CMP #RETCHAR BEQ ROUT
Add the Y register to the CURRent cursor position to move the cursor. CHECK prevents illegal cursor movement. LASTWORD is called if the end of the word cannot be found before we reach the end-of-text.
ADYCURR CLC TYA ADC CURR STA CURR LDA CURR+1 ADC #0 STA CURR+1 WRTN JMP CHECK LASTWORD LDA LASTLINE STA CURR LDA LASTLINE+1 STA CURR+1 JMP CHECK
ENDTEX is tricky. If the end-of-text pointer would point to an area already visible on the screen, we just move the cursor there and call REFRESH. Otherwise, we step back 1K from the end-of-text and then scroll to the end. This is necessary since in the worst case only 18 characters of return-marks would fill the screen.
ENDTEX LDA #0 STA TOPLIN LDA LASTLINE+1 SEC SBC #4 CMP TEXSTART+1 BCS SAFE LDA TEXSTART+1 SAFE STA TOPLIN+1 JSR REFRESH JMP LASTWORD
Change the border color. The display list interrupt automatically places SCRCOL into the hardware background color register #2.
BORDER INC SCRCOL INC SCRCOL RTS SCRCOL .BYTE 8
Change text luminance. TEXCOLR is stored into hardware color register #1 during the display-list interrupt.
LETTERS INC TEXCOLR INC TEXCOLR LDA TEXCOLR AND #15 STA TEXCOLR RTS TEXCOLR .BYTE 2
Sentence left. We look backward for ending punctuation or a return-mark, then go forward until we run out of spaces.
SLEFT LDA CURR STA TEX LDA CURR+1 STA TEX+1 DEC TEX+1 LDY #$FF PMANY LDA (TEX),Y CMP #'.-32 BEQ PSRCH CMP #'!-32 BEQ PSRCH CMP #'?-32 BEQ PSRCH CMP #RETCHAR BNE PSLOOP PSRCH DEY BNE PMANY RTS PSLOOP LDA (TEX),Y CMP #'.-32 BEQ PUNCT CMP #'!-32 BEQ PUNCT CMP #'?-32 BEQ PUNCT CMP #RETCHAR BEQ PUNCT DEY BNE PSLOOP DEC TEX+1 LDA TEX+1 CMP TEXSTART BCS PSLOOP JMP FIRSTWORD PUNCT STY TEMP DEC TEMP SKIPSPC INY BEQ REPEAT LDA (TEX),Y CMP #SPACE BEQ SKIPSPC DEY JMP WROUT REPEAT LDY TEMP JMP PSLOOP FIRSTWORD LDA TEXSTART STA CURR LDA TEXSTART+1 STA CURR+1 JMP CHECK
Sentence right. We look forward for ending punctuation, then skip forward until we run out of spaces.
SRIGHT LDY #0 SRLP LDA (CURR),Y CMP #'.-32 BEQ PUNCT2 CMP #'!-32 BEQ PUNCT2 CMP #'?-32 BEQ PUNCT2 CMP #RETCHAR BEQ PUNCT2 INY BNE SRLP INC CURR+1 LDA CURR+1 CMP LASTLINE+1 BEQ SRLP BCC SRLP SREXIT JMP LASTWORD PUNCT2 INY BNE NOFIXCURR INC CURR+1 LDA CURR+1 CMP LASTLINE+1 BCC NOFIXCURR BEQ NOFIXCURR JMP LASTWORD NOFIXCURR LDA (CURR),Y CMP #SPACE BEQ PUNCT2 CMP #'.-32 BEQ PUNCT2 CMP #'!-32 BEQ PUNCT2 CMP #'?-32 BEQ PUNCT2 CMP #RETCHAR BEQ PUNCT2 JMP ADYCURR
The text buffer starts at a fixed location, but the end of the buffer is changed as text is added to it. To clear the buffer, we just set the end of the buffer to the value of the start of the buffer. No text is actually erased.
KILLBUFF LDA TEXBUF STA TPTR LDA TEXBUF+1 STA TPTR+1 JSR TOPCLR LDA # <KILLMSG LDY # >KILLMSG JSR PRMSG LDA #1 STA MSGFLG RTS
This is the second level of the general-purpose delete routines. UMOVE is the primitive core of deleting. For CTRL-D, the CURRent cursor position is the source; then a cursor command is called to update the cursor pointer. This becomes the destination. For CTRL-E, the CURRent cursor position is the destination; a cursor movement routine is called, and this becomes the source. UMOVE is then called. We actually move more than the length from the source to the end-of-text. Some extra text is moved from past the end-of-text. Since everything past the end-of-text is spaces, this neatly erases everything past the new end-of-text position. Naturally, the end-of-text pointer is updated. Before the actual delete is performed, the text to be deleted is stored in the buffer so that it can be recalled in case of error. The buffer doubles as a fail-safe device, and for moving and copying text. Checks are made to make sure that the buffer does not overflow.
DEL1 SEC LDA CURR SBC TEXSTART STA TEMP LDA CURR+1 SBC TEXSTART+1 ORA TEMP BNE DEL1A DELABORT PLA PLA RTS DEL1A LDA CURR STA FROML LDA CURR+1 STA FROMH RTS DEL2 SEC LDA CURR STA DESTL EOR #$FF ADC FROML STA GOBLEN LDA CURR+1 STA DESTH EOR #$FF ADC FROMH STA GOBLEN+1 DELC LDA FROML STA FROMSAV LDA FROMH STA FROMSAV+1 LDA DESTL STA DESTSAV STA FROML LDA DESTH STA DESTSAV+1 STA FROMH SEC LDA GOBLEN+1 ADC TPTR+1 CMP BUFEND+1 BCC GOSAV JSR TOPCLR LDA # <BUFERR LDY # >BUFERR JSR PRMSG LDA #1 STA MSGFLG RTS GOSAV LDA TPTR STA DESTL LDA TPTR+1 STA DESTH LDA GOBLEN STA LLEN CLC ADC TPTR STA TPTR LDA GOBLEN+1 STA HLEN ADC TPTR+1 STA TPTR+1 JSR UMOVE LDA FROMSAV STA FROML LDA FROMSAV+1 STA FROMH LDA DESTSAV STA DESTL LDA DESTSAV+1 STA DESTH SEC LDA LASTLINE SBC DESTL STA LLEN LDA LASTLINE+1 SBC DESTH STA HLEN JSR UMOVE SEC LDA LASTLINE SBC GOBLEN STA LASTLINE LDA LASTLINE+1 SBC GOBLEN+1 STA LASTLINE+1 RTS
Most delete commands end up calling the above routines. The single-character deletes must subtract 1 from the buffer pointer so that single characters are not added to the buffer. But note how short these routines are.
Delete character (BACK S)
DELCHAR JSR DEL1 JSR LEFT JSR DEL2 FIXTP SEC LDA TPTR SBC #1 STA TPTR LDA TPTR+1 SBC #0 STA TPTR+1 RTS
CTRL-BACK S
DELIN JSR RIGHT JSR DEL1 JSR LEFT JSR DEL2 JMP FIXTP
Called by CTRL-D. As mentioned, it stores CURR into FROML/FROMH, moves the cursor either by sentence, word, or paragraph, then stores the new position of CURR into DESTL and DESTH. The above routines perform the actual delete. CTRL-D always discards the previous contents of the buffer, for deleting text backward creates a buffer of out-of-order text. Notice how we change the color of the command window to red to warn the user of the impending deletion.
DELETE JSR KILLBUFF LDA #RED STA WINDCOLR JSR TOPCLR LDA # <DELMSG LDY # >DELMSG JSR PRMSG JSR GETAKEY PHA JSR SYSMSG PLA AND #95 ORA #64 CMP #'W BNE NOTWORD DELWORD JSR DEL1 JSR WLEFT JMP DEL2 NOTWORD CMP #'S BNE NOTSENT DELSENT JSR DEL1 JSR SLEFT JMP DEL2 NOTSENT CMP #'P BNE NOTPAR JSR DEL1 JSR PARLEFT JMP DEL2 NOTPAR RTS
Home the cursor. This is called by the START key. We check to see if START is held down for at least 1/2 second. If it is, we move the cursor to the top of text.
HOME SEC LDA CURR SBC TOPLIN STA TEMP LDA CURR+1 SBC TOPLIN+1 ORA TEMP BEQ TOPHOME LDA TOPLIN STA CURR LDA TOPLIN+1 STA CURR+1 WAITST LDA #0 STA 20 STA 53279 HOMEPAUSE LDA 20 CMP #30 BNE HOMEPAUSE OUTHOME JMP CHECK TOPHOME LDA TEXSTART STA CURR LDA TEXSTART+1 STA CURR+1 JMP WAITST
This deletes all spaces between the cursor and following nonspace text. Sometimes inventing labels can be fun.
EATSPACE LDA CURR STA TEX STA DESTL LDA CURR+1 STA TEX+1 STA DESTH LDY #0 SPCSRCH LDA (TEX),Y CMP #SPACE BNE OUTSPACE INY BNE SPCSRCH LDA TEX+1 CMP LASTLINE+1 BCC GOINC LDA LASTLINE STA TEX LDA LASTLINE+1 STA TEX+1 LDY #0 JMP OUTSPACE GOINC INC TEX+1 JMP SPCSRCH OUTSPACE CLC TYA ADC TEX STA FROML LDA #0 ADC TEX+1 STA FROMH SEC LDA LASTLINE SBC DESTL STA LLEN LDA LASTLINE+1 SBC DESTH STA HLEN SEC LDA FROML SBC DESTL STA GOBLEN LDA FROMH SBC DESTH STA GOBLEN+1 JSR UMOVE SEC LDA LASTLINE SBC GOBLEN STA LASTLINE LDA LASTLINE+1 SBC GOBLEN+1 STA LASTLINE+1 RTS
Insert 255 spaces. Notice how it and other insert routines use TAB2.
LOTTASPACE LDA #255 STA INSLEN JMP TAB2 TAB LDA #5 STA INSLEN JSR TAB2 LDA (CURR),Y CMP #SPACE BNE NOINCY INY NOINCY JMP ADYCURR TAB2 LDA #0 STA INSLEN+1 JSR INSBLOCK LDA #SPACE LDX INSLEN LDY #0 FILLSP STA (CURR),Y INY DEX BNE FILLSP RTS
Insert a single space.
INSCHAR LDA #1 STA INSLEN LDA #0 STA INSLEN+1 JSR INSBLOCK LDA #SPACE LDY #0 STA (CURR),Y JMP CHECK
A general routine to insert as many spaces as are specified by INSLEN.
INSBLOCK CLC LDA LASTLINE ADC INSLEN LDA LASTLINE+1 ADC INSLEN+1 CMP TEXEND+1 BCC OKINS PLA PLA JMP INOUT OKINS CLC LDA CURR STA FROML ADC INSLEN STA DESTL LDA CURR+1 STA FROMH ADC INSLEN+1 STA DESTH SEC LDA LASTLINE SBC FROML STA LLEN LDA LASTLINE+1 SBC FROMH STA HLEN JSR DMOVE CLC LDA LASTLINE ADC INSLEN STA LASTLINE LDA LASTLINE+1 ADC INSLEN+1 STA LASTLINE+1 INOUT RTS
Toggle insert mode. The INSMODE nag doubles as the color of the command line.
INSTGL LDA INSMODE EOR #BLUE STA INSMODE RTS
Another example of modular code. This is called anytime a yes/no response is called for. It prints “Are you sure? (Y/N),” then returns with the zero flag set to true if Y was pressed, ready for the calling routine to use BEQ or BNE as a branch for yes or no. We trap out the clear-screen key in case this routine is called by Erase All, since otherwise repeating keys may instantly cancel the command. The AND #223 zaps out the distinction between uppercase and lowercase Y.
YORN LDA # <YMSG LDY # >YMSG JSR PRMSG YORNKEY JSR GETIN AND #127 BEQ YORNKEY CMP #125 BEQ YORNKEY AND #223 CMP #'Y RTS
Erase all text. Allowed only if the OPTION key is held down with SHIFT-CLEAR. It calls YORN to affirm the deadly deed, then calls ERASE to erase all text, INIT2 to reset some flags, then jumps back to the MAIN loop. LDX #$FA / TXS is used to clean up the stack.
CLEAR LDA #8 STA 53279 LDA 53279 CMP #3 BEQ OKCLEAR RTS OKCLEAR LDA #RED STA WINDCOLR JSR TOPCLR LDA # <CLRMSG LDY # >CLRMSG JSR PRMSG JSR YORN BEQ DOIT JMP SYSMSG DOIT LDX #$FA TXS JSR ERASE JSR INIT2 JMP MAIN
Paragraph right.
PARIGHT LDY #0 PARLP LDA (CURR),Y CMP #RETCHAR BEQ RETFOUND INY BNE PARLP INC CURR+1 LDA CURR+1 CMP LASTLINE+1 BCC PARLP BEQ PARLP JMP LASTWORD RETFOUND INY BNE GOADY INC CURR+1 GOADY JMP ADYCURR
Paragraph left. Notice the trick of decrementing the high byte of the pointer, then starting the index at 255 in order to search backward.
PARLEFT LDA CURR STA TEX LDA CURR+1 STA TEX+1 DEC TEX+1 LDY #$FF PARLOOP LDA (TEX),Y CMP #RETCHAR BEQ RETF2 PARCONT DEY CPY #255 BNE PARLOOP DEC TEX+1 LDA TEX+1 CMP TEXSTART+1 BCS PARLOOP JMP FIRSTWORD RETF2 SEC TYA ADC TEX STA TEX LDA #0 ADC TEX+1 STA TEX+1 SEC LDA TEX SBC CURR STA TEMP LDA TEX+1 SBC CURR+1 ORA TEMP BNE TEXTOCURR STY TEMP CLC LDA TEX SBC TEMP STA TEX LDA TEX+1 SBC #0 STA TEX+1 JMP PARCONT TEXTOCURR LDA TEX STA CURR LDA TEX+1 STA CURR+1 JMP CHECK
This enables the display-list interrupt (DLI). The DLI allows separate background colors for the command line and the rest of the screen. It lets us change the color of the top line to flag insert mode or to warn the user with a red color that he/she should be careful. Since it is an interrupt, it is always running in the background. Interrupt routines must always be careful not to corrupt the main program.
HIGHLIGHT turns off any DLIs (by storing #64 into $D40E), sets the NMI pointer ($200/$201), creates a custom display list of IRG mode 3 (lowercase descenders, GRAPHICS 0 1/2) With DLI set in one line, then enables DLIs ($C0 into $D40E) and returns. The routine DLI is now running constantly in the background, changing the screen color of all text below the DLI.
HIGHLIGHT LDA #64 STA $D40E LDA # <DLI STA $0200 LDA # >DLI STA $0201 LDA 560 STA TEMP LDA 561 STA TEMP+1 LDY #0 DLOOP LDA DLIST,Y STA (TEMP),Y INY CPY #28 BNE DLOOP LDY #4 LDA $58 STA (TEMP),Y LDA $59 INY STA (TEMP),Y LDY #26 LDA TEMP STA (TEMP),Y LDA TEMP+1 INY STA (TEMP),Y LDA #$C0 STA $D40E RTS
The custom display list.
DLIST .BYTE 112,112,112,3+64+128,0,0 .BYTE 3,3,3,3,3,3,3,3,3,3,3,3,3 .BYTE 3,3,3,3,3,16,65,0,0
The display-list interrupt routine stores the SCReen COLor and TEXt COLoR into the appropriate hardware registers, then stores the WINDow COLoR into 710, and #10 into 709 to set the color of the top line of the screen. This line is automatically set by the normal vertical-blank interrupt. We also force the character-set pointer to keep our character set in place whenever we’re on the editing screen.
DLI PHA LDA SCRCOL STA $D40A STA $D018 STA 712 LDA TEXCOLR STA $D017 LDA WINDCOLR STA 710 LDA #10 STA 709 LDA #$20 STA 756 LDA #0 STA $02B6 PLA RTI
ERAS is called by CTRL-E. It works much like CTRL-D. Notice that the ORA #64 allows users to press either S, W, P, or CTRL-S, CTRL-W, CTRL-P, in case they have a habit of leaving the control key held down. It must call REFRESH after each move and adjust the new position of the cursor. If OPTION is held down with CTRL-E, we don’t erase the previous contents of the buffer, letting the user chain non-contiguous sections into the buffer for later recall.
ERAS LDA #8 STA 53279 LDA 53279 CMP #3 BEQ ERAS1 JSR KILLBUFF ERAS1 JSR TOPCLR LDA # <ERASMSG LDY # >ERASMSG JSR PRMSG ERASAGAIN LDY #0 LDA (CURR),Y EOR #$80 STA (CURR),Y JSR REFRESH LDY #0 LDA (CURR),Y EOR #$80 STA (CURR),Y LDA #RED STA WINDCOLR JSR GETAKEY AND #95 ORA #64 CMP #'W BNE NOWORD ERASWORD JSR ERA1 JSR WRIGHT JMP ERA2 NOWORD CMP #'S BNE UNSENT ERASENT JSR ERA1 JSR SRIGHT JMP ERA2 UNSENT CMP #'P BNE NOPAR JSR ERA1 JSR PARIGHT JMP ERA2 NOPAR JSR CHECK JMP SYSMSG ERA1 LDA CURR STA DESTL STA SAVCURR LDA CURR+1 STA DESTH STA SAVCURR+1 RTS ERA2 SEC LDA CURR STA FROML SBC SAVCURR STA GOBLEN LDA CURR+1 STA FROMH SBC SAVCURR+1 STA GOBLEN+1 JSR DELC LDA SAVCURR STA CURR LDA SAVCURR+1 STA CURR+1 JSR REFRESH JMP ERASAGAIN
The INPUT routine is used to get responses from the command line. It returns the complete line in INBUFF. INLEN is the length of the input. A zero byte is stored at INBUFF+INLEN after the user presses RETURN. This routine is foolproof (I know...), since no control keys other than BACK S are allowed, unless preceded by ESCape. The SELECT key can be held down to enter inverse-video characters. The system cursor is turned on for this routine (by putting #0 into 752), then turned off when we exit (by putting #1 into 752). This routine also prevents the user from typing past the end of the command line. If the limit of typing length must be set arbitrarily, LIMIT is preset and INPUT is called at INP1. CURSIN is the MAIN loop.
INPUT LDA #39 SBC 85 STA LIMIT INP1 LDY #0 STY INLEN STY 752 LDA #32 JSR CHROUT LDA #126 JSR CHROUT CURSIN STY INLEN JSR GETAKEY LDY INLEN BIT ESCFLAG BMI ESCKEY CMP #27 BNE NOESC LDA #128 STA ESCFLAG STA $02A2 JMP CURSIN NOESC CMP #155 BEQ INEXIT CMP #126 BNE NOBACK DEY BPL NOTZERO INY JMP CURSIN NOTZERO LDA #126 JSR CHROUT JMP CURSIN NOBACK STA TEMP AND #127 CMP #32 BCC CURSIN CMP #125 BCS CURSIN CPY LIMIT BEQ CURSIN LDA TEMP ESCKEY AND #127 LDX #8 STX 53279 LDX 53279 CPX #5 BNE SKIPSEL ORA #128 SKIPSEL STA INBUFF,Y JSR CHROUT LDA #0 STA ESCFLAG INY JMP CURSIN INEXIT LDX #1 STX 752 LDA #0 STA INBUFF,Y TYA RTS .END
Filename: SUPPORT
This module supports most primitive input/output functions, including a routine to clear the screen and reset the screen editor (OPENEDITOR), print a character (CHROUT), and get a key from the keyboard (GETAKEY).
OPENEDITOR LDX #0 LDA #12 STA ICCOM JSR CIO LDX #0 LDA # <ENAME STA ICBADR LDA # >ENAME STA ICBADR+1 LDA #2 STA ICBLEN STX ICBLEN+1 LDA #3 STA ICCOM,X JMP CIO
Put the ATASCII value of the character into the accumulator and call CHROUT to print a character. The Y register is preserved. We call CIO with a buffer length of zero.
CHROUT STY CHRYSAVE LDX #0 STX ICBLEN STX ICBLEN+1 STX $02FF LDY #11 STY ICCOM JSR CIO LDY CHRYSAVE RTS
The filename of the Editor device.
ENAME .BYTE "E:"
OUTNUM and PROUTNUM print decimal numbers to the display or printer. The integer to be printed is passed with the low byte in the X register and the high byte in the accumulator. The integer to floating-point routine ($D9AA) is called first, followed by floating-point to ATASCII routine, which creates a string of ATASCII digits. The last digit of the number has bit 7 set, which we use to terminate printing.
PROUTNUM LDY #128 JMP OVERZAP OUTNUM LDY #0 OVERZAP STY WHICHFLAG STX $D4 STA $D5 JSR $D9AA JSR $D8E6 LDY #0 ONUMLOOP LDA ($F3),Y PHA AND #$7F BIT WHICHFLAG BMI GOPCHR JSR CHROUT JMP OVERPCHR GOPCHR JSR PCHROUT OVERPCHR PLA BMI ONUMEXIT INY BNE ONUMLOOP ONUMEXIT RTS CHRYSAVE .BYTE 0
The system keyboard fetch routine interferes with the display-list interrupt, since the blip of each key is timed with WSYNC, which freezes the ANTIC chip for one line. This causes annoying flicker. This routine uses POKEY sound decaying from volume 15 to 0 for the keyboard feedback tone. It’s not hard to create any sound effect you want for the keyboard blip. This routine mimics the system routine fairly closely. It’s easy to expand it to allow many more keyboard functions and full processing of new keystrokes just by changing some of this code and the keyboard table.
GETIN LDA 764 CMP #$FF BNE GETCHAR LDA #0 RTS GETCHAR LDA 764 CMP #$FF BEQ GETCHAR STA KEYVAL LDA #$FF STA 764
Clear break flag.
STA $11 JSR BLIP LDA KEYVAL
Check for SHIFT+CTRL.
CMP #$C0 BCS GXIT AND #63 CMP #60 BNE NOTCAPS LDA KEYVAL AND #64 BEQ NOTSET STA SHFLOK GXIT LDA #0 RTS
The CAPS/LOWR key toggles the SHiFtLOcK flag to allow either only uppercase, or both uppercase and lowercase.
NOTSET LDA SHFLOK EOR #64 STA SHFLOK LDA #0 RTS NOTCAPS LDX KEYVAL LDA KEYBOARD,X BIT SHFLOK BVC NOTLOCKED CMP #'a BCC NOTLOCKED CMP #'z+1 BCS NOTLOCKED AND #223 NOTLOCKED CMP #$80 BEQ GXIT RTS
The sound effect for the keyboard “blip.”
BLIP PHA LDA #50 STA $D200 LDX #$AF SNDLOOP STX $D201 LDY #128 SLOW DEY BNE SLOW DEX CPX #$9F BNE SNDLOOP PLA RTS KEYBOARD .BYTE 108,106,59,128,128,107 .BYTE 43,42,111,128,112,117 .BYTE 155,105,45,61,118,128 .BYTE 99,128,128,98,120,122 .BYTE 52,128,51,54,27,53 .BYTE 50,49,44,32,46,110 .BYTE 128,109,47,$80,114,128 .BYTE 101,121,127,116,119,113 .BYTE 57,128,48,55,126,56 .BYTE 60,62,102,104,100,128 .BYTE 130,103,115,97,76,74 .BYTE 58,128,128,75,92,94 .BYTE 79,128,80,85,155,73 .BYTE 95,124,86,128,67,128 .BYTE 128,66,88,90,36,128 .BYTE 35,38,27,37,34,33 .BYTE 91,32,93,78,128,77 .BYTE 63,$80,82,128,69,89 .BYTE 159,84,87,81,40,128 .BYTE 41,39,156,64,125,157 .BYTE 70,72,68,128,131,71 .BYTE 83,65,12,10,123,128 .BYTE 128,11,30,31,15,128 .BYTE 16,21,155,9,28,29 .BYTE 22,128,3,128,128,2 .BYTE 24,26,128,128,133,128 .BYTE 27,128,253,128,0,32 .BYTE 96,14,128,13,128,$80 .BYTE 18,128,5,25,158,20 .BYTE 23,17,128,128,128,128 .BYTE 254,128,125,255,6,8 .BYTE 4,128,132,7,19,1 .END
Filename: DOSPAK
DOSPAK is a self-contained substitute for the DOS menu, although it uses several routines built into SpeedScript. The concept of DOSPAK is that all directory entries should fit on one screen. A large cursor is used to move from filename to filename. At any time, you can delete, rename, lock, unlock, or load the selected filename, just by pressing one key, or a CTRL key combination. Except for Rename, you don’t have to type the filename. You can also format the entire disk or redisplay the directory.
CATALOG fits the entire disk directory onto the screen by skipping over the sector counts, trimming up spacing, and placing three items per line. The cursor position of each filename is saved into a slot in memory so that the cursor routine can quickly and easily skip about.
CATALOG JSR CLOSE7 LDX #$70 LDA # <DIRNAME STA ICBADR,X LDA # >DIRNAME STA ICBADR+1,X LDA #5 STA ICBLEN,X LDA #0 STA ICBLEN+1,X LDA #6 STA ICAUX1,X LDA #3 STA ICCOM,X JSR CIO BMI CLOSE7 LDA #0 STA XPTR REDIR LDX XPTR LDA $64 STA SLOT,X LDA $65 STA SLOT+1,X INC XPTR INC XPTR JSR GET7 BMI CLOSE7 CMP #'*+1 BCS ENDIR JSR CHROUT JSR GET7 BMI CLOSE7 LDA #0 STA DIRCOUNT DIRLOOP JSR GET7 BMI CLOSE7 DNOTCR JSR CHROUT INC DIRCOUNT LDA DIRCOUNT CMP #8 BNE DNOT8 LDA #'. JSR CHROUT JMP DIRLOOP DNOT8 CMP #11 BNE DIRLOOP LDA #5 STA TEMP THROW5 JSR GET7 DEC TEMP LDA TEMP BNE THROW5 JMP REDIR CLOSE7 LDX #$70 LDA #12 STA ICCOM,X JSR CIO LDX #$70 LDY ICSTAT,X RTS ENDIR PHA LDA #155 JSR CHROUT PLA JSR CHROUT ENDLP JSR GET7 BMI CLOSE7 JSR CHROUT JMP ENDLP GET7 LDX #$70 LDA #0 STA ICBLEN,X STA ICBLEN+1,X LDA #7 STA ICCOM,X JMP CIO
The main DOS routine calls the CATALOG routine to fill the screen with filenames, then puts the cursor on the current filename, waiting for a keypress.
DOS JSR DELITE JSR OPENEDITOR JSR DELITE LDA #1 STA 752 STA 82 LDA #125 JSR CHROUT JSR CATALOG JSR DOSMSG GETNAME LDA SLOT STA SCR LDA SLOT+1 STA SCR+1 LDA #0 STA XSLOT DEC XPTR DEC XPTR NAMELP JSR INVNAME JSR GETAKEY LDX #1 STX 752
Now that we’ve got a keypress, we look it up in the keypress table, then vector to the appropriate routine. This is the same ML ON-GOTO routine that we’ve used in several places in SpeedScript, including the CONTROL routine.
LDX DOSTABLE CMP #97 BCC NOPROB AND #95 NOPROB STA TEMP FINDIT CMP DOSTABLE,X BEQ FOUNDIT DEX BNE FINDIT JMP JNAME FOUNDIT DEX TXA ASL A TAX LDA DOSADR+1,X PHA LDA DOSADR,X PHA RTS
The braces surround control characters, some entered with the ESCape key: cursor-left, cursor-right, cursor-up, cursor-down, CTRL-D, ESCape, and CTRL-L.
DOSTABLE .BYTE 15 .BYTE "{LEFT}{RIGHT}{UP}{DOWN}{D}RLUF1234{ESC}{L}" DOSADR .WORD DLEFT-1,DRIGHT-1,DUP-1,DDOWN-1,DELFILE-1,RENAME-1 .WORD LOCK-1,UNLOCK-1,FORMAT-1,DRIVE-1,DRIVE-1,DRIVE-1 .WORD DRIVE-1,ESCDOS-1,LOADIT-1
Move bar cursor left by decrementing slot pointer.
DLEFT JSR INVNAME LDX XSLOT BEQ NRANGE DEX DEX JMP RESLOT
Move bar cursor right by incrementing slot pointer.
DRIGHT JSR INVNAME LDX XSLOT INX INX CPX XPTR BCS NRANGE
Store new slot index.
RESLOT STX XSLOT LDA SLOT,X STA SCR LDA SLOT+1,X STA SCR+1 NRANGE JMP NAMELP
Move bar cursor up by subtracting 6 from the slot pointer (each slot is two bytes).
DUP JSR INVNAME LDA XSLOT CMP #6 BCC NRANGE SEC SBC #6 TAX JMP RESLOT
Move bar cursor down by adding 6 to the slot pointer.
DDOWN JSR INVNAME LDA XSLOT CLC ADC #6 CMP XPTR BCS NRANGE TAX JMP RESLOT
This routine turns a filename pointed to by the bar cursor into a legal CIO filename, complete with Dx: and legal extension.
NAMER LDX #0 COPYD LDA DIRNAME,X STA FNBUFF,X INX CPX #3 BNE COPYD LDY #1 COPYNAME LDA (SCR),Y AND #127 JSR INTOAS CMP #32 BEQ NOSTOR STA FNBUFF,X INX NOSTOR INY CPY #13 BNE COPYNAME LDA FNBUFF-1,X CMP #'. BNE NOTDOT DEX NOTDOT STX FNLEN LDA #0 STA FNBUFF,X RTS
This routine passes any CIO command along with a formed filename.
XIO LDX #$70 STA ICCOM,X LDA FNLEN STA ICBLEN,X LDA #0 STA ICBLEN+1,X LDA # <FNBUFF STA ICBADR,X LDA # >FNBUFF STA ICBADR+1,X JMP CIO
The DOS functions are quite short. NAMER builds the name; then we simply pass the number of the DOS CIO function unto XIO. If there’s no error, we return to waiting for the next keystroke; otherwise, print the DOS error message and wait for a keystroke.
DELFILE JSR NAMER LDA #33
Jump to the XIO routine.
GOXIO JSR XIO BPL JNAME JMP DOSERR JNAME JSR INVNAME JMP NAMELP
Lock a file.
LOCK JSR NAMER LDA #35 JMP GOXIO
Unlock a file.
UNLOCK JSR NAMER LDA #36 JMP GOXIO
We ask for the new name of the file, build the rename string, then jump to the XIO routine.
RENAME JSR BOTCLR LDA # <RENMSG LDY # >RENMSG JSR PRMSG LDA #64 STA $02BE JSR INPUT LDA #0 STA $02BE LDA INLEN BEQ NONAME JSR NAMER LDX #0 LDY FNLEN LDA #', STA FNBUFF,Y INY COPYR LDA INBUFF,X STA FNBUFF,Y INY INX CPX INLEN BNE COPYR STY FNLEN LDA #0 STA FNBUFF,Y JSR DOSMSG LDA #32 JMP GOXIO NONAME JSR DOSMSG JMP JNAME
Format routine. We use YORN to af firm this operation, which erases an entire disk. BOTCLR clears the bottom line of the screen.
FORMAT JSR BOTCLR LDA # <FORMSG LDY # >FORMSG JSR PRMSG JSR YORN BNE NONAME JSR DOSMSG JSR NAMER LDA #254 JMP GOXIO
Select new drive number and redisplay directory.
DRIVE LDA TEMP STA DIRNAME+1 JMP DOS
The Load-from-directory routine opens the file, then jumps into the SpeedScript Load routine.
LOADIT LDX #$70 STX IOCB LDA #4 STA ICAUX1,X LDA #0 STA INDIR STA INDIR+1 JSR NAMER
Command 3 is for OPEN file.
LDA #3 JSR XIO BMI DOSERR JSR ERASE JSR LOADLINK
If the load ended with an error, we display the error; otherwise, we exit the DOSPAK at ESCDOS.
BMI DOSERR
The ESCape DOS routine clears the stack, clears the screen, reenables the display-list interrupt, prints the “SpeedScript” message, then jumps back to the editing loop.
ESCDOS LDX #$FA TXS LDA #125 JSR CHROUT JSR HIGHLIGHT JSR SYSMSG JMP MAIN
BOTCLR erases the bottom two lines of the screen by positioning the cursor on the next-to-the-last line, then printing two INSERT LINE characters that push any text on these lines off the bottom of the screen. Nifty, eh?
BOTCLR LDA #22 STA 84 LDA #157 JSR CHROUT JMP CHROUT
This is the error routine for the DOSPAK. We print “ERROR #”, then print the error number with OUTNUM, a bell character (actually sounds like an annoying buzzer, appropriate Pavlovian treatment), then “Press RETURN.” We wait for a keystroke, then return to getting keys for the DOSPAK commands.
DOSERR STY YSAVE JSR CLOSE7 JSR BOTCLR LDA # <ERRMSG LDY # >ERRMSG JSR PRMSG LDX YSAVE LDA #0 JSR OUTNUM LDA #253 JSR CHROUT LDA # <DIRMSG LDY # >DIRMSG JSR PRMSG JSR GETAKEY JSR DOSMSG JMP JNAME
Inverse the filename field of the currently selected filename. Used to create the bar cursor.
INVNAME LDY #12 INVLP LDA (SCR),Y EOR #128 STA (SCR),Y DEY BPL INVLP RTS
DOSMSG erases the bottom line of the screen and prints the DOSPAK command line, an abbreviated menu.
DOSMSG JSR BOTCLR LDA # <DIRINS LDY # >DIRINS JSR PRMSG LDA DIRNAME+1 JMP CHROUT .END
Filename: SPEED.2
This is the main input/output portion of SpeedScript, responsible for loading, saving, and all printing functions.
CAST and CINSTOAS (standing for Convert to ASCII and Convert INTernal code to ASCII) translate the way SpeedScript stores text in memory (internal screen codes) into ASCII so that disk files will be compatible with most other software. In addition, the return-mark is changed to character 155, and vice versa. This is why you can’t load a machine language file into SpeedScript, edit it, then save it back as a runnable modification. All back-arrows are turned into carriage returns on output, and all carriage returns (155’s) are turned into back-arrows (30’s) on input.
CAST LDA #0 STA CONVFLAG JMP CAST1 CINTOAS LDA #128 STA CONVFLAG CAST1 LDA TEXSTART STA TEX LDA TEXSTART+1 STA TEX+1 JMP CIN CASTOIN LDA #0 STA CONVFLAG LDA CURR STA TEX LDA CURR+1 STA TEX+1 CIN SEC LDA LASTLINE+1 SBC TEX+1 TAX INX LDY #0 CVLOOP LDA (TEX),Y BIT CONVFLAG BMI COTHER CMP #155 BNE NOTRTN LDA #RETCHAR JMP OVEROTHER NOTRTN JSR ASTOIN JMP OVEROTHER COTHER CMP #RETCHAR BNE NOTRC LDA #155 JMP OVEROTHER NOTRC JSR INTOAS OVEROTHER STA (TEX),Y INY BNE CVLOOP INC TEX+1 DEX BNE CVLOOP RTS
Here is where most of the input/output routines start. TSAVE saves the entire document area using the CIO block output routine (PUT TEXT). TOPEN is called by both TSAVE and TLOAD to get the filename and open the file. The device specification (D: or C:) must be typed in by the user.
TSAVE prints the Save: prompt, goes to TOPEN with an 8 (for output, the same number in OPEN 1,8,0,"D:file"), and uses IOCB #7 (LDX #$70) to send a PUT TEXT command (11). Text is written from the start-of-text with a length of LASTLINE − TEXSTART.
TSAVE JSR TOPCLR LDA # <SAVMSG LDY # >SAVMSG JSR PRMSG LDA #8 JSR TOPEN BMI ERROR JSR CINTOAS LDX #$70 LDA TEXSTART STA ICBADR,X LDA TEXSTART+1 STA ICBADR+1,X SEC LDA LASTLINE SBC TEXSTART STA ICBLEN,X LDA LASTLINE+1 SBC TEXSTART+1 STA ICBLEN+1,X LDA #11 STA ICCOM,X JSR CIO
The N (negative) bit is set when an error occurs after a call to CIO or a routine that ends up calling CIO. Therefore, we can use BMI to branch on an error condition.
BMI ERR1 JSR CAST JSR CLOSE7 BMI ERROR JMP FINE ERR1 TYA PHA JSR CAST PLA TAY
The error routine uses the error number found in the Y register, prints the error message with PRMSG, and the error number with OUTNUM. The open file is closed. If the BREAK key was used to stop the operation, we distinguish this from an ordinary error, and print “BREAK Abort” instead.
ERROR CPY #128 BEQ STOPPED TYA PHA LDA #125 JSR CHROUT LDA # <ERRMSG LDY # >ERRMSG JSR PRMSG PLA TAX LDA #0 JSR OUTNUM ERXIT JSR IOCLOSE JSR HIGHLIGHT LDA #1 STA MSGFLG RTS STOPPED JSR TOPCLR LDA # <BRMSG LDY # >BRMSG JSR PRMSG JMP ERXIT
General file closing routine. IOCB contains the channel number times 16.
IOCLOSE LDX IOCB LDA #12 STA ICCOM,X JMP CIO
TOPEN is used to get a filename, including the device specification. It’s used by Save, Load, and Print. It forces the CAPS key to uppercase for the filename, which is not quite as satisfactory as converting the filename if lowercase was used. It does return the CAPS key to its former value, though. TOPEN opens the file and returns with the error code in the Y register.
TOPEN LDX #$70 STX IOCB STA ACCESS
Save current CAPS value.
LDA SHFLOK PHA
CAPS On.
LDA #64 STA SHFLOK JSR INPUT
Restore CAPS value.
PLA STA SHFLOK LDA INLEN BNE OPCONT OPABORT JSR SYSMSG PLA PLA JMP HIGHLIGHT OPCONT JSR IOCLOSE LDX IOCB LDA # <INBUFF STA ICBADR,X LDA # >INBUFF STA ICBADR+1,X LDA INLEN STA ICBLEN,X LDA #0 STA ICBLEN+1,X LDA ACCESS STA ICAUX1,X LDA #3 STA ICCOM,X JMP CIO
The Load routine checks the cursor position. If the cursor is at the top-of-text (CURR=TEXSTART), we call the ERASE routine to wipe out memory before the load. Otherwise, the load starts at the cursor position, performing an append, and we change the command line to green ($C4, sorry about not using a label) to warn the user. We open the file for reading by passing a 4 to TOPEN, then at LOADLINK use GET TEXT (command 7) to get no more than the length of the text area. The actual length loaded is found in ICBLEN, so we add this to TEXSTART and the offset between the cursor position and TEXSTART to get the position of the end-of-text (LASTLINE).
A funny thing happens, though. Up to 255 garbage characters appear following an otherwise normal load, after the end-of-text. I was never able to figure out why (and I puzzled over it for a week), so I wrote a stopgap routine to just clear out one page past the end-of-text. The bug is not fixed per se, but it has no effect anymore! I still think it must be the fault of the operating system (I know...).
TLOAD SEC LDA CURR SBC TEXSTART STA TEX STA INDIR LDA CURR+1 SBC TEXSTART+1 STA TEX+1 STA INDIR+1 ORA TEX BEQ LOAD2 LDA #$C4 STA WINDCOLR LOAD2 JSR TOPCLR LDA # <LOADMSG LDY # >LOADMSG JSR PRMSG LDA #4 JSR TOPEN BPL OKLOD GOERROR JMP ERROR OKLOD LDA WINDCOLR CMP #$C4 BEQ NOER JSR ERASE NOER JSR LOADLINK CPY #128 BCC JFINE JMP ERROR JFINE JMP FINE
Entry point for linked files loading.
LOADLINK LDX IOCB LDA CURR STA ICBADR,X LDA CURR+1 STA ICBADR+1,X SEC LDA TEXEND SBC CURR STA ICBLEN,X LDA TEXEND+1 SBC CURR+1 STA ICBLEN+1,X LDA #7 STA ICCOM,X JSR CIO BPL TEXOK CPY #136 BEQ TEXOK RTS TEXOK LDX IOCB CLC LDA ICBLEN,X ADC TEXSTART STA LASTLINE LDA ICBLEN+1,X ADC TEXSTART+1 STA LASTLINE+1 CLC LDA LASTLINE ADC INDIR STA LASTLINE LDA LASTLINE+1 ADC INDIR+1 STA LASTLINE+1 JSR CASTOIN LDA LASTLINE STA TEX LDA LASTLINE+1 STA TEX+1 LDA #0 TAY NOGARBAGE STA (TEX),Y INY BNE NOGARBAGE RTS FINE JSR IOCLOSE BPL PROKMSG JMP ERROR PROKMSG LDA #125 JSR CHROUT LDA # <OKMSG LDY # >OKMSG JSR PRMSG JMP ERXIT
Disable display-list interrupt and restore screen colors.
DELITE LDA #$40 STA $D40E LDA SCRCOL STA 710 STA 712 LDA TEXCOLR STA 709 RTS
A rather short routine that converts a string of ASCII digits into a number in hex and the accumulator. It takes advantage of decimal mode. In decimal mode, the accumulator is adjusted after additions and subtractions so that it acts like a two-digit decimal counter. We shift BCD over a nybble and add in the left nybble of the ASCII number until we reach the end of the ASCII number. We then subtract 1 from BCD and increment X (which doesn’t conform to decimal mode) until BCD is down to 0. The X register magically holds the converted number. Naturally, decimal mode is cleared before this routine exits, or it would wreak major havoc. ASCHEX is used to convert the parameters of printer commands like left margin.
ASCHEX LDX #0 STX BCD STX BCD+1 STX HEX STX HEX+1 DIGIT SEC LDA (TEX),Y SBC #16 BCC NONUM CMP #10 BCS NONUM ASL BCD ROL BCD+1 ASL BCD ROL BCD+1 ASL BCD ROL BCD+1 ASL BCD ROL BCD+1 ORA BCD STA BCD INY BNE DIGIT INC TEX+1 JMP DIGIT NONUM SED DECHEX LDA BCD ORA BCD+1 BEQ DONENUM SEC LDA BCD SBC #1 STA BCD LDA BCD+1 SBC #0 STA BCD+1 INC HEX BNE NOHEXINC INC HEX+1 NOHEXINC JMP DECHEX DONENUM LDA HEX CLD RTS
Insert the buffer. This is the recall routine called by CTRL-R. It must not allow an insertion that would overfill memory. It calls DMOVE to open a space in memory, then UMOVE (which is a little faster than DMOVE) to copy the buffer to the empty space.
INSBUFFER SEC LDA TPTR SBC TEXBUF STA BUFLEN LDA TPTR+1 SBC TEXBUF+1 STA BUFLEN+1 ORA BUFLEN BNE OKBUFF JSR TOPCLR LDA # <INSMSG LDY # >INSMSG JSR PRMSG LDA #1 STA MSGFLG RTS OKBUFF CLC LDA CURR STA FROML ADC BUFLEN STA DESTL LDA CURR+1 STA FROMH ADC BUFLEN+1 STA DESTH SEC LDA LASTLINE SBC FROML STA LLEN LDA LASTLINE+1 SBC FROMH STA HLEN CLC ADC DESTH CMP TEXEND+1 BCC OKMOV JSR TOPCLR LDA # <INSERR LDY # >INSERR JSR PRMSG LDA #1 STA MSGFLG RTS OKMOV JSR DMOVE CLC LDA BUFLEN STA LLEN ADC LASTLINE STA LASTLINE LDA BUFLEN+1 STA HLEN ADC LASTLINE+1 STA LASTLINE+1 LDA CURR STA DESTL LDA CURR+1 STA DESTH LDA TEXBUF STA FROML LDA TEXBUF+1 STA FROMH JSR UMOVE JMP CHECK
Exchange the character highlighted by the cursor with the character to the right of it. Not a vital command, but it was included due to the brevity of the code.
SWITCH LDY #0 LDA (CURR),Y TAX INY LDA (CURR),Y DEY STA (CURR),Y INY TXA STA (CURR),Y RTS
Change the case of the character highlighted by the cursor.
ALPHA LDY #0 LDA (CURR),Y AND #63 CMP #33 BCC NOTALPHA CMP #59 BCS NOTALPHA LDA (CURR),Y EOR #64 STA (CURR),Y NOTALPHA JMP RIGHT
Convert internal (screen code) format to Atari ASCII (ATASCII). Used to convert the screen-code format of SpeedScript documents to ASCII for the sake of printing.
INTOAS PHA AND #128 STA TEMP PLA AND #127 CMP #96 BCS XINT INCONT CMP #64 BCC INT1 SBC #64 JMP XINT INT1 ADC #32 XINT ORA TEMP RTS
The start of the printer routines. This part could logically be called a separate program, but many variables are common to the above code.
DEFTAB: Table of default settings for left margin, right margin, page length, top margin, bottom margin, etc. See the table starting at LMARGIN at the end of this source code.
DEFTAB .BYTE 5,75,66,5,58,1,1,1,0,1,0,80
Table of default printer codes.
PRCODES .BYTE 27,14,15,18
Another advantage of modular coding is that you can change the behavior of a lot of code by just changing one small common routine. This is a substitute for the normal CHROUT routine. It checks to see if the current page number equals the page number specified by the user to start printing. It also checks for the BREAK to abort the printing and permits printing to be paused with CTRL-1.
PCHROUT STA PCR TXA PHA TYA PHA SEC LDA PAGENUM SBC STARTNUM LDA PAGENUM+1 SBC STARTNUM+1 BCC SKIPOUT LDA #1 STA 766 LDX #$70 LDA #0 STA ICBLEN,X STA ICBLEN+1,X LDA #11 STA ICCOM,X LDA PCR JSR CIO PHP LDA #0 STA 766 PLP BPL SHIFTFREEZE ERRLINK JSR ERROR LDX #$FA TXS JMP MAIN SHIFTFREEZE LDA $02FF ;CTRL-1 BNE SHIFTFREEZE SKIPOUT PLA TAY PLA TAX LDA PCR RTS
Displays “Printing...”
PRIN JSR TOPCLR LDA # <PRINMSG LDY # >PRINMSG JMP PRMSG PBORT JMP PEXIT
Called by CTRL-P. We get the filename to print to (usually P:, although you can use E: to print to the screen) with ICAUX1 set to 8 for output. We exit on any error. The DELITE routine turns off the display-list interrupt, which might otherwise interfere with output timing.
PRINT JSR TOPCLR LDA # <FNMSG LDY # >FNMSG JSR PRMSG JSR DELITE LDA #8 JSR TOPEN BPL PROK JMP PEXIT
Reset several flags (footer length, header length, true ASCII, underline mode, and linefeed mode). Notice how DELITE is called again. This isn’t a mistake. The first time we called DELITE, we then may have opened a file to the Editor device. This reset the screen to the default colors, so the second DELITE retains the user’s true color choice.
PROK JSR DELITE JSR PRIN LDX #0 STX FTLEN STX HDLEN STX NEEDASC STX UNDERLINE STX LINEFEED
Copy definition tables and default printercodes.
COPYDEF LDA DEFTAB,X STA LMARGIN,X INX CPX #12 BNE COPYDEF LDA #$FF STA LINE STA NOMARG LDX #4 COPYDEFS LDA PRCODES-1,X STA CODEBUFFER+16,X DEX BNE COPYDEFS
Reentry point for printing after linked files.
RETEX LDA TEXSTART STA TEX LDA TEXSTART+1 STA TEX+1
Main printing loop. We print the left margin, grab a line of text, scan backward until we find a space or a carriage return, then break the line there. If printer codes are encountered, they’re passed on to the SPECIAL routine. Otherwise, we end up calling BUFPRT to print the line and process some other control codes.
PLOOP LDY #0 STY POS CPY NOMARG BEQ PLOOP1 LDA LMARGIN STA POS PLOOP1 LDA (TEX),Y BPL NOTSP JMP SPECIAL NOTSP CMP #RETCHAR BEQ FOUNDSPACE NOTRET STA PRBUFF,Y INY INC POS LDA POS CMP RMARGIN BCC PLOOP1 STY FINPOS FINDSPACE LDA (TEX),Y CMP #SPACE BEQ FOUNDSPACE DEC POS DEY BNE FINDSPACE LDY FINPOS FSPACE INY LDA (TEX),Y CMP #SPACE BEQ FOUNDSPACE DEY FOUNDSPACE STY FINPOS OVERSTOR TYA SEC ADC TEX STA TEX LDA TEX+1 ADC #0 STA TEX+1 LDY #0
If this is the first page, we need to print the header, if any, with JSR TOP.
DOBUFF LDA LINE CMP #$FF BNE DOBUF2 JSR TOP DOBUF2 LDA NOMARG BEQ OVERMARG JSR LMARG OVERMARG SEC ROL NOMARG LDA FINPOS STA ENDPOS LDA # <PRBUFF STA INDIR LDA # >PRBUFF STA INDIR+1 JSR BUFPRT
A line has been printed. We check to see if we’ve hit the bottom margin and, if so, go to PAGE, which goes to the end of the page, prints the footer (if any), and feeds to the next page.
ZBUFF JSR CRLF LDA LINE CMP BOTMARG BCC NOTPAGE JSR PAGE
Have we reached the end-of-text?
NOTPAGE SEC LDA TEX SBC LASTLINE STA TEMP LDA TEX+1 SBC LASTLINE+1 ORA TEMP BEQ DORPT BCC DORPT
If so, we check for a footer. If there is one, we set HDLEN and TOPMARG to 0 (so that the printhead will end up at the right place on the last page) and call PAGE, which prints the footer. If there is no footer, we leave the printhead on the same page so that paper isn’t wasted.
LDA FTLEN BEQ PXIT LDA #0 STA HDLEN STA TOPMARG JSR PAGE
Exit routines. If screen output was selected, we wait for a keystroke before going back to editing mode.
PXIT LDA INBUFF CMP #'E BNE PEXIT LDA #155 JSR CHROUT LDA # <DIRMSG LDY # >DIRMSG JSR PRMSG JSR GETAKEY PEXIT JSR CLOSE7 LDX #$FA TXS JSR HIGHLIGHT LDA #125 JSR CHROUT JSR SYSMSG JMP MAIN DORPT JMP PLOOP
Paging routines. We skip (PAGELENGTH − LINE) — two blank lines to get to the bottom of the page, print a footer (if there is one) or a blank line (if not), then page to the beginning of the next page, skipping over the paper perforation. If the wait mode is enabled, we wait for the user to insert a new sheet of paper.
PAGE SEC LDA PAGELENGTH SBC LINE TAY DEY DEY BEQ NOSK BMI NOSK NEXPAGE JSR CR DEY BNE NEXPAGE NOSK LDA FTLEN BEQ SKIPFT STA ENDPOS LDA # <FTBUFF STA INDIR LDA # >FTBUFF STA INDIR+1 JSR LMARG JSR BUFPRT SKIPFT JSR CR JSR CR JSR CR
Increment the page number.
INC PAGENUM BNE NOIPN INC PAGENUM+1
The page wait mode is inappropriate when printing to the screen or to disk, or when skipping over pages with the ? format command.
NOIPN LDA CONTINUOUS BNE TOP SEC LDA PAGENUM SBC STARTNUM LDA PAGENUM+1 SBC STARTNUM+1 BCC TOP JSR TOPCLR LDA # <WAITMSG LDY # >WAITMSG JSR PRMSG JSR GETAKEY JSR PRIN
Print the header; skip to the top margin.
TOP LDA HDLEN BEQ NOHEADER STA ENDPOS LDA # <HDBUFF STA INDIR LDA # >HDBUFF STA INDIR+1 JSR LMARG JSR BUFPRT NOHEADER LDY TOPMARG STY LINE DEY BEQ SKIPTOP BMI SKIPTOP TOPLP JSR CR DEY BNE TOPLP SKIPTOP RTS
Left margin routine. This routine is not called if NOMARG is selected (margin release).
LMARG LDA #32 LDY LMARGIN STY POS BEQ LMEXIT LMLOOP JSR PCHROUT DEY BNE LMLOOP LMEXIT RTS
CRLF is called at the end of most printed lines. It increments the LINE count and takes into account the current line spacing mode set by the a format command.
CRLF LDY SPACING CLC TYA ADC LINE STA LINE CRLOOP JSR CR DEY BNE CRLOOP RTS
CR just prints a single carriage return and linefeed (if specified).
CR LDA #155 JSR PCHROUT LDA LINEFEED BEQ NOLF JSR PCHROUT NOLF RTS
Handle special printer codes like left margin. This looks up the printer code using a routine similar to CONTROL.
SPECIAL STA SAVCHAR AND #127 JSR INTOAS LDX SPTAB SRCHSP CMP SPTAB,X BEQ FSP DEX BNE SRCHSP DEC POS JMP DEFINE FSP DEX TXA ASL A TAX STY YSAVE LDA # >SPCONT-1 PHA LDA # <SPCONT-1 PHA LDA SPVECT+1,X PHA LDA SPVECT,X PHA RTS
After the format code is processed, we must skip over the format command and its parameter so that it’s not printed.
SPCONT SEC LDA YSAVE ADC TEX STA TEX LDA TEX+1 ADC #0 STA TEX+1 JMP PLOOP
If the format command ends with a return-mark, we must skip over the return-mark as well.
SPCEXIT LDA (TEX),Y CMP #RETCHAR BEQ NOAD DEY NOAD STY YSAVE RTS
Special format code table. It starts with the number of format commands, then the characters for each format command.
SPTAB .BYTE 17 .BYTE "wlrtbsnhf@p?xmigj"
The address-1 of each format routine.
SPVECT .WORD PW-1,LM-1,RM-1,TP-1 .WORD BT-1,SP-1,NX-1,HD-1,FT-1 .WORD PN-1,PL-1,SPAGE-1,ACROSS-1 .WORD MRELEASE-1,COMMENT-1,LINK-1 .WORD LFSET-1
m Margin release. INY is used to skip over the format character.
MRELEASE INY LDA #0 STA NOMARG JMP SPCEXIT
x Columns across, used by centering.
ACROSS INY JSR ASCHEX STA PAGEWIDTH JMP SPCEXIT
? Start printing at specified page.
SPAGE INY JSR ASCHEX STA STARTNUM LDA HEX+1 STA STARTNUM+1 JMP SPCEXIT
@ Set starting default page number.
PN INY JSR ASCHEX STA PAGENUM LDA HEX+1 STA PAGENUM+1 JMP SPCEXIT
p Page length.
PL INY JSR ASCHEX STA PAGELENGTH JMP SPCEXIT
w Set page wait mode.
PW LDA #0 STA CONTINUOUS INY JMP SPCEXIT
j Set linefeed mode.
LFSET LDA #10 STA LINEFEED INY JMP SPCEXIT
l Left margin.
LM INY JSR ASCHEX STA LMARGIN JMP SPCEXIT
r Right margin.
RM INY JSR ASCHEX STA RMARGIN JMP SPCEXIT
t Top margin.
TP INY JSR ASCHEX STA TOPMARG JMP SPCEXIT
b Bottom margin.
BT INY JSR ASCHEX STA BOTMARG JMP SPCEXIT
s Set line spacing.
SP INY JSR ASCHEX STA SPACING JMP SPCEXIT
n Jump to next page.
NX LDY YSAVE INY TYA PHA JSR PAGE PLA TAY STY YSAVE RTS
h Define header. Copy header into header buffer.
HD JSR PASTRET DEY STY HDLEN LDY #1 HDCOPY LDA (TEX),Y STA HDBUFF-1,Y INY CPY HDLEN BCC HDCOPY BEQ HDCOPY INY JMP SPCEXIT
Skip just past the return-mark.
PASTRET INY LDA (TEX),Y CMP #RETCHAR BNE PASTRET RTS
f Define footer.
FT JSR PASTRET DEY STY FTLEN LDY #1 FTCOPY LDA (TEX),Y STA FTBUFF-1,Y INY CPY FTLEN BCC FTCOPY BEQ FTCOPY JMP SPCEXIT
i Ignore a line of information.
COMMENT JSR PASTRET JMP SPCEXIT
Define programmable printkeys. We check for =. If not found, this is not an assignment, so we just skip past the code. Otherwise, we use the screen code value as the index into the CODEBUFFER and put the value there, ready to be called during printing by BUFPRT.
DEFINE INY LDA (TEX),Y CMP #'=-32 BEQ DODEFINE DEY LDA SAVCHAR JMP NOTRET DODEFINE INY JSR ASCHEX PHA LDA SAVCHAR AND #127 TAX PLA STA CODEBUFFER,X JSR SPCEXIT JMP SPCONT
g Link to next file. We get the filename from text and put it into the input buffer, just as if the filename were typed in with INPUT. We then jump into the TOPEN routine to open the file, and into the Load routine to load the file. After the load, we check for a load error, then jump to RETEX to continue printing.
LINK LDY #1 LDX #0 FNCOPY LDA (TEX),Y CMP #RETCHAR BEQ FNEND JSR INTOAS STA INBUFF,X INY INX CPX #14 BNE FNCOPY FNEND STX INLEN LDA #0 STA INBUFF,X LDX #$60 STX IOCB LDA #4 STA ACCESS JSR OPCONT BPL LNOERR JMP ERRLINK LNOERR LDA #0 STA INDIR STA INDIR+1 JSR ERASE JSR LOADLINK BPL LCONT JMP ERRLINK LCONT PLA PLA LDX #$70 STA IOCB JMP RETEX
Global search and replace. This just links together the search-specify routine, the replace-specify routine, then repeatedly calls Hunt and Replace, until Hunt returns “Not Found.” (FPOS+1 is $FF after a search failure.)
SANDR JSR RESET LDA HUNTLEN BEQ NOSR JSR ASKREP SNR JSR CONTSRCH LDA FPOS+1 CMP #$FF BEQ NOSR JSR REPL JSR REFRESH JMP SNR NOSR JMP SYSMSG
If OPTION is held down with CTRL-F, we ask for and store the search phrase. If OPTION is not down, we perform the actual search. The line in the INBUFF is compared with characters in text. If at any point the search fails, we continue the comparison with the first character of INBUFF. The search is a failure if we reach the end-of-text. If the entire length of INBUFF matches, the search succeeds, so we change the CURRent cursor position to the found position, save the found position for the sake of the replace routine, then call CHECK to scroll to the found position.
HUNT LDA #8 STA 53279 LDA 53279 CMP #3 BNE CONTSRCH RESET JSR TOPCLR LDA # <SRCHMSG LDY # >SRCHMSG JSR PRMSG JSR INPUT STA HUNTLEN BNE OKSRCH JMP SYSMSG OKSRCH LDY #0 TOBUFF LDA INBUFF,Y STA HUNTBUFF,Y INY CPY INLEN BNE TOBUFF JMP SYSMSG CONTSRCH LDA CURR STA TEX LDA CURR+1 STA TEX+1 LDA #$FF STA FPOS+1 LDY #1 SRCH0 LDX #0 LDA HUNTLEN BEQ NOTFOUND SRCH1 LDA HUNTBUFF,X JSR ASTOIN CMP (TEX),Y BEQ CY CPX #0 BNE SRCH0 DEX CY INY BNE NOVFL INC TEX+1 LDA TEX+1 CMP LASTLINE+1 BEQ NOVFL BCS NOTFOUND NOVFL INX CPX HUNTLEN BNE SRCH1 CLC TYA ADC TEX STA TEMP LDA TEX+1 ADC #0 STA TEMP+1 LDA LASTLINE CMP TEMP LDA LASTLINE+1 SBC TEMP+1 BCC NOTFOUND SEC LDA TEMP SBC HUNTLEN STA CURR STA FPOS LDA TEMP+1 SBC #0 STA CURR+1 STA FPOS+1 JSR CHECK RTS NOTFOUND JSR TOPCLR LDA # <NFMSG LDY # >NFMSG JSR PRMSG LDA #1 STA MSGFLG RTS
The change (replace) routine checks to see if OPTION is held down with CTRL-C. If it is, we ask for a replace phrase, and exit. If not, we check to see if the cursor is at the position previously located by the search routine. If it is, we delete the found phrase, then insert the replace phrase. The cursor is moved past the replace phrase for the sake of the next search. This also prevents endless recursion, as in replacing in with winner.
REPSTART LDA #8 STA 53279 LDA 53279 CMP #3 BNE REPL ASKREP JSR TOPCLR LDA # <REPMSG LDY # >REPMSG JSR PRMSG JSR INPUT STA REPLEN BEQ NOREP LDY #0 REPMOV LDA INBUFF,Y STA REPBUFF,Y INY CPY INLEN BNE REPMOV NOREP JMP SYSMSG REPL SEC LDA CURR STA DESTL SBC FPOS STA TEMP LDA CURR+1 STA DESTH SBC FPOS+1 ORA TEMP BNE NOREPL LDA #$FF STA FPOS+1 CLC LDA HUNTLEN ADC CURR STA FROML LDA #0 ADC CURR+1 STA FROMH SEC LDA LASTLINE SBC DESTL STA LLEN LDA LASTLINE+1 SBC DESTH STA HLEN JSR UMOVE SEC LDA LASTLINE SBC HUNTLEN STA LASTLINE LDA LASTLINE+1 SBC #0 STA LASTLINE+1 LDA REPLEN BEQ NOREPL STA INSLEN LDA #0 STA INSLEN+1 JSR INSBLOCK LDY #0 REPLOOP LDA REPBUFF,Y JSR ASTOIN STA (CURR),Y INY CPY REPLEN BNE REPLOOP CLC LDA CURR ADC REPLEN STA CURR LDA CURR+1 ADC #0 STA CURR+1 NOREPL JMP CHECK
Suddenly, we’re back to a PRINT subroutine. This examines the buffer as it’s being printed, checking for printkeys and Stage 2 commands like centering.
BUFPRT LDY #0 BUFLP CPY ENDPOS BEQ ENDBUFF LDA (INDIR),Y BMI SPEC2 JSR INTOAS JSR PCHROUT
In underline mode, after we print the character, we backspace the printhead and print an underline character.
LDA UNDERLINE BEQ NOBRK LDA #8 JSR PCHROUT LDA #95 JSR PCHROUT NOBRK INY JMP BUFLP ENDBUFF RTS
Stage 2 format commands.
SPEC2 STY YSAVE AND #127 STA SAVCHAR JSR INTOAS OTHER CMP #'c BNE NOTCENTER
c Centering looks at the length of the line, then sends out extra spaces (the left margin has already been printed) to move the printhead to the right place.
SEC LDA PAGEWIDTH SBC ENDPOS LSR A SEC SBC LMARGIN TAY LDA #32 CLOOP JSR PCHROUT DEY BNE CLOOP LDY YSAVE JMP NOBRK NOTCENTER CMP #'e BNE NOTEDGE
e Edge right. This subtracts the length of the line from the right margin position and moves the printhead to this position.
EDGE SEC LDA RMARGIN SBC ENDPOS SEC SBC LMARGIN TAY LDA #32 JMP CLOOP NOTEDGE CMP #'u BNE NOTOG
u Toggle underline mode.
LDA UNDERLINE EOR #1 STA UNDERLINE NOTOG CMP #'# BNE DOCODES
# Substitute the current page number for the # symbol.
DOPGN STY YSAVE LDX PAGENUM LDA PAGENUM+1 JSR PROUTNUM LDY YSAVE JMP NOBRK
Do special format codes. This just uses the screen-code value of the character as an index into the CODEBUFFER, then sends out the code. SpeedScript makes no judgment on the code being sent out.
DOCODES LDX SAVCHAR LDA CODEBUFFER,X JSR PCHROUT JMP NOBRK
Display free memory using OUTNUM.
FREEMEM JSR TOPCLR SEC LDA TEXEND SBC LASTLINE TAX LDA TEXEND+1 SBC LASTLINE+1 JSR OUTNUM LDA #1 STA MSGFLG RTS .END
Filename: DATA
Data tables
Messages are stored in ATASCII, with a zero byte for a delimiter.
MSG1 .BYTE "SpeedScript 3.0" .BYTE 0 MSG2 .BYTE " by Charles Brannon" .BYTE 0 KILLMSG .BYTE "Buffer Cleared" .BYTE 0 BUFERR .BYTE "Buffer Full" .BYTE 0 DELMSG .BYTE "Delete (S,W,P)" .BYTE 0 YMSG .BYTE ": Are you sure? (Y/N):" .BYTE 0 CLRMSG .BYTE "ERASE ALL TEXT" .BYTE 0 ERASMSG .BYTE "Erase (S,W,P): RETURN to exit" .BYTE 0 SAVMSG .BYTE "Save (Device:Filename)>" .BYTE 0 ERRMSG .BYTE "Error #" .BYTE 0 BRMSG .BYTE "BREAK Key Abort" .BYTE 0 OKMSG .BYTE "No Errors" .BYTE 0 LOADMSG .BYTE "Load (Device:Filename)>" .BYTE 0 DIRMSG .BYTE " Press RETURN" .BYTE 0 DIRNAME .BYTE "D1:*.*" INSERR .BYTE "Memory Full" .BYTE 0 INSMSG .BYTE "No text in buffer" .BYTE 0 FNMSG .BYTE "Print (Device:Filename)>" .BYTE 0 PRINMSG .BYTE "Printing..." .BYTE 155,155,0 WAITMSG .BYTE "Insert next sheet, press RETURN" .BYTE 0 SRCHMSG .BYTE "Find:" .BYTE 0 NFMSG .BYTE "Not found" .BYTE 0 REPMSG .BYTE "Change to:" .BYTE 0
The {ESC}’s represent the ESCape key. The arrows are the cursor keys, which must be preceded by ESC to be entered into text. There is actually only one space between the e of Rename and the E of ESC.
DIRINS .BYTE "{ESC}{up}{ESC}{down}{ESC}{left}{ESC}{right} CTRL-Delete Lock Unlock Rename ESC CTRL-Load Drive [1 2 3 4]: ",0 RENMSG .BYTE "Rename to:",0 FORMSG .BYTE "Format disk",0
The .OPT NO OBJ and .OPT OBJ pseudo-ops turn on and off object code generation. This insures that no object code is generated for the variable table.
.OPT NO OBJ TEXSTART *= *+2 ;Start-of-text area TEXEND *= *+2 ;End-of-text area TEXBUF *= *+2 ;Start of buffer BUFEND *= *+2 ;End-of-buffer area LENTABLE *= *+1 ;Length of first screen line TOPLIN *= *+2 ;Home position in text MSGFLG *= *+1 ;Message flag INSMODE *= *+1 ;Insert mode ENDPOS *= *+1 ;Used by delete routines FINPOS *= *+1 ;"" LASTLINE *= *+2 ;End-of-text position LIMIT *= *+1 ;Used by INPUT INLEN *= *+1 ;"" BOTSCR *= *+2 ;Bottom of screen in text LBUFF *= *+40 ;Line buffer (REFRESH) INBUFF *= *+40 ;INPUT buffer SAVCURR *= *+2 ;Used by delete routines BCD *= *+2 ;Used by ASCHEX HEX *= *+2 ;"" TPTR *= *+2 ;Last character in buffer BUFLEN *= *+2 ;Buffer length GOBLEN *= *+2 ;Size of deleted text FROMSAV *= *+2 ;Used by delete routines DESTSAV *= *+2 ;"" HDLEN *= *+1 ;Header length FTLEN *= *+1 ;Footer length LMARGIN *= *+1 ;Holds left margin RMARGIN *= *+1 ;Right margin PAGELENGTH *= *+1 ;Page length TOPMARG *= *+1 ;Top margin BOTMARG *= *+1 ;Bottom margin SPACING *= *+1 ;Line spacing CONTINUOUS *= *+1 ;Page wait mode PAGENUM *= *+2 ;Page number STARTNUM *= *+2 ;Start printing at # PAGEWIDTH *= *+1 ;Columns across NOMARG *= *+1 ;Margin release flag POS *= *+1 ;POSition within line LINE *= *+1 ;Line count YSAVE *= *+1 ;Preserves Y register SAVCHAR *= *+1 ;Preserves accumulator INSLEN *= *+1 ;Length of an insertion DEVNO *= *+1 ;Device number NEEDASC *= *+1 ;True ASCII flag UNDERLINE *= *+1 ;Underline mode flag FPOS *= *+2 ;Found position PCR *= *+1 ;Used by PCHROUT HUNTLEN *= *+1 ;Length of hunt phrase HUNTBUFF *= *+30 ;Holds hunt phrase REPLEN *= *+1 ;Length of replace phrase REPBUFF *= *+30 ;Holds replace phrase CODEBUFFER *= *+128 ;Holds definable printkeys PRBUFF *= *+256 ;Printer line buffer HDBUFF *= *+256 ;Holds header FIRSTRUN *= *+1 ;Has program been run before? FTBUFF *= *+256 ;Holds footer SAVCOL *= *+1 ;Save SCRCOL LINEFEED *= *+1 ;Linefeed mode flag ESCFLAG *= *+1 ;Was ESC pressed? CONVFLAG *= *+1 ;Used by CAST and CINTOAS SELFLAG *= *+1 ;The SELECT key flag IOCB *= *+1 ;Which IOCB is OPEN ACCESS *= *+1 ;Direction of ACCESS (read/write) FNBUFF *= *+40 ;Filename buffer FNLEN *= *+1 ;Filename length XSLOT *= *+1 ;Number of filename slots (DOSPAK) SLOT *= *+130 ;Slot positions (DOSPAK) XPTR *= *+1 ;Current filename slot (DOSPAK) WHICHFLAG *= *+1 ;Which key is pressed DIRCOUNT *= *+1 ;Directory count BLINK *= *+1 ;Cursor blink flag LINELEN *= *+1 ;Length of screen lines RLM *= *+1 ;REFRESH Left margin value KEYVAL *= *+1 ;Which key is pressed END = * ;High byte of this +$100 is TEXSTART .OPT OBJ
Autorun vector
*= $02E2 .WORD BEGIN .END
Label Cross Reference. This chart makes it easier to find your place in the object code while looking at the source code. The number to the left of each label is its value or position within the object code. Labels preceded by an = mark are equates. Others are internal labels for object code positions.
43BA ACCESS 3A2E ACROSS 294B ADYCURR 3721 ALPHA 3614 ASCHEX 3C3C ASKREP 262C ASTOIN 3FCD BCD 1F00 BEGIN 446A BLINK 3029 BLIP = 0074 BLUE 2983 BORDER 33AA BOTCLR 3FE1 BOTMARG 3F79 BOTSCR 24D3 BREAK 3E3A BRMSG 3A92 BT 3F6C BUFEND 3DBB BUFERR 3FD3 BUFLEN 3CDE BUFLP 3CDC BUFPRT 33FF CAST 340C CAST1 3419 CASTOIN 3100 CATALOG 27CF CHECK 282D CHECK2 2F7F CHROUT 2FCB CHRYSAVE 3426 CIN 3407 CINTOAS = E456 CIO 284C CK3 2D02 CLEAR 2501 CLEARED 28E2 CLEFT 3D1F CLOOP 3184 CLOSE7 254C CLR2 24F4 CLRLN 2543 CLRLOOP 3DED CLRMSG 4033 CODEBUFFER 3AF0 COMMENT 3FE3 CONTINUOUS 2732 CONTROL 3BB7 CONTSRCH 43B7 CONVELAG 24D7 COPY 3296 COPYD 37EC COPYDEF 3801 COPYDEFS 32A3 COPYNAME 3332 COPYR 3446 COTHER 3998 CR 25AF CRIGHT 3986 CRLF 3991 CRLOOP 2753 CTBL = 0086 CURR 2EE7 CURSIN 3430 CVLOOP 3BDC CY 3282 DDOWN 3654 DECHEX 3AF6 DEFINE 3752 DEFTAB 2A6C DEL1 2A80 DEL1A 2A89 DEL2 2A7D DELABORT 2AA0 DELC 2B32 DELCHAR 2B5C DELETE 32E5 DELFILE 2B4D DELIN 35FF DELITE 3DC7 DELMSG 288A DELSENT 2B7D DELWORD = 0083 DESTH = 0082 DESTL 3FD9 DESTSAV 3FEF DEVNO 3622 DIGIT 4469 DIRCOUNT 3F00 DIRINS 3156 DIRLOOP 3E6C DIRMSG 3E7A DIRNAME 25E9 DISKBOOT 3247 DLEFT 2E0A DLI 2DEE DLIST 2DC8 DLOOP 2474 DMOV1 244D DMOVE 2476 DMOVLOOP 3170 DNOT8 315B DNOTCR 3873 DOBUF2 3869 DOBUFF 3D62 DOCODES 3B04 DODEFINE 26F4 DOINS 2D25 DOIT 3678 DONENUM 3D50 DOPGN 38EB DORPT 31BB DOS 3229 DOSADR 33B6 DOSERR 33FF DOSMSG 3219 DOSTABLE 3254 DRIGHT 336F DRIVE 3271 DUP 2BD9 EATSPACE 3D2F EDGE 2F99 ENAME = 446E END 3D00 ENDBUFF 3194 ENDIR 319E ENDLP 3F73 ENDPOS 2967 ENDTEX 2814 EQA 2E97 ERA1 2EA6 ERA2 2E33 ERAS 2E42 ERAS1 2E4C ERASAGAIN 251F ERASE 2E7B ERASENT 3DFC ERASMSG 2E6E ERASWORD 34A7 ERR1 379B ERRLINK 3E32 ERRMSG 34AE ERROR 34C7 ERXIT 27BD ESC 3399 ESCDOS 43B6 ESCFLAG 2F2E ESCKEY 2C75 FILLSP 3201 FINDIT 3841 FINDSPACE 35E8 FINE 3F74 FINPOS 4283 FLRSTRUN 29F4 FIRSTWORD 2B3B FIXTP 2687 FLIPIT 43BB FNBUFF 3B1D FNCOPY 3B2F FNEND 43E3 FNLEN 3E9E FNMSG 3355 FORMAT 3F5A FORMSG 2740 FOUND 320C FOUNDIT 3858 FOUNDSPACE 3FF2 FPOS 3D6E FREEMEM = 0081 FROMH 0080 FROML 3FD7 FROMSAV 39BF FSP 3850 FSPACE 3AD7 FT 42B4 FTBUFF 3AE0 FTCOPY 3FDC FTLEN 31A9 GET7 256F GETAKEY 2FD6 GETCHAR 2FCC GETIN 31D6 GETNAME 2D4F GOADY 3FD5 GOBLEN 3565 GOERROR 2C06 GOINC 2FC1 GOPCHR 2AD4 GOSAV 32EA GOXIO 3001 GXIT 3AB5 HD 4183 HDBUFF 3ABE HDCOPY 3FDB HDLEN 3FCF HEX 2DAD HIGHLIGHT = 0085 HLEN 2BA1 HOME 2BC3 HOMEPAUSE 3B85 HUNT 3FF6 HUNTBUFF 3FF5 HUNTLEN = 034A ICAUX1 = 034B ICAUX2 = 0344 ICBADR = 0348 ICBLEN = 0342 ICCOM = 0343 ICSTAT 3FA3 INBUFF 250C INCNOT 3744 INCONT = 008E INDIR 2F4D INEXIT 2589 INIT 25EA INIT2 2726 INKURR 3F78 INLEN 2CE1 INOUT 2ED5 INP1 2ECE INPUT 2868 INRANGE 2C92 INSBLOCK 367D INSBUFFER 2C7C INSCHAR 3E80 INSERR 3FEE INSLEN 3F72 INSMODE 3E8C INSMSG 2CE2 INSTGL 374D INT1 3738 INTOAS 33E5 INVLP 33E3 INVNAME 03B9 IOCB 34E0 IOCLOSE 2575 JDOS 357B JFINE 32F2 JNAME 3040 KEYBOARD 2694 KEYPRESS 446D KEYVAL 2A50 KILLBUFF 3DAC KILLMSG 3F75 LASTLINE 295A LAST WORD 3F7B LBUFF 3B5A LCONT 28B8 LEFT 3F6E LENTABLE 298B LETTERS 3A68 LFSET 3F77 LIMIT 3FEB LINE 43B5 LINEFEED 446B LINELEN 3B19 LINK = 0084 LLEN 3A74 LM 3975 LMARG 3FDD LMARGIN 3985 LMEXIT 397F LMLOOP 3B49 LNOERR 3554 LOAD2 3377 LOADIT 357E LOADLINK 3E54 LOADMSG 32F8 LOCK 2C4C LOTTASPACE 2645 LOWR 2648 MAIN 2651 MAIN2 2428 MOV1 242A MOV2 242F MOVLOOP 3A25 MRELEASE 3D88 MSG1 3D98 MSG2 3F71 MSGFLG 31E5 NAMELP 3294 NAMER 3FF0 NEEDASC 38FC NEXPAGE 3EEB NFMSG 39ED NOAD 2F1B NOBACK 28AC NOBIGGER 2583 NOBLINK 3CFC NOBRK 28E8 NODEC 3571 NOER 2F04 NOESC 2A37 NOFIXCURR 35E2 NOGARBAGE 3963 NOHEADER 3675 NOHEXINC 272C NOINC2 28B5 NOINCR 2C63 NOINCY 3929 NOIPN 39A5 NOLF 3FE9 NOMARG 26B8 NOMSG 334F NONAME 3653 NONUM 2E91 NOPAR 31FF NOPROB 3C5C NOREP 3CD9 NOREPL 3902 NOSK 3B82 NOSR 32B2 NOSTOR 3735 NOTALPHA 26AC NOTBKS 300F NOTCAPS 3D2B NOTCENTER 26C2 NOTCR 2642 NOTCTRL 32BF NOTDOT 3D40 NOTEDGE 3C20 NOTFOUND 26F7 NOTINST 3024 NOTLOCKED 2455 NOTNULL 3D4C NOTOG 389E NOTPAGE 2BA0 NOTPAR 344F NOTRC 382F NOTRET 3440 NOTRTN 26A6 NOTSEL 2B93 NOTSENT 3004 NOTSET 382B NOTSP 2B86 NOTWORD 2F13 NOTZERO 3BEA NOVFL 2E77 NOWORD 326E NRANGE 3AA6 NX 24C7 NXCUR 2941 OIDS 27FF OK1 282C OK2 36A5 OKBUFF 2D0F OKCLEAR 2CA9 OKINS 3568 OKLOD 36DF OKMOV 3E4A OKMSG 3BA6 OKSRCH 27C6 ONOFF 2FCA ONUMEXIT 2FB1 ONUMLOOP 3508 OPABORT 3510 OPCONT 2F59 OPENEDITOR 3D0C OTHER 244C OUT 2BC9 OUTHOME 2FA0 OUTNUM 287A OUTRANGE 2C0B OUTSPACE 26E2 OVERCTRL 387B OVERMARG 3452 OVEROTHER 2FC4 OVERPCHR 385B OVERSTOR 2FA2 OVERZAP 38EE PAGE 3FDF PAGELENGTH 3FE4 PAGENUM 3FE8 PAGEWIDTH 2D64 PARCONT 2D31 PARIGHT 2D52 PARLEFT 2D5E PARLOOP 2D33 PARLP 3ACF PASTRET 37BB PBORT 3762 PCHROUT 3FF4 PCR 2514 PDONE 38D7 PEXIT 3A58 PL 24B1 PLINE 3814 PLOOP 3824 PLOOP1 29A7 PMANY 3A48 PN 3FEA POS 24AF PPAGE 40B3 PRBUFF 375E ERCODES 256E PREXIT 37B1 PRIN 3EB7 PRINMSG 37BE PRINT 2564 PRLOOP 2559 PRMSG 37D5 PROK 35F0 PROKMSG 2F9B PROUTNUM 29BD PSLOOP 29B9 PSRCH 29DE PUNCT 2A26 PUNCT2 3A62 PW 38C1 PXIT = 0032 RED 312D REDIR 2826 REF 248B REFRESH 3308 RENAME 3F4F RENMSG 4015 REPBUFF 29EF REPEAT 3C5F REPL 4014 REPLEN 3CBD REPLOOP 3C50 REPMOV 3EF5 REPMSG 3C30 REPSTART 3B91 RESET 3261 RESLOT = 005E RETCHAR 380A RETEX 2D75 RETF2 2D4A RETFOUND 2885 RIGHT 446C RLM 2925 RLOOP 3A7E RM 3FDE RMARGIN 2933 ROUT 297A SAFE 3B64 SANDR 3FED SAVCHAR 43B4 SAVCOL 3FCB SAVCURR 3E1A SAVMSG 24D2 SBRK = 0088 SCR 298A SCRCOL 43B8 SELFLAG = 02BE SHFLOK 37A4 SHIFTFREEZE 2481 SKIPDMOV 1F34 SKIPERAS 3918 SKIPFT 2448 SKIPMOV 37A9 SKIPOUT 2F3E SKIPSEL 29E2 SKIPSPC 3974 SKIPTOP 299B SLEFT 24C3 SLOOP 43E5 SLOT 3036 SLOW 3031 SNDLOOP 3B6F SNR 3A9C SP = 0000 SPACE 3FE2 SPACING 3A38 SPACE 39E6 SPCEXIT 39D5 SPCONT 2BE7 SPCSRCH 3D01 SPEC2 39A6 SPECIAL 39F1 SPTAB 3A03 SPVECT 2735 SRCH 3BC6 SRCHO 3BCD SRCH1 3EE5 SRCHMSG 39B1 SRCHSP 2A23 SREXIT 2A01 SRIGHT 2A03 SRLP 3FE6 STARTNUM 34D3 STOPPED 28F9 STRIP 2903 STRLOOP 37B1 SWITCH 260A SYSMSG 2C54 TAB 2C66 TAB2 = 008C TEMP = 008A TEX 3F6A TEXBUF 299A TEXCOLR 3F68 TEXEND 35AB TEXOK 3F66 TEXSTART 2DA2 TEXTOCURR 3178 THROWS 3539 TLOAD 3BA8 TOBUFF 28DF TOOSMALL 394D TOP 261A TOPCLR 34EB TOPEN 2BCC TOPHOME 3F6F TOPLIN 261E TOPLOOP 396E TOPLP 3FE0 TOPMARG 3A88 TP 3FD1 TPTR 345D TSAVE 2410 UMOVE = 0090 UNDERCURS 3FF1 UNDERLINE 3300 UNLOCK 2E84 UNSENT 2777 VECT 2667 WAIT 3EC5 WAITMSG 2BBC WAITST 4468 WHICHFLAG = 0091 WINDCOLR 28ED WLEFT 2906 WLOOP 2923 WRIGHT 2914 WROUT 2957 WRTN 374F XINT 32C8 XIO 4467 XPTR 43E4 XSLOT 3DD6 YMSG 2CEB YORN 2CF2 YORNKEY 3FEC YSAVE 3890 ZBUFF
ASCII files 13
ASCII value, use of in defining a
printkey 21-22
Atari DOS 2.0, use of 4, 15
Atari DOS 3.0, use of 4, 15
“The Automatic Proofreader” 34-36
preparing the program 34
program listing 35-36
using the program 35
command line 5
control key commands 7-15
CTRL-A 14
CTRL-B 14
CTRL-C 11-12
CTRL-CLEAR 7
CTRL-D 9, 10
CTRL-DELETE/BACK S 9
CTRL-E 9, 10
CTRL-F 11
CTRL-G 11, 12
CTRL-I 8
CTRL-INSERT 8
CTRL-K 10
CTRL-L 11-12
CTRL-M 13
CTRL-O 14
CTRL-P 16
CTRL-R 10
CTRL-S 12
CTRL-T 14
CTRL-U 6
CTRL-X 14
CTRL-Z 8, 13
CTRL-1 16
CTRL-+ 7
CTRL-* 7
CTRL-- 7
CTRL-= 7
ESC key, use of with CTRL 8
explanation of how to enter 7
OPTION button, use of with CTRL 7, 11, 14
cursor movement 7-8
cursor-down key 7
cursor-left key 7
cursor-right key 7
cursor-up key 7
delete mode 9-10
disk commands 13-14
entering of text 5-9
erase mode 9
erasing of text 9-10
format commands 15-23
SELECT key 16-17, 21
Stage 1 commands 16-20
Stage 2 commands 20-21
summary of 19
insert mode 8-9
keyboard commands 7-12. See also
control key commands; keyboard
map, illustration of
BREAK key 16
CAPS/LOWR key 15
DELETE/BACK S key 9
OPTION-CTRL-C 11
OPTION-CTRL-F 11
OPTION-CTRL-G 11
OPTION-CTRL-+ 14
OPTION-CTRL-* 14
SELECT key 16-17, 21
SHIFT-DELETE/BACK S 9
SHIFT-INSERT 8
SHIFT-+ 7
SHIFT-* 7
SHIFT-- 7
SHIFT-= 7
START button 8
SYSTEM RESET button 15
TAB key 8
keyboard map, illustration of 18
loading of a document 12
loading of program
binary disk file 4
boot tape 4-5
“The Machine Language Editor: MLX” 27-33
commands 4, 28-29
ending address 3, 27, 37
explanation of use 27
program listing 29-33
run/init address 3, 27, 37
starting address 3, 27, 37
typing in multiple sittings 4-5
MAC/65 Assembler 69
merging, of files 13
Optimized Systems Software, Inc. 5, 69
OPTION button, use of 11
OS/A+ DOS, use of 4, 15
overscanning 14
parsing 6
printing of documents
default settings 16
explanation of use 15-23
to an RS-232 printer 16
printkey, defining of 21-23
program listing 37-65
return-mark 7
saving of the program
as a binary file 3, 27
as a boot tape 3, 27
screen formatting 6-7
scrolling 6-7
search and replace 11-12
source code 69-111
explanation of 69-70
listing of 71-111
start a new document 11
storing of a document 12
text buffer 10
typing it in 3-5
in multiple sittings 4-5
using the program 3-23
width of the screen, how to change it 14
word wrap 6
Thousands of people have already made SpeedScript COMPUTE! Publications’ most popular program ever. Offering nearly every feature and convenience you expect to find in a quality word processor, SpeedScript is the perfect writing tool. With SpeedScript, writing, editing, formatting, and printing any document—from the shortest letter to the longest novel—become easier. Anything can be changed, modified, or rewritten with just a few keystrokes on your Atari 400/800, 600XL/800XL, 1200XL, or new XE and at least 24K of memory. The mechanics of writing become less intrusive—so you can concentrate on the writing, not the process itself.
SpeedScript 3.0 is our most powerful version of this easy-to-use word processor. Commands have been added, other features enhanced, to give you the best possible writing instrument.
Here are just a few of the features of this book:
- Complete program listing for SpeedScript 3.0
- Detailed documentation that shows you how to use all of SpeedScript’s commands and capabilities
- “The Machine Language Editor: MLX,” an entry program which insures that you’ll type in SpeedScript right the first time
- SpeedScript 3.0’s source code (by studying it, you’ll see how SpeedScript was written)
SpeedScript is a most impressive word processor. It’s a writer’s tool that you can use from the moment you run it. With SpeedScript The Word Processor for the Atari, you have a complete package—the word processor and the complete documentation.
ISBN 0-87455-003-3