ZX-PANEL for Sinclair ZX-81
by Alan Lee
from Your Computer, July 1984


ZX PANEL is a program for the 16K ZX-81 providing a front panel
display similar to those found on Research Machines and Memotech
computers. It provides a means of easily entering and debugging
machine code programs.

ZX Panel is initially stored in a REM statement for the purpose of
saving it, but relocates itself above RAMtop upon loading. The REM
statement is of length 1099 bytes; this can be entered in the
following way; enter
	1 REM @@100 CHR$@@
Edit this line, changing the line number to 2, and adding an extra
five characters after the REM. Edit line two eight times to create
lines 3 to 10 all of the same length. Then type in the following
statements directly; do not attempt to list the program automatically
by pressing new line as this will crash the computer.
POKE 16511,77
POKE 16512,4
POKE 16514,118
POKE 16515,118
POKE 16510,0

Then enter program 1, the hex loader. Run this program and enter the
hex codes - program 2 - in the normal fashion. When the last code has
been entered the hex loader will stop. Now delete the hex loader, and
enter program 3. Type RUN, and the program will be saved on cassette.
When the save is completed press E and ZX Panel will locate above
RAMtop, which will be set to 28672, and execute NEW ... Now enter
	RAND USR 29126
and the display should appear as in figure 1. If the computer crashes
at this point, or any other during the testing, reset the computer and
reload the program from tape. When the message appears on the screen
after loading, press Break and enter program 4, the hex checker. Run
the program and check the codes displayed against those in program 2.
If any discrepancies are found, correct them with a direct POKE
statement.

If all is well so far, we will now explore the program. The hex
address near the centre of the screen indicated by the Sinclair
program cursor is called the current address. Code can be entered at
the current address by merely typing in one, or a string of up to 15,
two-digit hex numbers. The panel provides eight routines, which are
accessed by typing full-stop followed by the number of the routine
required, followed by Newline. Various parameters are then requested
for that routine. The routines are as follows:

ROUTINE 0: This is a routine to change the current address. To change
the current address to an address where we can enter code enter ".0
Newline", and in response to the prompt "START?" enter 7436, followed
by Newline. All inputs are in hex, so only key presses from full-stop
to F will be acknowledged, though Rubout can be used as normal,
Newline will increment the current address by 1, cursor up (shifted 7)
will decrement the current address by 1. Enter a short program at this
address; eg.:
	3E0106FFD710FDC9 Newline

ROUTINE 1: This moves a block of code. These are three parameters to
be entered, Start and Finish are the first and last addresses of the
block to be moved, To is the address the block will be moved to. To
test this routine enter ".1 Newline" and enter 7436, 743D and 7437
respectively in response to the prompts. The program you entered
should now have moved forward 1 byte. To move it back again enter
7437, 743E and 7436 in response to Start, Finish and To. Code can also
be moved larger distances; eg. from REM to above RAMtop.

ROUTINE 2: This runs a machine code subroutine. The registers AF, BC,
DE, HL, IX and IY take the values indicated in the top left corner of
the display before starting the subroutine - these can be altered (see
Routine 7) and on returning from the sub- routine, the values of the
registers as they were at the end will be displayed.

When the subroutine has finished, a key must be pressed to return to
the panel display. To run the program we entered, enter ".2 Newline",
and 7436 in response to the prompt. The screen will clear and a series
of blocks will be displayed, press any key to return to the panel
display. Breakpoints may also be set using Routine 4.

ROUTINE 3: This fills a block of memory with a constant. There are
three parameters, Start and Finish are the first and last addresses of
the block to be filled, With defines the constant. The constant is an
8-bit - 2 digit - hex number, though it must be entered as four
digits; eg. to fill a block from 7438 to 7440 with FF, enter 7438,
7440 and 00FF in response to Start, Finish and To.

ROUTINE 4: This sets a breakpoint at the address specified. When your
machine code subroutine reaches a breakpoint, it will jump back to the
panel display, showing the values of the Z-80 registers at that point
in your sub- routine. When the breakpoint is reached, the memory at
that is replaced to its original contents, so if the breakpomt is
required again it will have to be set again.

ROUTINE 5: This displays a block of memory from the addrs specified by
Start, but displays the contents of the memory as characters
corresponding to the value of the address. Enter the routine by ".5
Newline", and in response to Start, type 0100 newline. This displays a
part of the ZX81 ROM where the data for the keywords is stored. To
advance the display press Z, to go backwards press 1. To teturn to the
normal panel display type H. Only those characters with codes 0-63 and
their inverses are displayed; others are shown as spaces.

ROUTINE 6: This quits the panel display, and returns to Basic. To
re-nter the panel type:
	RAND USR 29126

ROUTINE 7: This allows you to change the values ofthe Z-80 registers
AF, BC, DE, HL, IX and IY as shown in the top left corner of the
display. This can be useful if you wish to give a particular register
a value before jumping to a machine code sub-routine with ".2". The
register cursor, as shown in figure 1, indicates which register is to
be changed. It is moved by typing shifted 6.

When you have selected the register to be altered, enter ".7 Newline",
and you will be prompted for the value you wish the register to take.
This value will not take effect until you run a machine code
subroutine using ".2". Do not attempt to alter the values of IX and IY
unless you know what you are doing, as you could crash the computer.

These are the only routines implemented at present, though there is
the facility for at least eight more that you may wish to implement
yourself. A jump table is located at 72A1 hex from which the program
is vectored to each of the routines. The vector of the first unused
routine, that is ".8", is located at 72B3. The start address of your
routine would be stored low byte at 72B3 and high byte at 72B4. The
start address for ".9" would be stored at 72B5 and so on, up to ".F'
which would be stored at 72C1 hex.

If you wish to input parameters for your routine there are subroutines
within the program which will help you. To input a start address call
72E7, on reeta the value input will be in the DE register, and also
stored at 702F/7030 hex.

To input a finish address call 72F5, on return the value input will be
in the DE register and also stored at 7031/7032 hex. To input a
parameter with a different prompt message, store your message in the
memory at a convenient point, load the DE register with the start
address of the message, load the BC register with the length of the
message, then call 72C3.

This subroutine will display the prompt, input the value, and return
with the value input in the DE register. Only four-digit hex numbers
can be input in this way. End your routine with a jump either to 71C6
if the screen has been cleared, or to 71CC otherwise. Some routines
that come to mind are search and replace routines, a disassembler, or
some Basic utilities.

A general breakdown of the program is (all addresses in hex):

7000-702B: Data for messages.
702C-7044: System variables.
7045-705E: Print at B register (y coord), C register (x coord).
705F-706F: Print value of B reg in hex.
7070-707D: Print value of HL followed by colon.
707E-70B1: Print four columns of hex addresses/contents.
70B2-70F9: Routines for printing in decimal.
70FA-715A: Routines to store, load and print registers.
715B-716D: Move register cursor.
716E-7181: Print two dotted lines across screen.
7182-719E: Clear bottom six lines of screen.
719F-71B7: Wait for key press, return value in A reg.
71B8-71C5: Decode a hex number on screen, value in A reg.
71C6-728A: Accept key presses, check and evaluate inputs.
728B-72A0: Jump to selected routine.
72A1-72C2: Jump table.
72C3-7302: Input routines already discussed.
7303-7435: Routines 0 to 7.

