RAMTOP/ATOMIC NOs (16K ZX-81)
by Michael Sims
from Popular Computing Weekly (4 November 1982), page 15

This program is for a 16K ZX81 with a printer attached. It has two
interesting features, the first being that it uses some custom designed
characters on the printer, by means of a modified COPY routine from the ROM,
and an alternative character set placed above RAMTOP.

The second feature is that although space above RAMTOP is required by the
program it will reserve this space for itself by resetting RAMTOP without
clearing RAM. The routine that does this is contained in Line 8095. It does
not use USR 1040 because it doesn't work.

The routine will reset RAMTOP and re-configure BASIC to the address Poked
into the bytes at 16507 and 16508. Since this involves moving the Z80 machine
stack and BASIC's Return stack for GOSUBs, anything that might later these
stacks during the move would cause a crash, and so INTs and NMIs must be
prevented by routine the routine in FAST mode.

The program itself computes and draws an electronic configuration diagram of
an atom on being given an Atomic Number between 1 and 112. Such a diagram
shows the levels, sub-levels, and orbitals in which the electrons are
arranged in an atom.

The diagram will appear on the printer as a series of boxes arranged in rows
with a label for each row. The first number in the label is the level number,
the letter is the type of orbital arrangement, followed by the number of
electrons in that sub-level. The higher the level the more room there is for
orbitals and therefore the more sub-shells in the level.

Each sub-shell has a particular arrangement of orbitals (S, P, D, F)
containing 1, 3, 5 and 7 orbitals respectively, and each orbital can hold up
to two electrons. Since electrons have spin, and this is important, the
electrons are represented in the diagram as up-arrows and down-arrows in a
convention found in most textbooks on the subject.

Since Sinclair characters do not support the characters needed for the
program, and since only software techniques are portable, the ZX Printer is
used as the main output device, as custom characters can be produced on it
using programming techniques. This works by duplicating the ROM COPY routine
in RAM and altering one byte to make it use the address 32256 as the base
address for the character-generator instead of the normal 7680.

The ROM C-Gen is copied above RAMTOP and 32 bytes are altered, redrawing four
Graphics characters (1 to 4). The diagram is drawn on the screen first and
then COPYed to the printer by Line 8001.

The first thing is to GOTO 8040. This will read the char-generator into Q()
to be SAVEd with the program, so that on being LOADed the program will RUN
automatically resetting RAMTOP and building the char-generator from Q().

If you haven't a printer then alter S$ to "space|inverse less-than|inverse
greater-than"; T$ to "space|inverse less-than|inverse space"; I$ to
"space|inverse space|inverse space". You won't need Line 305, 8000 to 8130.
Start the program using RUN.


PROGRAM NOTES:

Lines
20-40		N() is the level number, L() is the sub-shell type.
50-56E()	is the full electron number, S$ is a full orbital, T$ is a half empty
		orbital, and I$ an empty orbital. The graphic characters are
		altered for the printer, and no Sinclair characters will give a
		sensible display anyway.
305		GOSUB 8000 is the routine that COPYs the screen to the printer.
470-500		Subtract a full sub-shells-worth of electrons from the Atomic
		number, if the remainder R is zero or less. As long as R is
		positive a full row of orbitals containing two electrons each
		may be printed. C is the number of electrons, and if R is less
		than zero not all the orbitals will be full, and C is reduced
		accordingly.
605		Prints the sub-shell label.
610		B is the number of orbitals (boxes) in the current sub-shell.
		T is the number of full orbitals if one or more. If T=B then
		all the orbitals are full. If T is negative, some orbitals must
		be empty.
650		B - ABS T gives the number of half-empty orbitals.
675		T now gives the number of empty orbitals.
700-799		Formats the label list and prints it.
8040-8080	Store the character generator (above RAMTOP) in Q() to SAVE it
		on tape with the program.
8091-8092	16507 and 16508 are where the RAMTOP routine expects to find
		the new value for RAMTOP.
8094		Adds five to the value of NXTLIN system variable to get the
		start of machine code routine in the next line of BASIC.
		(RAMTOP routine)
8100		Transfer the character generator to above RAMTOP.