Charles Bachand’s short lived “non-tutorial” from A.N.A.L.O.G. Computing. Initially a column on the Assembler/Editor cartridge, the last column inexplicably presented an Archimedes’ Spiral graphics demo.
A.N.A.L.O.G. ISSUE 2 / MARCH 1981 / PAGE 44

Assembler/Editor:
A Non-Tutorial

By Charles Bachand

One of the editors called me, quite unexpectedly the other day. “Hi, this is Lee”, he said. “I just came up with a great idea for an article that you can write for the next issue. How ’bout a tutorial on the new Assembler/Editor cartridge?” Now, I hate to even read tutorial articles, let alone write them, but I kept listening anyway. “Oh, and by the way”, he said as he baited his trap, “when the article is finished, I will let you borrow my video tape copy of FLASH GORDON!” That did it. I had to turn out some kind of tutorial article. Even though I hate tutorials, I was being forced to submit one for publication. After all, how long could it possibly take to write one little tutorial? It shouldn’t take more than five or six double spaced sheets of paper, maybe a week to ten days at the most. “When do you need this finished?”, I asked, not expecting the answer that followed. “I need this article by Friday”, was his reply. He couldn’t mean this Friday? This Friday was only three days away. “That’s this Friday”, he reiterated. My worst fears about Lee’s mental stability had been confirmed. He had lost his mind!

Since I missed “FLASH GORDON” when it was playing at the theater, giving Lee the benefit of the doubt seemed the safest thing to do. After all, a person writing a tutorial has three choices. He can write a tutorial, or he can write about something else and call it a tutorial (hoping that a certain person, in his crazed state will not notice), or he can do a little of both, like I am doing. I just don’t want to bore myself when I have to read this later, checking the spelling, etc.

This is a good time as any to put in a word about writing articles for A.N.A.L.O.G. magazine. We need you to share your ideas with the rest of us ATARI owners. People are always complaining that they can just type into their computers. It is really your own fault. Half the enjoyment of writing a “game” program, for example, is knowing that other people are enjoying your work right along with you. And when it is printed in a magazine, thousands can join in the fun too. Now I do have a selfish reason for telling you all this. The more people who write articles and submit programs, the less I have to do, and I can get down to the business of writing terrific game programs.

The Assembler/Editor cartridge which was released only a few months ago, is a much needed accessory, useful by those who are serious about writing compact and efficient programs. It was a long time in coming, since the cartridge was ready almost a year before the documentation. ATARI decided to wait until the manual was ready before releasing the ROM. The people who created this program managed to get a lot of features in the 8K memory space they had to work with. There are three separate sections ot the Assembler/Editor.

The Editor, is an enhanced version of the screen editor built into the ATARI personality module. Besides the regular edit features of the cursor positioning and character-line insertion and deletion, it also contains commands to renumber lines (the line numbering increments at a specified interval), so if the line numbers originally were 10, 12, 13, 22, then typing REN would produce line numbers of the sequence 10, 20, 30, 40. Besides deleting a line by typing it’s line number, you can now delete a group of lines in a program by typing DEL XX, YY. If you want to erase all the lines in a program between 300 and 450 inclusive, all you would have to do is DEL 300, 450.

Did you ever get bored of typing the line numbers of the program in, especially when they are set up in a numerical sequence? Did you ever wish that the machine could do it for you? Well, get out your whistles and party hats, the Assembler/Editor can do it all for you! After you type in the statement NUM, the editor will come up with the line numbers after every return you type in. You enter the statements. The computer does the rest. Oh, I wish that a few of these features had been implemented in ATARI BASIC.

We now come to the two string type commands that someone was thoughtful enough to include in the editor. The first is FIND. This command is used to find a specified string in a program. For example, let’s say we want to find the string “START”. Just type in ‘FIND/START/,’ and the first occurence of this string will be listed. More than likely, you want to list all occurances of the string that you are looking for. Just append an ‘A’, to the command so that it becomes ‘FIND/START/,A’ and the machine will list all the lines which contain the string “START” to the screen. You can even specify line delimiters, listing all lines between line X and line Y that have the string. During all of this, I have been using the chracter “/” as a delimiter. In reality, any character except a space, tab, and return can be used. And if the string you are searching for contains the character “/”, you will have to use something else. FIND./2.,A is legal. Here “.” was used instead of “/”, because the string contained a “/”. FIND?/2?,A is also legal. It sure beats looking through a 500 line program listing for a few spelling errors.

What if, after finding all the occurances of string “/2”, you realize that you have made a mistake. You want them all to be “/4” instead. You can either go through every line that contains the string, or you can let the computer do it for us. This brings us to the last edit feature that I find note worthy. That is the command REP. To replace all occurances of string “/2” with “/4” all we have to type is REP./2./4.,A and presto chango, it is done. This time I used the period “.” as a delimiter, as long as the character used is not in the strings. If the “/,A” was left off the end, only the first occurance of “/2” would have changed. You can even specify a line number range in which to replace, like the command “FIND”. But what if you do not want to replace every occurance? If you tack an “,Q” on the end of the command’ instead of an “,A”, the computer will list the line with the string and prompt you with a question “?”. If you type a “Y” followed by a return, the string will be changed. If you just type a return, the string will be left intact.

To do I/O (Input/Output) to the editor, you have three statements that may be used. Loading a program into the computer is the function of the command “ENTER”. You type the word ENTER followed by the pound sign “#”, and the device to load from. Entering a program from the cassette is “ENTER#C:”. From a disk file, you could use “ENTER#D:YIPPIE”.

Saving a program is done with a variation of the “LIST” command. Normally the LIST command is used to list a program on the screen, “LIST”, or on a printer. “LIST#P:”. In order to save a program on the cassette recorder, we LIST it to device C:; LIST#C:. To save it on a disk file, one types “LIST#D:YIPPIE”. The cartridge does have the commands “LOAD” and “SAVE” but these are used in the storage of binary load files only.

A variation on LIST is the command PRINT. PRINT does the same thing as LIST except it drops the line numbers in the process. I have not found much use for this command yet, except in one instance. One day while generating a data file of strings (yes folks, this cartridge does not check for syntax errors like BASIC does, because it does not store programs in a tokenized form). I had typed in the lines with line numbers so that the editor would not accept them as commands. After all the editing was done and the line numbers were no longer needed, I was going to write a BASIC program to read them in, and write them back out, minus the line numbers. Lee, however, came up with a great idea. “Why not do a PRINT to the disk drive with the data, then you don’t have to write a conversion program”, he said. You know, there may be hope for him yet.

Now, how would you like to use the added editing features on your BASIC programs. That is right! You can delete groups of lines, replace character strings. and enter lines with automatic line numbers. How do you do all this to your BASIC programs, you ask? First, after powering up with BASIC and loading your program, you LIST it to your storage device, be it cassette “C:” or disk “D:YIPPIE”. Then you remove the BASIC cartridge and insert the Assembler/Editor cartridge. As ENTER from your cassette or disk is performed, and voila, you can now work on your BASIC program with a much superior editor. To go back, we simply LIST the program to the storage device, swap back to BASIC, and perform ENTER from the device in BASIC. Now, it is just a simple matter of resaving programs, and you are done.

