amichlin at swerlin.com
Sun Jul 30 08:19:08 EDT 2017
On 7/30/2017 4:52 AM, Evan Koblentz via vcf-midatlantic wrote:
> This popped into my mind: what if you want to display a large amount of text? I assume there's some better way than loading each individual character. The book I'm reading may explain it in a later chapter, and maybe it's counterproductive for me to ask at this point! Not looking for a code example right now. But someone please assure me assembly isn't always * this tedious *.
I posted what follows on Facebook and share it with members here with
the understanding that while my expertise is in teaching high school
students 6502 assembly and I'm pretty good at breaking things down into
digestible bites there are people on this list here who know *insanely*
more about 6502 assembly than I do, so feel free to to tear me apart.
All is good in the pursuit of knowledge!
It depends on what you need by a larger amount of text. A line or a
couple of lines, you'd use a loop. A lot more than that, you might have
to read it off disk.. which is an entirely different conversation.
Check out this for a simple hello world Merlin style:
A few things to note:
We put the characters directly into memory. Memory stores both the
program and any data for the program. This is possible without an
assembler, but you then have to hand calculate the addresses for all the
data (kind of like when you have to hand calculate PEEKs in BASIC).
The BEQ and BPL instructions are what are called branch logic
conditions. Think of them kind of like an if statements. The BEQ is
interesting because we take advantage of the 0 at the end of the string
(so called NULL termination - note the HEX 0 after the ASC command). So
we load each character into the A register, print each character, and
then check if equal. Well, testing for equal just means subtract (if the
subtraction equals 0, the two numbers are equal, set the zero status
flag). So if we load 0 in A, we also set the zero status flag and get to
skip the subtraction part. The zero status flags tells the computer to
take the branch and we brand to the RTS at the end of the program. All done.
What is tricky about hand coding branch instruction is it uses
*relative* addressing. That is, you don't say:
Branch to 0300hex and do something
Branch -30hex relative to my current memory address
This has the amazing advantage of lowering the memory requirements of
the program (since you need only the storage for the opcode - always -
and the and the smaller relative address). But it also limits how far
you can branch. FFhex instead of FFFFhex.
This, however, is a prime reason to use an assembler. If you hand
assemble you have to figure out the relative address on your own. And if
you are going backwards in memory, you have to know how the Apple II
represents negative numbers (something called 2s complement notation).
Ever wonder why you do CALL -151? 2s complement notation.
But, see, the wonderful assembler just does this all for you since it
can easily calculate relative addresses and knows all about things like
2s complement notation.
Not to discourage you from learning 2s complement notation, but it will
make a lot more sense once you've assembled a few programs with
something like Merlin.
More information about the vcf-midatlantic