S-C Macro Assembler "Makes assembly language programming on the Apple as easy as programming in BASIC." S-C Software Corporation 2331 Gus Thomasson, Suite 125 P.O. Box 280300 Dallas, Texas 75228 (214) 324-2050 --------------------------------------------------------------------- ABOUT THE DISKETTE The S-C Macro Assembler is provided on a single diskette using standard 16-sector DOS 3.3 format. Neither the diskette nor the files are "protected" against copying. You should make a working copy now, using the copy program from your Apple DOS 3.3 System Master diskette. Keep the original diskette in a safe place, and use your copies. NOTICE This manual and the software product it describes are copyrighted by S-C Software Corporation. Neither the manual nor the diskette, nor any part thereof, may be copied by any means without prior written consent (except for the personal use of the registered owner). CREDITS The S-C Macro Assembler was programmed and this manual written by Bob Sander-Cederlof, with assistance from Lee Meador, Mike Laumer, and Bill Morgan. Copyright (C) February, 1982 S-C Software Corporation 2331 Gus Thomasson Road, Suite 125 P. O. Box 280300 Dallas, TX 75228 (214) 324-2050 --------------------------------------------------------------------- TABLE OF CONTENTS 1. Introduction General 1-1 Significant New Features 1-2 2. Tutorial Description of Source Program 2-1 Saving a Source Program on Disk 2-2 Assembling a Source Program 2-2 Executing the Object Program 2-3 Modifying a Source Program 2-3 Easier Entry of Source Programs 2-4 3. Source Programs Automatic Line Numbering 3-1 Built-In Tab Stops 3-1 Label Field 3-2 Normal Labels 3-2 Local Labels 3-3 Private Labels 3-4 Opcode Field 3-4 Operand Field 3-4 Comment Field 3-4 Comment Lines 3-5 Escape-L 3-5 Cursor Controls 3-5 4. Commands Assembler Commands 4-1 Source Commands 4-2 NEW 4-2 LOAD 4-2 SAVE 4-2 TEXT 4-3 HIDE and MERGE 4-4 RESTORE 4-6 Editing Commands 4-7 Range Parameters 4-7 String Parameters 4-8 LIST and FIND 4-9 EDIT 4-10 REPLACE 4-11 DELETE 4-12 RENUMBER 4-13 COPY 4-14 Listing Commands 4-15 FAST and SLOW 4-15 PRT 4-15 " 4-15 --------------------------------------------------------------------- Object Commands 4-16 ASM 4-16 MGO 4-16 VAL 4-17 SYMBOLS 4-17 Miscellaneous Commands 4-18 AUTO 4-18 MANUAL 4-18 INCREMENT 4-18 MEMORY 4-19 MNTR 4-19 RST 4-19 USR 4-20 DOS Commands 4-21 Monitor Commands 4-22 5. Directives .OR -- Origin 5-1 .TA -- Target Address 5-1 .TF -- Target File 5-3 .IN -- Include 5-4 .EN -- End of Program 5-4 .EQ -- Equate 5-4 .DA -- Data 5-5 .HS -- Hex String 5-6 .AS -- ASCII String 5-6 .AT -- ASCII String Terminated 5-6 .BS -- Block Storage 5-7 .TI -- Title 5-8 .LIST -- Listing Control 5-8 .PG -- Page Control 5-9 .DO -- Conditional Assembly 5-9 .ELSE -- Conditional Assembly 5-9 .FIN -- Conditional Assembly 5-9 .MA -- Macro Definition 5-11 .EM -- End of Macro 5-11 .US -- User Directive 5-11 6. Operand Expressions Elements 6-1 Decimal Numbers 6-1 Hexadecimal Numbers 6-1 Labels 6-1 Literal ASCII Characters 6-2 Asterisk (*) 6-2 Operators 6-3 Arithmetic: +, -, *, / 6-3 Relational: <, =, > 6-3 --------------------------------------------------------------------- 7. Macros Definition and Example 7-1 Call Paraneters 7-2 Private Labels 7-2 Listing the Macro Expansions 7-3 Using Conditional Assembly in Definitions 7-3 Nested Macro Definitions 7-5 Possible Errors 7-7 Sample Macros in MACRO LIBRARY 7-7 8. 6502 Programming Programming Model 8-1 Addressing Modes 8-3 Implied Mode 8-3 Relative Mode 8-3 Accumulator Mode 8-4 Immediate Mode 8-4 Direct Modes 8-4 Indirect Modes 8-5 Instructions 8-7 Transfer Operations 8-8 Arithmetic Operations 8-9 Logical Operations 8-10 Shift Operations 8-10 Compare Operations 8-11 Conditional Branch Operations 8-12 Unconditional Jump Operations 8-13 Return Operations 8-13 Other Operations 8-13 Instruction Chart 8-14 9. SWEET-16 Programming Model 9-1 Registers 9-2 Opeodes 9-2 Sample Programs 9-3 Appendix A -- Operation and Memory Usage Appendix B -- Error Messages Appendix C -- Printer Software Appendix D -- Customizing Appendix E -- Bibliography Index Quick Reference Card Registration Card --------------------------------------------------------------------- Chapter 1 -- INTRODUCTION S-C Software Corporation is pleased to introduce the S-C Macro Assembler, the latest version of our most popular product. The S-C Assembler II Version 4.0 already has the reputation of being the easiest editor/assembler to learn, to remember, and to use.. now the S-C Macro Assembler provides a new level of power and performance for the beginner and professional programmer alike. The S-C Macro Assembler boasts 20 directives (pseudo-ops) and 29 commands, including a convenient EDIT command with 15 subcommands. COPY and REPLACE commands further simplify entry and modification of even the most complex programs. The S-C Macro Assembler will operate in any Apple II or Apple II Plus with at least 32K RAM and one disk drive. Any additional memory or disk drives will be used as required. A Language Card version is also included. A memory size of 48K allows source programs of over 24,000 bytes to be handled entirely within RAM. The Language Card version allows source programs of over 32,000 bytes. Much larger programs can be edited and assembled using the "INCLUDE" and "TARGET FILE" capabilities, up to the limit of on-line disk storage. Programs can be edited, assembled, and tested entirely within the framework of the S-C Macro Assembler. The editor and assembler are co-rezident, allowing rapid cycles of modification, re-assembly, and check-out. All DOS and Apple Monitor commands are active as well, providing a familiar interface to the standard Apple features. The S-C Macro Assembler uses its own technique to store source files, but it also can read or write standard TEXT files. With this ability, you can EXEC in files from another assembler, use some other text editor to prepare files, keep a library of routines on disk to EXEC into any program, or use S-C Macro Assembler to prepare EXEC files for any purpose. Already well-known for excellent support, S-C Software Corporation pledges to continue development of new features, and to help owners gain the maximum benefit from the S-C Macro Assembler. In addition to telephone consultation, a monthly newsletter is available by subscription (currently $15/year). The "Apple Assembly Line" covers items of interest to assembly language programmers at all levels, and has helped many to advance their programming skills. 1 - 1 --------------------------------------------------------------------- New Features Here is a brief summary of the new features the S-C Macro Assembler has that S-C Assembler II Version 4.0 did not. For more details on these new features, see the relevant chapters of this manual. The highlights are of course macros, conditional assembly and the new commands EDIT, COPY and REPLACE. But they are not all! COMMANDS There are 10 new commands: EDIT Select a line, a range of lines, or a range of lines that contain a particular string. Edit the lines using some of the 15 convenient sub-commands. TEXT Write source program to disk, as a TEXT file. Write it with or without line numbers! REPLACE Global search and replace. Your search string can include wildcards; you can limit the search to a line, a range of lines, or search the entire program. The search can be made sensitive or insensitive to upper/lower case distinctions. And you can select Auto or Verify mode for replacement. COPY Copy one or more lines from one place to another in the source code. Rearrange your code as you please! AUTO Generate automatic line numbers after every carriage return. Allows ordinary TEXT files to be EXECed into S-C Macro Assembler! You still can use the Version 4.0 form of automatic line numbers. Now you have a choice! MANUAL Turn off automatic line numbering. SYMBOLS Print out the symbol table, in case you missed the first time. MNTR Enter the system monitor (just like CALL -151 in BASIC). Of course all the Monitor commands can be executed within S-C Macro Assembler, but if you really WANT to leave.... RST Change the Autostart Monitor RESET vector to the specified address. " Send setup control strings to your printer. 1 - 2 --------------------------------------------------------------------- There are also improvements in the older commands: The spelling of commands is now checked. In older versions, only the first three characters were tested. The first three are still all that are necessary, but any additional letters you type must be correct. For example, LIS will list your program, and so will LIST. But, LISX will give a syntax error. LIST and FIND now have the same syntax (in fact, they are processed by the same routine.) They may now specify either a line range, a search string, or both. The search string now requires a delimiter. Line ranges in the LIST, FIND, COPY, EDIT, and DELETE commands may be written with a leading or trailing comma (as in Applesoft): LIST ,2500 List from beginning through 2500. LIST 2500, List from 2500 through end. The NEW command now restarts the automatic line numbering at 1000, rather than continuing from the last line number you entered. The SLOW and FAST commands no longer use the Monitor output hooks at $36 and $37. To leave the Macro Assembler, type FP or INT. You no longer have to also type PR#0. After using the PR#slot command to run your printer, use PR#0 to turn it off. FAST won't do it anymore. DIRECTIVES There are 7 new directives: .MA and .EM For macro definition. .DO expr Start conditional block. .ELSE Toggle condition flag. .FIN End conditional block. .TI num,title Title and number each page of the assembly listing. .AT string Like .AS, but the last character has the high-bit set opposite from the rest. The .DA directive may now have a list of expressions. The .EQ directive may now be used with local labels. The .LIST directive has new options to control listing of macro expansions. 1 - 3 --------------------------------------------------------------------- SOURCE ENTRY Control-O (Override) will allow any control character to be typed into a source line in the normal input mode or in edit mode. The control character will appear in inverse video. The editor no longer double spaces after each line is entered. The escape-L comment line produces one less dash, so that the line lists on the screen without a blank line after it. Operand expressions can now include * and / as operators, as well as + and -. The relational operators (<, =, and >) may also be used. The tab routine has been changed to include up to five tab stops. The stop values are kept in a user-modifiable list starting at $1010. These are the actual column numbers (not 3 less, as in version 4.0). You may use any values up to column 248. The tab character (control-I, $89) is kept at $100F now, so you can change it if you like some other character better. Any sequence of the same character repeated 4 or more times in the source code is replaced by a token $C0, the character code, and the repeat count. (multiple blanks are still replaced by a single byte between $80 and $BF.) This reduces both the memory requirements and disk file size for your source programs. If you want to shrink your source file a little, and if you have been using the Escape-L to generate comment lines that have all those dashes in them, type "EDIT" and hold down the RETURN and REPEAT keys until the etitire program has been scanned. Type MEM before you do it, and after it is finished; you will probably notice a significant saving! A parameter at location $1017 allows the extra compression to be turned on or off. If the contents of $1017 is $04, compression is on. If it is $FF, compression is off. You can experiment with this parameter to see what effect it has on program size. 1 - 4 --------------------------------------------------------------------- ASSEMBLY Older versions of the assembler terminated assembly after finding one error. The S-C Macro Assembler keeps going, but rings the bell and prints an error message, so you know about it. If any errors are found during pass one, assembly terminates before doing pass two. At the end of assembly, the number of errors found is printed. Typing the RETURN key during assembly will abort the assembly (even if the listing has been turned off with LIST OFF directive). MEMORY USAGE All page zero variables used by the assembler have been concentrated, so $00 through $lF are completely free for the user. The standard version of the S-C Macro Assembler now occupies $1000 through $3lFF. The symbol table starts at $3200 and grows upward; the source code still starts at $9600 and grows downward. The Language Card version fills the 16K RAM card from $D000 through about $F300. The symbol table begins at $1000 rather than $3200. There are no variables within the body of the assembler. The Language Card version could be burned into ROM and placed on a firmware card, if you so desire. 1 - 5 --------------------------------------------------------------------- Chapter 2-- TUTORIAL In this chapter, we'll go step-by-step through the process of writing a small progran with the S-C Macro Assembler. First enter S-C Macro Assembler from DOS by booting the disk or by typing "BRUN ASM MACRO". Then type in the following short program: 1000 TONE LDA $C030 1010 LOOP DEY 1020 BNE LOOP 1030 JMP TONE Now type "LIST" to see the program as the computer has it. The display should look like this: :LIST 1000 TONE LDA $C030 1010 LOOP DEY 1020 BNE LOOP 1030 JMP TONE Description of the Source Program: The listing above is called a source program. It is the text form of an assembly language program. Later we will go through the steps necessary to convert it to executable form, but for now let's observe what the source form looks like. The first column contains line numbers. These are always 4-digit numbers. Assembler line numbers work just like BASIC line numbers for diting, inserting and deleting lines, but have nothing to do with the flow of control (no GOTO linenumber.) The second column contains labels. These are used instead of line numbers for controlling the program flow. They also can act like BASIC variables. In our example, the labels are TONE and LOOP. The third column contains opcodes (OPeration codes). These are either standard 6502 instructions, SWEET-16 instructions, or special "directives" to the S-C Macro Assembler. In our example, all the opcodes are 6502 instructions (LDA, DEY, BNE, and JMP). The opcode field may also contain macro calls. The fourth column contains operands. The opcode tells the computer what to do; the operand tells what to do it to. The operand can be a number, a label, or an arithmetic expression. Sometimes the opcodes does not use an operand, as in the DEY above. Others use a more complicated format. The operand on the first line above, "$C030", is a hexadecimal number. The operands on the BNE and JMP lines are labels. 2 - 1 --------------------------------------------------------------------- Saving a Source Program on Disk: To save the program to a disk, type "SAVE NOISY". This is a standard DOS SAVE command, just like you would use in BASIC. Note that S-C Macro Assembler source files are type "I" files. DOS thinks they are Integer BASIC programs, but they will not run as they are. (DOS is fooled, but Integer BASIC would not be fooled at all.) NOTE: You do NOT need to have Integer BASIC in your machine to use the S-C Macro Assembler. To clear memory for a new program type "NEW". To reload the program from disk type "LOAD NOISY". Assembling a Source Program: A program must be assembled into binary form before it can be executed. The command to assemble a program is "ASM". Try it now.... Our program is now assembled into memory starting at address $0800. The display should look like this: :ASM 0800- AD 30 C0 1000 TONE LDA $C030 0803- 88 1010 LOOP DEY 0804- DO FD 1020 BNE LOOP 0806- 4C 00 08 1030 JMP TONE SYMBOL TABLE 0803- LOOP 0800- TONE : Notice that two more columns have been added to the left of those we saw when we typed "LIST". The first new column contains the memory addresses (in hexadecimal) into which the program assembled The second column has one, two, or three hex numbers (two digits each) which are the contents of the memory jocations. The Symbol Table is a list of all the labels and the values assigned to them. The program is now in memory in two forms. The source program is there, right beneath DOS. The executable form, called the "object" program, is in memory from $0800 through $0808. 2 - 2 --------------------------------------------------------------------- Executing the Object Program: To run the program, type "MGO TONE". Do you hear the tone coming from your Apple speaker? It is being produced by continually toggling the position of the speaker coil by addressing $C030, at about 800 toggles per second. This makes a tone of about 400 Hertz. As soon as you get tired of it, hit the RESET key to stop the noise. Note that you can run a program from the assembler by MGO-ing to a label, and that the RESET key reenters the assembler. (If you have the Autostart ROM, that is. If you don't, you will get the "*" prompt: type 3D0G to reenter the assembler) Now we have walked through the entry, assembly, and execution of a very small program. The same steps would work for a large program, but there are many other features built-in to the S-C Macro Assembler which can make programming in assembly language even easier than programming in BASIC. Modifying a Source Program: To get the flavor of some more of the features of the S-C Macro Assembler, let's modify the TONE program a little. It would be nice if the TONE program would stop gracefully without hitting the RESET key. I like to set it up to quit when any key is pressed on the keyboard. I do it like this: 1030 LDA $C000 LOOK AT KEYBOARD 1040 BPL TONE NO KEY PRESSED YET 1050 STA $C010 CLEAR KEYBOARD STROBE 1060 RTS RETURN Note that a new column has been added: the comments column. The operand column ends with a blank; any useful comments to help you understand next week what you did today cam be written after that blank. If you type in those four lines, and then type the LIST command, you will see that they are now part of your source program. Line 1030 has been replaced, since you typed a new line 1030. Now type ASM, to create the new version of your program in executable (object) form. And execute it, by typing MGO TONE. This time you can stop the tone by pressing any key. 2 - 3 --------------------------------------------------------------------- Easier Entry of Source Programs: Now let's try an easier way to enter source lines. First save the latest version of your TONE program on a disk by typing SAVE NOISY again. Then type "NEW" to erase the source program from memory. (It is still on the disk.) Now hold down the CTRL key ("CTRL" means "control"), and type the letter I. We call that typing "control-I". Look at the screen. You will see that the Apple printed "1000", and the cursor is blinking after that. Type control-I again, and you will see the cursor move over about 7 character positions. Whenever you type control-I at the beginning of a line, the S-C Macro Assembler will automatically generate the next line number for you. Usually this will be ten higher than the last line number you entered or deleted. (The increment is settable to whatever interval you like.) Whenever you type control-I inside a line (beyond the beginning), the cursor will move to the next tab stop. Play with this a while, and you will find that the tab stops lime up nicely with the source program format. Why don't you try typing in the TONE program again, with a few more comments for good measure? This time use control-I for the line numbers and tabbing. Start by typing NEW, so we know that there are no stray line numbers left from some previous work. I am going to help you, showing control-I with the symbol "^I". Now type: :^ITONE^ILDA $C030^ITOGGLE THE APPLE'S SPEAKER :^ILOOP^IDEY^I^IDELAY FOR ABOUT 1250 MICROSECONDS :^I^IBNE LOOP :^I^ILDA $C000^ILOOK AT KEYBOARD :^I^IBPL TONE^INO KEY PRESSED YET :^I^ISTA $C010^ICLEAR KEYBOARD STROBE :^I^IRTS^I^IRETURN :LIST Type ASM again, and MGO TONE. The program should work just like it did the first time. Stop it by pressing any key. With this brief introduction, you should now be ready to dive into the following chapters. As you study each new command or feature, experiment with it until you really understand what is happening. Look up some of the books mentioned in the Reference Bibliography for help in understanding the 6502 language. If you need some personal help, call us at (214) 324-2050. 2 - 4 --------------------------------------------------------------------- Chapter 3-- SOURCE PROGRAMS Source programs are entered a line at a time, with a line number identifying each line. The line numbers may run from 0 through 9999. The automatic line numbering and the RENUMBER command use numbers from 1000 through 9999 to keep the columns straight, but this is not necessary if you prefer lower numbers. Source program lines are kept sorted in line-number order; the numbers are used for editing purposes, just as in BASIC. A blank must always follow the line number. After the blank there are four fields of information: the label, opcode, operand, and comment fields. Adjacent fields must be separated by at least one blank. Lines may be up to 248 characters long. Automatic Line Numbering: Although you may type the line number yourself, in the same way as in either Applesoft or Integer BASIC, the S-C Macro Assembler includes two convenient and powerful means for automatic line number generation. The first method is really semi-automatic, because you do have to type a control-I to get the next line number. Any time the cursor is at the beginning of a line (right after the prompting colon), typing a control-I will cause the next line number to be generated. Immediately after loading, the "next line number" will be 1000. The number will be displayed as four digits and a trailing blank. The cursor will be in position for the first character of a label, or the asterisk denoting a comment line. If you type the control-I in any other position than the beginning of a line, it will cause a tab to the next tab stop. The second method is invoked by typing the AUTO command, with or without a starting line number. In the AUTO mode, the next line number is automatically generated at the beginning of every line. If you don't want to use the line number, or want one out of sequence, you can backspace up to the prompt and type a command or line number. The AUTO mode is terminated by the MANUAL command, by hitting RESET, or by any error message. The "next number" is always the value of the previous line number plus the current "increment". The standard increment is 10, but you can change it to any reasonable value with the INCREMENT command. Built-In Tab Stops: Although the opcode, operand, and comment fields are not required to begin in any particular column, it is neater to align them. Therefore tab stops are included in S-C Macro Assembler at columns 14, 18, 27, and 32. 3 - 1 --------------------------------------------------------------------- The standard tab stops allow a label field of six characters, an opcode field of three characters, and a comment field beginning in column 41 of the assembly listing. Control-I is the standard ASCII tab character, and is used by the S-C Macro Assembler. Normally control-I will generate enough spaces to move the cursor to the next tab stop. If control-I is typed at the beginning of a line, the next line number and one space will be generated. If you are already past or at the last tab stop, control-I will generate a single space. Some printer interface cards with firmware drivers use control-I for setting various modes. If you wish to change the tab character, you may do so. It is stored at location $100F. An alternative is to change the printer interface control character, which is usually stored at $06F8+slott. Space has been reserved inside S-C Macro Assembler for a total of five tab stops. They are stored in locations $1010 through $1014, as column numbers. You may change them if you wish. If you want fewer than five tab stops, set the remaining ones to zero. Label Field: The label field may be left blank, or may contain a label. There are three types of labels used in S-C Macro Assembler: normal labels, local labels, and private labels. The first character of the label must be in the second column after the line number. 1000 START.HERE (normal label) 1010 .23 (local label) 1020 :12 (private label) Normal Labels: Used to name places in your program to which you will branch, as well as constants and variables. Normal labels may be up to 32 characters long. The first character must be a letter; subsequent characters may be letters, digits, or the period character (".") The period is useful for making long labels readable. For example, a subroutine to extract the next character from a buffer might be named "GET.NEXT.CHAR.FROM.BUFFER". The standard tab stops assume your labels will be six or less characters long. However, since the assembler is relatively free-format, you may type any length label followed by a blank and the opcode, operand, and comment fields. Or, if you wish, you nay type the long label on a line all by itself. In this form, the label is assigned the current value of the location counter, just as if you had appended ".EQ *" to the line. 3 - 2 --------------------------------------------------------------------- 1000 * SAMPLE PROGRAM WITH NORMAL LABELS 1010 * 1020 SOURCE.LINE.POINTER EQ $13 (WITH $14) 1030 CHAR.POINTER EQ $12 1040 * 1050 READ.NEXT.CHARACTER.FROM LINE 1060 LDY CHAR.POINTER 1070 LDA (SOURCE.LINE.POINTER),Y 1080 INC CHAR.POINTER 1090 RTS Local Labels: Used to name branch points within a module. The main purpose for local labels is to make programs more readable by reducing the number of label names you must invent. As a side effect, local labels save considerable space in the synbol table during assembly; they only require two bytes each. The use of local labels also encourages structured programming habits. Local labels have a period as the first character, followed by one or two digits. Any label from ".0" through ".99" may be used. (Please note that these are label names, not decimal fractions. Consequently, the label ".1" is treated as exactly equivalent to the label ".01"; in fact, it will be listed in the symbol table listing as ".01".) A local label is defined internally relative to the normal label which comes before it in the source program. (There must be one before it, or you will get an error message.) The value must be no more than 255 greater than the value of the associated normal label. Since each set of local labels is associated with a particular normal label, you may re-use the same local labels as often as you wish. Here is an example of three little routines in the same source program, using normal and local labels. 1000 PRINT.MESSAGE 1010 PHA SAVE A-REGISTER 1020 .1 JSR PRINT.CHARACTER 1030 INY 1040 LDA MESSAGES,Y 1050 BNE .1 =0 FOR END OF MESSAGE 1060 PLA RESTORE A-REGISTER 1070 RTS 1080 * 1090 GET.NEXT.CHARACTER 1100 LDY CHAR.POINTER 1110 LDA INPUT.BUFFER,Y 1120 CMP #RETURN 1130 BEQ .1 END OF LINE 1140 INC CHAR.POINTER 1150 .1 RTS 3 - 3 --------------------------------------------------------------------- 1160 * 1170 GET.NEXT.NONBLANK.CHAR 1180 .1 JSR GET.NEXT.CHARACTER 1190 BEQ .2 END OF LINE 1200 CMP #BLANK 1210 BEQ .1 1220 .2 RTS Private Labels: Used primarily within macros as branch points. Private labels are maintained in a separate symbol table, and hence do not interfere with either normal labels or local labels. Each private label is associated with a particular invocation of a macro, so that the assembler treats the recurrence of the same label number as a unique label. Private labels are discussed in more depth in the chapter on MACROS. Opcode Field: The opcode field contains a machine language or SWEET-16 operation code, a macro name, or an assembler directive. If you are using the tab stops, the opcode field normally starts in column 14. However, opcodes may begin in any column after at least one blank from a label or at least two blanks from a line number. The S-C Macro Assembler uses the standard 6502 instruction mnemonics as defined by MOS Technology, and the standard SWEET-16 mnemonics as defined by author Steve Wozniak. The 6502 opcodes, SWEET-16, macros, and assembler directives are all discussed later in this manual. Operand Field: The operand field usually contains an operand expression. Some of the 6502 instructions have no written operand, such as NOP, BRK, DEX, and others. Four of the 6502 instructions (ROL, ROR, ASL, and LSR) may be used either with or without a written operand. If no operand is written with these four instructions, you must type at least two blanks before a comment. Comment Field: Comments are separated from the operand field by at least one blank. For your convenience, a tab stop is set at column 26. In the assembly listing, tabbed comments will begin in column 41, which is the beginning of the next line on your Apple screen. 3 - 4 --------------------------------------------------------------------- Comment Lines: Full lines of comments may be entered by typing an asterisk (*) in the first column of the label field. This kind of comment is useful in separating various routines from each other, and labelling their contents. It is analogous to the REM statement in BASIC. Lines which are completely blank are also treated as comments. Escape-L: A special comment line is built-in to the S-C Macro Assembler. If you are at the beginning of the label field (where a comment line could begin), typing the ESC key and then the letter "L" will generate the built-in comment line. The built-in comment line is a line of dashes which just fill one line on the screen. It is very commonly used to set off blocks of comments. If a comment line of dashes is not your favorite, you may change the repeated character. The ASCII code of the character is kept at $1015. It is currently $AD, which is ASCII for "-". If you type Escape-L at the beginning of a line (before a line number), it has a different meaning. In this case it will cause the first six characters of the line on the screen to be changed to " LOAD ". Then the rest of the line will be read from the screen, and issued as a LOAD command. The purpose is to facilitate loading a source file from the disk, after displaying a CATALOG. Cursor Controls: The standard Apple II screen editing tools are supported by S-C Macro Assembler. You can edit lines of assembly language source in just the same way that you edit lines in your Integer BASIC or Applesoft program. Whether or not you have the Autostart ROM, you may use the new Apple standard cursor movement controls: escape-I, -J, -K, and -M. The older escape-A through escape-F and escape-@ are also supported by S-C Macro Assembler. 3 - 5 --------------------------------------------------------------------- Chapter 4-- COMMANDS You will use three types of commands in S-C Macro Assembler: Assembler Commands, DOS Commands, and Monitor Commands. The Assembler Commands allow you to edit, assemble, and execute your assembly language programs. The Apple Monitor and DOS commands are also recognized, although they are not all of use from within the S-C Macro Assembler. Commands are typed immediately after the prompt symbol, which is a colon (:). ASSEMBLER COMMANDS There are 29 commands recognized by the S-C Macro Assembler. All Assembler Commands may be abbreviated to the first three letters if you so desire. As many characters of the command name that you do type are checked for spelling. (Two DOS Commands, LOAD and SAVE, are used so frequently that they might be thought of as Assembler commands. However, they are DOS Commands, and as such cannot be abbreviated to the first three letters.) The 29 Assembler Commands can be conveniently grouped into source commands, editing commands, listing control commands, · object commands, and miscellaneous commands. Group Commands Source NEW, LOAD, SAVE, TEXT, HIDE, MERGE, and RESTORE Editing EDIT, COPY, LIST. FIND, REPLACE, DELETE, and RENUMBER Listing SLOW, FAST, PRT, and " Object ASM, MGO, VAL. and SYMBOLS Misc AUTO, MANUAL. INCREMENT, MEMORY, RST, MNTR, and USR 4 - 1 --------------------------------------------------------------------- Source Commands: NEW, LOAD, SAVE, TEXT, HIDE, MERGE, RESTORE Source Commands are used to erase the current program from memory. load a program from disk or tape, save a program on disk or tape. and append a program from disk or tape. NEW Command: :NEW Deletes the current source program from memory and restarts S-C Macro Assembler. Clears the screen, writes "SC MACRO ASSEMBLER II Vl.0" on the top line. restarts the automatic line numbering at 1000 and waits for you to type a source line or another command. LOAD Command: :LOAD :LOAD filename Deletes the current source program (unless it is "hidden" with the HIDE command), and then reads in a new one from cassette tape. It works exactly the same as the LOAD command in Integer BASIC or Applesoft. If you type a filename after the LOAD command, it is intercepted by DOS and a source program is loaded from disk instead of tape. :LOAD (load from tape) :LOAD BANANA (load disk file named "BANANA5") SAVE Command: :SAVE :SAVE filename Writes the source program currently in memory to cassette tape. It works exactly the same as the SAVE command in Integer BASIC or Applesoft. If you type a filename after the SAVE command, it will be intercepted by DOS to write the source program on disk rather than tape. It will appear in the disk directory as a type "I" file. :SAVE (save on tape) :SAVE BANANA (save on disk file "BANANA") 4 - 2 --------------------------------------------------------------------- TEXT Command: :TEXT filename :TEXT# filename :TEXT/ filename Saves the source program to disk as a DOS text file, so it can be EXECed into this or another assembler, or edited with another text editor. There are three forms of this command: TEXT writes the lines with no line number. This is very handy for building EXEC files for use with DOS, BASIC, or any general use. They can be read back into the S-C Macro Assembler by turning the AUTO line numbers on (see AUTO command), and using the EXEC command. TEXT# writes them with line numbers, exactly as they list on the screen. These files can be EXECed into Applesoft, or back into the S-C Macro Assembler. TEXT/ writes the lines with a control-I in place of the line number. You can keep disk files of often-used routines that can be EXECed into a program wherever they are needed. The control-I at the beginning of each line will cause a line number to be generated when the line is read by the S-C Macro Assembler. :TEXT ROUTINE (writes the current source program on a text file named ROUTINE, with no line numbers) :TEXT# ROUTINE (writes the current source program on a text file named ROUTINE. with line numbers.) :TEXT/ ROUTINE (writes the current source program on a text file named ROUTINE. with control-I's in place of line numbers.) 4 - 3 --------------------------------------------------------------------- HIDE and MERGE Commands: :HIDE :MERGE These two commands, used together with the LOAD command, allow you to join a program from disk or tape to a program that is already in memory. To remind you that you are HIDE-mg, the prompt symbol changes from ":" to "H:". After HIDE-mg a program, you can LOAD another one from disk or tape with the LOAD command. Then you type MERGE to join the two programs together. After this sequence of commands, the program which was already in memory will follow after the program just LOADed. If the line numbers are not already as you wish them to be, you should use RENUMBER to assign new ones. For example, suppose that we have two source programs on the disk named "SRCONE" and "SRCTWO". We want to join them together so that "SRCONE" precedes "SRCTWO". Here are the two programs: :LOAD SRCONE :LIST 1000 * PROGRAM NUMBER ONE 1010 MAIN JSR SUBROUTINE 1020 RTS :LOAD SRCTWO :LIST 1000 * 1010 SUBROUTINE 1020 LDA BLAH.BLAH.BLAH 1030 STA SOMEWHERE 1040 RTS 4 - 4 --------------------------------------------------------------------- Now let's HIDE the source of SRCTWO, LOAD in the source from SRCONE, and MERGE them together. :HIDE H:LIST (Note that nothing lists, because the H:LOAD SRCONE source has been hidden.) H:LIST 1000 * PROGRAM NUMBER ONE 1010 MAIN JSR SUBROUTINE 1020 RTS H:MERGE :LIST 1000 * PROGRAM NUMBER ONE 1010 MAIN JSR SUBROUTINE 1020 RTS 1000 * SUBROUTINE TO DO SOMETHING 1010 SUBROUTINE 1020 LDA BLAH.BLAH.BLAH 1030 STA SOMEWHERE 1040 RTS You can see that the two programs are now both in memory. but the line numbers are not in sequence. RENUMBER will fix the line numbers. :RENUMBER :LIST 1000 * PROGRAM NUMBER ONE 1010 MAIN JSR SUBROUTINE 1020 RTS 1030 * SUBROUTINE TO DO SOMETHING 1040 SUBROUTINE 1050 LDA BLAH.BLAH.BLAH 1060 STA SOMEWHERE 1070 RTS 4 - 5 --------------------------------------------------------------------- RESTORE Command: :RESTORE Restores the root source program if an assembly is aborted while inside an "included" module. The "root source program" is the source program that is in memory at the time you issue the ASM command. If this source program uses the IN directive to include additional source files, it is possible that assembly might be aborted while the "root" program is "hidden". An assembly may be aborted either manually by typing a RETURN key while the assembly is in progress, or automatically due to an error in the source program. If the assembly is aborted during the time that the root program is hidden, the prompt character changes from ":" to "I:". The RESTORE command will reset the memory pointers so that the included file is released, and the root program is no longer hidden. The prompt character will change back to ":". You do not have to use the RESTORE command after an aborted assembly unless you wish to get back to the root source program for editing purposes. If you type the ASM command, the assembler automatically restores before starting the assembly. If an assembly aborts due to an error in a source line, you may correct the source line, SAVE the module on the appropriate file, and type ASM to restart the assembly. 4 - 6 --------------------------------------------------------------------- Editing Commands EDIT, COPY, LIST, FIND, REPLACE, DELETE, RENUMBER The editor in S-C Macro Assembler combines the Apple screen editing features with a BASIC-like line editor. Source programs are entered and edited in almost exactly the same way you would enter and edit an Integer BASIC or Apples oft program. Editing commands allow you to list your source program, delete lines, search for lines, replace portions of selected lines, renumber lines, copy blocks of limes from one location to another. There is also powerful EDIT command, similar to Neil Konzen's Program Line Editor for BASIC. Range Parameters: Most editing commands (LIST, FIND, EDIT, REPLACE, and DELETE) can use range parameters to operate on just part of the program. A range parameter may be written with one or two line numbers, or in most cases it may be omitted. If there are two line numbers, separate them with a comma. If there is only one line number. it may stand alone, or with a comma; the comma may precede or follow the line number. Each of these five possible arrangements has a specific meaning: (no number) Specifies the entire source program. , Specifies the entire source program. # Specifies line number #. ,# Specifies lines from the beginning of the source program through #. #, Specifies lines from 9 through the end of the source program. #1,#2 Specifies lines from #1 through #2. Here are some specific examples: :LIST (lists all lines) :LIST 2000 (lists line 2000 only) :DEL 2000,3000 (deletes lines from 2000-3000) :EDIT 2000, (edits all lines from 2000 through the end of the program) :FIND ,2000 (finds all lines from the beginning of the program through line 2000) You can also use a period (.) to mean "the last line entered". The period, or "dot", is always defined as the number of the last line entered into or deleted from the source program. 4 - 7 --------------------------------------------------------------------- String Parameters: Some commands (LIST, FIND, EDIT, AND REPLACE) can also use a search string parameter to operate only on lines containing that string. The search string is of the form dstringd, where a is a delimiter of your choice. The delimiter can be any printing character that does not occur in your search string, except comma (,), period (.), or a digit (0-9). Some examples: :LIST /COUT/ (lists all lines containing COUT) :EDIT "/DESTU" (edits all lines containing /DEST) You can use a wildcard character in search strings if you want to operate on all lines containing partial matches to your search string. The standard wildcard character is control-W. You have to first type a control-O, and then a control-W. The control-O character is an override to allow the insertion of control characters in commands and source lines. The control-W will appear on the screen in inverse video. For example: :FIND ?ASWTA? (imagine with me that the "W" is a control-W) 1100 LDA AS.DATA 1120 LDA AS.DATA 1200 STA BASKETA 4 - 8 --------------------------------------------------------------------- LIST Command: :LIST :LIST range :LIST dstringd :LIST dstringd range FIND Command: :FIND :FIND range :FIND dstringd :FIND dstringd range Actually, FIND is just an alternate name for the LIST command. Many people find it more natural to use LIST with line number ranges and FIND with a search string, but either command will work with either parameter (or both parameters!). Both FIND and LIST list a single line, a range of lines, or an entire source program. If you specify a search string, only those lines which match the string will be listed. While a program or range of lines is listing, you can momentarily stop the listing by hitting the space bar. Tapping the space bar again will restart the listing. You can abort the listing by hitting the RETURN key. The SLOW and FAST commands allow you to control the listing speed. If you list a single line, it is displayed on the screen in a position which makes it easy to edit using the Apple screen editing tools. :LIST (list entire program) :LIST 1230 (list only line 1230) :LIST 1230,2890 (list lines 1230 through 2890) :LIST 1230, (list all lines from 1230 through end) :LIST ,1230 (list all lines from beginning through 1230) :FIND /ASCII/ (lists all lines containing the string "ASCII") :FIND "BI",1200 (lists all lines up through 1200 that contain the string "BI") 4 - 9 --------------------------------------------------------------------- EDIT Command: :EDIT :EDIT range :EDIT dstringd :EDIT dstringd range Allows very easy editing of program lines. Since this command is typed so frequently, there is a short form: instead of typing "EDIT", you can just type control-E. The characters "EDIT " will magically appear on the screen; you fill in the line number. and proceed to edit the line. If you specify no range or string, the whole source program, one line after another, will be presented for editing. If you specify a range, those lines in the range will be presented for editing. If you specify a search string, only those lines matching the string will be presented. EDIT presents a line for editing by displaying that line, clearing from the end of that line to the bottom of the screen, and placing the cursor at the beginning of the label field. You can proceed to edit with the following commands: control-B Move cursor back to beginning of the label field. control-D Delete character under cursor. control-Fx Move cursor to next occurence of "x" in line (if any). You may type any character you wish for "x". control-H (left arrow) Move cursor left. control-I Begin insertion mode; characters will be inserted until another control character is typed. control-L Store current edited line and start editing the next line. control-M (RETURN) Store the edited line. control-N Move cursor to end of line. control-O Begin insertion mode, but allow next character typed to be inserted even if it is a control-character. control-Q Finish edit mode, chopping off all characters from cursor to end of line. control-R Restore the original line without leaving edit-mode. control-T Move cursor to next tab stop. control-U (right arrow) Move cursor right. control-X Abort the EDIT command. control-@ Erase from cursor to end of line without leaving edit-mode. 4 - 10 --------------------------------------------------------------------- REPLACE Command: :REPLACE dstringdstringd :REPLACE dstringdstringd range :REPLACE dstringdstringd options :REPLACE dstringdstringd range options Searches for and replaces character strings in your source code. REPLACE operates on all fields, from the first character in the label field through the end or each line. It can be global (search the entire'program), or it can be made local by using range parameters to restrict which lines are searched. When REPLACE finds your search string in a line it will print that line, with the matching string shown in inverse video. The program will then ask "REPLACE?", and wait for you to type "Y", "N", or some other character. If you type "Y" the corrected line will be listed, then the search will continue. If you type "N" it will simply continue searching. If you type some other character, the REPLACE command will terminate. There are two possible options which may be selected by appending the letters "A" or "U" to the command line. A letter "A" on the end of the command line causes automatic operation, without the prompting at each replacement. A letter "U" means ignore any difference between upper and lower case letters. It is possible to replace more than one matching string in the same source line. :REP /CONT/GO.ON/ (change a label name) 1130 BNE CONT ==== REPLACE? Y (The underlined 1130 BNE GO.ON characters appear 1210 * NOW WE CAN CONTINUE in inverse video.) ==== REPLACE? N 1360 CONT JSR BYTEIN ==== REPLACE? Y 1360 GO.ON JSR BYTEIN You may use wildcard characters in the search string. The entire matching string will be replaced with the replacement string. Do not put any wildcard characters in the replacement string. 4 - 11 --------------------------------------------------------------------- DELETE command: :DELETE range Deletes a line or range of lines from your source program, just as in BASIC. Another way to delete a single line is to type its line number followed immediately by a RETURN, or by a space and RETURN. (warning: DELETE followed by a file name is a DOS command, and will delete a file from your diski) DELETE must be followed by a range parameter and cannot have a search string parameter. :DEL (doesn't work) *** SYNTAX ERROR :DEL 1230 (delete only line 1230) :DEL 1230,2890 (delete lines 1230 through 2890) :DEL 1230, (delete all lines from 1230 through end) :DEL ,1230 (delete all lines from beginning through 1230) :DEL , (delete entire program!) 4 - 12 --------------------------------------------------------------------- RENUMBER Command: :RENUMBER :RENUMBER base :RENUMBER base,inc :RENUMBER base,inc,start Renumbers all or part of the lines in your source program with the specified starting line number and increment. There are three optional parameters for specifying the line number to assign the first renumbered line (base), the increment, and the place in your program to begin renumbering (start). There are four possible forms of the command: :REN Renumber the whole source program: BASE=1000, INC =10. START=0 :REN # Renumber the whole source program: BASE=#, INC=10. START=0 :REN #1,#2 Renumber the whole source program: BASE=#1, INC=#2, START=0 :REN #1,#2,#3 Renumber from line #3 through the end: BASE=#1, INC=#2, START=#3 The last form above is useful for opening up a "hole" in the line numbers for entering a new section of code. :LIST 1000 * LITTLE RENUMBER EXAMPLE 1005 SAMPLE LDA $35 1006 STA $37 1010 RTS :RENUMBER :LIST 1000 * LITTLE RENUMBER EXAMPLE 1010 SAMPLE LDA $35 1020 STA $37 1030 RTS :RENUMBER 100 :LIST 0100 * LITTLE RENUMBER EXAMPLE 0110 SAMPLE LDA $35 0120 STA $37 0130 RTS :RENUMBER 2000,4 :LIST 2000 * LITTLE RENUMBER EXAMPLE 2004 SAMPLE LDA $35 2008 STA $37 2012 RTS :RENUMBER 3000,10,2008 :LIST 2000 * LITTLE RENUMBER EXAMPLE 2004 SAMPLE LDA $35 3000 STA $37 3010 RTS 4 - 13 --------------------------------------------------------------------- COPY Command: :COPY range,target Copies a range of lines from one place in the program to another. A copy of all the lines in the range specified is placed just before the target line. If the target line does not exist, the range will be copied where the target line should have been. If the target is line 9999, and there is no line 9999, the copied lines will be placed at the end of the source program. COPY does not delete the original section or renumber the copy, so this command should be followed immediately by a RENUMBER command. :LIST 1000 * LITTLE COPY EXAMPLE 1005 SAMPLE LDA $35 1006 STA $37 1010 RTS :COPY 1005,1006,9999 :LIST 1000 * LITTLE COPY EXAMPLE 1005 SAMPLE LDA $35 1006 STA $37 1010 RTS 1005 SAMPLE LDA $35 1006 STA $37 :RENUMBER :LIST 1000 * LITTLE COPY EXAMPLE 1010 SAMPLE LDA $35 1020 STA $37 1030 RTS 1040 SAMPLE LDA $35 1050 STA $37 :COPY 1020,1040,1010 : RENUMBER :LIST 1000 * LITTLE COPY EXAMPLE 1010 STA $37 1020 RTS 1030 SAMPLE LDA $35 1040 SAMPLE LDA $35 1050 STA $37 1060 RTS 1070 SAMPLE LDA $35 1080 STA $37 4 - 14 --------------------------------------------------------------------- Listing Control Commands FAST, SLOW, PRT, " The listing control commands are used to control the speed of display on the screen, and to control printing of listings on other devices. One special command allows sending setup control characters to your printer. FAST and SLOW Commands: :FAST :SLOW FAST sets the listing speed to the normal speed, which is too fast for most people to read. When you first enter S-C Macro Assembler, it is already in the FAST mode. If you abort a listing by hitting the RETURN key, the system returns to the FAST mode. SLOW sets the listing speed slow enough that you can read it as it goes by on your screen. In both the FAST and SLOW modes, you can momentarily stop the listing by tapping the space bar (or any other key except RETURN). You can abort the listing by typing the RETURN key. When the listing is stopped1 pressing two keys at the same time will cause one additional line to be listed. PRT Command: :PRT Provides a "hook" for a user-supplied printer driver. If you have an Apple parallel or serial printer board, the usual PR#slot will activate your printer. If you have a printer driven through the game port, or an interface board which requires special handling, you can use the PRT command to turn it on. If you don't need it for a printer, PRT can serve as a second USR command. PRT executes a JSR $1009, where you can put a JMP to your printer driver. A sample printer driver is included on the disk as a source program, called SAMPLE PRINTER DRIVER. Appendix C includes a listing and description of this program. You can examine it to learn how to write your own. " Command: :"string Sends the specified string to the currently selected output device. If your printer is currently selected, you can send control-codes to it. Remember that in order to enter a control-character on an input line, you type the control-O (override) followed by the desired character. 4 - 15 --------------------------------------------------------------------- Object Commands ASM, MGO, VAL, SYMBOLS Object commands are used to assemble source programs into object programs, execute object programs, and to print the value of label expressions after assembly. ASM Command: :ASM Initiates assembly of your source program. The S-C Macro Assembler is a two-pass assembler. During the first pass it builds a symbol table with the definition of every label used in your program. During the second pass the assembler stores object code into memory (or writes it on a disk file) and produces an assembly listing on the screen and/or the printer. At the end of the second pass all the labels and their values are listed in alphabetical order. The assembly listing may be momentarily interrupted and restarted by tapping the space bar. You may abort the assembly by typing the RETURN key. The assembly listing may also be controlled with the LIST directives, to print any part of it or none at all. If any errors are detected in either pass, they are printed along with a copy of the offending line. Assembly normally continues after an error, so that you can catch as many errors as possible in one pass. If any errors are detected during pass one, pass two is not attempted. At the end of assembly the total number of errors is printed. All the assembly error messages with their probable causes are listed in Appendix B. MGO Command: :MGO expression Begins execution of your object program. An expression or label name must follow the MGO command to define the place to begin execution. Remember that an object program is the result of an assembly, so you must have used the ASM command before the MGO will execute your program. :MGO BEGIN (Start execution at label BEGIN) :MGO $803 (Start execution at $803) Your program can return to S-C Macro Assembler either by using an "RTS" instruction, by a "JMP $3D0" (if DOS is active), or by a "JMP $l003" ($D003 for language card version). You may also abort your program by hitting the RESET key. If your Apple has the Autostart RON, you will come out in the assembler. If you come out in the monitor, type 3D0G to reenter the assembler. In the tape version of the S-C Macro Assembler, the MGO command is named "RUN". The disk version uses "MGO" because the word "RUN" is a DOS command. If you type a RUN command, DOS will attempt to load an Integer BASIC or Applesoft program (possibly clobbering the assembler or the source program in memory). 4 - 16 --------------------------------------------------------------------- VAL Command: :VAL expression Evaluates any legal operand expression, and prints the value in hexadecimal. It may be used to quickly convert decimal numbers to hexadecimal, to determine the ASCII code for a character, or to find the value of a label from the last assembled program. :VAL 12345 3039 VAL -21846 AAAA :VAL 'X 0058 :VAL LOOPA+3 084E SYMBOLS Command: :SYMBOLS Displays a copy of the Symbol Table, just like the one that normally is printed at the end of pass two of an assembly. :SYMBOLS 21C2- LIST.SOURCE.IF.LISTING 1CC6- LOAD 1896- LIST.ASM.LINE .01=18A4, .02=lBAC, .04=18B7, .15=18B9 .03=l8BF 31A0- MACLBL 4 - 17 --------------------------------------------------------------------- Miscellaneous Commands AUTO, MANUAL, INCREMENT, MEMORY, RST, MNTR, USR The last seven commands do not fit in any other category. AUTO Command: :AUTO :AUTO # Turns on automatic line numbering mode. In this mode, a new line number is automatically generated every time you end a line. Lines are ended by typing RETURN, by backspacing over the prompt symbol, and by typing control-X. If AUTO is used with no parameter, the generated line numbers will start with the next number after the last line you entered or deleted. The next number is formed by adding the current INCREMENT value. The increment can be changed with the INCREMENT command. AUTO followed by a line number will start the numbering at that parameter. You can type commands while in the AUTO mode by typing backspaces to the beginning of the line (next to, not over, the prompt) and then typing any command. You can leave the AUTO mode by typing the MANUAL command. The AUTO mode is also terminated by hitting RESET, and after any error message. AUTO should be used when EXEC-ing in text files from another source. This way, you can even use S-C Macro Assembler to edit BASIC programs which have been listed into text files (as long as you don't need to renumber the BASIC line numbers). MANUAL Command: :MANUAL Terminates the automatic line numbering (AUTO) mode. INCREMENT Command: :INCREMENT number Sets the increment used for automatic line number generation (both control-I generated numbers and AUTO mode numbers.) The increment is normally 10. but you may set it to any value between 0 and 9999. (Of course, an increment of 0 makes no sense. Neither does a large value like 9999. But you can use them if you wish!) INC 5 (set increment to 5) INC 10 (set increment to 10) 4 - 18 --------------------------------------------------------------------- Memory Command: :MEMORY Displays the beginning and ending memory addresses of the source program and of the symbol table. :MEM SOURCE PROGRAM: $94F3-9600 SYMBOL TABLE: $3200-3274 Memory between the top of the symbol table and the bottom of the source program is free to be used without clobbering anything. The assembler automatically protects memory (during assembly) from $1000 to the top of the symbol table, and from the bottom of the source program through $FFFF. This insures that your object program will not clobber the assembler, the source program, or DOS. MNTR command: :MNTR Enters the Apple system Monitor. This is the same as CALL -151 from BASIC. You may reenter the S-C Macro Assembler by typing 1003G or 3D0G. :MNTR * RST command: :RST expression Changes the RESET vector to the specified value. Normally this is set to by DOS to reenter the assembler, but you may change it to enter the monitor, BASIC, or your own program. If you are using the Autostart Monitor, pressing the RESET key causes a branch to the address in the RESET vector. :RST -151 (RESET enters the monitor) :RST $FF69 (also enters the monitor) :RST $3D0 (RESET enters DOS and assembler) :RST $800 (RESET enters program at $800) 4 - 19 --------------------------------------------------------------------- USR Command: :USR whatever An open-ended command, waiting for you to design and activate. When you type the command "USR", a JSR $1006 instruction is executed. If you have not installed a JMP to your own program at $1006, the command is equivalent to a "No Operation" command. You can write a program to process your own command, and put a JMP instruction to it at $1006. The entire command line is stored in the monitor input buffer, starting at $0200. Your USR command processor can scan the input buffer to pick up any parameters you wish. Sample USR command processors are published from time to time in the Apple Assembly Line newsletter. 4 - 20 --------------------------------------------------------------------- DOS COMMANDS All the Apple DOS commands are valid, even though you are operating from within S-C Macro Assembler. This feature allows you to maintain your source and object programs on disk using the LOAD, SAVE, BLOAD, and BSAVE commands. Source programs will appear in the disk catalog with a type code of "I", just as though they were Integer BASIC programs. Housekeeping Commands: CATALOG, RENAME, DELETE, LOCK, UNLOCK, VERIFY, MON, NOMON, and MAXFILES can be used as you desire. They will function exactly the same within S-C Macro Assembler as they do within BASIC. Source Maintenance Commands: LOAD and SAVE when used with a filename will be interpreted by DOS. If no file name is included, S-C Macro Assembler will interpret them as cassette tape commands. Object Maintenance Commands: BSAVE, BLOAD, and BRUN commands may be used to maintain object programs on the disk and to execute then. Be careful when using BLOAD and BRUN that the program you are loading does not load on top of anything you want to keep! I/O Selection Commands: PR#, IN#, and EXEC commands may be used. PR#slot will turn on Apple intelligent interfaces for printers and other output devices. IN#slot may be used with other terminals, modems, et cetera. EXEC will execute a stream of commands or read in a series of source lines from a text file. BASIC Commands: INT and FP may be used to exit the S-C Macro Assembler and enter either Integer BASIC or Applesoft. Commands you should not use: RUN, CHAIN, and INIT will not do what you expect. Avoid typing the "RUN filename" command, because it will be recognized by DOS as an attempt to load and execute an Integer BASIC or Applesoft program. However, since the DOS links have been set up for S-C Macro Assembler, the program will not execute. It will just clobber memory, possibly your source program or the assembler itself! The CHAIN command is equally dangerous. INIT will properly format a disk, but it will write your source program (which is not executable) as the HELLO program! It is much better to INIT from within Applesoft or Integer BASIC. 4 - 21 --------------------------------------------------------------------- MONITOR COMMANDS All of the Apple II Monitor commands are available from within S-C Macro Assembler. You use them by typing a dollar sign ($) after the prompt symbol, followed by any monitor command. Monitor commands are explained on pages 40-66 of the Apple II Reference Manual. With these commands you may examine, change, move or verify memory; read and write cassette tapes; dis-assemble machine language programs; execute programs; and perform hexadecimal arithmetic. If you have the old Monitor ROM (rather than the Autostart ROM), you may use the trace and single-step debugging features. If you have Integer BASIC in ROM or language card, and it is currently selected, you may call the mini-assembler at $F666. The availability of all these commands makes it much easier for you to develop and debug assembly language programs. 4 - 22 --------------------------------------------------------------------- Chapter 5 -- DIRECTIVES Twenty assembler directives are available in the S-C Macro Assembler to control the assembly process and to define data in your programs. These are all indicated by a period followed by two or more letters. .OR ORigin .BS Block storage .TA Target Address .LIST Control Assembly LISTing .TF Target File .TI TItle .IN INclude file .US USer defined directive .EN ENd of program .PG PaGe eject .EQ EQuate .DO Conditional Assembly .DA DAta .ELSE Conditional Assembly .HS Hex String .FIN Conditional Assembly .AS Ascii String .MA MAcro definition .AT Ascii Terminated .EM End Macro Origin: .OR expression Sets the program origin and the target address to the value of the expression. Program origin is the address at which the object program will be executed. Target address is the memory address at which the object program will be stored during the assembly. The .OR directive sets both of these to the same value, which is the normal way of operating. If you do not use the .OR directive, the assembler will set both the program origin and the target address to $0800. If the expression is not defined during pass one prior to its use in the .OR directive, an error message is printed. If a .TF (Target File) was active before the .OR directive, it will be closed out. Target Address: .TA expression Sets the target address at which the object code will be stored during assembly. The target address is distinct from the program origin (which is either set by the .OR directive, or is implicitly set to $0800). The .OR directive sets both the origin and the target address; the .TA directive sets only the target address. Object code is produced ready to run at the program origin, but is stored starting at the target address. When you wish to assemble a program which will execute at an address normally occupied by the assembler ($1000-3lFF), the symbol table ($3200 up), or the source program text (bottom of DOS down), you need to use the .TA and .OR directives. Set the origin first, using the .OR directive; then set the target address to a safe value using the .TA directive. It is usually safe to start the target area at $0800, provided your object 5 - 1 --------------------------------------------------------------------- code does not extend beyond $0FFF. If you are using macros, that will take some space from $OFFF down. See the chapter on macros for details. 1000 * 1010 * SAMPLE PROGRAM TO ILLUSTRATE 1020 * THE ".TA" DIRECTIVE 1030 * 1040 .OR $1000 1050 .TA $0800 1000- AD 0C 10 1060 DEMO LDA AVALUE 1003- AE 0D 10 1070 LDX XVALUE 1006- AC 0E 10 1080 LDY YVALUE 1009- 4C 00 10 1090 JMP DEMO 1100 * 100C- 0C 1110 AVALUE .DA #12 100D- 22 1120 XVALUE .DA #34 100E- 38 1130 YVALUE .DA #56 SYMBOL TABLE 100C- AVALUE 1000- DEMO 100D- XVALUE 100E- YVALUE 0000 ERRORS IN ASSEMBLY As you can see in the example, the assembly listing looks as though the program were stored at $1000. However, the ob~ect code is actually stored at $0800, which is the target address set in the TA directive. If we dis-assemble memory starting at $0800, we Bee: :$800L 0800- AD 0C 10 LDA $100C 0803- AE 0D 10 LDX $100D 0806- AC 0E 10 LDY $100E 0809- 4C 00 11 JMP $1000 After the assembly is complete, there are several ways to position tbe code in memory where it really should be. 1. You can save the object code on cassette using the Apple Monitor "W" command. 2. You can save the object code on disk using the DOS "BSAVE" command. Be sure you do not try to reload it while you are executing the assembler, or you may clobber it! 3. You can use the Monitor's memory move command (addrl bytes on the file. All the bytes written will have the value $00. 5 - 7 --------------------------------------------------------------------- 0800- 34 12 1000 A .DA $1234 0802- 1010 B .BS 2 1020 *------------------------------ 0804- AD 00 08 1030 LDA A 0807- 8D 02 08 1040 STA B 080A- AD 01 08 1050 LDA A+1 080D- 8D 03 08 1060 STA B+l SYMBOL TABLE 0800- A 0802- B 0000 ERRORS IN ASSEMBLY Title: .TI expression,title When .TI is in effect the assembly listing will have a title line and page number at the top of each page. The expression specifies the maximum number of lines you want to print on each page. The title can be up to 70 characters long and will be printed starting at the left margin. " PAGE xxxx" will be printed immediately after the title. If there is no title the page number will be printed at the left margin. Spacing or centering of the title and page number can be adjusted by adding leading or trailing spaces to the title. The S-C Macro Assembler will issue an automatic formfeed when a page fills up. If you want to end a page early, use the .PG directive. You can use more than one .TI directive in a program if you like. The .TI directive also issues a formfeed command. You can turn off titling by using .TI with a pagelength of zero. Listing Control: .LIST optionlist Controls the listing output of the assembler. "Optionlist" is a list of one or more of the following keywords: OFF Listing off. ON Listing on. MOFF Macro expansion listing off. MON Macro expansion listing on. If .LIST OFF is put at the beginning of the source program, and no LIST ON is used, no listing at all will be produced. The program will assemble much faster without a listing, as most of the time is consumed in putting characters on the screen and scrolling the screen up. 5 - 8 --------------------------------------------------------------------- If you put LIST OFF at the beginning of your source program, and LIST ON at the end, only the alphabetized symbol table will print. You may also use this pair of directives to bracket any portion of the listing you wish to see or not see. Page Control: .PG Prints an ASCII Form Feed character ($0C). If the assembly listing is being printed on a printer which recognizes this character, a form feed will occur and the next listing line will appear at the top of the next page. The .PG lime itself is not listed. With .LIST MON in effect, the complete macro expansion will be listed. The call line will be printed with its line number, then the expansion lines, each with a line number of "0000>". (rather than the Autostart ROM), you may use the trace and single-step debugging features. If you have Integer BASIC in ROM or language card, and it is currently selected, you may call the mini-assembler at $F666." 5-8 About two-thirds down, "formeed" should be "formfeed". --------------------------------------------------------------------- 5-9 The following should be inserted before "Page Control": With .LIST MON in effect, the complete macro expansion will be listed. The call line will be printed with its line number, then the expansion lines, each with a line number of "0000>". When .LIST MOFF is in effect, only the macro call line will be listed. Conditional Assembly: .DO expression .ELSE .FIN With these directives, you can include or exclude a particular section of code in the assembly, depending on a condition set earlier. The operand expression is evaluated as a truth value, and must be defined before the .DO. Zero means skip lines, non-zero means assemble them. The .ELSE directive toggles the current truth value, allowing an if..then..else kind of structure. There may be more than one .ELSE directive within the .DO - .FIN block; each time .ELSE is encountered the truth value is switched. .FIN terminates the conditional section. .ELSE is optional but .FIN is required. .DO - .FIN blocks may be nested, up to 8 deep. These directives are often used to produce different specialized versions of a program from the same source code. For example, the main memory and language card versions of S-C MACRO Assembler were assembled from the same source file, using a .DO flag called LCASM. When a change is made to the assembler, we only have to edit one source line to generate the two differnt versions. We assemble it twice: once with LCASM=l, once with LCASM=O. .DO - .FIN blocks can also be used to exclude testing routines from the finished program, and to add or delete extra variables. 5 - 9 --------------------------------------------------------------------- :LIST 1000 * CONDITIONAL ASSEMBLY DEMO 1010 *-------------------------------------- 1020 FLAG .EQ 0 1030 .DO FLAG 1050 .ELSE 1040 JSR SOMEPLACE 1060 JSR ANOTHER.PLACE 1070 .ELSE 1080 JSR ONE.MORE.PLACE 1090 .FIN 1100 RTS 1110 *-------------------------------------- 1120 SOMEPLACE RTS 1130 ANOTHER.PLACE RTS 1140 ONE.MORE.PLACE RTS :ASM 1000 * CONDITIONAL ASSEMBLY DEMO 1010 *-------------------------------------- 0000- 1020 FLAG .EQ 0 1030 .DO FLAG 1050 .ELSE 0800- 20 05 08 1060 JSR ANOTHER.PLACE 1070 .ELSE 1090 .FIN 0803- 60 1100 RTS 1110 *-------------------------------------- 0804- 60 1120 SOMEPLACE RTS 0805- 60 1130 ANOTHER.PLACE RTS 0806- 60 1140 ONE.MORE.PLACE RTS :1020 FLAG .EQ 1 :ASM 1000 * CONDITIONAL ASSEMBLY DEMO 1010 *-------------------------------------- 0001- 1020 FLAG .EQ 1 1030 .DO FLAG 0800- 20 07 08 1040 JSR SOMEPLACE 1050 .ELSE 1070 .ELSE 0803- 20 09 08 1080 JSR ONE.MORE.PLACE 1090 .FIN 0806- 60 1100 RTS 1110 *-------------------------------------- 0807- 60 1120 SOMEPLACE RTS 0808- 60 1130 ANOTHER.PLACE RTS 0809- 60 1140 ONE.MORE.PLACE RTS 5 - 10 --------------------------------------------------------------------- Macro Definition: .MA macro name End Macro: .EM A macro definition must begin with the directive .MA and end with the EM directive. For detailed information see the chapter on macros. User Directive: label .US whatever To allow for possible expansion of the assembler by users, the .US directive has been included. When the opcode is processed, it will branch to $100C. That location normally contains a JMP instruction, which treats the US as a comment. The source line will be in the system buffer starting at $0200 (without the line number). If you desire to use the .US directive, change $l00C-$lOOE to jump to your own program. Some details of the steps necessary toimplement your own directives are published in the Septenber, 1981 issue of Apple Assembly Line, pages 12-15. You may also disassemble S-C Macro Assembler, if you wish, and examine the existing directives. 5 - 11 --------------------------------------------------------------------- Chapter 6 OPERAND EXPRESSIONS Operand expressions are written using elements and operators. The valid operators are +, -, *, /, <, =, and >. Terms may be decimal or hexadecimal numbers, labels, a literal ASCII character, or an asterisk (*) The first term in an expression may be preceded by a + or - sign. ELEMENTS Decimal Numbers: Any number in the range from 0 through 65535, written in the normal way. 0800- A9 C8 1000 LDA #200 0802- A2 F6 1010 LDX #-10 0804- 6B 8B 1020 .DA 35691 FFFF- 1030 FLAG .EQ -l Hexadecimal Numbers: Any number in the range from $0 through $FFFF. Hexadecimal numbers are indicated by a preceding dollar sign, and may have from one to four digits. 1050 .OR $880 0880- A9 2F 1060 LDA #$2F 0882- 85 CA 1070 STA $CA 0884- D0 1D 1080 BNE $8A3 0886- 20 2A E0 1090 JSR $E02A 00AB- 1100 VALL .EQ $AB 1278- 1110 NUM .EQ $1278 0888- 78 12 1120 DATA .DA $1278 Beware of leaving out the dollar sign; the assembler may be quite satisfied to think of your hexadecimal number as a decimal one if you omit the $. In some cases even a number with letters in it, such as 23AB, may be acceptable; it may be interpreted as decimal 23 and a comment "AB". Labels: There are three types of labels in S-C Macro Assembler. Normal labels are from 1 to 32 characters long. The first character must be a letter; following characters may be letters, digits, or periods. Local labels are written as a period followed by one or two digits. Private labels are written as a colon followed by one or two digits. Labels must be defined somewhere if they are to be used in an expression. Labels used in operand expressions after .OR, TA, .BS, and .EQ directives must be defined prior to use (to prevent an undefined or ambiguous location counter). Labels are defined by being written in the label field of an instruction or directive line. In previous versions of S-C Assemblers, special care was necessary to assure that all zero-page labels were defined prior to their use in the address fields of certain 6502 instructions. This care is no longer needed, because the S-C Macro Assembler handles forward references properly in such cases. 6 - 1 --------------------------------------------------------------------- Literal ASCII Characters: Literal characters are written as an apostrophe followed by the character. The value is the ASCII code of the character (a value from $00 through $7F). 0041- 1000 LTRA .EQ 'A 0930- 58 41 00 1010 .DA #'X,'A 0933- C9 5A 1020 CMP #'Z If you wish to use literal ASCII values with the sign bit equal to 1 (codes $80-$FF), you can do so by adding $80 in the operand expression: 00C1- 1000 LTRA .EQ 'A+$80 0930- D8 C1 00 1010 .DA #'X+$80,'A+$80 0933- C9 DA 1020 CMP #'Z+$80 Asterisk (*): Stands for the current value of the location counter. This is useful for storing the length of a string as a constant in a program. I also use it in filling up to the end of the page to assure that following code begins at an even page boundary. 080A- 08 1070 QT .DA IQTSZ 080B- 41 4E 59 080E- 20 4D 45 0811- 53 53 41 0814- 47 45 1080 .AS /ANY MESSAGE/ 0008- 1090 QTSZ .EQ *-QT-l 0816- 00 00 1100 VAR .DA *-* 0818- 1110 FILLER .BS $900-* FILL UP 1120 * THROUGH $8FF 6 - 2 --------------------------------------------------------------------- OPERATORS You can use arithmetic and relational operators in operand expressions. Expressions are evaluated strictly from left to right, with no other precedence implied. Parentheses cannot be used to change this order. Arithmetic Operators (+-*/): Any of the four arithmetic operators may be used in an operand expression. All operations are performed on 16-bit values. Multiplication returns the low-order 16-bits of the 32-bit product. Overflow and division-by-zero are not considered assembly errors. Overflow merely truncates, returning the low-order 16-bits. Division-by-zero returns the value $FFFF (65535). Relational Operators (<=>): The three relational operators compare two 16-bit values. If the relation is true, the result is 1. If the relation is false, the result is 0. The result can be used in further calculations, and as the truth value for conditional assembly (.DO directive). Only the three elementary operators are available: less than (<), equal (=), and greater than (>). They cannot be combined as they are in BASIC to form <=, <>, or >=. The result of a relational expression is a true or false value. A value of zero is considered to be false, and a non-zero value is considered to be true. You may operate on logical values with * and + operators: * has the effect of the logical and, and + has the effect of the logical or operation. If you are in doubt how an expression will evaluate, you can use the VAL command to see. Or you can go ahead and assemble your program and see how it turns out. 6 - 3 --------------------------------------------------------------------- Chapter 7-- MACROS A macro is a single instruction in your source code, which when assembled is replaced by a defined series of instructions. With macros, you can use a shorthand for commonly used sequences, effectively define your own instructions for the 6502, or even rename the 6502 opcodes. A Simple Macro How often do you increment a 16-bit variable like this: 1100 INC PTR INCREMENT LOW BYTE 1110 BNE .1 CARRY? 1120 INC PTR+l YES, INCREMENT HIGH BYTE 1130 .1 (whatever) NO, GO ON We can define a macro called INCD to do all that. Just put this definition at the beginning of the program: 1000 .MA INCD MACRO NAME 1010 INC ]1 CALL PARAMETER 1020 BNE :1 PRIVATE LABEL 1030 INC ]1+l 1040 :1 1050 .EM END OF DEFINITION Now you only need to enter: 1100 >INCD PTR 1110 (whatever) The object code will be the same in either case. If an operation is used only once or twice in a program, it isn't really worth the effort to define a macro for it, but if you have to do the same operation on several different variables, a macro can save a lot of work. It can also help prevent common mistakes, such as mixing up the high- and low-bytes of 16-bit variables. Now to explain that definition. The directive .MA signals the start of a macro definition, and is followed by the macro name. The operand "]1" is a macro call parameter. In the assembly, it will be replaced by the operand in the macro call line (in our example, PTR). The label ":l" is a private label used to name a branch point within the macro. The directive .EM signals the end of a macro definition. A macro must be defined before it is called, so it is best to put all macro definitions together at the beginning of the program. Once you have defined a macro, it can be called at any time by typing >name in the opcode field and any parameters needed in the operand field. At assembly time, the assembler will insert the correct code from the macro definition. 7 - 1 --------------------------------------------------------------------- Call parameters Macro call parameters are dummy variables used in the macro definition. When the macro is called from a program, these parameters are replaced by the expressions used in the macro call line operand field. There can be up to nine call parameters, ]l through ]9. There is also a parameter named ]#, which represents the number of operands passed to the macro. (Enter the "]" character by typing shift-M.) Parameters are written in the operand field of the macro call line, separated by commas. If you want a parameter to include a comma or space, enclose the parameter in quotation marks. If you want it to also include a quotation mark, use two quotation marks in a row wherever you want one. For example, 1200 >SAM JONES,$1234,"ABC DEF","ABC, DEF, "" GHI" The macro called is named SAM. ]1 is JONES. ]2 is $1234. ]3 is ABC DEF. ]4 is ABC, DEF, " GHI ]# is 4. Private labels Private labels are used inside a macro definition to name branch points in the same way that labels are used in the main program. They are written as a colon (:) followed by one or two digits. The S-C Macro Assembler treats each use of a private label as though the label included a macro call number. This allows you to re-use the same private label numbers over and over in your program. Private labels do not interfere in any way with local labels. Here is an example using both private labels and local labels: 1000 .MA INCD 1010 INC 11 1020 BNE :1 1030 INC 11+1 1040 :1 1050 .EM 1060 *-------------------------------- 1070 DEMONSTRATE .LOCAL.AND. PRIVATE 0800- A5 34 1080 LDA $34 0802- D0 06 1090 BNE .1 0804- 1100 >INCD $12 0804- E6 12 0000> INC $12 0806- D0 02 0000> BNE :1 0808- E6 13 0000> INC $12+l 0000> :1 080A- EA 1110 .1 NOP 7 - 2 --------------------------------------------------------------------- Each private label takes up five bytes of storage during assembly (it makes no difference in the object code). This storage starts at $FFF and goes down to $800, so there can be a maximum of 409 private labels used in a program. Note that this is the free space below the assembler, often used for object code. If your object code collides with the private label table, you will get a *** MEMORY PROTECT ERROR; in this case you should, use a .TA or .TF directive to direct the object code elsewhere in memory or to a disk file. Listing the Macro Expansions There are two directives to control the appearance of macros in the assembly listing. With .LIST MON in effect, the complete macro expansion will show. The call line will be printed first, and then the assembled code on subsequent lines. The expansion lines will have line numbers of "0000>" and be indented one space. When LIST MOFF is in effect, only the macro call line will be printed. This saves space and makes the logic of the program easier to follow; however, you lose the listing of the object code, showing exactly what is stored at each address. Using Conditional Assembly in Macro Definitions You can use the .DO, .ELSE, and .FIN directives inside macro definitions. They will be executed during macro expansion, so that the same macro can be expanded in different ways depending on parameters. The example on the next page shows how you might use conditional assembly inside a macro definition. The INCD macro defined above works equally well for zero-page or non-zero-page variables. However, it would not work for variables indexed by a ",X". Using the .DO-.ELSE-.FIN trio, and the ]# parameter, we can write a more general version. Note also that even though the private label ":3" is used over and over, the assembler sees each definition as unique. 7 - 3 --------------------------------------------------------------------- 1000 *-------------------------------- 1010 * DEMONSTRATE CONDITIONAL ASSEMBLY IN 1020 *-------------------------------- MACRO 1030 .MA INCD 1040 .DO ]#=2 1050 INC ]1,]2 1060 BNE :3 1070 INC ]1+1,]2 1080 :3 1090 .ELSE 1100 INC ]1 1110 BNE :3 1120 INC ]1+1 1130 :3 1140 .FIN 1150 .EM 1160 *-------------------------------- 0800- 1170 >INCD $12 0000> .DO 1=2 0000> .ELSE 0800- E6 12 0000> INC $12 0802- D0 02 0000> BNE :3 0804- E6 13 0000> INC $12+1 0000> :3 0000> .FIN 0806- 1180 >INCD $1234 0000> DO 1=2 0000> .ELSE 0806- EE 34 12 0000> INC $1234 0809- D0 03 0000> BNE :3 OBOB- EE 35 12 0000> INC $1234+1 0000> :3 0000> .FIN OBOE- 1190 >INCD $12,X 0000> DO 2=2 OBOE- F6 12 0000> INC $12,X 0810- D0 02 0000> BNE :3 0812- F6 13 0000> INC $12+1,X 0000> :3 0000> .ELSE 0000> .FIN 0814- 1200 >INCD $1234,X 0000> DO 2=2 0814- FE 34 12 0000> INC $1234,X 0817- D0 03 0000> BNE :3 0819- FE 35 12 0000> INC $1234+1,X 0000> :3 0000> .ELSE 0000> .FIN 7 - 4 --------------------------------------------------------------------- Nested Macro Definitions You can call macros within macro definitions. I do not of recommend it, but many programmers delight in the intricacies nested and recursive macros. Suppose you want to write a macro which can be used to call one or more subroutines on a single source line. For example, CALL SAM should translate to JSR SAM. CALL SAM,TOM should generate two JSR's, and so on. You could do it at least two ways: using conditional directives, or using nested macro definitions. Using conditional directives is fairly straightforward. The following program shows how. The ]# parameter is tested to determine whether another parameter is present, and if so a JSR line is produced. 1000 .MA CALL 1010 JSR ]l 1020 .DO ]#>1 1030 JSR ]2 1040 .FIN 1050 .DO ]1>2 1060 JSR ]3 1070 .FIN 1080 .EM 0800- 1090 >CALL SAM,TOM,JOE 0800- 20 0F 08 0000> JSR SAM 0000> .DO 3>1 0803- 20 11 08 0000> JSR TOM 0000> .FIN 0806- 20 10 08 0000> .DO 3>2 0000> JSR JOE 0000> .FIN 0809- 1100 >CALL SAM,TOM 0809- 20 0F 08 0000> JSR SAM 0000> .DO 2>1 OBOC- 20 11 08 0000> JSR TOM 0000> .FIN 0000> .DO 2>2 0000> .FIN 080F- 60 2000 SAM RTS 0810- 60 2010 JOE RTS 0811- 60 2020 TOM RTS 7 - 5 --------------------------------------------------------------------- The other approach uses a nested macro definition. I have set up three separate macros, one for each possible number of parameters: CALL1 for one parameter, CALL2 for two, and CALL3 for three. Then I defined CALL to call the appropriate one of those. 1000 .MA CALL1 1010 JSR ]1 1020 .EM 1030 *-------------------------------- 1040 .MA CALL2 1050 JSR ]l 1060 JSR ]2 1070 .EM 1080 *-------------------------------- 1090 .MA CALL3 1100 JSR ]l 1110 JSR 12 1120 JSR ]3 1130 .EM 1140 *-------------------------------- 1150 .MA CALL 1160 >CALL]# ]l,]2,13 1170 EM 1180 *-------------------------------- 0800- 1190 >CALL SAM 0800- 0000> >CALL1 SAM,, 0800- 20 12 08 0000> JSR SAM 0803- 1200 >CALL SAM,JOE 0803- 0000> >CALL2 SAM,JOE, 0803- 20 12 08 0000> JSR SAM 0806- 20 13 08 0000> JSR JOE 0809- 1210 >CALL SAM,JOE,TOM 0809- 0000> >CALL3 SAM,JOE,TOM 0809- 20 12 08 0000> JSR SAM 080C- 20 13 08 0000> JSR JOE 080F- 20 14 08 0000> JSR TOM 1215 *-------------------------------- 0812- 60 1220 SAM RTS 0813- 60 1230 JOE RTS 0814- 60 1240 TOM RTS SYMBOL TABLE 0813- JOE 0812- SAM 0814- TOM 7 - 6 --------------------------------------------------------------------- Possible Errors What happens if you have more parameters on a macro call line than the macro definition expects? The extra parameters are simply ignored. You can use the ]# parameter with conditional assembly directives (.DO, .ELSE, and .FIN) to test for the correct number if you wish. And what if you do not have enough parameters on the call line? The missing ones will be treated as null strings. Again, you may test for the correct number if you wish using conditional assembly directives. There are three error conditions that the S-C Macro Assembler tests for. If you call a macro that has not been defined earlier in the program, you will see "*** UNDEFINED MACRO ERROR". If you use a .MA directive with no name in the operand field, you will get "*** NO MACRO NAME ERROR". If you use the "]" character in a macro definition without a digit 1-9 or "#" character following, you will get "*** BAD MACRO PARAMETER ERROR". Sample Macros in MACRO LIBRARY The file named "MACRO LIBRARY" on the S-C Macro Assembler disk contains more examples of macro definitions. There are at least two ways you can use some of these macros in your programs. The easiest way is to include them with ".IN MACRO LIBRARY" at the beginning of your source program. This technique wastes memory for the unused macros in the source code and in the symbol table, but that's no problem unless your program is very large. A second way to use them is to first LOAD MACRO LIBRARY, then DELETE the lines containing the definitions you don't need, RENUMBER, and start entering your program. 7 - 7 --------------------------------------------------------------------- Chapter 8-- 6502 PROGRAMMING The microprocessor inside the Apple II is called a "6502". It was originally designed and manufactured by MOS Technology (now part of Commodore). It is now also manufactured by Synertek and Rockwell International. The 6502 is also used in other popular computers, such as Atari, Commodore Pet, and Ohio Scientific. Although the 6502 was designed several years before the Zilog Z-80 microprocessor, it is not at all inferior. The 6502 in the Apple II, running with a 1 MHz clock, compares quite favorably with machines using Z-80's at 4 MHz. Time spent learning how to program the 6502 in assembly language is well spent. The information in this chapter is not meant to be an exhaustive treatment of how to program the 6502. For this you should read and study one or more of the references listed in the bibliography in Appendix E. For the absolute beginner I recommend "Apple Machine Language" by Don and Kurt Inman. For the more advanced I recommend "6502 Assembly Language Programming" by Lance A. Leventhal. Programming Model The 6502 microprocessor is capable of performing 56 different operations. Each of these 56 operations is assigned a unique 3-letter mnemonic, called an opcode. The 6502 microprocessor contains five 8-bit registers and one 16-bit register of interest to the programmer. The 16-bit register is the program counter (PC). It always holds the memory address of the next instruction to be performed. As each instruction is performed, the PC-register is updated to point at the next instruction in line. Some instructions modify the PC-register directly to change the order of operations (branches and jumps). The 8-bit registers are called A, X, Y, S, and P. The A-register is an accumulator register. It is the register used in performing addition, subtraction, and logical operations. The X- and Y-registers are index registers. As such, they are used in computing the effective address of indexed instructions. The S-register holds the address of the current top-of-stack. The "stack" consists of the memory addresses $0100 through $01FF. Certain operations "push" a byte onto the stack by storing the byte at the location the S-register points to, and then decrementing the S-register. Other operations "pull" a byte off the stack by incrementing the S-register, and then read~ng the byte that the S-register points to. 8 - 1 --------------------------------------------------------------------- The P-register contains seven status bits. (One bit is unused.) Four of these bits can be tested by conditional branch instructions. The entire P-register can be loaded from the stack (PLP instruction) or copied onto the stack (PHP instruction). Some of the bits can be set and cleared directly; some are indirectly affected by the results of operations. The bits are arranged like this: 7 6 5 4 3 2 1 0 N V * B D I Z C The bits have the following meaning: N -- Negative 0 if last result +, 1 if - V -- Overflow 0 if last result did not overflow, and after CLV instruction; 1 if last result did overflow * -- Unused B -- Break Status 1 after a BRK instruction D -- Decimal Mode 0 after CLD instruction, 1 after SED I -- Interrupt 0 after CLI instruction (IRQ interrupt enabled), 1 after SEI instruction (IRQ interrupt disabled) Z -- Zero 0 if last result non-zero, 1 if last result zero. C -- Carry 0 if last result did not carry, and after CLC instruction; 1 if last result did carry, and after SEC The diagram below illustrates the data flow between the registers and memory. +-------------------------------------------------------------------+ | MEMORY $0000-$FFFF | +-------------------------------------------------------------------+ ^ | ^ | ^ | | | | | | | STX LDX STA LDA STY LDY | | | | | | | V | V | V +------------+ ---TXA--> +------------+ <--TYA--- +------------+ | X-REGISTER | | A-REGISTER | | Y-REGISTER | +------------+ <--TAX--- +------------+ ---TAY--> +------------+ | ^ | ^ | | | | TXS TSX PLA PHA | | | | V | V | +------------+ +-------------------+ ---PLP--> +---------------------+ | S-REGISTER | | STACK $0100-$01FF | | P-REGISTER NV*BDIZC | +------------+ +-------------------+ <--PHP--- +---------------------+ 8 - 2 --------------------------------------------------------------------- Addressing Modes One of the features of the 6502 microprocessor which makes it so powerful is its great variety of addressing modes. There are thirteen different modes in all, although no single opcode can use every one of them. The charts later in this chapter show which modes can be used with each opcode. But first, here is a chart showing an example of each mode and the way it is written in assembly language. Mode Example Implied DEY (at least two blanks Accumulator Mode ASL (before coments Relative Mode BEQ label Immediate Mode LDA #expr (low-order byte) LDA /expr (high-order byte) Direct Modes Not Indexed Zero Page LDA expr ( The assembler Absolute LDA expr ( uses zero-page Indexed by X ( form if possible; Zero Page LDA expr,X ( if not possible, Absolute LDA expr,X ( the assembler Indexed by Y ( uses the absolute Zero Page LDA expr,Y ( form. Absolute LDA expr,Y Indirect Modes Not Indexed JMP (expr) Pre-Indexed Indirect LDA (expr,X) Post-Indexed Indirect LDA (expr),Y Implied Mode: The address is implied by the nature of the instruction; the operand field is left blank. You need at least two blanks after the opcode if there are comments on the same line. All of the opcodes in this class are only one byte l5ng. They are: BRK DEX PHA RTS TAY CLC DEY PHP SEC TSX CLD INX PLA SED TXA CLI INY PLP SEI TXS CLV NOP RTI TAX TYA Relative Mode: Used only by the conditional branch instructions. The expression is convertedto a signed offset from the location following the branch instruction. The result must be in the range -128 through +127 to be legal. When the instruction is executed, if the condition tested is true then the one-byte signed offset is added to the contents of the PC-register to get the address of the next instruction to be executed. All of the branch instructions are two bytes long. They are: BCC BEQ BNE BVC BCS BMI BPL BVS 8 - 3 --------------------------------------------------------------------- Accumulator Mode: Only used by the four shift instructions. These four instructions can also use some of the more complex addressing modes. Each of the shift instructions uses only one byte when in the accumulator mode. The contents of the A-register are shifted, so no memory address is needed. The four shift instructions are: ASL LSR ROL ROR Immediate Mode: Used by eleven of the opcodes. In this mode the operand is the actual value used, rather than the address of a value. For example, "LDA $10" means to load the contents of memory location $0010 into the A-register. On the other hand, "LDA #$10" means to put the value $10 into the A-register. Another way of looking at this is that the "effective address" in immediate mode is the address of the second byte of the instruction. All of the immediate mode opcodes use two bytes. They are: ADC AND CMP CPX CPY EOR LDA LDX LDY ORA SBC Direct Modes: A one- or two-byte address follows the opoode byte. A two-byte address specifies an address in memory from $0000 to $FFFF. If the address is only one byte long, the memory addressed is assumed to be in page-zero (from $0000 to $00FF). If the opcode indicates indexing by X, the contents of the X-register are added to the one- or two-byte value from the instruction. The sum is used as the effective address for the operation. If the opcode indicates indexing by Y, the contents of the y-register are added to the one- or two-byte value from the instruction. The sum is used as the effective address for the operation. 8 - 4 --------------------------------------------------------------------- Indirect Modes: A one- or two-byte address follows the opcode byte. The address is used to pick up two consecutive bytes which in turn are used in the effective address computation. A two-byte address specifies an address in memory from $0000 to $FFFF. The two-byte form is only usable with one instruction: JMP. It is written as "JMP (expr)". The contents at the address "expr" and "expr+l" are put into the PC-register. The one-byte address forms specify an address in page zero ($0000 to $00FF). That location and the following one are expected to contain the two-bytes of an address which is used in the effective address computation. There are two modes: pre-indexed indirect and post-indexed indirect. Pre-indexed indirect, written as "(expr,X)", adds the contents of the x-register to "expr" to get the address of the two bytes which contain the effective address. This mode is hardly ever used. In fact, the only times I have used it are in the special case where the value in the x-register is zero. If (X)=0, then the effective address is the same as if no indexing were performed. Post-indexed indirect, written as "(expr),Y", looks up the address in the two bytes pointed to by "expr" and "expr+l", and adds the contents of the Y-register to that address. This mode is frequently used to load and store bytes out of a table of bytes. For example, if I have a table of 15 bytes starting at MYTABLE, I can pick up the third byte and store it in the 9th byte like this: 1000 LDA #MYTABLE 1010 STA $64 MAKE A POINTER TO MYTABLE 1020 LDA /MYTABLE IN $64 AND $65 1030 STA $65 1040 LDY #2 POINT AT THIRD BYTE 1050 LDA ($64),Y GET THAT THIRD BYTE 1060 LDY #8 POINT AT NINTH BYTE 1070 STA ($64),Y STORE INTO NINTH BYTE The chart on the next page shows which instructions use each of the various direct and indirect modes. 8 - 5 --------------------------------------------------------------------- ACCUM- IMMED- ---- D I R E C T ---- ---- I N D I R E C T ---- ULATOR IATE INDEXED INDEXED blank #expr expr expr,X expr,Y (expr) (expr,X) (expr),Y /expr ZP/ABS ZP/ABS ZP/ABS ADC -- 69 65/6D 75/7D --/79 -- 61 71 AND -- 29 25/2D 35/3D --/39 -- 21 31 ASL 0A -- 06/0E 16/1E --/-- -- -- -- BIT -- -- 24/2C --/-- --/-- -- -- -- CMP -- C9 C5/CD D5/DD --/D9 -- C1 D1 CPX -- E0 E4/EC --/-- --/-- -- -- -- CPY -- C0 C4/CC --/-- --/-- -- -- -- DEC -- -- C6/CE D6/DE --/-- -- -- -- EOR -- 49 45/4D 55/5D --/59 -- 41 51 INC -- -- E6/EE F6/FE --/-- -- -- -- LDA -- A9 A5/AD B5/BD --/B9 -- A1 31 LDX -- A2 A6/AE --/-- B6/BE -- -- -- LDY -- AO A4/AC B4/BC --/-- -- -- -- LSR 4A -- 46/4E 56/5E --/-- -- -- -- ORA -- 09 05/0D 15/1D --/19 -- 01 11 ROL 2A -- 26/2E 36/3E --/-- -- -- -- ROR 6A -- 66/6E 76/7E --/-- -- -- -- SBC -- E9 E5/ED F5/FD --/F9 -- E1 F1 STA -- -- 85/8D 95/9D --/99 -- 81 91 STX -- -- 86/8E --/-- 96/-- -- -- -- STY -- -- 84/8C 94/-- --/-- -- -- -- JMP -- -- --/4C --/-- --/-- 6C -- -- JSR -- -- --/20 --/-- --/-- -- -- -- 8 - 6 --------------------------------------------------------------------- Instructions The 56 instructions which the 6502 microprocessor understands can be divided into ten classes: Transfer Operations LDA, STA, LDX, STX, LDY, STY TXA, TAX, TYA, TAY, TXS, TSX PLA, PHA, PLP, PHP Arithmetic Operations ADC, SBC INC, INX, INY DEC, DEX, DEY Logical Operations AND, ORA, EOR, BIT Shift Operations ASL, LSR, ROL, ROR Compare Operations CMP, CPX, CPY Status Operations SEC, SED, SEI CLC, CLV, CLD, CLI Conditional Branch Operations BCC, BVC, BNE, BPL BCS, BVS, BEQ, BMI Unconditional Jump Operations JNP, JSR Return Operations RTS, RTI Other Operations NOP, BRK I will now try to very briefly describe each of the instructions. In the following descriptions, I will use these symbols: A A-register C carry status bit D decimal mode status bit I interrupt mask status bit M effective address N negative status bit S S-register (stack pointer) V overflow status bit X X-register Y Y-register Z zero status bit <-- replacement thing described on right goes into place named on left --> replacement thing described on left goes into place named on right ( ) "the contents of" the place named between the parentheses 8 - 7 --------------------------------------------------------------------- Transfer Operations: These operators move one byte of data from one register to another, or between registers and memory. LDA A <-- (M). Load the byte at the effective address into the A-register. Affects N and Z status bits. LDX X <-- (M). Load the byte at the effective address into the X-register. Affects N and Z status bits. LDY Y <-- (M). Load the byte at the effective address into the Y-register. Affects N and Z status bits. STA M <-- (A). Store the A-register at the effective address. Does not change the A-register or status. STX M <-- (X). Store the X-register at the effective address. Does not change the X-register or status. STY M <-- (Y). Store the Y-register at the effective address. Does not change the Y-register or status. TAX (A) --> X. Copies the A-register into the X-register. Affects the N and Z status bits. TAY (A) --> Y. Copies the A-register into the Y-register. Affects the N and Z status bits. TXA (X) --> A. Copies the X-register into the A-register. Affects the N and Z atatus bits. TYA (Y) --> A. Copies the Y-register into the A-register. Affects the N and Z status bits. TSX (S) --> X. Copies the stack pointer into the Xregister. Affects the N and Z status bits. TXS (X) --> S. Copies the X-register into the stack pointer. Does not affect status. PHA M(S) <-- (A), S <-- (S) - 1. Push the A-register onto the stack. Does not affect status. PHP M(S) <-- (P), S <-- (S) - 1. Push the status register onto the stack. Does not affect status. PLA S <-- (S) + 1, A <-- M(S). Pull a byte from the stack into the A-register. Affects the N and Z status bits. PLP S <-- (S) + 1, P <-- M(S). Pull a byte from the stack into the status register. 8 - 8 --------------------------------------------------------------------- Arithmetic Operations: These operations perform addition and subtraction on register or memory contents. The operations on the A-register affect the N1 Z, and C status bits; the operations on memory and the X- and Y-registers only affect the N and Z status bits. ADC A <-- (A) + (M) + (C). Adds the byte at the effective address and the carry status to the byte in the A-register. The result is stored in the A-register. If the addition produces a value greater than $FF, carry is set (1 --> C), otherwise carry is cleared (0--> C). SBC A <-- (A) - (M) + (C) - 1. Subtracts the byte at the effective address and the "borrow" from the value in the A-register. The result is stored in the A-register. If the subtraction requires a borrow, the carry bit will be cleared (0 --> C); otherwise carry will be set (1 --> C). ("Borrow" is the complement of "carry"; before beginning a subtraction, set carry to 1.) INC M <-- (M) + 1. Increments (adds one to) the byte at the effective address. Does not change the carry status. INX X <-- (X) + 1. Increments (adds one to) the value in the X-register. Does not change the carry status. INY Y <-- (X) + 1. Increments (adds one to) the value in the Y-register. Does not change the carry status. DEC M <-- (M) - 1. Decrements (subtracts one from) the value at the effective address. Does not change the carry status. DEX X <-- (X) - 1. Decrements (subtracts one from) the value in the X-register. Does not change the carry status. DEY Y <-- (X) - 1. Decrements (subtracts one from) the value in the Y-register. Does not change the carry status. 8 - 9 --------------------------------------------------------------------- Logical Operations: These operations perform bit-by-bit logical combinations between the operand and the byte in the A-register. All four of the operations affect the N and Z status bits. AND A <-- (A) and (M). Forms the logical product of the byte at the effective address and the byte in the A-register, leaving the result in the A-register. For each bit position, the following table gives the result value for each combination of operand bits: | 0 1 ---+------- 0 | 0 0 1 | 0 1 EOR A <-- (A) eor (M). Forms the exclusive-or result of the byte at the effective address with the byte in the A-register, leaving the result in the A-register. For each bit position, the following table gives the result value for each combination of operand bits: | 0 1 ---+------- 0 | 0 1 1 | 1 0 ORA A <-- (A) or (M). Forms the inclusive-or result of the byte at the effective address with the byte in the A-register, leaving the result in the A-register. For each bit position, the following table gives the result value for each combination of operand bits: | 0 1 ---+------- 0 | 0 1 1 | 1 1 BIT Z <-- (A) and (M), N <-- (M) bit 7, V <-- M bit 6. Forms the logical product of the byte at the address and the A-register, setting the z-flag to the result, but discarding the result. Also sets the N- and V-flags to the values of the corresponding bits of the byte at the address. Shift Operations: These four operations shift the contents of the A-register or of a memory location by one bit position left or right. ASL C <-- (7......0) <-- 0. Arithmetic shift left. Bit 7 of the selected byte is copied into C, bit 6 into bit7, and so on. A zero is shifted into bit 0. LSR 0 --> (7......0) --> C. Logical shift right. Bit 0 of the selected byte is copied into C, bit 1 into bit 0, and so on. A zero is shifted into bit 7. ROL C <-- (7.......0) <-- C. Rotate left. Circular shift the selected byte and C one bit to the left. ROR C --> (7......0) --> C. Rotate right. Circular shift the selected byte and C one bit to the right. 8 - 10 --------------------------------------------------------------------- Compare Operations: These operations compare the byte at the effective address with register contents. The comparison is done by subtracting the memory byte from the register byte; the N, Z, and C status bits are affected, but the difference is not stored anywhere. If the two values compared are equal, the Z status bit will be set. If the two values are considered as unsigned values (0-255), carry will be set if (A) is larger than or equal to (M). If the difference was in the range from $80 to $FF, the N status bit will be set. CMP N,Z,C <-- (A) - (M). Subtract the byte at the effective address from the byte in the A-register. Set the condition flags, but discard the result. CPX N,Z,C <-- (X) - (M). Subtract the byte at the effective address from the byte in the X-register. Set the condition flags, but discard the result. CPY N,Z,C (-- (Y) - (M). Subtract the byte at the effective address from the byte in the Y-register. Set the condition flags, but discard the result. Status Operations: These operations will directly set or clear specific status bits. The C and V bits are also affected indirectly by other operations. CLC 0 --> C. Clear carry (or set borrow). SEC 1 --> C. Set carry (or clear borrow). CLD 0 --> D. Clear the decimal arithmetic mode. (ADC and SBC will perform normal binary arithmetic.) SED 1 --> D. Set the decimal arithmetic mode. (ADC and SBC will perform packed BCD arithmetic. CLI 0 --> I. Clear the IRQ interrupt inhibit status bit. (Allow IRQ interrupts.) SEI 1 --> I Set the IRQ interrupt inhibit status bit. (Do not allow IRQ interrupts.) CLV 0 --> V. Clear the overflow status bit. 8 - 11 --------------------------------------------------------------------- Conditional Branch Operations: These operations use the relative addressing mode. The branch is taken if the condition tested is true; otherwise execution proceeds with the next instruction in sequence. BCC Branch if carry clear (C=O). After a compare operation, if the bytes compared are considered to be unsigned values, BCC is equivalent to "branch if less than". BCS Branch if carry set (C=1). After a compare operation, if the bytes compared are considered to be unsigned values, BCS is equivalent to "branch if greater than or equal". BEQ Branch if equal (Z=l). After a transfer operation BEQ will branch if the value transfered was zero. After a compare operation, BEQ will branch if the two values compared were equal to each other. BMI Branch if minus (N=1). BNE Branch if not equal (Z=0). BPL Branch if plus (N=0). BVC Branch if overflow clear (V=0). Overflow is set by an ADC or SBC instruction when the carries out of bit 6 and 7 are not equal. It is cleared when they are equal, or by a CLV instruction. Overflow is also set equal to bit 6 of the byte addressed by a BIT instruction. BVS Branch if overflow set (V=1). Unconditional Jump Operations: These two operations transfer the effective address to the PC-register unconditionally. JMP Jump to the effective address. May be direct or indirect. JSR Jump to a subroutine at the effective address. Before jumping, push the current program counter address (PC) on the stack. 8 - 12 --------------------------------------------------------------------- Return Operations: RTS Return from a subroutine. Pulls the return address fron the stack, adds one to it, and branches to that address. RTI Return from an interrupt. Pulls the status from the stack, and then the return address. Unlike RTS, the return address is not incremented before branching. Other Operations: NOP No operation. Does nothing but consume two clock cycles. BRK Break. Sets the B status bit to 1, and interrupts through the IRQ interrupt vector at $FFFE and $FFFF. The interrupt involves pushing the current address in the PC-register on the stack, followed by the current status register (with the B-bit set to 1, in this case); setting the I-bit to 1 to inhibit further IRQ interrupts; and loading the PC-register from $FFFE and $FFFF. 8 - 13 --------------------------------------------------------------------- A I Z A Z A Z A ( ( c m e b P b P b Z Z c m r s , s , s P P u e o o X , Y , , ) m d P l X Y X , u i a u ) Y l a g t a t e e t e ADC Add with carry -- 69 65 6D 75 7D -- 79 61 71 NV....ZC A <-- (A) + (M) + (C) -- 2 3 4 4 *4 -- *4 6 *5 AND Logical "And" -- 29 25 2D 35 3D -- 39 21 31 N.....Z. A <-- (A) and (M) -- 2 3 4 4 *4 -- *4 6 *5 ASL Shift Byte Left 0A -- C6 CE 16 1E -- -- -- -- N.....ZC C <-- (7......0) <-- C 2 -- 5 6 6 7 -- -- -- -- BIT Test Bits in Memory -- -- 24 2C -- -- -- -- -- -- NV....Z. Z <-- (A) and (M), -- -- 3 4 -- -- -- -- -- -- N <-- (M) bit 7, V <-- (M) bit 6 CMP Compare with A-register -- C9 C5 CD D5 DD -- D9 C1 D1 N.....ZC N,Z,C <-- (A) - CM) -- 2 3 4 4 *4 -- *4 6 *5 CPX Compare with X-register -- E0 E4 EC -- -- -- -- -- -- N.....ZC N,Z,C <-- CX) - CM) -- 2 3 4 -- -- -- -- -- -- CPY Compare with Y-register -- C0 C4 CC -- -- -- -- -- -- N.....ZC N,Z,C <-- (Y) - (M) -- 2 3 4 -- -- -- -- -- -- DEC Decrement Memory Byte -- -- C6 CE D6 DE -- -- -- -- N.....Z. M <-- (M) - 1 -- -- 5 6 6 7 -- -- -- -- EOR Exclusive-Or -- 49 45 4D 55 5D -- 59 41 51 N.....Z. A <-- (A) eor (M) -- 2 3 4 4 *4 -- *4 6 *5 INC Increment Memory Byte -- -- E6 EE F6 FE -- -- -- -- N.....Z. M <-- (M) + 1 -- -- 5 6 6 7 -- -- -- -- LDA Load A-register -- A9 A5 AD B5 BD -- B9 A1 B1 N.....Z. A <-- (M) -- 2 3 4 4 *4 -- *4 6 *5 LDX Load X-register -- A2 A6 AE -- -- B6 BE -- -- N.....Z. X <-- (M) -- 2 3 4 -- -- 4 *4 -- -- LDY Load Y-register -- AC A4 AC B4 BC -- -- -- -- N.....Z. Y <-- (M) -- 2 3 4 4 *4 -- -- -- -- LSR Shift Byte Right 4A -- 46 4E 56 5E -- -- -- -- N.....ZC C--> (7......0) --> C 2 -- 5 6 6 7 -- -- -- -- ORA Inclusive-Or -- 09 05 0D 15 1D -- 19 01 11 N.....Z. A <-- (A) or (M) -- 2 3 4 4 *4 -- *4 6 *5 ROL Roll Byte Left 2A -- 26 2E 36 3E -- -- -- -- N.....ZC C <-- (7......0) <-- C 2 -- 5 6 6 7 -- -- -- -- ROR Roll Byte Right EA -- 66 6E 76 7E -- -- -- -- N.....ZC C --> (7......0) --> C 2 -- 5 6 6 7 -- -- -- -- SBC Subtract with Borrow -- E9 E5 ED F5 FD -- F9 E1 F1 NV....ZC A <-- (A) - (M) + (C) - 1 -- 2 3 4 4 *4 -- *4 6 *5 STA Store A-register -- -- 85 8D 95 9D -- 99 81 91 ........ M <-- (A) -- -- 3 4 4 5 -- 5 6 6 STX Store X-register -- -- 86 8E -- -- 96 -- -- -- ........ M <-- (X) -- -- 3 4 -- -- 4 -- -- -- STY Store Y-register -- -- 84 8C 94 -- -- -- -- -- ........ M <-- (Y) -- -- 3 4 4 -- -- -- -- -- * Add 1 cycle if indexing causes crossing of page boundary 8 - 14 --------------------------------------------------------------------- Relative Branch Instructions BPL Branch if Plus (Branch if N=0) 10 2 cycles if BMI Branch if Minus (Branch if N=1) 30 no branch; BVC Branch if No Overflow (Branch if V=0) 50 3 cycles if BVS Branch if Overflow (Branch if V=1) 70 branch into same page; BCC Branch if Carry Clear (Branch if C=0) 90 BCS Branch if Carry Set (Branch if C=1) B0 4 cycles if branch into BNE Branch if Not Equal (Branch if Z=0) D0 different BEQ Branch if Equal (Branch if Z=1) F0 page. (applies to all branches) Jump Instructions JMP Unconditional Jump Absolute 4C 3 JMP Unconditional Jump Indirect 6C 5 JSR Jump to Subroutine 20 6 Implied Address Mode Instructions BRK Break (Set B=1,Generate IRQ Interrupt) 00 7 ...B.I.. CLC Clear Carry C <-- 0 18 2 .......C CLD Clear Decimal Mode D <-- 0 D8 2 ....D... CLI Clear Interrupt Mask I <-- 0 58 2 .....I.. CLV Clear Overflow Status V <-- 0 B8 2 .V...... DEX Decrement X-register X <-- (X) - 1 CA 2 N.....Z. DEY Decrement Y-register Y <-- (Y) - 1 88 2 N.....Z. INX Increment X-register X <-- (Y) + 1 E8 2 N.....Z. INY Increment Y-register Y <-- (Y) + 1 C8 2 N.....Z. NOP No Operation Does Nothing EA 2 ........ PHA Push A-register on stack M(S) <-- (A), 48 3 ........ S <-- (S) - 1 PHP Push P-register on stack M(S) <-- (P), 08 3 ........ S <-- (S) - 1 PLA Pull Stack to A-register S <-- (S) + 1, 68 4 N.....Z. A <-- (M(S)) PLP Pull Stack to P-register S <-- (S) + 1, 28 4 restored A <-- (M(S)) RTI Return from Interrupt Pull to P and PC 40 6 restored RTS Return from Subroutine Pull to PC 60 6 ........ SEC Set Carry C <--1 38 2 .......C SED Set Decimal Mode D <--1 FB 2 ....D... SEI Set Interrupt Mask I <-- 1 78 2 .....I.. TAX Transfer A to X X <-- (A) AA 2 N.....Z. TAY Transfer A to Y Y <-- (A) A8 2 N.....Z. TSX Transfer S to X X <-- (S) BA 2 N.....Z. TXA Transfer X to A A <-- (X) 8A 2 N.....Z. TXS Transfer X to S S <-- (X) 9A 2 ........ TYA Transfer Y to A A <-- (Y) 98 2 N.....Z. 8 - 15 --------------------------------------------------------------------- Chapter 9 -- SWEET-16 SWEET-16 is a powerful programming tool developed by Steve Wozniak in the early days of Apple. Chances are that you do have this tool, whether you know it or not. The standard version is hidden away inside the Integer BASIC system. If you have Integer BASIC on your mother board, or in a firmware card, or in a 16K RAM card, then you have SWEET-16. I have included a commented source file of SWEET-16 on your S-C MACRO ASSEMBLER II disk, so you can assemble your own copy if you wish. SWEET-16 is really a language, just like 6502 machine language, BASIC, Pascal, FORTRAN. It looks a lot like a machine language for a computer that does not really exist, so "Woz" has called it his "dream machine". You can read all about it in an old issue of BYTE Magazine (November, 1977, pages 150-159): "SWEET-16 -- The 6502 Dream Machine". Another article you may want to find is "SWEET-16 Revisited", by Charles F. Taylor. in MICRO--The 6502/6809 Journal. January, 1982, pages 25-42. The beauty of SWEET-16 is in its ability to perform 16-bit arithmetic and data moves using automatically updated address pointers. And to add icing to the cake, most of the instructions are only one byte long! You can write extremely compact code, if you are willing to pay the price of slower execution. (A typical program will take half as many bytes, but ten times longer to execute.) Does anyone really use SWEET-16? Yes, in a big way. I used it in several places inside the early versions of S-C Assembler II. The TED/ASM assembler, and all its descendants (including DOS Tool Kit, TED 11+, Big Mac, Merlin, and others) use SWEET-16 heavily. Several of the programs in the Apple Programmer's Aid ROM use SWEET-16. including the Integer BASIC Renumber/Append program. The standard version of SWEET-16 is invoked by the 6502 instruction "JSR $F689"; the bytes immediately following contain opcodes for SWEET-16 to process. SWEET-16 opcodes will be executed until the "RTN" opcode, which returns to 6502 mode. Programming Model The SWEET-16 "machine" has sixteen 16-bit registers (R0-R15). R0 is actually the two memory bytes at $0000 and $0001. The next two bytes are called R1; R15 is stored in $001E and $001F. Several of the registers have special functions: R0 is used as an accumulator (like the 6502's A-register); R12 is the subroutine return stack pointer; R13 receives the results of comparisons; R14 is a status register; R15 is the program address counter. 9 - 1 --------------------------------------------------------------------- SWEET-16 REGISTERS Register 6502 Address Purpose 0 $00,01 Accumulator 1 $02,03 General 2 $04,05 General . . . . . . . . . 11 $16,17 General 12 $18,19 Subroutine Stack Pointer 13 $1A,1B Difference of comparands 14 $1C,1D Status 15 $1E,1F Program address There are two general types of opoodes recognized by SWEET-16: register and non-register opcodes. The non-register opcodes all have the form "0x", where x is a hexadecimal digit from 0 through C. (Opcodes 0D, 0E, and 0F are not used.) These opcodes are used for relative branches, subroutine call and return, and to leave SWEET-16. The register opcodes have the format "xR", where x is a hexadecimal digit from 0 through F, and R is a register number (0-F). SWEET-16 OPCODES Non-Register Opcodes: RTN, BK, and RS are one byte opcodes. The rest have a second byte which is a relative address, similar to the relative branch addresses used in 6502 opcodes. The conditional branches use status bits found in R14. 00 RTN Return to 6502 code. 0l ea BR addr Unconditional Branch. 02 ea BNC addr Branch if Carry=0. 03 ea BC addr Branch if Carry=1. 04 ea BP addr Branch if last result positive. 0S ea BM addr Branch if last result negative. 06 ea BZ addr Branch if last result zero. 07 ea BNZ addr Branch if last result non-zero. 08 ea BM1 addr Branch if last result = -1. 09 ea BNM1 addr Branch if last result not -1. 0A BK Execute 6502 BRK instruction. 0B RS Return from SWEET-16 subroutine. 0C ea BS addr Call SWEET-16 subroutine. 9 - 2 --------------------------------------------------------------------- Register Opcodes: The SET opcode uses three bytes, to load a 16-bit immediate value into a register. All the rest of the register opcodes only use one byte. ("MA" = memory address) 1n lo hi SET n,value Rn <-- value. 2n LD n R0 <-- (Rn). 3n ST n Rn <-- (R0). 4n LD @n MA = (Rn), ROL <-- (MA), Rn <-- MA+1, R0H <-- 0. 5n ST @n MA = (Rn), MA <-- (R0L), Rn <-- MA+1. 6n LDD @n MA = (Rn), R0 <-- (MA, MA+1), Rn <-- MA+2. 7n STD @n MA = (Rn), MA,MA+l <-- (R0), Rn <-- MA+2. 8n POP @n MA = (Rn)-1, R0L <-- (MA), R0H <-- 0, Rn <-- MA. 9n STP @n MA <-- (Rn)-1, (MA) <-- R0L, Rn <-- MA. An ADD n R0 <-- (R0) + (Rn). Bn SUB n R0 <-- (R0) - (Rn). Cn POPD @n MA = (Rn)-2, MA,MA+l <-- R0, Rn <-- MA. Dn CPR n R13 <-- (R0) - (Rn), R14 <-- status flags. En INR n Rn <-- (Rn) + 1. Fn DCR n Rn <-- (Rn) - 1. The S-C Assembler II includes all of the SWEET-16 opcodes, in the formats shown above. You can write programs which mix both 6502 code and SWEET-16 together in any combination. Here are a few examples which illustrate programming in SWEET-16. 1000 *------------------------------------- 1010 * CLEAR A BLOCK OF MEMORY 1020 *------------------------------------- F689- 1030 SWEET.16 .EQ $F689 0A00- 1040 BLOCK .EQ $A00 0234- 1050 N .EQ $234 1060 *------------------------------------- 0800- 20 89 F6 1070 CLEAR JSR SWEET.16 0803- 10 00 00 1080 SET 0,0 0 FOR CLEARING WITH 0806- 11 00 0A 1090 SET 1,BLOCK ADDRESS OF BLOCK 0809- 12 34 02 1100 SET 2,N # BYTES TO CLEAR 080C- 51 1110 .1 ST @1 STORE IN BLOCK 080D- F2 1120 DCR 2 080E- 07 FC 1130 BNZ .1 NOT FINISHED YET 0810- 00 1140 RTN SYMBOL TABLE 0A00- BLOCK 0800- CLEAR .1=080C 0234- N F689- SWEET.16 0000 ERRORS IN ASSEMBLY 9 - 3 --------------------------------------------------------------------- 1000 *---------------------------- 1010 * MOVE A BLOCK OF MEMORY 1020 *---------------------------- F689- 1030 SWEET.16 .EQ $F689 0A00- 1040 SOURCE .EQ $A00 0A80- 1050 DESTIN .EQ $A80 0023- 1060 N .EQ $23 1070 *---------------------------- 0800- 20 89 F6 1080 MOVE JSR SWEET.16 0803- 11 00 0A 1090 SET 1,SOURCE ADDRESS OF SOURCE BLOCK 0806- 12 80 0A 1100 SET 2,DESTIN ADDRESS OF DESTINATION BLOCK 0809- 13 23 00 1110 SET 3,N # BYTES TO MOVE 080C- 41 1120 .1 LD @1 GET BYTE FROM SOURCE 080D- 52 1130 ST @2 STORE IN DESTINATION 080E- F3 1140 DCR 3 080F- 07 FB 1150 BNZ .1 NOT FINISHED YET 0811- 00 1160 RTN SYMBOL TABLE 0A80- DESTIN 0800- MOVE .01=08CC 0023- N 0A00- SOURCE F689- SWEET.16 0000 ERRORS IN ASSEMBLY 1000 *------------------------------- 1010 * RENUMBER S-C ASSEMBLER SOURCE CODE 1020 *------------------------------- F689- 1030 SWEET.16 .EQ $F689 004C- 1040 HIMEM .EQ $4C,4D 00CA- 1050 PP .EQ $CA,CB 1060 *------------------------------- 1070 RENUMBER 0800- 20 89 F6 1080 JSR SWEET.16 0803- 11 CA 00 1090 SET 1,PP PP HAS ADDRESS OF SOURCE CODE 0806- 61 1100 LDD @1 GET ADDRESS OF SOURCE CODE 0807- 31 1110 ST 1 ...IN R1 0808- 12 0A 00 1120 SET 2,10 INCREMENT = 10 080B- 13 4C 00 1130 SET 3,HIMEM HIMEM HAS ADDR OF END OF SOURCE 080E- 63 1140 LDD @3 GET ADDRESS IN HIMEM 080F- 33 1150 ST 3 ...IN R3 0810- 14 DE 03 1160 SET 4,990 START=990 (1ST LINE WILL BE 1000) 0813- 21 1170 .1 LD 1 TEST IF FINISHED 0814- D3 1180 CPR 3 0815- 03 0E 1190 BC .2 YES 0817- 41 1200 LD @1 GET # BYTES IN THIS SOURCE LINE 0818- 35 1210 ST 5 ... INTO R5 0819- 24 1220 LD 4 GET SEQUENCE NUMBER 081A- A2 1230 ADD 2 ADD INCREMENT 081B- 34 1240 ST 4 ... INTO R4 AGAIN 081C- 71 1250 STD @1 ... AND ALSO INTO SOURCE LINE 081D- F1 1260 DCR 1 BACK UP POINTER 081E- F1 1270 DCR 1 081F- F1 1280 DCR 1 0820- 21 1290 LD 1 ADD LENGTH OF LINE TO POINTER 0821- A5 1300 ADD 5 0822- 31 1310 ST 1 POINT AT NEXT SOURCE LINE 0823- 01 EE 1320 BR .1 0825- 00 1330 .2 RTN 0826- 60 1340 RTS SYMBOL TABLE 004C- HIHEM 00CA- PP 0800- RENUMBER .01-0813, .02-0825 F689- SWEET.16 0000 ERRORS IN ASSEMBLY 9 - 4 --------------------------------------------------------------------- Appendix A OPERATION AND MEMORY USAGE Configuration Requirements S-C Macro Assembler will run in any Apple II or Apple II Plus with at least 32K RAM. You can assemble much larger source programs if you have 48K of RAM. You will need at least one standard Apple disk drive. If you have a RAM card (16K RAM or larger) in slot 0, you can use the language card version of the assembler for still larger source programs. Contents of the Disk The disk you received with your S-C Macro Assembler is a standard 16-sector DOS 3.3 disk. It can be copied with Apple's disk copy programs, and the individual files are copyable with FID. (If you do not have DOS 3.3, the files can be de-MUFFINed; or, you can order a special copy on a 13-sector disk.) There are two versions of the S-C Macro Assembler on the disk. S-C.ASM.MACRO is the standard version, which loads at $1000. S-C.ASM.MACRO.LC is the language card version; it loads at $DOOO in any 16K RAM card. The type "T" file named LOAD LCASM is a control (EXEC) file used to load the language card version. The type "I" file named MACRO LIBRARY is an assembly language source file with some sample macro definitions. You may find them useful tools in your programming. The rest of the type "I" files are sample assembly language source files. The assembler uses file type "I" for source program files. They will LOAD into Integer BASIC, but they will be meaningless there. True Integer BASIC files will LOAD into the S-C Macro Assembler, but they will be meaningless there. A brief description of the sample programs appears later in this Appendix. Memory Usage The standard version of the S-C Macro Assembler program is about 8704 bytes long ($2200), and occupies $1000 through $3lFF in memory. The symbol table begins at $3200 and extends upward; your source program begins at the bottom of DQS ($9600 in a 48K machine) and extends downward. The language card version of the S-C Macro Assembler program is a little longer than the standard version. It loads into the A - 1 --------------------------------------------------------------------- language card at $D000. The EXEC file which loads the assembler into the language card also configures it so that DOS thinks of it as the alternate to the language in ROM on the mother board. The symbol table is set up to begin at $1000 rather than $3200. During source program entry or editing, memory usage is monitored so that the source program does not grow so large as to overlap the symbol table. Overlapping will cause the "MEM FULL ERROR" message to print. During assembly, memory required by the symbol table is monitored, to prevent the symbol table from overlapping the source program. Overlapping will generate the "MEM FULL ERROR" message and abort the assembly. In addition, memory usage by the object program is monitored, so that it will not destroy the source program, DOS, the S-C Macro Assembler, the symbol table, or switch any I/O addresses. Therefore, if the object program bytes are directed at any memory address between $1000 and the top of the symbol table, or any address above the beginning of the source program, the "MEM PROTECT ERROR" will be printed and assembly aborted. If you are using macros with private labels, the private label table extends from $0FFF downward toward $0800. The private label table is also protected during assembly. Each private label uses five bytes in this table; the maximum number of private labels in an assembly is therefore 409. The assembler also uses many locations in page zero during editing or assembly. Of particular importance are $4A-4D, $CA-CD, $73-74, and $D9. Location $D9 is used by DOS as a flag to allow commands to be entered. The other locations are used to point at the beginning and end of your source program and symbol table. Locations $00 through $lF are not used at all by S-C Macro Assembler; you may use them as you wish without any fear of conflict. Page one ($100-1FF) is used both as a stack and as storage for various items. The high addresses in page one are used for the stack. The low end is used for a symbol buffer and for pointers to the 27 hash chains used in storing the symbol table. The block from $170 through $1BF is used for holding search and replace strings by the editor, and for .TI titles during assembly. Page two ($200-2FF) is used as an input buffer. The high end of page three ($3D0-3FF) is used by DOS and by the assembler. You must not change any bytes between $3D0 and $3EF. $300-3CF is free to be used in any way you wish. Locations $400-7FF are used by the Apple II as the screen buffer. There are 32 bytes which are unused by the screen image, which are instead used by certain peripheral boards such as the disk controller or printer interface boards. A - 2 --------------------------------------------------------------------- Locations $800-$FFF are free to be used for storing your object program, unless you are using private labels. With care and planning, you can find space for object program storage between the top of the symbol table and the bottom of the source program. If the space there is too difficult to determine, or insufficient size, you need to use the ".TF" directive to store the object program directly on a binary disk file. ROM USAGE The S-C Macro Assembler takes full advantage of subroutines inside the Apple Monitor ROM. Here is a list of all the subroutines used: F941 Print 4-digit hex value from A,X F94A Print (X) blanks FB2F Set text mode, full screen window parameters FBF4 Advance cursor FC10 Backspace cursor FC1A Move cursor up one line FC22 VTAB to current CV value FC2B An RTS instruction FC42 Clear to end of page FC58 Clear screen, home cursor FC66 Move cursor down one line FC9C Clear to end of line FCA8 Delay FD0C Read next input character from keyboard FD18 Read next input character through $38,39 FD84 Add char to input line FD99 Print (Y,X) in hex with dash FDDA Print (A) in hex FDED,FDF0 Print (A) as ASCII char FE00 Display memory in hex FE2C Move block of memory FE89 Set input to keyboard FE93 Set output to screen FECD Write block of memory on tape FEFD Read tape into memory FF2D Print "ERR", ring bell FF3A Ring bell FF69 Enter Monitor for MNTR Command FFA7 Get hex number FFBE Process monitor command FFC7 Clear monitor mode byte FFCC Table of monitor commands A - 3 --------------------------------------------------------------------- SAMPLE PROGRAMS ON THE DISK Some sample assembly language programs are included on the disk. They are not only samples, but are actually useful programs which you might find valuable in your work. SWEET-16: The source code for the interpreter by the same name, written by Steve Wozniak. If you do not have Integer BASIC in ROM or on a language card, you can assemble this file to get SWEET-16 capability. SEARCH BINARY STRING: Search a range of memory for a matching byte pattern. Allows wildcard bytes. Sets up a pseudo monitor command using the control-Y command. GENERAL ML LOADER: Allows you to move an Applesoft program up in memory by any amount. Then assembly language routines can be BLOADed at $800 for easy reference from within the Applesoft program. CATALOG PRINT ROUTINE: Prints out a catalog without pausing at full screen. SAMPLE PRINTER DRIVER: Shows one way to use the PRT command. Runs a printer connected to the game port AN0 output through a software driven serial interface. A - 4 --------------------------------------------------------------------- Appendix B ERROR MESSAGES If you make a mistake, S-C MACRO Assembler will probably catch you. Here are the error messages you may see. *** SYNTAX ERROR There is a misspelled command or bad line number. *** MEM FULL ERROR Either you do not have enough memory for the source program, or for the source plus the symbol table, or a tape read error has occurred. *** MEM PROTECT ERROR Your program tried to assemble into an area of memory occupied by the assembler, the symbol table, or your source code. Use the .TA or .TF directives. *** RANGE ERROR The relative offset for a branch instruction was not between -128 and +127. *** NO LABEL ERROR There was no label with an equate (.EQ) directive. *** BAD OPCODE ERROR The characters in the opcode field are not a valid opcode or directive. *** EXTRA DEFINITION ERROR The same label was defined more than once. *** UNDEFINED LABEL ERROR A symbol in the operand field is not defined. *** BAD SYMBOL ERROR A character in the label field is not a legal character for a label. *** BAD ADDRESS ERROR This one is a catch-all for syntactical errors in the operand expression, as well as for use of a particular address mode with an opcode that does not support that mode. B - 1 --------------------------------------------------------------------- *** VALUE > 255 ERROR A local label is more than 255 bytes from its normal label. *** NO NORMAL LABEL ERROR A local label is used with no normal label present. *** NESTED .IN ERROR There is an .IN directive within an included file. *** MISSING .DO ERROR There is a .FIN or .ELSE without a corresponding .DO *** .DO NEST TOO DEEP ERROR .DO - .FIN blocks are nested more than eight levels deep. *** KEY TOO LONG The search string in a command is longer than 38 characters. *** REPLACE TOO LONG ERROR The REPLACE command tried to create a line longer than 248 characters. *** NO MACRO NAME ERROR The .MA directive has no name in the operand field. *** UNDEFINED MACRO ERROR The macro name called has not been defined. *** BAD MACRO PARAMETER ERROR The character following a square bracket (]) must be a number (1-9) or a (#). When an error is discovered during assembly, the error message is printed along with the offending line. The assembler then continues its pass, looking for more errors. At the end of the pass it will print "XXXX ERRORS IN ASSEMBLY", where XXXX is the number of errors it found in that pass. If there are any errors discovered during pass one, assembly will not continue into pass two. Some errors are catastrophic, and abort assembly without continuing to the end of the pass. B - 2 --------------------------------------------------------------------- Appendix C PRINTER SOFTWARE If you have a standard Apple parallel or serial printer interface, with firmware in RON on the card, you probably do not need any special printer software. You can turn your printer on from within the S-C Macro Assembler using the "PR#s1ot" command, and turn it off with UPRIOU. If you have a special interface, which requires non-standard setup not handled by the PR# command, you can use the PRT comniand. When you type the PRT command, the S-C Macro Assembler executes a "JSR $1009" instruction. At $1009 there is a JMP instruction, which you can patch to point at your special printer setup routine. For example, if you have a special printer driver loaded at $300, your setup program might look like this: 1000 *--------------------------------- 1010 * SAMPLE PRINTER DRIVER 1020 *--------------------------------- 0800- A9 0C 1030 PRT LDA #DRIVER 0802- 85 36 1040 STA $36 0804- A9 08 1050 LDA IDRIVER 0806- 85 37 1060 STA $37 0808- 20 EA 03 1070 JSR $3EA DOS I/O REHOOK 1080 * OTHER SETUP WOULD COME HERE 080B- 60 1090 RTS 1100 *--------------------------------- 1110 DRIVER 1120 * 1130 * WHATEVER IT TAKES TO TALK TO YOUR PRINTER 1140 * GOES HERE 1150 * 080C- 60 1160 RTS The S-C Macro Assembler Diskette includes a more extensive printer driver, written to use a serial interface connected to one of the output pins of the Apple II game connector. C - 1 --------------------------------------------------------------------- Appendix D CUSTOMIZING A number of features within the S-C Macro Assembler have been parameterized, to make it easier for you to customize it the way you like. The parameters are all grouped at the beginning of the program, at $1006-101D in the normal version, and $D006-D01D in the language card version. You can adjust the parameter values as you like, and BSAVE the resulting personal version for a permanent copy. $1000: Hard entry point. Performs major initialization. If you want some additional initialization you can modify the address of this JSR, and have your program end by JMP to the address which was in $1001,1002. $1003: Soft entry point. If you desire some additional code here you can patch it in the same way as the hard entry above. $1006: USR Vector. If you want to implement a USR command, change the address in this JMP instruction to call your command. Your command should end with an RTS, or a JMP $1003 ($D003 for language card version). $1009: PRT Vector. If you want to implement your own PRT command, put the address of your command processor in bytes $100A and $100B. Your command should end as the USR command described above. $100C: .US Directive Vector. $100F: Tab Control Character: Normally $89, which is control-I. You can change it to some other control character if you wish. $1010-1014: Tab Column Settings. Up to five tab stops. Normally set to 14, 18, 27, 32, and 0. If you wish fewer than five tab stops, use 0 for the unused ones. $1015: Escape-L Comment Line Repeated Character. Normally $AD, which is "-" If you want a line of asterisks, use $AA. Use any printing character you want. $1016: Lower-Case Mod Flag. Normally 0. Set to $FF if all three conditions are true: 1) you have installed a lower case display modification in your Apple; 2) you have installed a shift-key modification in your Apple (a wire from the shift-key solder terminal to pin 4 of the game connector); 3) you want to use lower-case in your source programs. D - 1 --------------------------------------------------------------------- $1017: Compression flag. Normally $04, which means compression is ON. Set to $FF to turn compression OFF. When off, source files will be compatible with S-C Assembler II Version 4.0; when ON, they will not be. The compression switched by this flag replaces strings of repeated non-blank characters of 4 or more in length with a 3-byte token sequence. Multiple blank compression is not affected by this flag. $1018: Search string wildcard character. Normally $17, which is control-W. $1019: Character Output Vector. Normally contains "JMP $FDED", but you can use your own character output routine if you wish. Most output from the editor and assembler is vectored through this point. $101C: Always $A9, first byte of LDA-immediate instruction. $101D: Symbol Table starting page number. Normally $32 for normal version, $10 for language card version. D - 2 --------------------------------------------------------------------- Appendix E BIBLIOGRAPHY There are now in print a number of good books and periodicals for learning how to program the 6502 microprocessor. Here are the ones I have found helpful. Periodicals: Apple Assembly Line, a monthly newsletter published by S-C SOFTWARE, See advertisement inside back cover for details. Assembly Lines, a monthly column by Roger Wagner in SOFTALK magazine. NIBBLE Magazine. MICRO, the 6502/6809 Journal. Call A.P.P.L.E. magazine. Books: 6502 Software Design, Leo J. Scanlon. one of the Blacksburg Continuing Education Series, published by Howard W. Sams & Co., 1980. 270 pages, paper, $10.50. 6502 Assembly Language Programming, Lance A. Leventhal. Osborne/McGraw-Hill, Inc., 1979. $16.99, paper. Over 80 programming examples, tested on an Apple II. (I recommend this one to the really serious programmer, and keep some on hand at $16.00 each.) Programming & Interfacing the 6502, With Experiments, Marvin L. De Jong. One of the Blacksburg Continuing Education Series, published by Howard W. Sams & Co., 1980. 414 pages, paper, $13.95. 6502 Software Gourmet Guide & Cookbook, Robert Findley. Scelbi Publications, 1979. 204 pages, paper, $10.95. Includes listings of conversion routines, search and sort routines, and floating point routines. 6502 Games, Rodney Zaks, SYBEX. The third in the SYBEX series on programming the 6502. Includes listings of games in assembly language, of the type which are usually programmed in BASIC. Wozpak II and Other Assorted Goodies. A collection of Apple II documentation published by the publishers of CALL A.P.P.L.E. It contains many useful programs in assembly language which can be used and/or studied. E - 1 --------------------------------------------------------------------- Practical Microcomputer Programming: the 6502, W. J. Weller, Northern Technology Books, 1980. 459 pages, $32.95, cloth. Includes a listing of a 6502 assembler and of a debugging package. Programming a Micro-Computer: 6502, Caxton C. Foster, Addison-Wesley Publishing Company, 1978. 234 pages, $9.95. Oriented toward KIM-l, but has very good explanations and examples of machine language. Real Time Programming -- Neglected Topics, Caxton C. Foster, Addison-Wesley Publishing Company, 1978. 190 pages, $8.95. Covers interrupt handling, I/O interfaces, synchronizing, sampling, closed-loop control, communication, and more. Concise, clear explanations by a good teacher. Apple Machine Language, Don & Kurt Inman, Reston Books (Prentice-Hall), 1981. 296 pages, $12.95 paper, $16.95 cloth. For the ultimate beginner. (I stock this book at $12.00 each.) How to Program Microcomputers, William Barden, Jr., Howard W. Sams & Co., 1977. 256 pages, $8.95. Covers the 6502, 6800, and 8080 microprocessors. Using 6502 Assembly Language, Randy Hyde, Datamost Inc., 1981. 283 pages, $19.95. An excellent book, although it promotes Randy's LISA Assembler. Beyond Ganes: Systems Software for Your 6502 Personal Computer, Ken Skier, BYTE/McGraw-Hill, 1981. 432 pages, $14.95. Sounds a lot better than it is. E - 2 --------------------------------------------------------------------- INDEX 6502 Programming 8-1/15, E-1/2 Accumulator Mode 8-4 Addressing Modes 8-3/6 Arithmetic Operators 6-3 Arithmetic Operations 8-9 ASCII Characters 3-2, 3-5, 5-6, 6-2 ASCII Strings 1-3, 5-6 Assembly 1-5, 2-2, 4-6, 4-16, 5-1/4, 5-9, 7-1, 7-3, A-2 ASM Command 2-2, 4-16 Asterisk (*) 1-4, 3-2, 5-5, 6-1/3 AUTO Command 1-2, 3-1, 4-3, 4-18 Autostart ROM 1-2, 2-3, 3-5, 4-16, 4-22 Block Storage 5-7, 6-1 BSAVE Command 4-21, 5-2, D-1 Commands 4-1/22 ASM 2-2, 4-16 AUTO 1-2, 3-1, 4-3, 4-18 COPY 1-2, 1-3, 4-14 DELETE 1-3, 4-12, 4-21 EDIT 1-2, 1-3, 4-10 FAST 4-9, 4-15 FIND 1-3, 4-9 HIDE 4-4 INCREMENT 3-1, 4-18 LIST 1-3, 2-1, 4-9 LOAD 4-2 MANUAL l-2, 3-1, 4-18 MEMORY 4-19 MERGE 4-4 MGO 2-3, 4-16 MNTR 1-2, 4-19 NEW 1-3, 2-2, 2-4, 4-2 PRT 4-15, C-1, D-1 RENUMBER 3-1, 4-13 REPLACE 1-2, 4-11, B-2 RESTORE 4-6 RST 1-2, 4-19 SAVE 4-2 SLOW 1-3, 4-9, 4-15 SYMBOLS 1-2, 4-17 TEXT 1-2, 4-3 USR 4-20, D-1 VAL 4-17, 6-3 " 4-15 Comment Field 2-3, 3-4 Comments 1-4, 2-3, 3-4/5, D-1 Compare Operations 8-11 Compression 1-4, D-2 Conditional Assembly 1-3, 5-9/10, 7-3, 7-5, 7-7, B-2 Conditional Branch Operations 8-12 Control codes 4-10 Control-I 1-4, 2-4, 3-1, 4-10, D-1 Control-O 1-4, 4-10, 4-15 --------------------------------------------------------------------- Control-W 4-8, D-2 COPY Command 1-2, 1-3, 4-14 Cursor 2-4, 3-1, 3-5, 4-10 Data 1-3, 5-5, 5-6 Decimal Numbers 6-1 DELETE Command 1-3, 4-12, 4-21 Disk Operations 1-2, 2-2, 4-1, 4-2, 4-3, 4-16, 4-21, 5-3, 5-4 Directives 5-1/11 .AS 5-6 .AT 1-3, 5-6 .BS 5-7, 6-1 .DA 1-3, 5-5 .DO 1-3, 5-9, 7-3, 7-7, B-2 .ELSE 1-3, 5-9, 7-3, 7-7, B-2 .EM 1-3, 5-11. 7-1 .EN 5-4 .EQ 1-3, 5-4, 6-1, B-1 .FIN 1-3, 5-9, 7-3, 7-7, B-2 .HS 5-6 .IN 4-6, 5-3, 5-4, B-2 .LIST 1-3, 5-8, 7-3 .MA 5-11, 7-1, B-2 .OR 5-1, 6-1 .PG 5-9 .TA 5-1, 6-1, 7-3 .TF 5-1, 5-3, 7-3 .TI 5-8 .US 5-11, D-1 Direct Modes 8-4 DOS Commands 4-21 BSAVE 5-2, D-1 DELETE 4-12 EXEC 1-1, 1-2, 4-3 FP 1-3 INT 1-3 LOAD 2-2, 4-2, 4-4, A-1 MON 5-3, 5-4 PRt 1-3, C-1 SAVE 2-2, 4-2 EDIT Command 1-2, 1-3, 4-10 Editing 1-2, 3-1, 3-5, 4-7/14, A-2 End of Macro 1-3, 5-11, 7-1 End of Program 5-4 Equate 1-3, 5-4, 6-1, B-1 Errors 1-5, 4-6, 4-12, 5-4, 7-3, 7-7, A-2, B-1/2 Escape codes 3-5 Escape-L 1-4, 3-5, D-1 EXEC Command 1-1, 1-2, 4-3, 4-21 EXEC Files 4-3, 4-21 FAST Command 4-9, 4-15 Fields Comment 2-3, 3-4 Label 2-1, 3-2, B-1 Opeode 2-1, 3-4, 7-1, B-1 Operand 2-1, 3-4, 6-1/3, 7-1, B-1 --------------------------------------------------------------------- Files A-1, A-4 EXEC 4-3, 4-21 Object 4-21, 5-3 Source 2-2, 4-2/6, 4-21, 5-4, 7-7 Text 1-2, 4-3, 4-21 FIND Command 1-3, 4-9 FP Command 1-3, 4-21 Hexadecimal Numbers 6-1 Hex Strings 5-6 HIDE Command 4-4 Immediate Mode 8-4 Implied Node 8-3 INCREMENT Command 3-1, 4-18 Include 4-6, 5-3, 5-4, B-2 Indirect Modes 8-5 INT Command 1-3, 4-21 Label Field 2-1, 3-2, B-1 Labels Local 3-3, 6-1, B-2 Normal 2-1, 2-2, 3-2, 4-16, 4-17, 5-4, 6-1, B-2 Private 3-4, 6-1, 7-1, 7-2 Language Card 1-5, 9-1, A-1, D-2 Line Numbers 1-2, 1-3, 2-1, 2-3, 3-1, 4-7, 4-13, 4-18 Line Ranges 1-3, 4-7, 4-9/12 LIST Command 1-3, 2-1, 4-9 Listing, Assembly 1-3, 2-2, 4-16, 5-6/9, 7-3 Listing Control 1-3, 5-8, 7-3 Literal ASCII Characters 6-2 LOAD Command 2-2, 3-5, 4-2/4, 4-21, A-1 Local Labels 3-3, 6-1, B-2 Logical Operations 8-10 Lower-case Characters 4-11, D-1 Macros 3-4, 5-B, 5-11, 7-1/7, A-2, B-2 MANUAL Command 1-2, 3-1, 4-18 MEMORY Command 4-19 MERGE Command 4-4 MGO Command 2-3, 4-16 MNTR Command 1-2, 4-19 Modifying the assembler 1-4, 3-2, 3-5, 4-20, 5-3, 5-11, D-1/2 MON Command 4-21, 5-3/ Monitor 1-2, 1-3, 4-16, 4-19, 4-22, 5-2, A-3 NEW Command 1-3, 2-2, 2-4, 4-2 NOMON Command 4-21 Normal Labels 2-1/2, 3-2, 4-16/17, 5-4, 6-1, B-2 Object Code 2-2/3, 4-16/17, 4-22, 5-1/3, 5-7, A-2, B-1 Object Files 4-21, 5-3 Opcode Field 2-1, 3-4, 7-1, B-1 Operand Field 2-1, 3-4, 6-1/3, 7-1, B-1 Operand Expressions 6-1/3 Operand Elements 6-1/2 --------------------------------------------------------------------- Operators 6-3 Origin 5-1, 5-3, 6-1, 7-3 Override 1-4, 4-10, 4-15 Page Control 5-9 Page Numbers 5-8 Parameters Assembler internal 1-4, 3-2, 3-5, 4-20, 5-3, 5-11, D-1/2 Line number 1-3, 4-7, 4-9/12 Macro call 7-1/2, 7-5, 7-7, B-2 String 1-3, 4-8, 4-9/11 Printers 1-2, 1-3, 3-2, 4-15, 4-21, 5-8, 5-9, A-4, C-1, D-1 Private Labels 3-4, 6-1, 7-1/2 Prompt 3-1, 4-1 PR# Command 1-3, 4-21, C-1 PRT Command 4-15, C-1, D-1 Range Parameters 1-3, 4-7, 4-9/12 Relational Operators 6-3 Relative Mode 8-3 RENUMBER Command 3-1, 4-13 REPLACE Command 1-2, 4-11, B-2 RESTORE Command 4-6 Return Operations 8-13 RST Command 1-2, 4-19 SAVE Command 2-2, 4-2, 4-21 SLOW Command 1-3, 4-9, 4-15 Source Code 1-4, 2-1/4, 3-1/5, 4-2/14, 5-4, 7-1, A-2, B-1 Source Files 2-2, 4-2/6, 4-21, 5-4, 7-7 String Parameters 1-3, 4-8, 4-9/11 SWEET-16 2-1, 3-4, 9-1/4, A-4 SYMBOLS Command 1-2, 4-17 Symbol Table 1-2, 1-5, A-2, D-2 Tabbing 1-4, 2-4, 3-1, D-1 Target Address 5-1, 6-1, 7-3 Target File 5-1, 5-3, 7-3 TEXT Command 1-2, 4-3 Text Files 1-2, 4-3, 4-21 Title 5-8 Transfer Operations 8-8 Unconditional Jump Operations 8-13 User Directive 5-11 USR Command 4-20, D-1 VAL Command 4-17, 6-3 Wildcard Character 1-2, 4-8, 4-11, D-2 Zero Page 1-5, 5-4, 6-19, 8-3/5, 9-1/2, A-2 " Command 1-2, 4-15 ---------------------------------------------------------------------