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.]