In this issue, I have discussed only the features of the Editor. In the next issue the Assembler will be covered, which allows you to produce machine language programs. And the Debugger, which allows you to examine memory locations, trace program execution, disassemble machine code, and many other things. This cartridge is well worth having, and like I said before, a long time in coming.


So you don’t think I read articles before they go in Charlie??? Well next issue, you had better get me that assembly language tutorial, or no borrowing any more science fiction video tapes! — Lee

A.N.A.L.O.G. ISSUE 3 / MAY 1981 / PAGE 16

Assembler/Editor
Non-Tutorial: Part II

By Charles Bachand

This column is about the ATARI Editor/Assembler cartridge, which is of course available from ATARI. In the last issue, I talked about the new editing features of the cartridge, some tricks of the trade, and losing my Sci-Fi video tape privileges. But there is some good news, folks! I have just acquired a 32K memory board and have transplanted it into my ATARI 400. That’s right, the big kid has a little 400!

The Assembler half of the Editor/Assembler has one fault that everyone who has used it is aware of. It is very, very slow ! If your assembly program is over several hundred lines long, you might as well start reading “War and Peace” because it is going to take forever before it is finished. Assembly speed seems to be about two hundred lines a minute, which I consider to be terribly slow. Maybe ATARI will speed things up in their Macro Assembler that is rumored to be on the way. We will just have to wait!

This Assembler has a lot of plus features going for it, the nicest being the use of pseudo operations, also known as directives. These wonderful non-instructions (after all, this is a non-tutorial) enable special features in the Assembler. The most general case non-instruction is the .OPT directive. With it, you can set or reset a number of switches in the Assembler. It can be used to suppress the program listing, the generation of object code, the flagging of errors, and the page ejects that are normally inserted in an assembly listing every 56 lines. Whew, what a mouthful! Broken down, here is what the options look like.

.OPT NOLIST turns listing off
.OPT LIST turns listing on (default)
.OPT NOOBJ turns code generation off
.OPT OBJ turns code generation on (default)
.OPT NOERR turns error messages off
.OPT ERR turns error messages on (default)
.OPT NOEJECT turns page ejects off
.OPT EJECT turns page ejects on (default)

Multiple options may be enabled or disabled by inserting them on the same line, separated by commas.

.OPT NOEJECT, NOOBJtwo options in one

I am not going to go into too much detail here about the use of .OPT because when you buy the cartridge, you also receive an excellent eighty-page user’s manual which goes into much more detail than I possibly could. Please read the manual!

Another interesting feature is that you can also title the pages of the assembly listings. This makes for a more professional appearance. People will actually think that you know what you are doing. To title each page of the listing, just insert the directive .TITLE followed by a string in quotes. For example, .TITLE "STAR RAIDERS BY C.BACHAND" (just kidding folks!) would put the string that is in quotes at the top of every page in the listing. You can even put a subtitle on each page to identify the routines there. This will not change the main title, but it will force a page eject. Subtitles use the directive .PAGE instead of .TITLE.

I hope that everyone realizes that when you enter a directive, or any program line for that matter, into the computer, it must be preceeded by a line number. This point of interest might have slipped my mind earlier, so I am including it now. After all, I would not want people walking around with their heads cut off saying “The dang thing don’t work!”

This non-tutorial seems to have turned into a description of the unusual directives used by the Editor/Assembler cartridge. And so, not wanting to break with tradition, and since there seems to be only one other highly unusual non-instruction, I will now tell you the tale of the immortal .IF directive. This instruction to the Assembler allows you to selectively assemble blocks of code, depending on the value of a numeric expression. If the expression is equal to zero, then the code will be assembled. The format is shown below. First, the directive .IF, followed by a numeric expression, an at sign “@”, and last the label to jump to if the expression does not equal zero.

100 .IF SWITCH@NOASM
110 ;CODE TO ASSEMBLE
120 NOASM

You might be asking, “What use could this be to me?” Well, let us suppose that you are writing this great game program, all in assembly language. And you want it to handle either a joystick or a light pen. You do not need both devices in your program, but you do want to have two different versions of the game. This is where the .IF directive comes in very handy.

100 ;JUMP HERE FOR ALL GAME INPUTS WITH THE
110 ;LABEL JOYSTICK=0 FOR JOYSTICK INPUT OR
120 ;JOYSTICK=1 FOR LIGHT PEN INPUT
130 .IF JOYSTICK@NOJOYSTICK
140 JOYSTICK CODE GOES HERE.
150 NOJOYSTICK
160 .IF JOYSTICK-1@NOLIGHTPEN
170 ;LIGHT PEN CODE GOES HERE.
180 NOLIGHTPEN
190 ;END OF GAME INPUTS

Well, it is now about 2 o’clock in the morning and I am beginning to fall asleep in front of the typewriter. Only a few hours ago I received another phone call from our fearless leader and editor, (Count Drax to the uninformed) asking me for the umpteenth time “Where is the article?” I told him flat out that I have more important things to do with my time than to type away for him all day long. For example, I have to wash my car. I also have to catch a very important episode of “Gilligan’s Island” (this week, Gilligan volunteers to test the Professor’s home made thermo-nuclear device).

A.N.A.L.O.G. ISSUE 4 / SEPTEMBER 1981 / PAGE 50

ASSEMBLER/EDITOR
NON-TUTORIAL: PART III

by Charles Bachand

One piece of software that has come my way is an Assembler/Editor program by Optimized Systems Software (OSS) called EASMD. This is a disk based program that is remarkably similar to ATARI’s cartridge Assembler. And well it should be, for it was written by the same people who wrote the ATARI Assembler. Now, since this version is resident in RAM, the programmers were not limited to the space restraints of a ROM cartridge. They had plenty of space left for those little extras such as long error messages, a symbol table at the end of an assembler listing, verification of a line after changing characters using the command REP, and the feature that makes me pick it over the cartridge: the directive .INCLUDE #filename.

You might have guessed that programmers who do a lot of work with an Assembler (like maybe 4K of object code is a lot, eh!), tend to have very large source code files. So much source code in fact, it will not all fit into the available RAM space (even with 48K). This is where the .INCLUDE directive of OSS’s EASMD comes into play. Instead of one big file of source code, the program is written as a bunch of little files. As an example, we will call these files "D:FILE1", "D:FILE2", and "D:FILE3". These will be my source files. We now make one last file, which contains the following statements:

0100 .INCLUDE
0100 .INCLUDE #D:FILE1
0110 .INCLUDE #D:FILE2
0120 .INCLUDE #D:FILE3

When these statements are executed, OSS’s EASMD will open FILE1, read the source code, close FILE1, open FILE2, read that source code, etc., etc.

INCLUDE directives are not necessarily limited to a separate file. They may be included within the text of a program. An example of this would be the inclusion of often used subroutines in one’s programs. Many of my own machine language programs make extensive use of joysticks and the START, SELECT, and OPTION switches. Since the code to access these devices was written to be the same in all cases, it is to my advantage to have the Assembler INCLUDE the code while it is in the process of assembling. This cuts down not only on typing, but also your disk space usage. The INCLUDE feature is an absolute necessity when your lines of source code start to number in the thousands.

Getting back to some resemblance of a tutorial, I would like to tell you a little about binary load files and a curious problem I encountered. This problem, it turns out, was with my understanding of binary loaded files at the time. But first, what the @&.%"?# is a binary load file?

