INTO THE 128
by Toni Baker
from ZX Computing June 1987

Part Two by Toni Baker


In this, the second part in our series on the Spectrum 128 and the +2,
we turn our attention to the file storage system called the SILICON
DISC, or RAMDISC. In BASIC it is possible to save programs, data, or
code onto silicon disc in much the same way that you can save them
onto cassette, except that the command for accessing the silicon disc
system is SAVE! instead of just SAVE. Silicon disc has the advantage
of speed - the file is saved seemingly in an instant.

Likewise there are corresponding commands LOAD!, VERIFY! and MERGE!.
The disadvantage of silicon disc is that everything stored there will
be wiped out when the power is disconnected.

In this article we are going to look at the silicon disc organisation
from a machine code point of view. In point of fact, the terms
"silicon disc" and "RAMdisc" are not very accurate. There is no disc
of any description inside the 128; there is only 128K of RAM memory.
The system is called "silicon disc" purely because it mimics a normal
disc drive, but a disc system it certainly is not.


RAM page

Last month I told you about ROM and RAM pages. This month, I must
dwell on the subject of RAM pages for a little longer. As you recall
there are eight RAM pages numbered from 0 to 7, and each page contains
16K, making 128K in all. What you now need to realise is that these
RAM pages are divided into two distinct groups, which we may refer to
as "NORMAL RAM" and "SILICON DISC RAM". Figure 1 [IN2_1.GIF] shows
this distinction diagrammatically. As you can see, normal RAM contains
three 16K pages, making 48K in all - in this sense the 128 is not
really much different from the old 48K Spectrums. Normal RAM contains
a screen, some system variables, the current BASIC program together
with its BASIC variables and channel information, the calculator
stack, the user-defined graphics, and so on - just as before.
Everything new in the 128 happens in the other section of RAM - the
silicon disc area.

Normal RAM consists of RAM pages 5, 2 and 0 (in that order). You will
recall that page 5 is permanently mapped to address 4000h, and that
page 2 is permanently mapped to address 8000h. Under normal
circumstances you will find that page zero is paged in and mapped to
address C000 - this means that normal RAM contains 48K of memory with
continuous addressing from 4000h all the way up to FFFF . The same
cannot be said, however, for the silicon disc area. This consists of
RAM pages 1, 3, 4, 6 and 7 (in that order). However, none of these
pages are permanently mapped anywhere. This means that in order to
access part of the silicon disc memory you must page in one of its
pages, which will then reside at address C000 in place of RAM page
zero (which must be restored afterwards). It is not possible to access
all of the silicon disc area at once.

To make life easier, I shall introduce the concept of PAGE CODES. You
see, each of the eight RAM pages possesses a PAGE CODE, which is a
number between zero and five.

NB: THE PAGE CODE IS NOT THE SAME THING AS THE PAGE NUMBER.

It is the use of page codes which enables us to distinguish between
the two different regions of RAM, and to access the silicon disc area
sensibly. Pages 5, 2 and 0 (ie. normal RAM) all have a page-code of
five. Pages 1, 3, 4, 6 and 7 (ie. the silicon disc area) all have
page-codes less than five - in fact they run in sequence: 0, 1, 2, 3,
4.

This makes addressing of the Spectrum's memory a little simpler. Last
month we established the convention whereby every byte in RAM could be
referred to by a five digit hexadecimal number; for instance, the
first byte in the silicon disc area would be referred to as address
1C000. The "1" at the start refers to RAM page one, and the remaining
four digits are the address within that page.


----------

	INC  HL
	BIT  7,H
	RET  NZ
	LD   HL,C000
	INC  A
	RET

Figure 2.

----------


We can do almost exactly the same thing with page codes. For instance,
consider again the first byte in the silicon disc area. This exists on
RAM page one, but page one has a paging-code of zero (see Figure 1).
Therefore, we can specify the byte uniquely by supplying the page-code
(zero), and the address (C000). To avoid confusion with absolute page
numbers, we will not fuse these together into a single five digit
number. We will, instead, define a new convention as follows: place
the page-code within BRACKETS, and follow it by the address.

Using this second convention, the first byte of RAMdisc, in addition
to having an absolute address of 1C000, also has a PAGE-CODED ADDRESS
OF (0)C000.

Just to give you a better grasp of the new convention, here are some
equivalents, in both absolute and page-coded address systems:

	1FFFF = (0)FFFF
	3C001 = (1)C001
	4D800 = (2)D800
	6EE00 = (3)EE00
	7EBEC = (4)EBEC
	 4000 = (5)4000
	 ABCD = (5)ABCD
	 F000 = (5)F000

(Note that in the old absolute convention the last three items could
also be referred to as 5C000, 2EBCD and 0F000 respectively).

I hope all this makes sense. The point is that a single register pair
will not hold a 128K address, since a register pair can only hold four
hex digits. Therefore, to hold such an address in machine code we will
require three registers, not just two. We may use either the absolute
or the page-coded convention, whichever is most convenient at the
time. You will find that when working with the silicon disc area,
page-coded addresses are a lot more helpful. As an example, suppose we
wanted to store the page-coded address (4)EBEC in the register triplet
AHL. To do this A must contain 04, whilst HL must contain EBEC. As
long as you remember that this is a page-coded address and not an
absolute address then you won't go far wrong.

