Showing posts with label Merlin. Show all posts
Showing posts with label Merlin. Show all posts

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.



Thursday, November 24, 2022

Apple IIe - 6502 Assembly Programming - A Full Screen Editor!

Apple IIe
6502 Assembly Programming - A Full Screen Editor!

Merlin-8 2.48 has a full screen editor that is a little bit easier to use than the single line editor. If you read my prior post where I created the program BEEP which calls the built in beep routine, you'll appreciate switching to the full screen editor. 

The manual for Merlin-8 and 16 (for the IIgs) can be found here http://www.apple-iigs.info/doc/fichiers/merlin816.pdf

Chris has an excellent video describing how to use the full screen editor here Assembly Lines #5: Merlin 8 Full Screen Editor.

Everything else is pretty much the same. I am using the DOS 3.3 version of the program. If you prefer ProDOS, there is a later version for that.

Here are the Full Screen Editor commands you won't find in the single line editor. If you are using AppleWin, the Open Apple key is the ALT key:
 
Open Apple+BGo to beginning of the source
Open Apple+NGo to the end of the source
Open Apple+DDelete the current line
Open Apple+RReplace the current line
Open Apple+EExchange (find and replace)
Open Apple+FFind text
Open Apple+IInsert a blank line
Open Apple+LLocate label, marker, or line number
Open Apple+QReturn to Editor Control Mode
Open Apple+XClipboard cut
Open Apple+VClipboard paste
Open Apple+YSelect all text to the end
Open Apple+8Create a line of asterisks
Open Apple+9Create a box of asterisks


Wednesday, November 23, 2022

Apple IIe - 6502 Assembly Programming - Getting Setup with a BEEP!

Apple IIe 
Assembly Programming - Getting Setup with a BEEP!

We're going to start with AppleWin. Why? It's easier and will let us focus on learning Assembly without fiddling with disks, etc. Once I get my wDrive, I'll setup to work on my physical Apple IIe hardware. 

Please note, I will not be providing tediously detailed, step-by-step, keypress-by-keypress instructions like this going forward. This is just a self contained post to get you started. There are much more detailed and better references (see bellow) than this blog or even my YouTube videos. What I will be doing is blogging/vlogging my journey and observations along the way.  

Reference Material

We're going to need a book or two. Some tutorials. Probably a few YouTube videos. 

Assembly Lines: The Complete Book A beginner's Guide to 6502 Programming on the Apple ][.

The first few of Roger Wagner’s Assembly Lines articles from Softalk magazine were assembled into a book back in the 80's. Unfortunately, the remaining articles, although planned for a second edition, were never published in book form. In 2014, Chris Torrence assembled and edited all of the articles and published a book. You can read more about it at Chris's web site above. This will be our primary guide for learning 6502 assembly programming.
  
You can either purchase Assembly Lines from Chris's web site above or download the PDF version.

Chris has a series of YouTube videos discussing Assembly Lines here Assembly Lines - CT6502.

Roger Wagner mentions several references in the introduction to the first edition. Fortunately, these are available from archive.org. You may also be able to find used copies available for purchase.




An Assembler

We'll be using the Merlin Macro Assembler from Southwestern Data Systems, version 2.43. You'll find here at macgui.com

CiderPress

CiderPress is a great tool to use along with your virtual AppleWin environment. With it you can create blank disk images, add files to a disk image, and other things from your computer. You can download CicerPress from  http://a2ciderpress.com/.

Getting Started

There is a great YouTube video showing how to get setup with AppleWin, Merlin, and CiderPress by PJG Creations Ltd here Apple II Assembly Programming with Merlin - Getting Started

Create a Blank Disk

You'll want a disk to store your assembly source code and object files. 
  • Create a DOS 3.3 disk image using CiderPress.
  • Start up AppleWin.
  • Load the DOS 3.3 disk image you created earlier as the first disk in AppleWin.
  • Click the second drive, and type in a name for your blank disk in the file dialog, and click "Open". This will cause AppleWin to create an unformatted disk when it boots. I used the name "BLANK". Pick whatever you want as long as it is not the name of an existing disk image in the subdirectory you are using.
  • Boot into DOS 3.3.
  • Initialize your unformatted disk. From the DOS prompt "]", type in the command "INIT BLANK,D2" to initialize the disk. 

Fire Up Merlin

  • Expand your Merlin Assembler disk image to a working subdirectory for your disk images.
  • From AppleWin, select the Merlin Assembler disk image for disk drive 1.
  • Select the formatted blank disk you created for disk drive 2.
  • Boot AppleWin.
You should now see the following screen. I'm not going to go into all of the commands. We'll just do enough to create, assemble, and save a simple program.

Merlin-Pro 2.43 Command Screen