As you may have noticed, the menu for Atari’s Disk Operating Systems, DOS for short, come onto your television screen, there are two options displayed which are rarely used by many casual users. These are (L) Binary Load, and (M) Run at Address. The first loads a binary file into RAM and the second specifies the address to start executing a machine language program at.

A binary file is organized in such a way that a program, such as DOS, will be able to load it into memory. The format that was finally decided upon, and which is used by both DOS II and the Assembler/Editor Cartridge is to start the file with two bytes containing 255’s (or $FF to those HEXadecimal hacks out there. Yes, we know who we are!!) as a file header. A loader program will generate an error if during a load it does not first encounter these two bytes. The next two bytes contain the starting address, the location where the binary load is to begin. The micro-processor expects to see addresses with the low byte first, high byte second (for a hex address of $1234 for example, the first byte would be $34, and the second would be $12) and so for conformity, the binary loader handles memory addresses in the same way. Now that the loader knows where to start loading, it next needs to know how many bytes to load into memory. The next two bytes however, do not contain this information, but they do contain the next best thing, the ending address of the binary load, in low byte first, high byte second format. The bytes that follow are what make up the actual machine language program. No, that’s not entirely true. It is only the ENDING ADDRESS minus the STARTING ADDRESS number of bytes that are loaded, If the end-of-file (EOF) has not been reached, then it tries to load another block of memory by looking for another starting address (low byte, high byte), another ending address (low byte, high byte), and more machine language data. In this way, a binary load file can load data into low memory, into high memory, and memory in between.

Now that you understand that (I hope!), we can discuss my problem. After a binary file is loaded into memory, we need to find a way to start it executing. If it is going to just sit there, it is of no use to us. There are three ways of giving life to your creation. #1, use the USR function in BASIC, #2, use the (M) Run At Address command in DOS, or #3, use the G command of the Debugger that resides in the Editor/Assembler Cartridge (or OSS’s EASMD for that matter). But I have heard stories of load file software running itself after loading. If this has ever happened to you, please do not try to exorcise evil spirits, for it is perfectly natural. There is a fourth way to run your software.

There are two secret (not any more, eh!) bytes in DOS which contain the address that the loader program jumps to after every memory load. Normally, these two bytes point to the routines to load another block of memory, but since these two bytes are located in RAM, they can be changed. Give you any ideas! If we change these two bytes to point to the entry point of OUR routine instead of THEIR routine, our program will start up immediately after loading! Wonderful, isn’t it!!

Now for the particulars. The starting address of these two bytes is 736 decimal (for you HEX hacks, better make it $2E0). Now comes the fun part. To get your load files to run automatically, six bytes (is that all?) must be appended onto your files. The first two bytes are the starting address of 736 (or $2E0 HEX), low byte first (224 or $E0 HEX), high byte second (2 or $02 HEX). Then comes the ending address of 737 (or $2E1 HEX), again using the low byte (225 or $E1 HEX), high byte (2 or $02 HEX) sequence. Sound familiar? The last two, and final bytes contain the entry point address of YOUR software. I am not a mind reader, so I cannot tell you wht the numbers should be, but only that they should also be in reversed (low byte, high byte order). In Assembly language, it would look like this:

0900 *=$02E0 ;Generates START and END addresses
0910 .WORD INTRO ;Your execution address here!

Now for a word of warning! The Auto-boot has to be the last block in a binary file. Take it from someone who knows. I wrote a program and put the AUto-boot at the beginning. The subsequent load file was 32 sectors longs and you can imagine my surprise when it tried to run itself after loading only one of those 32 sectors. This had me going crazy for a whole weekend! What had happened, if you haven’t already guesses, was that the DOS had loaded the new Auto-boot address into its RAM location and proceeded to run my space war program, even before the game was loaded into memory. Like jumping into a swimming pool before the water is put in!

A.N.A.L.O.G. ISSUE 5 / JANUARY 1982 / PAGE 38

Assembler/Editor
Non-Tutorial: Part IV

By Charles Bachand

“Have you ever wondered how and why something works?” This question has been asked by countless books and magazines, mostly as a lead for them to tell you just How and Why. That question is a little lengthy. “Have you ever wondered why, when you use the BASIC function STICK(0), that it doesn’t return nice numbers such as 0=LEFT, 2=RIGHT, etc., but instead gives you weird numbers like 15=NOTHING, 11=LEFT, 7=RIGHT, etc.?”.

Now that I’ve done my “Andy Rooney talking about his ties” imitation, it is time to switch scenes again. “Hey Ma! My joystick is BROKE! You’ll have to buy me another one!”, the little boy said. “That’s the third one that you’ve broken. You’ll just have to wait till I can get to the store next week.”, was his mother’s reply. This, for the little boy, just would not do. He was very involved in a game of Missile Command (tm) and had already accumulated well over one hundred and twenty thousand points and would probably die of old age by next week anyway. Maybe the Joystick could be repaired? There was nothing to loose. He just had to find out. Did you ever wonder what is in a Joystick? Did you ever wonder how a Joystick works? Did you ever wonder why they call it a Joystick? Ever wonder how the little boy broke all three of his joysticks or why his mother has put up with him for so long? And did you ever wonder why I am constantly saying “Did you ever wonder”?

A Joystick is a very simple device. After removing four screws and taking the bottom off, one finds only a few plastic parts, some wires, and a circuit board containing push button switches. A Joystick is just five switches and a connecting stick. So where do the funny numbers for up, down, left, and right come from? Well, I am going to tell you all about it. Atari Joysticks are connected into the computer by a parallel input port. This means that when your program reads information from this parallel port, there is one bit for each switch. The lowest most significant bit (we will call it bit “0” since numbering systems using computers start counting with the number “0”) senses the upward push on a Joystick. The following table shows the other bit positions.

Now, the nibble or four bit subbyte, is not the value returned by the joystick ports. The value returned is the inverse of the values shown in the previous table. The correct values are shown in the next table.

The inverse bit values you receive from the joystick ports are due to the way the joysticks themselves are wired. The switch contacts are connected to the port lines with pull-up resistors. These resistors apply a constant +5 volts signal to the lines forcing the logic to a high level. When you push on the joystick, the switch or switches (in a diagonal position) close and bring the signal from d5 volts to volts, bringing the logic at the port to a low logic level. The bit read from its corresponding switch is changed from a logic 1 to 0. All we need now is a demonstration in machine language.

Enough About Joysticks

MAPWARE, written by Harry C. Koons, is one of the more interesting programs to come out of APX (Atari Program Exchange). Using this program, it is possible to generate maps of any section of the earth. The software is written in BASIC and is distributed on two diskettes. The first disk contains programs to generate maps using different projection methods and a program to display a previously generated and stored map. The second disk contains the coordinate data of every important land feature in the world. This disk contains over 640 blocks of information, which translates to over 80 thousand characters of information. It even generates the U.S. state boundaries. Since the programs are written in BASIC, they tend to be on the slow side, usually taking from ten to twenty minutes to generate a map, but the results are well worth it. I strongly recommend this package to anyone with a 40K system.

Now, what does this program have to do with joysticks, you might be wondering. What can a joystick do to a stationary map? Believe me, these maps won’t be stationary for very long!

You’ve all seen scrolling. It happens every time you enter a line in a BASIC program with a full screen. The lines of text before it all move up when you hit RETURN. This is known as coarse vertical scrolling. Also, coarse horizontal scrolling. You usually see this when editing text, especially when characters are inserted or deleted in the middle of a line. The rest of the text moves sideways. We have all seen this happen. It’s really no big deal.

