Character maps
Now we will close the gap between the Commodore's
version of ASCII and the real one. We'll also add a time-delay
routine to slow down the output. This routine isn't really of
interest to us right now, so we'll add a subroutine
called delay that executes 2,560*(accumulator)
NOPs. By the time the program is finished,
we'll have executed 768,000 no-ops.
There actually are better ways of getting a time-delay on the
Commodore 64; we'll deal with those in .
As a result, there isn't really a lot to discuss here. The later
tutorials will be building off of , so you may want to get familiar with
that. Note also the change to the body of
the greet macro.
On to the topic at hand. Let's change the code to use mixed case.
We defined the upper'case
and lower'case aliases back
in as part of the
standard
header, so we can add this before our invocations of
the greet macro:
lda #lower'case
jsr chrout
And that will put us into mixed case mode. So, now we just need
to redefine the data so that it uses the mixed-case:
hello1: .byte "Hello, ",0
hello2: .byte "!", 13, 0
target1: .byte "programmer", 0
target2: .byte "room", 0
target3: .byte "building", 0
target4: .byte "neighborhood", 0
target5: .byte "city", 0
target6: .byte "nation", 0
target7: .byte "world", 0
target8: .byte "Solar System", 0
target9: .byte "Galaxy", 0
target10: .byte "Universe", 0
The code that does this is in . If you assemble and run it, you will
notice that the output is not what we want. In particular, upper
and lowercase are reversed, so we have messages
like hELLO, sOLAR sYSTEM!. For
the specific case of PETSCII, we can just fix our strings, but
that's less of an option if we're writing for a game console that
puts its letters in arbitrary locations. We need to remap how
strings are turned into byte values.
The .charmap and .charmapbin
directives do what we need.
The .charmap directive usually takes two
arguments; a byte (usually in character form) indicating the ASCII
value to start remapping from, and then a string giving the new
values. To do our case-swapping, we write two directives before
defining any string constants:
.charmap 'A, "abcdefghijklmnopqrstuvwxyz"
.charmap 'a, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Note that the 'a constant in the second
directive refers to the a
character in the source,
not in the current map.
The fixed code is in , and will produce the expected results
when run.
An alternative is to use a .charmapbin
directive to replace the entire character map directly. This
specifies an external file, 256 bytes long, that is loaded in at
that point. A binary character map for the Commodore 64 is
provided with the sample programs
as petscii.map.
Versions of Ophis prior to 2.2 have a bug where only the first
argument to .byte would be translated. That's
fine for our example code here, with only one string per line, but
a more text-heavy title that relied on this should confirm their
version before getting too far in.