EUG PD


Block Move

 
Published in EUG #70

Description

This utility will move a section of memory - for example, a program - to a new location anywhere in RAM. The only memory affected by the move is the receiving area and the new location may overlap the old one without any corruption of data.

One possible use for this routine is in creating 'cloned' copies of programs in RAM so that one may be used for experimental purposes. This is not as crazy as it sounds. Suppose you have this utility in store at PAGE and you want to move a program down to overlay it. Clearly, you cannot use the Block Move routine to do the move as it is about to be obliterated - if this happens you may end up with two corrupted programs on your hands; both the utility and the program you were trying to move. One way out would be to use the utility to reproduce itself (they can't touch you for it) somewhere else in memory and then use that version for the move.

Use

As we have just seen, the initial position of the routine in store is not too important as it can always move itself off somewhere else. However, because it is a BASIC program it should always be located at a PAGE boundary.

When RUN the routine requests three addresses, all in hex (but you must not enter the &) - they are, respectively, the first and last bytes of the block to be moved and the new position of the first byte.

If you want to see the routine in action, type MODE 6 (RETURN) and then RUN (RETURN). Enter the address 6000, 7000 and 6020.

The contents of the screen will slide three bytes to the right, starting with the bytes at the bottom right of the screen and ending with the byte in the top left-hand corner. This is because &6000 is the start of the screen memory in Mode 6 and this little exercise will give you some indication of the speed of the move.

Another interesting experiemtn is to now LIST the progra and re-RUN (without typing MODE 6) using the same addresses. The overall effect will be the same but notice that the movement starts and finishes in the middle of the screen, which seems to suggest that the screen RAM doesn't start at &6000 any more! The explanation of this effect is that the Electron uses a technique known as 'hardware scrolling' which basically means that it reserves the right to decide where the screen RAM starts, within the range assigned to the screen. This enables the computer to perform extremely fast listings, as it hardly needs to reorganise the lines on the screen whilst it is scrolling them.

How It Works

The bytes are moved ('copied' is perhaps a more realistic description) one at a time using the '?' (query) operator. It is much faster to use '!' (pling), which moves four bytes at once, but you would have to know that you were moving a multiple of four bytes, which would not always be the case. Pling could be used to shift the bulk of the bytes and then query could move the last few so that exactly the right number are moved. This is very messy and is hardly worth including for the gain in speed required.

If the block is to be moved downwards, the operation takes place from the front and, if upwards, from the back - as in the screen example given earlier. This is absolutely essential so that the block does not get corrupted during the move. If the 'to' and 'from' areas do not overlap, then it is not important how the move is done, but obviously we should cater for all cases. Consider the two memory maps in the diagram:

Memory Map Diagrams

Here, F1 and L1 are the addresses of the first and last bytes of Area 1 and similarly for F2, L2 and Area 2. The two areas are the same size, namely (L1-F1+1) bytes long.

Suppose that we wish to move Area 1 to Area 2. It should be clear that we cannot start by moving the bytes at F1 to F2 as that would overwrite the byte at F2 within Area 1. The bytes have to be moved in the order:

L1 to L2
L1 - 1 to L2 - 1
L1 - 2 to L2 - 2
. . .   . . .
. . .   . . .
F1 to F2

 
Likewise, if Area 2 is to be shifted to overlay Area 1, the first byte to move would be F2 to F1 and the last would be L2 to L1. Before the move starts, the routine needs to know which of these two cases it is dealing with so that it can take the appropriate action.

Procedures

PROCaddr prompts with the parameter A$ and accepts an address which it stores in variable add%. Two separate routines are required to do the move depending on whether the move is up or down the memory and this is the function of PROCup and PROCdown. Only one of these is used during a RUN of the utility.

Variables

The diagram shows that the important variables in the move routine are the addresses of the start and finish bytes of the area moved from (froms% and fromf%) and those same addresses in the area moved to (tos% and tof%). Actually, one of these is redundant as it can be calculated from the relationship:

fromf%-froms%=tof%-tos%

if we know the other three items - that is why only three addresses are requested by the program.

Extensions

There's not really much to add to this - the most significant change would be to remove some coding if the utility was to be used for a specific task. If you are ever lucky enough to own discs, then some form of move routine is needed so that programs can be LOADed from disc and then shifted down to &E00, as though they had LOADed from tape. To do this job a very specialised block move is needed in which:

  1. the movement is always downwards
  2. tos% probably=&E00
  3. fros% probably =PAGE for your disc system
  4. Pling (!) can be used to speed up the move

The whole routine could then be fitted on a function key, leaving you with something like:

*KEY 0 I."Last byte",L$:L%=EV.("&"+L$:F. I%=PA. TOL% S.4:I%!-&B00=!I%:N.|M

Cryptic, but effective.

Reproduced from the book Invaluable Utilities For The Electron by Jeff Aughton, published by Pan Publishing in 1984.

Jeff Aughton