What you may not know is that the ATARI computer has the ability to FINE scroll vertically, and horizontally. Characters and pictures can be moved up and down in increments of one scan line on the television set. They can also be moved left and right in increments of one color clock (the width of a point in graphics mode 6 or 7). All this power is hidden in your machine, and you probably never know it unless you played such games as Atari’s SPACE INVADERS (horizontal scrolling) or ANALOG SOFTWARE’s Race In Space (vertical scrolling). We, using our map and out joystick are going to do both!

Now, it really does not have to be a map. You can use any picture that was drawn in full screen graphics mode 8 (GRAPHICS 8+16), as long as a screen dump of the picture has been stored on tape or diskette. The accompanying program will load your picture into RAM in full screen mode 6 (GRAPHICS 6° 16) even though the graphics were originally in full screen mode 8. The internal graphic representation between the two modes is the same, one pixel for each bit position in memory. And since graphics mode 6 has half the resolution, both horizontally and vertically, that graphics mode 8 has, you will be able to see only a quarter of the actual picture or map. The program will allow you to scroll the television’s screen over the picture while being controlled by the joystick. You will be able to see only 25% of the picture at any one time, but you will be able to choose which 25% to look at.

BITDIRECTIONNIBBLE
0UP0001
1DOWN0010
2LEFT0100
3RIGHT1000
DIRECTIONINVERSEDECIMAL
CENTER111115
UP111014
DOWN110113
LEFT101111
RIGHT01117
UP-LF101010
UP-RT01106
DN-LF10019
DN-RT01015
100 REM SCROLLING MAPWARE
110 REM DISPLAY PROGRAM
120 REM
130 REM BY CHARLES BACHAND 1982
140 REM
150 REM TO LOAD ANOTHER FILE,
160 REM PUSH SYSTEM RESET AND
170 REM TYPE RUN.
189 REM
190 DIM NAME$(20),MLOAD$(41)
200 DIM SCRL$(161),INIT$(130)
210 GRAPHICS 8:POKE 752,1:GOSUB 360
220 PRINT "MAP SCROLL PROGRAM":PRINT
230 PRINT "MAPWARE FILE NAME ==> ";
240 INPUT NAME*: TRAP 220:? :? :?
250 SETCOLOR 2,0,0:POKE 752, 1
260 PRINT "SCROLLING FILE => ";NAME$
270 REM
280 REM LOAD GRAPHICS DATA
290 REM
300 CLOSE #1:OPEN #1,4,0,NAME$
310 A=USR(ADR(MLOAD$))
320 IF A>127 THEN 220
330 FOR COUNT=1 TO 500:NEXT COUNT
340 A=USR(ADR(INIT$),ADR(SCRL$))
350 GOTO 350
360 REM
370 REM INITIALIZATION RUUTINES
380 REM FOR FINE SCROLLING OF DISPLAY
390 REM
400 REM BINARY DATA LOADER
410 REM
420 PRINT "LOADING ML SUBROUTINES"
430 FOR C0UNT=1 TO 41: READ VALUE
440 MLOAD$(COUNT)=CHR$(VALUE)
450 NEXT COUNT
460 REM
470 REM DISPLAY LIST INITIALIZER
480 REM
490 FOR COUNT=1 TO 130:READ VALUE
500 INIT$(COUNT)=CHR$(VALUE)
510 NEXT COUNT
520 REM
530 REM DISPLAY SCROLL ROUTINE
540 REM
550 FOR COUNT=1 TO 161: READ VALUE
560 SCRL$(COUNT)=CHR$(VALUE)
570 NEXT COUNT:POKE 752,0:PRINT
580 RETURN
590 REM DATA FOR MACHINE LANGUAGE
600 REM SUBROUTINES
610 REM
620 REM BINARY LOADER CODE
630 REM
640 DATA 104,162,16,169,7,157,66,3
650 DATA 169,0,157,72,3
660 DATA 169,30,157,73,3,165,88,157
670 DATA 68,3,165,89,157,69,3,32,86
680 DATA 228,189,67,3,133,212
690 DATA 169,0,133,213,96
700 REM
710 REM DISPLAY INITIALIZE CODE
720 REM
730 DATA 104,169,0,133,179,169,160
740 DATA 133,178,169,112,141,0,6
750 DATA 141,1,6,141,2,6,160,80
760 DATA 166,88,202,202,134,176,165
770 DATA 89,133,177,162,3,169,123
780 DATA 157,0,6,232,165,176,157,0,6
790 DATA 232,165,177,157,0,6,232
800 DATA 165,176,24,105,40,133,176
810 DATA 144,2,230,177,136,208,224
820 DATA 169,91,157,253,5,169,66
830 DATA 157,0,6,173,148,2,157,1,6
840 DATA 173,149,2,157,2,6,169,2
850 DATA 157,3,6,157,4,6,157,5,6
860 DATA 169,65,157,6,6,169,0,157,7,6
870 DATA 141,48,2,169,6,157,8,6
880 DATA 141,49,2,104,170,104,168
890 DATA 169,7,32,92,228,96
900 REM
910 REM FINE SCROLL CODE
920 REM
930 DATA 169,0,133,176,133,177
940 DATA 173,120,2,41,8,208,21
950 DATA 165,178,240,45,198,178
960 DATA 165,178,41,7,141,4,212
970 DATA 201,7,208,32,230,176
980 DATA 208,28,173,120,2,41,4
990 DATA 208,21,165,178,201,160
1000 DATA 240,15,230,178,165,178,41,7
1010 DATA 141,4,212,208,4,198,176
1020 DATA 198,177,173,120,2,41,2
1030 DATA 208,28,165,179,201,228
1040 DATA 240,22,230,179,165,179,41,1
1050 DATA 141,5,212,208,11,165,176,24
1060 DATA 105,40,133,176,144,2
1070 DATA 230,177,173,120,2,41,1
1080 DATA 208,28,165,179,240,24
1090 DATA 198,179,165,179,41,1
1100 DATA 141,5,212,201,1,208,11
1110 DATA 165,176,56,233,40,133,176
1120 DATA 176,2,198,177,160,0,185,4,6
1130 DATA 24,101,176,153,4,6,185,5,6
1140 DATA 101,177,153,5,6,200,200,200
1150 DATA 192,240,208,232,76,98,228
1160 END
0000        0100        .OPT  NOEJECT
            0110 ;
            0120 ; MAPWARE SCROLL PROGRAM
            0130 ; MACHINE LANGUAGE ROUTINES
            0140 ; BY CHARLES BACHAND 1982
            0150 ;
            0160 ; NOTE: ALL MACHINE LANGUAGE ROUTINES
            0170 ; PRESENTED HERE ARE RELOCATABLE
            0180 ; SINCE ALL JUMPS WITHIN THE ROUTINES
            0190 ; ARE RELATIVE JUMPS.
            0200 ;
            0210 ; SYSTEM EQUATES
            0220 ;