The advantage of page-codes is that they make everything nice; for
instance, the whole of normal RAM has the same page-code (5), and
furthermore, the page-codes of the silicon disc area run sequentially:
(0), (1), (2), (3) and (4). We may use this fact to our advantage in
machine code. For instance, suppose AHL contains the page-coded
address of a byte in the silicon disc area. How may we calculate the
page-coded address of the byte following it? Figure 2 shows a possible
solution. Imagine how messy this simple subroutine would become if we
were to use absolute addresses instead!


----------

The first nine bytes of a standard file contain the following
header information:

HD_00 (one byte):  File type: 00 = program
                              01 = numeric array
                              02 = string array
                              03 = bytes of code
HD_0B (two bytes): Length of file, excluding header info
HD_0D (two bytes): Start address from which file was SAVE!d
HD_0F (two bytes): Length of program, or name of array
HD_11 (two bytes): Auto-run line number

Figure 4.

----------


Memory

The very first subroutine in this month's main program is called
PAGE_(A), and its purpose is to page in the RAM page whose page-code
is held in the A register. If the page code specified is (5) then it
will page in RAM page zero, restoring normal RAM. The subroutine works
by converting the page-code to an absolute page number and then paging
in normally. This subroutine is the key to using silicon disc memory,
and both the 128 and the 128+2 contain similar sub-routines in their
new ROM.

Now it is time to look closer still at the silicon disc memory. Figure
3 [IN2_3.GIF] shows how this memory is organised. Growing upwards from
address (0)C000 is the file stack. Every time a file is saved it is
added to the top of the file stack. Each entry in the file stack
contains nine bytes of header information followed by the file itself
as it would be saved on cassette or microdrive. Figure 4 shows the
meanings of the nine bytes of header information which precede each
program, DATA or CODE file. Note that under normal circumstances this
header is transferred to the system variables HD_00 to HD_11 (5B71 to
5B79) while a file is being processed.

Growing downwards from address (4)EBFF is the catalogue stack. Each
entry takes exactly twenty bytes, so the first entry will begin at
address 4(EBEC), the second entry at (4)EBD8, and so on. Each entry in
the catalogue stack is a reference to one of the files in the file
stack - in other words, there are always exactly the same number of
entries in the catalogue stack as there are files in the file stack.
The top of the file stack is pointed to by the system variable
(SF_NEXT) at address 5B83. This is a two byte system variable
containing an address which is always assumed to point into page seven
(ie. page-code (4)). This means that the catalogue stack can never
grow beyond (4)C000 - as a consequence there is a maximum limit on the
number of entries the catalogue stack may contain - five hundred and
sixty-two in fact. This means that the file stack may in turn contain
at most 562 files, and therefore the maximum number of files which may
be saved in RAMdisc is 562, however small the files might be.

At the top of the catalogue stack is a twenty byte information block
called the "end-of-cat" marker. Only three of its bytes are important,
however. Figure 5 shows the information contained by each entry in the
catalogue stack, whilst Figure 6 shows the corresponding information
contained by the end-of-catalogue marker.


----------

This is a typical entry from the catalogue stack, assuming that IX
points to the first byte.

IX+00 SF_NAME  (ten bytes):   File name, with trailing spaces if
                              necessary
IX+0A SF_START (three bytes): Page-coded address of start of 
                              file in file stack
IX+0D SF_LEN   (three bytes): Length of file, including header
                              info
IX+10 SF_END   (three bytes): Page-coded address of first byte
                              in file stack beyond end file
IX+13 SF_FLAG  (one byte):    Normally reset (unless file
                              construction incomplete)

Figure 5.

----------


----------

This is the information contained by the end-of-catalogue marker,
assuming that IX points to the first byte. Note that this marker is
indexed by (4)(SF_NEXT).

IX+00          (ten bytes):   Not used
IX+0A SF_START (three bytes): Page-coded address of first
                              spare byte in RAMdisc
IX+0D          (seven bytes): Not used

Figure 6.

----------


Bearing all of this in mind, we can now examine the main program of
this article, which is called SUPERCAT! The program may be called from
BASIC with the command: RANDOMIZE USR 33200 which runs the machine
code from the label SUPERCAT. Note that (RAMTOP) must be less than
C000, so that the switching of pages will not affect the machine
stack.

The program will list on the screen a complete and highly detailed
catalogue of everything saved in RAMdisc - it will tell you what kind
of file it is, its auto-run line number (if it has one), its intended
location (if it's CODE); and so on. If you examine this program you
should see how the silicon disc area works, quite comprehensively. If
you're a masochist you might also like to refer to the last article in
the STREAMS AND CHANNELS series which ended quite recently in ZXC.

Next month I'll be looking at the possibilIties for extending BASIC on
the 128. See you then.

[The series was never finished, as ZX Computing ceased publication
after this issue.]

