Block MOVE and COPY for Version 4.0

How many times have you wished there was an easy way to move a bunch of lines of your source program to some other place?  I know it happens to me, and I frequently wish the assembler had this capability.  Now, at last, it is possible.  I no longer have to use DELETE, SAVE, HIDE, MERGE, LOAD in a very complicated sequence just to move that 20 line subroutine from the middle to the end of my source program!

The program as written assumes you have set up the USR command vector to jump to $800.  You do this by stuffing a 0 into $1007 and an 8 into $1008 (type $1007:00 08 as a command).  Then if you type, for example, "USR 1100,1190,1800", a copy of lines 1100 through 1190 will be inserted before line 1800.  A word of caution:  the lines in their new location will still have the old line numbers, until you RENUMBER.  You can LIST, SAVE, and LOAD while the lines are out of sequence like this, but beware of doing any further editing!  First, use the USR command to make the new copy of the lines; second, RENUMBER the program; third, DELETE the lines form their old location.  Voila!  You have moved them.

I just know someone (maybe everyone) is going to think that I should have made this program do its own renumbering.  The reason I am confident of this is that I feel the same way.  But the program as it stands is useful, and I will refine it later.  My plan is to add one more parameter which specifies the increment for the line numbers in their new location.  Then let the third parameter be the line number for the first line of the block being copied.  The program will check whether making the copy will clobber any existing lines, and error out if so.  If not, the copy will be made with its new line numbers.  Then a question will be asked of the form" DO YOU WISH TO DELETE THE OLD LINES? (Y/N)".  But for now, I will live with the more tedious but still very useful version you see here.

I would suggest that you put the object code of this program on a binary file, and then create an EXEC text file that contains the patch line to set up the USR command and a BLOAD command for the COPY program.  The quarterly AAL diskette contains just such a file.

Now let me describe how the COPY program works.  Notice that lines 1000-1060 are a summary of the operating syntax.  Line 1070, together with lines 2390 and 2400, make the last three symbols in the symbol table listing tell me the start, end, and length of the object code.  These are very useful for writing the object code out to a binary file.  (Of course, I could use the .TF directive and write it automatically.)

Lines 1090-1220 define the page-zero locations the program uses.  SS, SE, SL, and NEWPP are peculiar to this program; the rest of them are used by the monitor and the assembler.  PP points to the beginning of the first source line in memory, and LOMEM is the lowest PP can go.  A0, A1, A2, and A4 are used to pass addresses to the Apple Monitor Memory Move subroutine.

Linew 1240-1280 define some addresses of routines inside the S-C ASSEMBLER II Version 4.0.  SYNX is the Syntax Error routine.  You will get a syntax error message if you type in less than three parameters with the USR command, if the first two parameters are backwards or the same, if the block specified to be copied is empty, or if the target location is inside the block to be copied.  MFER is the routine to print MEM FULL ERR, and you will get this error message if there is not room to make a copy; that is, the space between PP and LOMEM is less than the size of the block you want to copy.

SCND is the assembler routine to scan an input line from the current position and look for a decimal number.  If it finds a decimal number, it will convert the number to binary and store it in A2L and A2H.  As explained on page 10 of the Upgrade manual for Version 4.0, the first two parameters will have already been stored in A0 and A1.

SERTXT is the assembler routine to find a line in your source program, given the line number.  It is called with the X-register containing the address of the first byte in page-zero of the byte-pair containing the line number you are looking for.  When SERTXT is finished, $E4,E5 points at the first byte of the line found, and $E6,E7 points at the first byte of the next line.  (Of course, if your line number could not be found, both pointers will point at the next larger line.)

MON.MOVE is a program inside the Apple Monitor ROM.  It will copy a block of memory whose first byte address is in A1, last byte address in A2, to a new place in memory starting at the byte address in A4.  This is the routine used when you use the monitor "M" command.  It works fine as long as the target is not inside the source block.

Now to the COPY program itself.  Briefly, the three parameters are checked for presence and consistency, and pointers are set up defining the area to be copied.  A new value of PP is computed based on the length of this block, and I check to see if there is room in memory.  Next I search for the target location, and check to make sure it is not inside the source block.  (We don't wat any infinite loops!)  If the target is higher in memory than the source block I adjust the source block pointers by subtracting the block length from them.  Then I move all source lines below the insertion point down in memory far enough to make a hole in the text into which the source block can be copied.  Finally, I copy in the source block, and return.

Some final comments...  The COPY program is very fast, so play with it a little on a scratch program to convince yourself it is working.  If you don't want to type in the source, you can just enter the hex codes from the monitor, and BSAVE it.  Or, your can order the Quarterly AAL diskette, which will have the source, object, and a textfile to EXEC for BLOADing and patching the USR vector.  Or, if you are very patient, you can wait till next August for Version 5.0 of the S-C ASSEMBLER II!