0600        0230 LIST   =    $0600     DISPLAY LIST
0010        0240 IOCB1  =    $10       CONTROL BLOCK OFFSET
0007        0250 GETCHR =    $07       GET CHARACTERS CMD
0058        0260 SAVMSC =    $0058     DISPLAY DATA PNTR
0294        0270 TXTMSC =    $0294     SPLIT SCREEN PNTR
0342        0280 ICCOM  =    $0342     I/O COMMAND BYTE
0343        0290 ICSTA  =    $0343     I/O STATUS BYTE
0344        0300 ICBAL  =    $0344     I/O BUFFER (LOW)
0345        0310 ICBAH  =    $0345     I/O BUFFER (HIGH)
0348        0320 ICBLL  =    $0348     BUFFER LENGTH (LOW)
0349        0330 ICBLH  =    $0349     BUFFER LENGTH (HIGH)
0230        0340 DLISTL =    $0230     DISPLAY LIST PNTR
0231        0350 DLISTH =    $0231     DISPLAY LIST PNTR
0278        0360 STICK  =    $0278     JOYSTICK REGISTER
D404        0370 HSCROL =    $D404     HORIZONTAL SCROLL
D405        0380 VSCROL =    $D405     VERTICAL SCROLL
E456        0390 CIOV   =    $E456     CENTRAL I/O VECTOR
E45C        0400 SETVBV =    $E45C     VBLANK SET VECTOR
E462        0410 XITVBV =    $E462     EXIT FOR V-BLANK
00D4        0420 BASVAL =    212       RETURNED VALUE ADDR
0000        0430 SIZEL  =    7680&$FF  SCREEN SIZE (LOW)
001E        0440 SIZEH  =    7680/256  SCREEN SIZE (HIGH)
            0450 ;
0000        0460        *=   $00B0
            0470 ;
            0480 ; PAGE 0 VARIABLE ASSIGNMENTS
            0490 ;
00B0        0500 OFFLO  *=   *+1       SCROLL DATA (LOW)
00B1        0510 OFFHI  *=   *+1       SCROLL DATA (HIGH)
00B2        0520 XPOS   *=   *+1       X-COORDINATE DATA
00B3        0530 YPOS   *=   *+1       Y-COORDINATE DATA
            0540 ;
00B4        0550        *=   $1000     RELOCATABLE CODE
            0560 ;
            0570 ; INITIALIZATION ROUTINE TO SET UP NEW
            0580 ; DISPLAY LIST, AND INITIALIZE POINTERS
            0590 ;
1000 68     0600 INIT   PLA            POP PARAMETER COUNT
1001 A900   0610        LDA  #0        BOTTOM OF SCREEN
1003 85B3   0620        STA  YPOS      INITIALIZE Y-COORD
1005 A9A0   0630        LDA  #160      RIGHT EDGE OF SCREEN
1007 85B2   0640        STA  XPOS      INITIALIZE X-COORD
1009 A970   0650        LDA  #$70      'SKIP 8 LINES' OPCODE
100B 8D0006 0660        STA  LIST      3*8=24 SCAN LINES
100E 8D0106 0670        STA  LIST+1    3*8=24 SCAN LINES
1011 8D0206 0680        STA  LIST+2    3*8=24 SCAN LINES
1014 A050   0690        LDY  #80       80 DISPLAY LINES
1016 A658   0700        LDX  SAVMSC    DISPLAY ADDR (LOW)
1018 CA     0710        DEX            OFFSET FOR HSCROLL
1019 CA     0720        DEX            OFFSET FOR HSCROLL
101A 86B0   0730        STX  OFFLO     DISPLAY POINTER (LOW)
101C A559   0740        LDA  SAVMSC+1  DISPLAY ADDR (HIGH)
101E 85B1   0750        STA  OFFHI     DISPLAY POINTER (HIGH)
1020 A203   0760        LDX  #3        DISPLAY LIST OFFSET
1022 A97B   0770 ILOOP  LDA  #$7B      MODE 6 W/H+VSCROL+LMS
1024 9D0006 0780        STA  LIST,X    STORE INSTRUCTION
1027 E8     0790        INX            INCREMENT INDEX
1028 A5B0   0800        LDA  OFFLO     DISPLAY POINTER (LOW)
102A 9D0006 0810        STA  LIST,X    LMS ADDRESS (LOW)
102D E8     0820        INX            INCREMENT INDEX
102E A5B1   0830        LDA  OFFHI     DISPLAY POINTER (HIGH)
1030 9D0006 0840        STA  LIST,X    LMS ADDRESS (HIGH)
1033 E8     0850        INX            INCREMENT INDEX
1034 A5B0   0860        LDA  OFFLO     DISPLAY POINTER (LOW)
1036 18     0870        CLC            CLEAR CARRY FOR ADD
1037 6928   0880        ADC  #40       MODE 8 BYTE COUNT
1039 85B0   0890        STA  OFFLO     STORE NEW VALUE
103B 9002   0900        BCC  INIT2     OVERFLOW ON ADD?
103D E6B1   0910        INC  OFFHI     YES, NEW HIGH BYTE.
103F 88     0920 INIT2  DEY            80 INSTRUCTIONS?
1040 D0E0   0930        BNE  ILOOP     NO, DO SOME MORE.
1042 A95B   0940        LDA  #$5B      MODE 6 W/HSCROL + LMS
1044 9DFD05 0950        STA  LIST-3,X  CHANGE LAST OPCODE
1047 A942   0960        LDA  #$42      MODE 0 W/LMS
1049 9D0006 0970        STA  LIST,X    STORE INSTRUCTION
104C AD9402 0980        LDA  TXTMSC    TEXT WINDOW PNTR (LOW)
104F 9D0106 0990        STA  LIST+1,X  STORE POINTER (LOW)
1052 AD9502 1000        LDA  TXTMSC+1  TEXT WINDOW (HIGH)
1055 9D0206 1010        STA  LIST+2,X  POINTER (HIGH)
1058 A902   1020        LDA  #$02      MODE 0 OPCODE
105A 9D0306 1030        STA  LIST+3,X  2ND LINE TEXT
105D 9D0406 1040        STA  LIST+4,X  3RD LINE TEXT
1060 9D0506 1050        STA  LIST+5,X  4TH LINE TEXT
1063 A941   1060        LDA  #$41      JUMP + WAIT FOR VBLANK
1065 9D0606 1070        STA  LIST+6,X  STORE OPCODE
1068 A900   1080        LDA  #LIST&$FF DISPLAY LIST (LOW)
106A 9D0706 1090        STA  LIST+7,X  JUMP ADDRESS (LOW)
106D 8D3002 1100        STA  DLISTL    OS POINTER (LOW)
1070 A906   1110        LDA  #LIST/256 DISPLAY LIST (HIGH)
1072 9D0806 1120        STA  LIST+8,X  JUMP ADDRESS (HIGH)
1075 8D3102 1130        STA  DLISTH    OS POINTER (HIGH)
1078 68     1140        PLA            VBLANK ROUTINE (HIGH)
1079 AA     1150        TAX            SET X REGISTER
107A 68     1160        PLA            VBLANK ROUTINE (LOW)
107B A8     1170        TAY            SET Y REGISTER
107C A907   1180        LDA  #$07      VBLANK SET CODE
107E 205CE4 1190        JSR  SETVBV    SET VBLANK ADDRESS
1081 60     1200        RTS            RETURN TO BASIC
1082        1220        *=  $2000      RELOCATABLE CODE
            1230 ;
            1240 ; FAST MAP LOADING CODE
            1250 ;
            1260 ; READS IN 7680 BYTES FROM DEVICE #1
            1270 ; TO SCREEN MEMORY VERY QUICKLY!
            1280 ;
