[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Applesoft BASIC PRINTs 7 bit data?
Heynony (nospam@noway.com) wrote:
: dalloff@gcfn.org (Dave Althoff Jr) wrote:
: > I hope that makes some kind of sense!
: Excellent! I had no idea where COUT was, or that the process would be
: that straightforward, all my manuals (along with the accompanying brain
: cells) are lost in history. Thanks very much.
Well, just for giggles, here's the general run-down of how text output
happens in the Apple ][. I'm working mostly from mostly-faulty memory
here so if somebody jumps in and corrects me, he's probably right... 8-)
When you want to output a character, you do it with a JSR to COUT which is
ALWAYS at $FDED. A look at the ROM code indicates that the intrinsic
routine, "Output a character to the screen" is not, in fact, located at
$FDED, but rather at $FDF0, a routine called "COUT1". This is the secret
to why it was possible to add DOS to the Apple in the first place, and the
reason that from Applesoft you have to do that "PRINT CHR$(4)" thing to
send DOS commands.
The COUT routine consists of a single instruction:
FDED: 6C 36 00 JMP (CSWL) ;CSWL = $0036
...which is a JMP to the location indicated in CSW. If you turn the
machine on and press RESET, then look in $0036, you should see:
*36 37
0036- F0 FD
Meaning that the COUT routine at $FDED is equivalent to:
FDED: 4C F0 FD JMP $FDF0
...which, ironically, happens to be the very next location in memory.
Odd, no? But look what that means: Every time a character is output to
the screen, there is an arbitrary jump to a routine pointed at by a
zero-page pointer. That means you can change it if you want! If you want
to direct the output to a peripheral card, for instance, you can store the
old contents of CSW (so that you know how to output to the screen) and
reset CSW to point to the routine that talks to your peripheral card, then
finish by jumping to the previous CSW location.
Likewise, if you want to install an operating system, you can hook it in
via CSW so that if, for example, somebody outputs a ^D at the beginning of
a line, you can intercept the characters coming through and interpret them
as a DOS command.
For BASIC programmers working in DOS (I think it's also true for
BASIC.SYSTEM) you can see why it is vitally important to always execute
PR#n commands as DOS commands (PRINT CHR$(4);"PR#";PSLOT) rather than as
Applesoft commands (PR# PSLOT). When you issue the Applesoft PR# command, CSW
gets reset to point at the selected peripheral slot, and when the slot
routine is done it will return the character to COUT1, leaving DOS out of
the loop. When you issue the DOS PR# command, CSW stays set to point at
DOS, but DOS resets the address that it returns to when it gets done to
point at the card slot routine instead of at COUT1.
Keyboard input is handled in a similar fashion, where the RDKEY routine at
$FD0C actually calls KEYIN at $FD1B via KSW at $0038, and it is done for a
similar reason. Somewhere I have a routine I wrote years ago that
exploits this to turn the input cursor into a twirling baton. One of
those things that took me weeks to write, then not too long after that I
found another routine that someone else wrote that did exactly the same
thing. Well, not exactly; my baton was "|/-\" while the other one was
"\!/-". Anyway, it's the same idea and done for the same reason...to
enable input to come from places other than just the keyboard. Also, if
you wanted to write a background event handler for the 8-bit Apple ][, the
easy way to implement it would be to check for event triggers while waiting
for keyboard input, since that's when the system isn't busy doing other things
anyway...
Just more rantings from someone who hasn't done much with this stuff in
years, but who still uses a IIgs every day...!
--Dave Althoff, ][.
--
/-\ _ _ *** Thanks for a great season!! ***
/XXX\ /X\ /X\_ _ /X\__ _ _ _____
/XXXXX\ /XXX\ _/XXXX\_ /X\ /XXXXX\ /X\ /X\ /XXXXX
_/XXXXXXX\__/XXXXX\/XXXXXXXX\_/XXX\_/XXXXXXX\__/XXX\_/XXX\_/\_/XXXXXX