Simple Assembly for Atari BASIC
A multi-part discussion of a few pet peeves about Atari BASIC and simple machine language utilities to fill in the gaps.
Part 1 - Introduction
Part 2 - Learn 82.7% of Assembly Language in About Three Pages
Part 3 - The World Inside a USR() Routine
Part 4 - Implement DPEEK()
Part 5 - Implement DPOKE
Part 6 - Various Bit Manipulations
Part 7 - Convert Integer to Hex String
Part 8 - Convert Integer to Bit String
Part 9 - Memory Copy
Part 10 - Binary File I/O Part 1 (XIO is Broken)
Part 11 - Binary File I/O Part 2 (XIO is Broken)
This actually isn't the project I meant to be working on. I ended up here, because of a series of other needs. Originally, I was working on converting some old examples from Compute! not written for the Atari and needed to demonstrate a machine language sort for an Atari BASIC numeric array. This required I understand Atari BASIC variables, and while writing that discussion I realized I needed facilities not included in Atari BASIC (16-bit peek and poke, memory moves, etc.) So, that brought me here to fill in some gaps missing in Atari BASIC.
Now that I'm done with this hopefully the Atari BASIC Variable article will be done soon, then I can get back to the machine language sort.
it will take a while to get these articles posted, reformatted, etc. Several will be posted today, and others over the next few days. For those who don't care to wait for the multi-part bloggitty-blog version the complete document is attached below in a couple formats:
LibreOffice ODT. Remove the .zip after downloading:
The Atari 8-bit computer was a paradigm-changing platform when introduced in 1979. The extensive, built-in color graphics and sound capabilities started computer-based “multimedia” years before the word existed. Atari would have been justified keeping it a completely closed box of mystery. Fortunately, they did not.
Atari provided a BASIC language with reasonable support for the computer’s custom hardware graphics and sound features. Many other computers introduced before and even after the Atari had BASIC languages providing little to no support for graphics or sound. They were little different from the original BASIC (circa 1964) developed in an era of time-sharing terminal printers intended for number and text processing.
Atari BASIC incorporates some good ideas. On program entry Atari BASIC converts commands to an abbreviated form called tokens. Using tokens cuts down memory use for program storage, speeds up program execution, and the tokenization process provides immediate syntax error feedback at the time a programmer enters a program statement.
Atari BASIC provides exceptionally high readability compared to other BASICs of the day. Atari BASIC nicely inserts spaces between commands and values in program listings. This spacing does not occupy the program's memory thanks to tokenization. Finally, Atari BASIC recognizes long variable names enhancing readability.
Some do not like the way strings work in Atari BASIC, but I find they make a lot of sense. When moving on to C years later, I credit the reduced learning curve for C strings to Atari BASIC; the way an Atari string behaves in memory is more like a C array of characters (less the ‘\0’ terminator) than Microsoft BASIC strings. Also, a character pointer in C is a concept similar to the Atari BASIC ADR() function.
Of course, nothing is perfect. Atari BASIC is missing some useful features for dealing with computer hardware on the computer’s terms. This is not really a critical failure of Atari BASIC, since many other BASICs do even less than Atari BASIC and part of the purpose of original BASIC was to protect the beginner programmer from architectural questions about the computer hardware. But, given the Atari’s additional graphics and sound features part of the fun of programming is making the Atari hardware do interesting things.
8-bit computers frequently have reason to deal with 16-bit, two-byte values. While Atari BASIC has PEEK and POKE working with single-byte values it lacks a way to work directly with two-byte values.
The Atari hardware provides many interesting bells and whistles for graphics and sound. (Literally, it can make bell and whistle sound effects.) Effective interaction with hardware registers and the operating system often require manipulating individual bits within a byte. Bit operations are not available in Atari BASIC.
Hand-in-hand with 16-bit values and bit operations is working with hexadecimal representation of values. When one becomes familiar with the hardware it begins to make a lot more sense to refer to and display values in their hexadecimal form. Hexadecimal value representation is not included in Atari BASIC.
Moving blocks of memory around has many practical uses in the Atari environment – copying character sets, animating characters or Player/Missile graphics, rapid updates of color registers, etc. Atari BASIC does not have a general purpose memory move feature. There is a common hack using Atari BASIC strings to perform a high-speed memory move. However, this method requires more setup, is not obvious to the casual programmer, and so is not as convenient and flexible as a command to move memory.
Atari BASIC’s I/O functions are missing the ability to load bulk, binary data into memory from a file, (such as graphics or character sets.) Atari BASIC must use slower loops to read a file, or waste memory by including the data within the BASIC program.
And the Ugly (or just darned weird)…
The worst weird thing about Atari BASIC does is that it handles all numbers as 6-byte, BCD, floating point. In spite of this it is still comparatively fast, so it makes one wonder how fast Atari BASIC could be if it used 16-bit integers instead of bogging down the 1.79 Mhz CPU with floating point math.
Another problem built into Atari BASIC is line lookup for statements. Atari BASIC identifies statements during execution by searching the line numbers from the beginning of the program to the desired statement. This causes statements at the end of a long program to execute slower than statements near the start of the program.
Atari BASIC has two different syntax options for GOTO. These are both valid:
What's up with that? It is a joke, right? I do hope the implementation cost less than a dozen bytes. Couldn't this have been replaced with a solution to one of the other problems, such as 16-bit PEEK and POKE?
All these issues with floating point use, line searching, and command syntax are fundamental to the internals of Atari BASIC, so solutions to these situations require writing a new version of BASIC. Since I’m not planning on making a career of this, contentment will have to come from resolving the easier problems mentioned earlier.
To fix these problems get a copy of OSS BASIC XL or BASIC XE, or TurboBasic XL. Really. Seriously. These BASICs can load and run all Atari BASIC tokenized programs (that is, SAVE’d programs) and ENTER Atari BASIC LIST’ed programs correctly at least 98% of the time. Both are faster than Atari BASIC and provide many of the useful features discussed here. And with the advent of high quality emulators you don't even need to concern yourself with acquiring the languages on physical ROM cartridges or disks. You can get the whole Atari experience plus modern convenience just by downloading a few digital image files. So, problem solved. Thanks for reading. See you later.
The Other Solutions
You're still here? The movie is over. Go home. . . .
So, trading up to a better BASIC is out of the question? For whatever questionable reason you are actually married to Atari BASIC and can’t switch to anything else? Fine. (Do not send me pictures of your children.) If there were no other options the article would end here. However, the miles of text (in the half dozen subsequent parts) must indicate interesting stuff follows.
Most of the issues are less difficult than they appear. In some cases a simple solution can be written using just Atari BASIC. However, given the speed of Atari BASIC the real problem becomes how to do it fast enough to be worthwhile. The best performance comes from machine language code. Even badly written assembly will produce machine code that runs circles around Atari BASIC. Below, the article will demonstrate that it has more than enough badly written assembly code to go around for everyone.
This article presents several reusable machine language utility programs expanding BASIC programs’ capabilities, and improving performance. These utilities are designed to be called from BASIC’s USR() function.
This article is not entirely a lecture on learning 6502 programming from scratch. But, the solutions are not terribly complicated, so it should not be too difficult for a beginner to follow. Final solutions with the utilities implemented in Atari BASIC test programs will appear for those who don't care about the assembly code.
Next time we will learn about Assembly language syntax and instructions in as few pages as possible.
For I know the plans I have for you, declares the Lord, plans for welfare and not for evil, to give you a future and a hope.