2000 68     1290 LOAD   PLA            POP PARAMCTER COUNT
2001 A210   1300        LDX  #IOCB1    CONTROL BLOCK #1
2003 A907   1310        LDA  #GETCHR   GET CHARACTERS CMD
2005 9D4203 1320        STA  ICCOM,X   SET COMMAND
2008 A900   1330        LDA  #SIZEL    SCREEN SIZE (LOW)
200A 9D4803 1340        STA  ICBLL,X   SET LENGTH (LOW)
200D A91E   1350        LDA  #SIZEH    SCREEN SIZE (HIGH)
200F 9D4903 1360        STA  ICBLH,X   SET LENGTH (HIGH)
2012 A558   1370        LDA  SAVMSC    POINTER TO DISPLAY
2014 9D4403 1380        STA  ICBAL,X   I/O BUFFER (LOW)
2017 A559   1390        LDA  SAVMSC+1  DISPLAY PNTR (HI)
2019 9D4503 1400        STA  ICBAH,X   I/O BUFFER (HIGH)
201C 2056E4 1410        JSR  CIOV      LOAD MAP DATA
201F BD4303 1420        LDA  ICSTA,X   GET STATUS BYTE
2022 85D4   1430        STA  BASVAL    RETURN VALUE
2024 A900   1440        LDA  #0        GET A ZERO
2026 85D5   1450        STA  BASVAL+1  ZERO HIGH BYTE
2028 60     1460        RTS            THAT'S ALL FOLKS!
            1470 ;
2029        1480      *=  $3000
            1490 ;
            1500 ; VERTICAL BLANK SCROLL ROUTINE
            1510 ;
3000 A900   1520 SCROLL LDA  #0        ZERO ACCUMULATOR
3002 85B0   1530        STA  OFFLO     ZERO OFFSET (LOW)
3004 85B1   1540        STA  OFFHI     ZERO OFFSET (HIGH)
3006 AD7802 1550        LDA  STICK     CHECK STICK
3009 2908   1560        AND  #$08      RIGHT BIT FOR LEFT?
300B D015   1570        BNE  CHKRT     NO, TRY RIGHT.
300D A5B2   1580        LDA  XPOS      LEFT EDGE?
300F F02D   1590        BEQ  CHKUP     YES, TRY UP.
3011 C6B2   1600        DEC  XPOS      DECREMENT X-COORD
3013 A5B2   1610        LDA  XPOS      GET X-COORD
3015 2907   1620        AND  #7        AND SCROLL BITS
3017 8D04D4 1630        STA  HSCROL    FINE SCROLL
301A C907   1640        CMP  #7        OVERFLOW?
301C D020   1650        BNE  CHKUP     NO, TRY UP.
301E E6B0   1660        INC  OFFLO     OFFSET FOR SCROLL
3020 D01C   1670        BNE  CHKUP     TRY GOING UP
            1680 ;
3022 AD7802 1690 CHKRT  LDA  STICK     CHECK STICK
3025 2904   1700        AND  #$04      LEFT BIT FOR RIGHT?
3027 D015   1710        BNE  CHKUP     NO, TRY UP.
3029 A5B2   1720        LDA  XPOS      GET X-COORD
302B C9A0   1730        CMP  #160      RIGHT EDGE?
302D F00F   1740        BEQ  CHKUP     YES, TRY UP.
302F E6B2   1750        INC  XPOS      INCREMENT X-COORD
3031 A5B2   1760        LDA  XPOS      GET X-COORD
3033 2907   1770        AND  #7        OVERFLOW?
3035 8D04D4 1780        STA  HSCROL    FINE SCROLL
3038 D004   1790        BNE  CHKUP     NO, TRY UP.
303A C6B0   1800        DEC  OFFLO     OFFSET FOR SCROLL
303C C6B1   1810        DEC  OFFHI     OFFSET FOR SCROLL
            1820 ;
303E AD7802 1830 CHKUP  LDA  STICK     CHECK STICK
3041 2902   1840        AND  #$02      DOWN BIT FOR UP?
3043 D01C   1850        BNE  CHKDN     NO, TRY DOWN.
3045 A5B3   1860        LDA  YPOS      GET Y-COORD
3047 C9E4   1870        CMP  #228      AT TOP EDGE?
3049 F016   1880        BEQ  CHKDN     YES, TRY DOWN.
304B E6B3   1890        INC  YPOS      INCREMENT Y-COORD
304D A5B3   1900        LDA  YPOS      GET Y-COORD
304F 2901   1910        AND  #$01      OVERFLOW CONDITION?
3051 8D05D4 1920        STA  VSCROL    FINE SCROLL
3054 D00B   1930        BNE  CHKDN     NO, TRY DOWN.
3056 A5B0   1940        LDA  OFFLO     GET OFFSET (LOW)
3058 18     1950        CLC            CLEAR CARRY BIT
3059 6928   1960        ADC  #40       BYTES IN MODE 8 LINE
305B 85B0   1970        STA  OFFLO     NEW OFFSET (LOW)
305D 9002   1980        BCC  CHKDN     VALUE > 255?
305F E6B1   1990        INC  OFFHI     YES, OFFSET (HIGH)
            2000 ;
3061 AD7802 2010 CHKDN  LDA  STICK     CHECK STICK
3064 2901   2020        AND  #$01      UP BIT FOR DOWN?
3066 D01C   2030        BNE  CHGDL     NO, CHANGE DISPLAY.
3068 A5B3   2040        LDA  YPOS      BOTTOM EDGE?
306A F018   2050        BEQ  CHGDL     YES, CHANGE DISPLAY.
306C C6B3   2060        DEC  YPOS      DECREMENT Y-COORD
306E A5B3   2070        LDA  YPOS      GET Y-COORD
3070 2901   2080        AND  #$01      AND SCROLL BITS
3072 8D05D4 2090        STA  VSCROL    FINE SCROLL
3075 C901   2100        CMP  #$01      OVERFLOW?
3077 D00B   2110        BNE  CHGDL     NO, CHANGE DISPLAY.
3079 A5B0   2120        LDA  OFFLO     GET OFFSET (LOW)
307B 38     2130        SEC            SET CARRY FOR SUBTRACT
307C E928   2140        SBC  #40       BYTES IN MODE 8 LINE
307E 85B0   2150        STA  OFFLO     NEW OFFSET (LOW)
3080 B002   2160        BCS  CHGDL     VALUE > 255?
3082 C6B1   2170        DEC  OFFHI     YES, OFFSET (HIGH)
            2180 ;
3084 A000   2190 CHGDL  LDY  #0        ZERO Y INDEX
3086 B90406 2200 CGI    LDA  LIST+4,Y  LOAD ADR (LOW)
3089 18     2210        CLC            CLEAR CARRY FOR ADD
308A 65B0   2220        ADC  OFFLO     ADD OFFSET (LOW)
308C 990406 2230        STA  LIST+4,Y  NEW LOAD ADR (LO)
308F B90506 2240        LDA  LIST+5,Y  LOAD ADR (HIGH)
3092 65B1   2250        ADC  OFFHI     ADD OFFSET (HIGH)
3094 990506 2260        STA  LIST+5,Y  NEW LOAD ADR (HI)
3097 C8     2270        INY            POINT TO NEXT BYTE
3098 C8     2280        INY            POINT TO NEXT BYTE
3099 C8     2290        INY            POINT TO NEXT BYTE
309A C0F0   2300        CPY  #240      END OF DISPLAY LIST?
309C D0E8   2310        BNE  CGI       NO, DO SOME MORE.
309E 4C62E4 2320        JMP  XITVBV    VERTICAL BLANK EXIT
30A1        2330        .END
A.N.A.L.O.G. ISSUE 6 / MAY 1982 / PAGE 50