Let Us BEEP!

Instead of "Hello, World!", the introductory assembly program appears to be a beep sound.
  • Switch to the blank disk you created to store your assembly source code and object files. Press the "D" key. You should see the "Drive: " switch from "1" to "2".
  • Type "C" for Catalog. The contents of disk 2 will be displayed. If you put in your empty disk, you should see something like the following:
BLANK Disk Volume

  • Press RETURN to leave the catalog view and return to the command screen.
  • Press "E" to start the assembly editor.
  • Press "A" and then RETURN to switch to append mode. A numeral one will appear with a block cursor following it, indicating you are on the first line of the program.
  • Press CTRL+P. A block of asterisks will appear. The asterisk in the first column, and any text following it, is ignored by the assembler as a comment. Press RETURN to begin the second line.
  • Press SPACE. This moves the cursor to the second column. And press CTRL+P again. An asterisk is placed at the beginning and ending of the second line with the cursor positioned after the first asterisk. Now you can space and type anything you wish on the line to describe your program. We'll use call this program "BEEP!". Press RETURN when you have finished typing.
  • Press CTRL+P again to finish the comment block. Press RETURN, type in an asterisk, and press RETURN again. You're screen should look something like the following:


Our Program Header for BEEP!

The assembly source code is organized into four columns. Labels go into the first column. The Operation Code goes into the second column, the Operand into the third, and then comments in the forth column.

Our first command needs to tell the assembler where to locate the program in memory when it starts. Read the first chapter, Apple's Architecture, from Assembly Lines so you understand what this means, and why it is important.

  • We are now on line five if you have typed in the program header as I have above. Press SPACE to move to the cursor to the Operation Code column and type "ORG". The ORiGin command defines the memory location where the program will be run. Press SPACE to move to the operand column and type "$300". We'll start the program at hexadecimal address 300. Press RETURN to move to the next line.
  • Now type the label "BELL", a SPACE, the operation code "EQU", a SPACE, and the operand "$FBDD". This will create a convenient reference we can use for the location in memory for causing a beep to be made by the computer. Press RETURN to move to the next line.
  • Type in the label "START", a SPACE, the operation code "JSR", a SPACE, the operand "BELL", a SPACE, and the comment ": RING BELL". The label START is a convenience, syntactic sugar if you will, referencing the start of our program. The operation Jump to SubRoutine, causes the computer to execute the code found at the memory address $FBDD (remember the line that EQUates the label BELL with memory address $FBDD), which rings the bell. At the end of the bell ringing code, there is an operand that returns execution to the address after the subroutine is called. Press RETURN to move to the next line.
  •  Type in the label "END", a SPACE, the operation code "RTS", two SPACEs, and the comment "; RETURN". The "END" label denotes the end of our program. The operation ReTurn from Subroutine, returns execution of our program back to where it was started, which will be the computer's operating system. Press RETURN to move to the next line.
  • Press SPACE, and the operation code CHK. CHecKsum is not a real operation code. It's a pseudo-opcode that instructs the assembler to insert a single byte containing the checksum for the entire program. You can use the checksum to verify the program was typed in correctly. Press RETURN to move to the next line.
  • Press RETURN, an empty line tells the editor to leave editing mode. Your screen should look something like the following:

The BELL! program completed in the editor


If you are having difficulty with the editor, you can reference Appendix B: Beginner's Guide to Merlin where you will find helpful instructions on using the editor and correcting mistakes. 

Code, Assemble!

Now we can assemble the code. Type ASM and press RETURN. You will be prompted with "UPDATE SOURCE (Y/N)?". Press "N". Your screen will scroll up and you'll see something like the following:

After running the assembler

If everything went well, you should see "Errors: 0" on the screen indicating no errors were found. If you have errors, you'll need to edit your program to correct any typos. 

Press "Q" and RETURN to quite the editor and return to command mode. 

Save That Source Code

At the "%" prompt, press "S" to save your source code. You are prompted with "Save:". Type in "BEEP" and press RETURN. The screen will refresh and you are returned to the "%" prompt.

Save The Object Code

Press "O" to save your object code. Since you just saved your source code, you are prompted with the same name you gave the source code file. Press "Y" to accept the name.

Was it Saved?

Press "C" to run the catalog command. You should see your program source and object code listed as "BEEP.S" and "BEEP". 

BEEP saved to disk

With your program source code and assembled object code saved to disk, you can leave Merlin. Press RETURN to leave the catalog and then "Q" to quit. You'll notice that you can reenter Merlin by typing "ASSEM" and RETURN at the "]" prompt. 

Run BEEP!

Let's give our program a test run. Type "BRUN BEEP" and RETURN to run the program. If all went well, you should hear a beep. If you don't, check your sound settings on AppleWin.