4.5 KiB
Use SPC() to repeat any character !
Introduction
You know how SPC()
can be used to PRINT a number of space characters. For example PRINT SPC(10)
will print 10 space characters.
Why didn't they allow to print something else than space characters ? It would have been interesting (?) to have the ability to repeat a sequence of any character.
Maybe like PRINT REPT("*",10)
would print 10 asterisks.
But Applesoft does not provide such an instruction. So are we doomed to use PRINT "**********"
?
Here's a technique that will allow you to repeat any character, even in FLASH
and INVERSE
without using additional 6502 routines.
Discovery
Let's see something weird ...
At the Applesoft prompt, type
FLASH
.
Then PRINT SPC(10)
. You should now see 10 flashing space characters.
Now, press CTRL-BREAK
. This exits the "flash" mode (do no type NORMAL
!!).
Type PRINT SPC(10)
again. And ...
WOW ! WHAT IS THAT ??
What are those inverted single quote characters doing here ? "Something" has replaced space characters with those inverted single quotes ...
If you have a loaded Applesoft program, I encourage you to
LIST
it. If not, quickly type a short one and see the results ...
As you can see, something is messed up !
Explanation
To understand what's happening here, you need to know how characters are printed on screen by Applesoft.
The general routine to print characters on screen is in $DB5C
.
Here's the routine, taken from S-C documentor website
1950 * PRINT CHAR FROM (A)
1960 *
1970 * NOTE: POKE 243,32 ($20 IN $F3) WILL CONVERT
1980 * OUTPUT TO LOWER CASE. THIS CAN BE CANCELLED
1990 * BY NORMAL, INVERSE, OR FLASH OR POKE 243,0.
2000 *--------------------------------
DB5C- 09 80 2010 OUTDO ORA #$80 PRINT (A)
DB5E- C9 A0 2020 CMP #$A0 CONTROL CHR?
DB60- 90 02 2030 BCC .1 SKIP IF SO
DB62- 05 F3 2040 ORA FLASH.BIT =$40 FOR FLASH, ELSE $00
DB64- 20 ED FD 2050 .1 JSR MON.COUT "AND"S WITH $3F (INVERSE), $7F (FLASH)
DB67- 29 7F 2060 AND #$7F
DB69- 48 2070 PHA
DB6A- A5 F1 2080 LDA SPEEDZ COMPLEMENT OF SPEED #
DB6C- 20 A8 FC 2090 JSR MON.WAIT SO SPEED=255 BECOMES (A)=1
DB6F- 68 2100 PLA
DB70- 60 2110 RTS
The routine is called with the accumulator containing the character to print every time Applesoft needs to print something (like when using PRINT
or INPUT
or ... SPC
!)
The routine that will effectively print the character on screen is COUT
(in $FDED
here named MON.COUT
) but this routine here is the pre-treatment of the character to print.
As you can see, before calling MON.COUT
, an ORA
with zero-page memory $F3
is executed. This ORA
is needed to display characters in flash mode. The problem is that $F3
, even after a CTRL-BREAK
is not reset and still contains #$40
(decimal 64), meaning that Applesoft is still (partially -- see below why) in flash mode.
But if it's in flash mode, how comes it prints NORMAL single quotes and not flashing characters ? Because $F3
is just a mask and is not enough to flash the characters on screen. Another mask, in zero-page $32
is also used, but this time by the MON.COUT
routine. In fact $32
is usually considered to be the memory that indicates if we are in normal (value #$FF
, decimal 255
), flash (value #$7F
, decimal 127
) or inverse (value #$3F
, decimal 63
) modes. But for the flash mode, the mask in $F3
is equally primordial. In fact, even in normal and inverse modes, the value in $F3
has an impact since the ORA
is called whatever the display mode is.
So, before any character is displayed on screen by Applesoft, two masking operation occur on the ASCII value of the character.
- an
ORA
with the value in$F3
- an
AND
with the value in$32
CTRL-BREAK
reset the value in $32
to 255
("normal" display mode) but it does not touch the value in $F3
. That's why we have these display glitches if we CTRL-BREAK
after FLASH
. Clearly, it's a bug.
Of course Applesoft expects and uses some specific values in $F3
and $32
.
NORMAL | FLASH | INVERSE | |
---|---|---|---|
$32 | 255 ($FF) | 127 ($7F) | 63 ($3F) |
$F3 | 0 ($00) | 64 ($40) | 0 ($00) |
Now