NON-TUTORIAL V

by Charles Bachand

PROGRAM PROTECTION

A DOS option known as a MEM.SAV file allows your BASIC program and the Disk Operation System to share the same memory space. It is in a sense a form of Time-Sharing as practiced on large computer systems. This new Disk Operating System, DOS II, loads into the computer’s memory in two parts. The first file, DOS. SYS, is loaded and initialized, and control is then transferred to the cartridge if one is inserted; otherwise DOS proceeds to load in part two, file DUP.SYS into memory. DOS. SYS allows your BASIC program to do I/O (Input/Output) to disk files, but if you need to copy a disk or an individual file, write DOS files to a disk, get a directory listing, or do anything that cannot be done from BASIC, then you will have to go into the DOS menu. This is accomplished by typing the word ‘DOS’ followed by a [return].

DOS 1 came up in the menu mode almost instantly after the user typed ‘DOS’ [return] because the menu part of the program was always resident in the computer’s memory. This used up a lot of the computer’s memory space, which meant that you had less room left for your program. Since DOS 1 also had a few bugs in it, like not being able to use random access files or not being able to boot up the ATARI 850 Interface Module, the programmers at ATARI decided to rewrite the software, fixing any bugs and incorporating a few enhancements.

Normally, when one is using DOS II and needs access to the DOS menu options, you type ‘DOS’ [return], do what you have to do, type the ‘B’ [return] (Run Cartridge option), and re-enter BASIC. But something nasty has happened to your program. It’s GONE!!

Now, you are probably wondering, “What the %#$& did this computer do with my program?” It was wiped from memory by the DOS. The Disk Operating System loaded its menu program right on top of your BASIC program. Too bad for you. You should have enabled the MEM.SAV feature. Yes, now even you can stop your programs from being clobbered by DOS. Just think, no one will ever again ask, “What happened to your program?” Just send $29.95 plus $2.00 shipping and handling to “Clobbered for the Last Time,” P.O. Box 123, Ripoff City ...

Actually, it is not going to cost you anything to save your programs, except for an increase in disk access time. It works almost like magic! All you need is a file, 45 sectors long, on your system disk named ‘MEM.SAV’. The computer does the rest. The DOS menu has the option to create such a ‘MEM.SAV’ file for you. Once enabled, the operating system automatically makes use of it.

Now, every time you call up DOS, the system checks for a ‘MEM.SAV’ file. If there is one on the disk, the computer will save a part of your BASIC program (the part that would normally be overwritten by DOS) to the ‘MEM.SAV’ file. The DOS menu program is then loaded and executed. When you want to get back into BASIC, the system first reads the part of your program stored in the ‘MEM.SAV’ file, back to where it first found it. Your BASIC program is now in its original state and can be edited or executed. And this feature is not limited to the BASIC cartridge. You can use it with the Assembler/Editor, the Music Composer or the Pilot cartridge.

HUNGRY FOR A BIG MACRO

There are certain types of utility software that can get an assembly language programmer really excited. It’s akin to buying a new car, and discovering what all the little buttons do. This is how I feel about two new machine language programs, the ATARI Macro Assembler and Program-Text Editor™. These two programs brought back all the fun of Christmas, and they are not even games!

Programs of this nature do what they were designed to do, but they are still loaded with extra ‘Bells and Whistles’. These are not really needed but are certainly welcome, and are a sight for these sore eyes. The preliminary documentation that 1 received for the Macro Assembler ran just over sixty pages. When you consider that this documentation was on the skimpy side, you have an idea as to the size of the final manual. The same holds true for the text editor manual.

PROGRAM-TEXT EDITOR

Programmers whose source files tended to become very lengthy (yeah, like six thousand lines is a lot, eh!), ran into problems with the ATARI Assembler Editor cartridge. In order to edit a file with this cartridge, the entire file must be able to reside in the computer’s memory. Even with all the comments removed, two thousand lines of code tend to fill the memory. Progress past this point can be made with the enhanced Assembler/Editor package by ‘Optimized Systems Software, Inc.’, in that you can now use many small files and have the Assembler sequentially access them during the assembly process. This surely works, but turns out to be a pain to edit.

Having the graphics routines on ‘D:FILE1’, the variable assignments on ‘D:FILE2’, system equates on ‘D:FILE3’, etc. sometimes becomes confusing. After a while, it is hard to keep ‘What goes where?’ straight in your mind. And let’s not forget those so called ‘necessary’ line numbers! In a six thousand line program, these numbers can use up at least 24K of disk space! What a waste.

ATARI’s new “Program-Text Editor” gets around the above mentioned problems. Line numbers are optional. BASIC seems to be the only language that really needs line numbers. This conserves both disk and memory space. Another place to conserve is in the implementation of the TAB key. Every program that I have seen that uses the TAB key has merely added extra spaces into the program. The Assembler cartridge does not need all these extra spaces, but programmers tend to include them to make the source code more readable. It was up to you whether to waste memory space, or get eye strain! The new ‘Program-Text Editor’ package can insert an actual TAB instruction in the code that when listed will tell the Editor to expand to the next defined tab column, thus saving even more memory space. Plus, as an added feature, your programs can now exceed the memory limits of your machine. You will now be able to edit a 200K-300K program, letting the editor swap the text into and out of the computer’s memory. The program will also automatically update the files and maintain a backup copy of your last editing session.

Next time, I will discuss ATARI’s ‘Program-Text Editor’ in greater depth along with talking about some of the many features of ATARI’s new ‘Macro Assembler’.

A.N.A.L.O.G. ISSUE 7 / SEPTEMBER 1982 / PAGE 60

NON-TUTORIAL VI

by Charles Bachand

I keep doing it, don’t I? For a number of times now, I have mentioned at the end of these tutorials the many interesting things that will be talked about in my next tutorial. And in all those times, I have traveled far away from the stated subject matter. Well, I promise not to do this ever again! From now on, there will be no more announcements (ha, fooled ya!). The reason for this being that by the time I’m ready to write all this stuff, something new has caught my attention. You are forced to take what you can get. And now, back to our story.

As more and more computer owners are finding the financial burden of owning their own printer more bearable (mainly due to the rapidly dropping prices, especially of those printers imported from Japan), they are asking for different ways to put their new-found toys to use. Many of the newer printers coming onto the market are microprocessor controlled, which allows them the ability to change not only character size and type style, but also the page length, line spacing, margin settings, underlining, and a host of other “neat” features. (“Yes, I use the Japanese character font every day. Doesn’t everyone?”)

Bernard Herrmann Music Starts Here…

“…but the feature that will concern us today is that of graphics, that unique and somewhat obscure ability to draw a picture on a screen and put it onto paper. For some, this is as easy as taking candy from a baby. For others, it is an impossibility, to be realized only in one’s mind. Join us now as we meet a man, a computer, and a not so ordinary printer, all of which are about to connect, in the “Twilight Zone”.”

