Opening this EUG is a demo giving the appearance of someone running
around the edges of your monitor screen, throwing pebbles into the
centre. These pebbles land to form the words "Electron User Group 63".
First, the program calculates the co-ordinates of each pebble that
makes up the letters of the message. This is done by examining the bits
of the character definitions using OSWORD 10. PROCassem1 is the code for
this. If you have seen my BBC Micro Demo 2, then STORE in PROCassem2 is
just a faster equivalent of the Basic prodecure PROCstore(a$,ox%,oy%).
a$ is the string of characters whose bit definitions are to be
converted into co-ordinates beginning at (ox%,oy%). It's stored at TEXT
and TXTPTR, the text pointer, is the index into it. The X and Y
registers point to location &80 in zero page, and a call to OSWORD with
A=10 returns the eight lines of the character definition in &81-&88.
Each line is inspected by loading it into the Accumulator and shift-
ing left the 8 bits in turn into the Carry. If C=1 the current x y co-
ordinates are inserted into XTARG and YTARG, tables of the target x and
y co-ordinates at pages &12 and &13, respectively. The index into the
tables is held in location &72, and at the end of the routine this con-
tains the total number of pebbles.
The values of each line of the character definition are multiplied by
two and ANDed with the original value. This produces thin text, for the
simple reason that it reduces the number of points that need to be
stored. But this is not done if the character is a user-defined one,
i.e. the ASCII code is <127 (a positive number in two's complement). So
they can be used as they are. For example, The word "Electron" for
instance, has to be defined in this way else it won't fit on the screen!
Note then, that normally you can only have up to 5 giant letters on
each line of the screen. A pebble takes up 1 column (8 bytes) and the
Mode 5 screen is 40 columns wide. Also, there mustn't be more than 255
pebbles as the animation routine can only address that number of bytes.
Once STORE has worked out the co-ordinates, it isn't needed any more
so PROCassem2, the animation routine proper, overwrites it. Assembly
starts at &1400, just after the end of the tables of the target co-
ordinates. The idea behind this is that you can save out the entire demo
as a *RUNnable machine code file later.
XPTS and YPTS are two more tables holding the initial co-ordinates
of the pebbles before they start flying toward their target positions.
Each entry is set to zero before anything happens (CLEAR), and LOOP
initially sets the co-ordinates to a point on the edge of the screen.
This point advances clockwise, going from (0,1) to (39,1); then (39,1)
to (39,31); (39,31) to (0,31); (0,31) to (0,1); (0,1) to (39,1) etc.
The x co-ordinate, XSTART, is in columns, and the y co-ordinate,
YSTART is the character row number. As we said, there are 40 columns
across the Mode 5 screen, and one column is a stack of 8 bytes. (A
normal-size text character occupies 2 columns so there are 20
characters across the screen.) The direction is held in DIR, which for
labelling convenience is associated with the four compass points:
0=east, 1=south, 2=west, 3=north.
Every time a new pair of co-ordinates is initiated, PATH is called
to animate that pebble and all other pebbles already in motion. Just
before this, a call is made to Osbyte with A=19. It's the equivalent of
*FX19 and waits for the start of the next screen refresh; helping
smooth the animation. If the value at the current position in YPTS is
0, it means the pebble has not yet been set going. We need that zero to
flag that this is the case, so that's why the y points going round the
edges of the screen run from 1 to 31 and not 0 to 31.
If the pebble's y co-ordinate (we'll call it YPT) is equal to YTARG
(the target y co-ordinate) and the x co-ordinate (XPT) is equal to XTARG
then the pebble has reached its target position and the routine drops
through to INPOS. If YPT <> YTARG and XPT <> XTARG, the pebble is erased
and plotted at a new position.
This new position is worked out as follows. If XPT < XTARG, we branch
to WESTOF because the pebble is to the west (left) of its target and is
INCremented to move it to the east/right. On the other hand, if XPT >
XTARG, it needs to be DECremented. If it's now 0, we drop through to
WESTOF (which, as we just said, moves it to the right).
Similarly, if YPT < YTARG, it is to the north (top) of the target and
needs to be INCremented. If YPT > YTARG and DECrementing it results in
0, we drop through to NORTHOF which INCrements it again. We now have
reached INPOS which will print the pebble at its new co-ordinates.
The erasing and printing is done by ERASE and PRINT respectively.
They both call CALC to calculate the screen address. CALC assumes that
the X register holds the current pebble number as an index into the
current y co-ordinate which itself becomes an index into SCRTAB. This is
a table of addresses of the start of each of the 32 character lines.
They are stored as 32 low bytes followed by 32 high bytes. This saves
trying to multiply the index by 2 and using it to index into a table of
32 two-byte pointers stored low-byte high-byte fashion.
The column number (XPT) is multiplied by 8 to get the offset from the
address obtained from SCRTAB. We only need the one ROL SCR+1 after three
ASLAs, because the maximum that the column number can be is 39. After
one ASLA, this would become 78, which still can be contained in one
byte. After the second ASLA, it becomes 156, again still a one-byte
number. Only after the third ASLA would it reach 312 which is a two-
byte number.
The pebble data is held at PEBDAT, and PEBBLE copies the 8 bytes into
the screen Ram at the address in SCR. ERASE just overwrites eight bytes
in the screen with zeros.
Now let's return from PATH to the main routine. It could be that all
the pebbles have been set in motion by the time COUNT reaches zero, but
not all of them have reached their target. The TIDY routine tidies up by
calling PATH at least enough times to get all of the remaining pebbles
to their targets. If you
are trying your own message and find that some

pebbles still haven't reached their finishing positions, just increase that 25 in line 560.
To save the demo as machine code, type: *SAVE DEMOMC 1200 173B 1400
&1200 is the start of the XTARG table. &173B is the value of
PRINT~P%, which tells you where the next machine code instruction would
be assembled to if you had any more machine code to assemble. If you get
a different answer, substitute it for the &173B. &1400 is where
execution starts (the value you should get if you type in PRINT~store).