!pr2
USR Command to List Major Labels Only......Bob Sander-Cederlof

Sometimes when I am working with a large source file in the S-C Macro Assembler it would be nice to be able to list only those lines that define major labels.  Seeing only them would give an overview of an entire file, and enable me to quickly find the section I want to work on.

A major label is one that starts with a letter.  Local labels start with a period, macro private labels start with a colon.  Lines might also start with an asterisk or semicolon, if they are comments, or with blank.

You can add commands to the Macro Assembler in several ways.  One easy built in one is the USR command.  A vector at $D007 (or $1007 with the low memory version) can point to the code to process a command of your own making.  Lines 1080-1140 in the following listing set up the vector for my special USR command.  Since it is in the high RAM area (sometimes called "language card"), I reference $C083 twice to write enable the RAM.

Once the USR vector is loaded, typing a command "USR" will execute my code.  When this happens, the entire command I typed will be in a buffer starting at $200.  Some routines exist inside S-C Macro which can help in parsing the command further and in implementing its functions, and I will use them in this example.  If you have the source code to one of the S-C Macro versions, it is not too difficult to find these routines.  And if you don't have it, you can always disassemble and analyze, a true form of adventure.  The addresses shown in lines 1040-1060 correspond to version 2.0 of the S-C Macro Assembler.

Line 1165 calls on a subroutine I call PARSE.LINE.RANGE (PLR).  PLR starts by setting up SRCP to point to the beginning of the source program, and ENDP to the end of same.  Then it looks at the command line for various forms of line numbers.  You might have none at all, in which case PLR is finished.  You might have one number alone, or a period.  (A period is shorthand for the last remembered line number.)  That might be preceded by or followed by a comma.  You might have two numbers separated by a comma.  Here is a table showing what happens in each case:

               SRCP    ENDP    CARRY
               ----    ----    -----
       none    pstart  pend    set
       #       #start  #end    clear
       #,      #start  pend    clear
       ,#      pstart  #end    clear
       #1,#2   #1start #2end   clear

       where # means number or "."
             pstart = address of start of source code
             pend = address of end of source code
             #start = address of starting line #
             #end = address of ending line #

Line 1170 call a routine in the assembler to compare SRCP and ENDP to see if we are finished or not.  The code is simply:
!pr1
               LDA SRCP
               CMP ENDP
               LDA SRCP+1
               SBC ENDP+1

Lines 1200-1210 pick up the first character after the line number.  The source line format in memory is one byte for a byte count, two bytes for the line number, the text of the line, and a final terminating 00 byte.  The blank which follows just after the line number in listings is not actually stored.

Characters in a source line are stored in "low" ASCII, values between $01 and $7F.  Values from $81 through $BF indicate 1 to 63 blanks.  The value $C0 indicates repetitions of some other character.  The byte following a $C0 is the repetition count, and the byte after that is the character to be repeated.  Lines 1220-1240 check for blanks and repeat tokens.  Lines 1340-1350 pick up the repeated character if we found a repeat token.

Lines 1360-1390 check if the first character is a letter.  If not, this line will not be listed.  Lines 1250-1320 are executed to skip over the current line without listing it.  Since the first byte of the line has a byte count, it is added to SRCP to move up the next line.

At line 1400 I call LIST.CURRENT.LINE to ... you guessed it.  This subroutine also advances SRCP, so after it is finished I jump back to the top to check pointers and get the next line.

After assembling the program, I type MGO INIT to hook it in.  Then "USR 1070," would list just lines 1080 and 1160.