Technical Stuff Starts Here!
or:
HATS OFF TO ATARI!!

This article contains a graphics program called “Archimedes Spiral”. The program, although quite short, takes nearly three hours to run! This is definitely not a quick demo. (To produce the transparent version of the spiral, delete line 240.) (it still looks like a hat to me. Ed.)

100 REM ARCHIMEDES SPIRAL
110 REM
129 REM ANALOG MAGAZINE
130 REM
140 GRAPHICS 8+16:SETCOLOR 2,0,0
150 XP=144:XR=4.71238905:XF=XR/XP
160 FOR ZI=-64 TO 64
170 ZT=ZI*2.25:ZS=ZT*ZT
180 XL=INT(SQR(20736-ZS)+0.5)
190 FOR XI=0-XL TO XL
200 XT=SQR(XI*XI+ZS)*XF
210 YY=(SIN(XT)+SIN(XT*3)*0.4)*56
220 X1=XI+ZI+160:Y1=90-YY+ZI
230 TRAP 250:COLOR 1:PLOT X1,Y1
240 COLOR 0:PLOT X1,Y1+1:DRAWTO X1,191
250 NEXT XI:NEXT ZI
260 GOTO 260

It would be so much simpler if you could hand out a hardcopy of the graphics to demonstrate your prowess with the computer. Your friends will be doing cartwheels and going hazoo-huzzah over your printing expertise. (Hazoo-huzzah?! Ed.) The most popular printers on the market today are the ones put out by Epson and C. Itoh. This being the case, we will write the hardcopy programs with these printers in mind.

Method #1

There are basically two ways to output graphic information to a printer. Since each of the eight hammers of the print head are individually addressable, the most efficient method is to output a column of eight pixels to the printer at a time. While this is the fastest way to do graphics, the code tends to be somewhat lengthy, and a somewhat obscure problem can crop up. This problem relates to the fact that a byte of the value 155 ($9B Hex) which is the ATARI’s internal representation of a (RETURN), converts it to the decimal value 13 ($0D Hex), what the outside world understands as producing a carriage return signal. If the information for the eight pixels that you are working on adds up to 155, it will not look right in the final print out. This conversion is done in the 850 Interface module and I know of no way around it at this time.

Method #2

The second method is to use only one hammer of the print head. It will take eight times longer to produce a hardcopy of a picture, since you will only be working with one scan line at a time, but the code will be shorter and simpler. A routine to produce a printed copy of the Archimedes spiral follows.

260 REM EPSON GRAPHICS 8 DUMPER
270 REM ONE LINE AT A TIME!
280 OPEN #1,8,0,"P:"
290 PUT #1,27:PUT #1,65:PUT #1,1
300 REM ABOVE SETS PIXEL SPACING TO 1
310 FOR Y=0 TO 191
320 PUT #1,27:PUT #1,75
330 PUT #1,64:PUT #1,1
340 REM ABOVE 4 BYTE GRAPHIC HEADER
350 FOR X=0 TO 319:LOCATE X,V,A
360 PUT #1,A:REM OUTPUT PIXEL
370 NEXT X:PRZNT #1:NEXT Y
380 END

Line 290 sets the printer’s line feed space of 1/72 of an inch. This the height of an individual print hammer. Lines 320 and 330 put the printer into graphics mode for one scan line. Line 330 specifies the number of bytes of graphic information to output to the printer. Since mode 8 graphics is 320 pixels across, we send this number to the printer in low byte, high byte format (64, 1). Line 350 sees if the pixel is a zero or a one, and line 360 sends it to be printed.

The next program listing is the same program written for the C.Itoh model 8510 printer. The main differences between this printer and the Epson is the method chosen to pass numeric values. A good example of this is how a 8510 is told that the next 320 bytes are to contain graphics. While the Epson people chose to specify number parameters as binary words (low byte, high byte) which is ideally suited to Assembly language programming, the manufacturer of the C.Itoh 8510 took an alternate route by passing numbers as character strings, something that BASIC can easily manipulate. Now the header of a 320 pixel line becomes: CHR$(27);"S0320".

260 REH C.ITOH GRAPHICS 8 DUMPER
270 REM
280 OPEN #1,8,0,"P:"
290 PRINT #1;CHR$(27);"T02"
300 REM ABOVE SETS PRINTER TO 1 PIXEL
310 FOR Y=0 TO 191
320 PRINT #1;CHRS(27);"S8320";
340 REM ABOVE OUTPUTS GRAPHICS HEADER
350 FOR X=0 TO 319:LOCATE X,Y,A
360 PUT #1,A;REM OUTPUT PIXEL
370 NEXT X:PRINT #1:NEXT Y
380 END

One thing to keep in mind if you are presently without a graphics printer but know someone who has one, is that all the information being sent to the printer does not have to go directly to it. The pixel data can be stored initially on a disk file, and later transferred to the printer, when one becomes available, using the copy file command in DOS. The only negative effect in using the above programs with disk files is that the information will use up about 500 sectors of disk space. The next two programs will correct this problem by outputting six pixels per byte. The six pixel combination was decided upon as the largest number that divided evenly into 192 (the number of scan lines) and could not possibly equal 155 (the carriage return conversion problem mentioned earlier.)

260 REM EPSON GRAPHICS 8 DUMPER
270 REM SIX LINES AT A TIME!
280 OPEN #1,8,6,"P:":REM TRY DISK?
290 PUT #1,27:PUT #1,65:PUT #1,6
300 REM ABOVE SETS PIXEL SPACING TO 6
310 FOR Y=0 TO 191 STEP 6
328 PUT #1,27:PUT #1,75
330 PUT #1,64:PUT #1,1
340 REM ABOVE 4 BYTE GRAPHIC HEADER
350 FOR H=0 TO 319:A=0
352 FOR Y1=Y TO Y+5: LOCATE X,Y1,Z
354 A=A+A+Z:NEXT Y1
360 PUT #1,A:REM OUTPUT SIX PIXELS
379 NEXT X:PRINT #1:NEXT Y
380 END
260 REM C-ITOH GRAPHICS 8 BUMPER
270 REM SIX LINES AT A TIME!
280 OPEN #1,8,0,"P:":REM TRY DISK?
290 PRINT #1;CHR$(27);"T12"
300 REM ABOVE SETS PIXEL SPACING TO 6
310 FOR Y=0 TO 191 STEP 6
320 PRINT #1;CHR$(27);"S8320";
340 REM ABOVE OUTPUTS GRAPHICS HEADER
350 FOR X=0 TO 313;A:=0
352 FOR Y1=Y+5 TO Y STEP -1
354 LOCATE X,Y1,Z;A=A+A+Z;NEXT Y1
360 PUT #1.A:REM OUTPUT PIXEL
370 NEXT X:PRINT #1:NEXT Y
380 END

These two programs will produce disk files that are now only 84 sectors long. A big improvement, don’t you think? Anyway, this will allow you to put eight of these files on each and every disk you own. After all, “Eight Is Enough”, don’t you know?

(Ed. Note: No one here at A.N.A.L.O.G is responsible for Charlie’s state of mind when he writes these non-tutorials, just thought you people would like to know.)

[Archimedes Spiral]
FIGURE ONE
[Archimedes Spiral]
FIGURE TWO