Friday, November 25, 2022

Apple II - 6502 Assembly Programming - BUGS?

Apple II
6502 Assembly Programming
DOS BUGS!

BRUN and COUT

Not surprisingly, there are bugs in Apple DOS 3.3. One that appears to trip up novice assembly programmers, at least this programmer, is found when running a program that makes calls to I/O subroutines like COUT ($FDED). 

COUT is used to conveniently output text to the screen. It handles scrolling and moving the location along as you push text characters to it. Why reinvent the wheel, eh?

Well, if you run your program using BRUN, you'll end up in an infinite loop. 

How to Defuse a Bomb or A Note about BRUN and COUT

There was an episode of M*A*S*H, where Hawkeye and Trapper follow poorly written instructions to defuse a CIA propaganda bomb, causing the bomb to go off. 
Carefully cut the wires... leading to the clockwork fuse at the head.
But first, remove the fuse.

On page 35 of Assembly Lines: The Complete Book A beginner's Guide to 6502 Programming on the Apple ][, there is a note about BRUN and COUT. Unfortunately for me, I didn't read this until after I typed in and ran the example program on page 31. I spent about an hour going over the code, attempting to "fix" it thinking there was a typographical error or an error in the example code. Woops.

In the future, I'll read he entire chapter before I try out the code.

Here's an excerpt from  http://www.textfiles.com/apple/ANATOMY/cmd.brun.bload.txt explaining what goes on.

*--------------------------- N O T E ----------------------------*
*     The "JSR INITIOHK" instruction (at $A391) resets the I/O   *
* hooks to point to DOS's own I/O handlers (INPTINCP, $9E81 and  *
* OPUTINCP, $9EDB).  Therefore, any input or output performed by *
* your BRUNed program is scrutinized by DOS.  Each time INPTINCP *
* or OPUTINCP are entered, the stack pointer is saved in         *
* STKSAVED ($AA75).  However STKSAVED was previously set in the  *
* command parsing and processing routines before the BRUN command*
* handler was entered.  Because the BRUN command resets the stack*
* pointer incorrectly, the computer goes into an infinite loop   *
* AFTER your BRUNed program is executed.  If MON is NOT in       *
* effect, execution keeps on branching back into your program.   *
* Your program is re-entered at the first byte after the last    *
* instruction that called the routine that contained the         *
* "JMP (KSW)" or "JMP (CSW)" instruction. 

What to Do?

So, what can you do? There are a couple of work arounds. First, and easiest, is to not use BRUN. Run your program using BLOAD or to run it from the Monitor. There are also programmatic workarounds described in the reference above. 

For now, I'm going to avoid BRUN and will look for a best practice approach after more experience. So far, I've only learned a handful of OpCodes and typed in a couple of example programs. A few more to go I think.



No comments:

Post a Comment