Dk'tronics 64K/256K Memory Expansion For The Amstrad CPC Computers
Dk'tronics 64K/256K Memory Expansion For The Amstrad CPC Computers
PAGE.
64K AND 256K MEMORY EXPANSION UNITS.
1.0 PREFACE 1
1.1 INSTALLATION 2
1.2 USING YOUR EXTRA RAM 2
1.3 RAM TEST 3
1.4 EXTENDED BASIC COMMANDS 3
1.5 WINDOWS AND PULLDOWN MENUS 4
1.5.1 MORE WINDOWING 5
1.6 ARRAYS, VARIABLES AND STRINGS 6
1.6.1 MORE ABOUT ARRAYS 9
1.6.2 STRING STORAGE 10
1.7 ANIMATION AND PICTURE SHOWS 11
1.8 ADVANCED PROGRAMMING 13
1.9 PEEKING AND POKING 15
1.10 PROGRAMMING WITHOUT RSX's 16
1.11 TECHNICAL DETAILS 17
1.11.1 THE LOAD ADDRESS 17
1.11.2 SAVING TO DISC 17
1.11.3 INCREASING CP/M 2.2 TPA 17
1.11.4 COMMERCIAL PROGRAM COMPATIBILITY 17
1.11.5 USING CP/M 2.2 18
1.12 ERROR MESSAGES 18
1.13 REFERENCE OF RSX COMMANDS 19
1.14 TECHNICAL DETAILS (HARDWARE) 20
1.15 CUSTOMIZING YOUR CP/M+ DISC 22
64K and 256K MEMORY EXPANSIONS.
These units are available for the CPC 464, 664 and 6128 computers.
By using the 64K upgrade the 464 and 664 computers will have the same amount
and configuration of RAM as the CPC 6128. The 256K gives an extra 192K on top
of this! The expansion will allow the use of CP/M+ as supplied with the CPC
6128 with its massive 61K TPA opening up an even larger software base for
Amstrad users. There is also an utility for increasing the TPA on CP/M 2.2 to
61K.
The RAM can be accessed by means of bank switching using a single I/0 port.
Memory is actually switched in and out of the 64K Z80 address space in 16K
sub-blocks, as are the ROMs. The port determines which particular combination
of the original four 16K sub-blocks and any new sub-blocks from the expansion
RAM will occupy the 64K address space at any time. Control of the I/0 port
can be from either BASIC or machine code.
To use the additional 64K/256K of RAM, the expansion is supplied with bank
switching software (although it can be switched without this software).
The software adds some extra BASIC commands, RSXs, which make it possible to
use the second 64K (or 3rd, 4th and 5th in the case of the 256K expansion)
for storage for screens, windows, graphics and BASIC arrays. This ability
means that you can write much larger BASIC programs, as most of the memory on
the unexpanded CPC464/664 is normally used for arrays, variables and
graphics.
These commands make such features as pull down menus, full screen animation
and large spreadsheet type programs or databases very easily programmed from
BASIC as never before possible on the unexpanded CPC464 and 664 computers.
-1-
WARNING.
Ensure that the power to your Amstrad computer is switched OFF before you fit
the interface to the expansion socket. Failure to comply with these
instructions may cause permanent damage to the RAM pack or the computer.
1.1 Installation.
Power down your Amstrad computer. Plug the RAM pack into the socket on the
back of the computer. On the CPC 464 this socket is labelled 'Floppy
Disc', on the CPC 664 and CPC 6128 the socket is labelled 'Expansion'.
Other expansions such as the Amstrad Disc interface for the CPC 464,
DK'tronics Lightpen and Speech Synthesizer, or ROM expansions can be
fitted into the expansion socket on the back of the RAM pack. Now switch on
the computer.
It is very unlikely that the computer will fail to power up with the RAM
pack alone. If this is the case, then the fault will probably lie with the
RAM pack. * Return the RAM pack to RAM ELECTRONICS if this is the case.
There are two ways to use the extra RAM. There is a cassette supplied with
the RAM pack containing extensions to BASIC. Here the extra RAM can be
used simply from BASIC programs. Alternatively, the RAM is accessible both
from BASIC and machine code using the OUT command. The experienced
programmer will be able to use the RAM for whatever he pleases and
write custom software for that purpose. Commercial programs will no
doubt use this approach.
The second method is described in detail in section 1.10. The first way
is explained in the following chapters:-
-2-
With the computer set up as above, load the RSX software from the cassette
tape supplied:-
When the RSX code is first loaded, it does an extensive RAM test.
Should the RAM not function correctly the program will inform you that an
error has been found. Along with this, it will print out diagnostic
information to help in the repair of the RAM pack.
In the unlikely event that an error is found, please note the information that
is given and return the RAM pack for replacement or repair.
(See warranty registration note.)
You may have noticed that during the RAM test, the computer printed out the
number of the 'bank' it was testing. Each bank is 16K of memory. For
the 64K expansion there are 4 banks while the 256K RAM pack has 16
banks. To access a particular part of the expansion's m em ory t he r e h as
t o be a b ank nu m ber an d pos si b ly a ba n k ad dr e ss.
The computer will respond with READY. What you have done is to store what
was on the screen into bank 1.
Now clear the screen using CLS. To get the screen's contents back,
type:- '|LOADS,1' and press <ENTER>
You can save as many screens as you have memory for. That means four
screens on the 64K RAM and sixteen screens for the 256K RAM. Screen displays
could be created from another program or drawn using a lightpen. Store these
on tape or disc then load them back into RAM for use throughout the program.
Screen displays which take a long time to create within a program, for
example mazes, can be created once, then stored for instant use whenever
necessary.
-3-
The command can be summarized:-
One of the features that makes the Amstrad's windows less flexible than
those on larger business machines, is the fact that the contents of a
window which overlaps another are lost when the other window is used.
There are two new commands which allow the contents of windows to be saved
and reloaded from RAM. This will allow the use of true pulldown menus,
that can cover text, but not remove it.
EXAMPLE:-
NEW
10 MODE 1
20 FOR i=0.05 TO 1 STEP 0.05 : REM Draw grid on screen
30 MOVE 640*i,0 : DRAW 640*i,400
40 MOVE 0,400*i : DRAW 640,400*i
50 NEXT i
60 WHILE INKEY$="" : WEND : REM Wait for a key press
70 WINDOW#1, INT(RND(1)*19+1),INT(RND(0)*9+INT(RND(1)*5+17)),
INT(RND(1)*14+1),INT(RND(0)*14+INT(RND(1)*10+5))
80 PEN#1, 2 : PAPER#1, 3
90 |SAVEW,1,1 : REM Save contents of window into RAM
100 CLS#1 : REM Clear window
110 WHILE INKEY$="" : REM Wait for 2nd key press
120 PRINT#l, "This is a window"
130 WEND
140 |LOADW,1,1 : REM restore window's contents
150 GOTO 60
The above program uses two new commands: |LOADW and |SAVEW. As you are
probably aware, there are eight windows (0-7) which can be defined. The
first parameter is the reference to a window. The second is the bank
number.
See the chapters in the user manual about windows for more details.
-4-
1.5.1 MORE WINDOWING.
A window of any size, even the whole screen, will fit into a single bank
of expansion RAM. This is fine if your window is nearly a full screen or
will vary in size like the above example. On the other hand if your window
was defined as 10 x 10 in Mode 1, then the amount of memory needed to
store this window would be less than 16K. In fact only 1600 bytes are
needed (see below). Thus to use a whole bank would mean wasting over 14K of
memory.
To deal with this problem, the RSX window command can take an extra
parameter to define where you want the window's contents to reside in the
RAM bank. In the 10 x 10 window you could place the data anywhere
between 0 and 14783.
In order to have more than one window per bank, you need to know how much
memory the window will take up. If the window will vary in size between
two limits, use the higher of the two. Depending on which mode you are
using, the figures are calculated as below.
EXAMPLE 2:-
-5-
80 IF keypress$="n" THEN GOSUB 110
90 IF keypress$="d" THEN GOSUB 190
100 GOTO 60
110 If level=7 THEN RETURN
120 level=level+1
130 WINDOW#level, 1+level*3, 14+level*3, 1+level*2, 10+level*2
140 |SAVEW,level,1,bankaddress
150 bankaddress=bankaddress+size
160 PEN#level,0 : PAPER#level, (level AND 1) + 1
170 CLS#level
180 RETURN
190 IF level=0 THEN RETURN
200 bankaddress=bankaddress – size
210 |LOADW,level,1,bankaddress
220 level=level-1
230 RETURN
The above program only uses one bank of RAM but all 8 windows are
defined. The variable 'level' is used to stand for the level of
windows and the variable 'bankaddress' points to the next free place in
the bank RAM.
There are two general purpose data moving commands to allow data from
the program to be moved to and from the RAM pack.
The first parameter references which bank you want to use. The start
location is a memory address where there is some data. The amount of data
is given as the length. Optionally a bank address can be given to allow
more than one type of data to be stored in the RAM.
It is possible to save all kinds of data using these commands, but we will
firstly discuss how to save simple numerical arrays these being the
easiest to understand.
Say for example that your program deals with stock control of up to 60
items. You may have a string array containing the names and a numerical array
containing the number of each item you have in stock.
This would use about 1K for the names and 300 bytes for the stock
figures. However what if you update the stock value every week and you want
to keep the last year of stock on record! Or even the last five years. Now
the figures would take up about 15K or even 75K.
-6-
Obviously, it would be easier to load all the records into RAM, then access
the data immediately:-
The address of any variable can be quickly found using the '@' before a
variable. For example, dimension the above array:-
The computer will reply by giving the memory address where the first
element of the array is stored. Try:-
PRINT @stock(1)
The number returned will be five higher in value. This is the address of
the second variable.
The '@' prefix will work in front of any variable. The first item of an
array is obviously '@stock(0)'. If you are using multi-dimensional arrays,
the first item is '@stock(0,0)' or '@stock(0,0,0,0)' depending on the number
of dimensions.
First of all, different types of array take different numbers of bytes per
element. For real numbers, there are 5 bytes per element. Integer arrays
take 2 bytes per element. String arrays are of variable length. And will be
dealt with later.
To find the total memory, multiply the total number of elements by the
amount of memory needed by each element.
-7-
The array we are using is 304 bytes long, and starts at @stock(0). In a
single bank of RAM we can store 305 bytes about 53 times. The bank address
starts at 0 and goes up in steps of 305 bytes:-
We shall store week 1 at bank address 305, week 2 at address 610 and so on
for all 52 weeks.
Data for test purposes could be written onto disc or tape by the
program below. Once the test file is written, keep it for use while you
are developing your program.
10 OPENOUT "stock.dat"
20 FOR week=1 TO 52
30 FOR item=1 TO 60
40 Print#90, INT(RND(1)*3000+100)
40 NEXT item
60 NEXT week
70 CLOSEOUT
80 END
10 DIM stock(60)
20 INPUT "read file (y/n)";ans$
30 IF LOWER$(ans$)="y" or LOWER$(ans$)="yes" THEN GOSUB 1000
40 REM rest of program ....
1000 REM subroutine to read data from disc.
1010 OPENIN "stock.dat"
1020 FOR week=1 TO 52
1030 FOR item=1 TO 60
1040 INPUT#9, stock(item)
1050 NEXT item
1060 |SAVED,4,@stock(0),61*5,week*305
1070 NEXT week
1080 CLOSEIN
1090 RETURN
The above program could be used to read the file from disc or tape. Once
the file is in bank RAM, the contents will stay there for use until the
computer is switched off, or some other data is put in that bank. This
means that data need only be read once from disc, then the program can be
rerun without losing the data. This could also be useful too if you
wish to write a number of programs to use the same data.
Once the data is in memory, you can access each week's data simply by
reloading the stock array. Add the section below to draw a bar graph for a
given section.
100 MODE 2
110 LOCATE 1,1
120 INPUT "Which item to analyse",itemno
130 IF itemno < 1 OR itemno > 60 THEN 120
-8-
140 CLS : LOCATE 30,1
150 PRINT "Bar Chart For Item"; itemno
160 LOCATE 10,25
170 PRINT"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec": REM 3 spaces
between each.
180 FOR loop=0 TO 4
190 LOCATE 1,24-loop*5
200 PRINT STR$(loop);"000"
210 NEXT loop
220 MOVE 60,328 : DRAW 60,0 : DRAW 61,0 : DRAW 61,368 :
MOVE 640,24 : DRAW 48,24
230 FOR loop=1 TO 4
240 MOVE 48,loop*80+24 : DRAW 60,loop*80+24
250 NEXT loop
260 FOR week=1 TO 52
270 If week/2=week/2 THEN n=l ELSE n=2
280 |LOADD,4,@stock(0),61*5,week*305
290 ycoord=(stock(itemno)/4000*320) AND 4092
300 FOR xcoord=1 TO 11 STEP n
310 MOVE 49 + xcoord + week*11,ycoord+26 :
DRAW 49 + xcoord + week*11, 26
320 NEXT xcoord
330 NEXT week : GOTO 110
If you have a program that uses all the memory of the computer due
to needing a large array, you can use the bank RAM for storing data
without even dimensioning an array.
Instead of having the whole array in BASIC memory, each element can be
accessed by using a subroutine to read out a value, and one to store a
value.
10000 REM load 'store%' from bank memory using 'year' & 'type'.
10010 p= (year*31 + type)*2
10020 bank=1 : IF p >=16000 THEN p=p-16000 : bank=2
10030 |LOADD, bank, @store%, 2, p
10040 RETURN
11000 rem copy 'store%' to bank using 'year' & 'type'
11010 p= (year*31 + type)*2
11020 bank=1 : IF p >=16000 THEN p=p-16000 : bank=2
11030 |SAVED, bank, @store%,2, p
11040 RETURN
Two banks are used, 1 and 2, and the variables 'year' and 'type' are
used to reference which element is required. On line 10030 and 11030,
there are just 2 bytes moved to and from the bank RAM because we are
using integers. The '*2' in lines 10010 and 11010 reflect the fact
that an integer is stored in two bytes. If real variables were used, 5
bytes would need to be used instead. Lines 10020 and 11020 decide
whether the element is in the first bank or the second.
-9-
If the array is to be filled with data from tape or disc, there is no need
to initially clear the values to nil. If you want all elements preset to
zero then the easiest way is to save a blank screen into each bank at
the start of the program:-
The major obstacle in storing strings is that they can vary in length and
can be stored anywhere in memory, including in a BASIC program. One
method of storing string arrays is outlined below. However you may find an
easier way to store strings than the one described below when you consider
exactly what you want to do.
Suppose that you wanted to store 500 names, up to 20 characters long each.
A bank is separated into units of memory 21 bytes each so that strings can
be randomly accessed. In each 21 byte segment there is one string, and one
byte to say how many letters there are in that string. That means that we
will use a total of just over 10K. If we use the variable 'name' to
specify the string we want then we can enter two subroutines; one to put
a string from bank 1 into 'name$' and one to store the contents of
'name$' into RAM bank number 1:-
A dummy string b$ is used to form the element before it is saved into RAM.
The first character is set to the length of 'name$'. The latter 20
characters are where the contents of 'name$' are stored. Then 21
characters are copied into bank RAM. When the string is retrieved the
characters are copied out and 'name$' is set to the right length by
looking at the first character.
String storage would come into its own if all the words were of the same
length because there would be no wastage. For example a word quiz program
using five, six and seven letter words. A bank of RAM could be used for each
length of word. A loader program would set up the data into the RAM, then
another could be CHAINed and use up to 36K of RAM for program.
A number array could also be stored in bank RAM to index the first
letters and so aid the speed of access to a particular word.
-10-
1.7 ANIMATION AND PICTURE SHOWS.
We have seen how screens and windows can be stored and retrieved.
Animation is the act of putting pictures on the screen quickly enough
so that the eyes see something move. With 64K or 256K of memory whole
screens can be stored away, then put on the screen to produce animation.
You may have noticed in section 4 that when a screen loads onto the
screen, you can see each line appear. To illustrate, type in the
following program:-
10 MODE 1
20 BORDER 0
30 FOR col=0 TO 3
40 INK col,0
50 NEXT col
60 FOR col=0 TO 3
70 PAPER col : CLS
80 |SAVES,col+1
90 NEXT col
100 INK 0,1 : INK 1,6 : INK 2,21 : INK 3,13
110 PEN 1 : PAPER 0
120 WHILE INKEY$=""
130 FOR screen=1 TO 4
140 |LOADS, screen
150 NEXT screen
160 WEND
170 END
The program saves four coloured screens into bank RAM, then loads then up in
sequence. Unfortunately, the effect is a striped pattern.
Whenever the swap is made, the computer is told, and all further text and
graphics appear on the selected screen.
-11-
To use this facility of swapping from one screen to another instantly, the
screen and window commands can have an added parameter which tells the
computer to load or save the data to and from the alternate screen.
If the swap value is zero, by default, then the command will act on the
screen that is presently being displayed. Alternatively, if the value is
one the computer will load and save data from the screen which is not
being displayed. When the work is done, the computer can swap screens and
the effect is that the screen appears to change instantly.
Now that the computer can build up the screen while another is being
displayed there is no pattern. The coloured screen appears to change
instantly.
Due to the fact that the bank memory moves into the address space at 16K
it takes longer for the transfer of screens to be made to the low screen
than to the high screen. Hence line 135 delays the computer as it is to
load the high screen. This means the time each screen is on the screen
remains the same. Try removing line 135 to see the difference.
If a longer delay were to be put between line 140 and 150 you would get
a picture show effect. Alternatively, you could select screens when a
key is pressed.
Note, that of less use is the fact that the contents of screens and
windows can be saved from a screen which is not on display simply by
adding a one for the swap parameter. For example if you want to load a
series of screens from tape or disc, load them into the low (16K)
screen. Messages generated by the tape system need not be switched off as
the screen's contents will not be changed in the low memory screen.
The above will load a screen then save it to bank 3. The screen the user
sees can have something else on it.
-12-
1.8 ADVANCED PROGRAMMING.
This section introduces one new command and some other programming
aspects which you may find useful.
The command allows certain constants to be found by the program you are
writing. For example it can return the number of banks available to the
program as this will change depending on whether you are using the 64K
RAM pack or the 256K RAM pack. The 'enquiry' value is a number 1 to 3 which
selects what you want to know. The answer is placed in an INTEGER variable
defined by the second parameter.
The last command can be used to make sure the RAM is there and ready to
use if in your programs you do not want to have to load the RSX loader
first. It is possible to load just the RSX machine code on its own:-
The program above will load the RSX machine code and put it into
memory. Nothing will be printed on the screen unless the RAM proves to be
faulty or not even there! The program 'part2' would be the bulk of the
program. Loading the program in two parts saves reloading the RSX code
every time the program is run.
-13-
If you want to use user defined graphics then add the following lines:-
The value in line 150 will be different depending on how many user
defined graphics you want.
If you have a program that defines the character set, the definitions
can be saved and loaded into bank RAM so that a program may have
multiple character sets.
10 SYMBOL AFTER 0
20 chars=HIMEM+1
30 REM define symbols here
1000 SAVE "set1.grp", B, chars, 2048
This program will save your character set onto disc or tape.
10 SYMBOL AFTER 0
20 chars=HIMEM+l
30 LOAD "set1,grp", chars : |SAVED, 1, chars, 2048, 0
40 LOAD "set2.grp", chars : |SAVED, 1, chars, 2048, 2048
50 LOAD "set4.grp", chars : |SAVED, 1, chars, 2048, 4096
Note that the variable 'set' is used. In the above loading sequence sets
1 to 3 will be valid. More or less could be added as it suits you.
All of this setting up can be done on the loader program, just once. When
the program is subsequently run, there is no need to reload the bank RAM.
The setting of chars can be found whenever needed by:-
This will remove any disc buffers that have been set up and 'chars' will
indeed point to the characters.
-14-
1.9 PEEKING AND POKING.
There are two commands which allow the memory in the banks to be
viewed and changed byte by byte.
|POKE works in a similar way to the original POKE. You need to supply a
bank number in addition to the normal address and value. The bank
address is in the range 0 to 16383 or 0 to 16K.
|PEEK is a command rather than the normal function. The bank and bank
address are the same as for |POKE. To find out the value, you need to
supply an integer variable in a similar way to the |ASKRAM command.
For example:-
10 value%=0
20 |PEEK, 3, 12345, @value%
30 PRINT value%
The above will read the byte from location 12345 in bank number 3. The @
character tells the RSX extension where the variable is in memory so that
its contents can be changed to the byte required.
|PEEK and |POKE are not really commands for the beginner, in fact they
have only been included for the more advanced programmer who wishes to
use the bank RAM in his own way.
Another advanced command which has been included for the experienced
programmer is |BANK.
Make sure you are accustomed to using |BANK, |POKE and |PEEK before you
risk creating a large program using them. Save the program frequently
in case you make a mistake and lose your work.
-15-
1.10 PROGRAMMING WITHOUT RSX's.
With no RSX software the programmer can still access the memory from the
RAM banks. To use the RAM yourself, some degree of understanding of the
memory map of the Amstrad is necessary.
From both BASIC and machine code, the original block of memory from
16384 to 32767 CANNOT be used for program. Hence in BASIC, you need to set
the top of memory to 16383. Machine code is free to use any memory that it
can normally except the block mentioned.
For 64K expansions the banks are 0 to 3. On the 256K, bank numbers are 0 to
15.(bank 0-3 = 196-199:bank 4-7 = 204-207 etc.)
-16-
1.11 T ECHNICAL DETAILS.
The software which loads from tape is relocatable. However the areas of
memory in which the program can go is limited to between 32768 and the top
of memory. This is because the banked RAM appears in the block 16384 to
32767. (See previous chapter for explanation of why!) Below the 16K
boundary, the RSX command table will no longer function. Hence, during
relocation, the code is loaded at 10000 in memory and moves to a place
higher in memory. Pressing <ENTER> while loading, will automatically
select the highest location available. Alternatively you may wish to load
the code to a lower address and reserve some space for your own programs.
The software on the cassette is NOT protected. Hence to save it onto disc
or even onto another tape at speed write 1 is a matter of loading the data
into memory, then saving it.
Boot up CP/M 2.2 that has CLOAD.COM on it. Copy the two programs NEWCPM.COM
and OLDCPM.COM from cassette to disc by typing:-
CLOAD "NEWCPM.COM <enter>.(Repeat for OLDCPM.COM)
Then create a new CP/M system file by typing:-
A> MOVCPM 255 * <enter>
A> SAVE 34 NEWCPM.SYS <enter>
The new working disc now contains your increased TPA CP/M, invoked at
any time by typing:-
A> NEWCPM
You can return to the original CP/M by typing:-
A> OLDCPM
This must be done before using some of the DFS utilities such as
format etc. as these will only work with OLDCPM.
The RAM expansion is compatible with the banked RAM supplied with the
6128. This means that a number of programs written for the 6128 will now
work on the CPC464. The RSX software provided will work on the 6128 where
the 256K pack will give 320K of banked RAM.
The bank switching software in its supplied state will only access 256K
or 16 banks of memory. If you add more memory or have the CPC6128 with a
256K memory pack, the RSX software can be told to access a full 512K of
banked memory (32 banks) by poking location 10006 with 1. See section 8 for
explanation of how to load the RSX software on its own.
-17-
If a commercial program fails to work on your CPC464 or CPC664 then try the
suggestions below.
1) The software may be using the new firmware vector at &BD58. If this is
the case, try running the RSX program before running your application
program.
Some programs which will function correctly after the RSX software
tape has been loaded in are Tasman's Tasword(R) word processor, Tasspell
and Tasprint for the C PC6 12 8 . In conjunction with these, Campbell
Systems' Masterfile 128 will provide a 64K filespace and interfaces with
Tasman's software.
Any programs that call the ROM identity routine will now be informed
that the computer is a CPC6128 and may now work correctly.
3) The software may use some features of the CPC6128 ROM which are
unavailable on the CPC464 and CPC664 machines. In this instance, you may
be able to get information on how the program can be altered to work on the
CPC464 or 664 from the manufacturers of the program in question.
CP/M 2.2 as supplied with all Amstrad computers will function as normal
with the extra memory fitted. However if you create and use the NEWCPM
program the TPA on C P/ M 2. 2 will be increased to 61K.
Programs of your own devising written under this operating system are free
to use the extra memory. See section 1.10 for details of how to use the
extra memory from machine code.
While you are using the RSX software, there will be some occasions when
the computer does not understand, or cannot carry out what you have
instructed. The software may issue some error messages in addition to
the normal messages that the computer will give. The errors and why
they are likely to occur are outlined below:-
-18-
3) Bad bank parameter You have referenced a bank which can
never be fitted to the computer.
4) Bad bank address The address you have given is out of
range: bank addresses range from 0 to
16383.
5) Value invalid The bank address may be too large for
the block of data defined. The
parameter for |ASKRAM is other than
1, 2 or 3. The size of a block to be
saved is larger that 16K.
6) Bad window definition The window referenced in |SAVEW or
|LOADW is above 7.
SCREENS.
|SAVES, [ bank ], [ swap ]
|LOADS, [ bank ], [ swap ]
WINDOWS.
|SAVEW, [ window number], [ bank ], [ bank address ], [ swap ]
|LOADW, [ window number], [ bank ], [ bank address ], [ swap ]
DATA BLOCKS.
|SAVED, [ bank ], [ start location ], [ length ], [ bank address ]
|LOADD, [ bank ], [ start location ], [ length ], [ bank address ]
ANIMATION.
|LOW (Low screen)
|HIGH (High screen)
|SWAP (Alternate between High and Low screens)
OTHER.
|POKE, [ bank ], [ bank address ], [ value ]
|PEEK, [ bank ], [ bank address ], [ variable ]
|BANK, [ bank ]
|ASKRAM, [ enquiry ], [ variable ]
([ enquiry ]: 1 = RAM, 2 = banks, 3 = error occurred?)
DEFINITIONS.
-19-
[ swap ] 0 or omitted means act on present
screen, 1 means act on alternate
screen.
[ start location ] and [ length] Define a block of original memory.
[ variable ] Give the location of an integer
variable to be assigned, for example
@b%.
These interfaces add either a single block (64K) or four blocks (4 x 64K)
of RAM to an existing CPC464, 664 or 6128. Thus, if 64K (one block)
is added to a 464, the total memory is two blocks, 128K.
For a given setup, calculate the total number of 64K blocks, this will
determine which of the block select codes mentioned later are relevant
to your system. The blocks are referred to by number: block one is the
original 64K, block two is equivalent to the second block present in the
6128, and so on.
Memory is actually switched in and out of the 64K Z80 address space in 16K
sub blocks (as are the ROMS). Which particular combination of the original
four 16K sub blocks used, and any 'new' sub blocks from RAM beyond the
original 64K, is called the memory map. The map is determined by an 8-bit code
byte sent to the gate array control port, &7F00, with the two top bits set
to 1. The following description of the codes refers only to the remaining six
bits, D5-D0.
Control Codes.
Bits D2-D0 control the way 16K sub blocks are arranged in the Z80
memory space, bits D5-D3 control selection of whichever 'new' 64K
block is to be used.
These bits select one of the eight maps into the 64K as follows:-
CODE 0 1 2 3 4 5 6 7
SUB BLOCK
C000-FFFF 3 3* 3* 3* 3 3 3 3
8000-BFFF 2 2 2* 2 2 2 2 2
4000-7FFF 1 1 1* 3 0* 1* 2* 3*
0000-3FFF 0 0 0* 0 0 0 0 0
The numbers 0, 1, 2, 3 refer to the four 16K sub blocks in a 64K block in the
obvious way. The star (*) indicates that the memory is from a 'new' block, i.e.
block 2 or higher, otherwise the 'original', block 1, is implied.
Thus, code 0 selects the original, unmapped 64K, code 2 selects a completely
new block of 64K, the other codes are a mixture.
-20-
Notes.
2. The VDU circuitry always reads from the original 64K (block 1),
independently of the code.
3. If code 3 is used, reads from &4000 to &7FFF, on CPC 464 and 664 machines,
will only return the correct data if the upper ROM is disabled. This is at
variance with CPC 6128 operation, but is unlikely to be a significant
difference.
D5 D4 D3 BLOCK.
0 0 0 2 (ie, 'new' memory sub blocks came from block 2, as
in CPC 6128.
0 0 1 3
0 1 0 4
0 1 1 5
Which of the above codes are relevant to your machine depends on total memory
(see previous remarks).
Notes.
2. Bits D5, D4, D3 above 'count up' as blocks are selected. This may assist the
programmer.
3. If 2x256K memory expanders are fitted to the machine, and option links are
set appropriately, all patterns on D5-D3 can be used giving a maximum of 512K
extra memory. (The memory that is used for a 256K silicon disc is correctly
mapped to provide the extra 256K to give 512K total!)
-21-
1.15 CUSTOMIZING YOUR CP/M+ SYSTEM DISC.
Converting A 464 Keyboard Scan To That Of A 6128.
Some CP/M+ programs will not run correctly on the 464 computer because of the
way the 6128 scans the keyboard.
The following program and instructions convert (fool) CP/M+ into thinking that
it is running on a 6128.
1. Make a working copy of both sides of your system disc (sides 1 and 2).
a) Use your standard CP/M 2.2 System disc and type '|CPM'
b) For Single drive systems use DISCCOPY. For dual drives use COPYDISC.
(Remember to do both sides).
c) Put your original system disc away in a safe place to keep as a backup
in case your working disc is damaged.
3. Reset the machine, then enter CP/M+. Only one drive is necessary but
if you have two you may wish to disconnect the second drive because all the
changes are to be made on the working disc and with a single drive the
computer can use both sides.
ED PATCH.ASM
i
ORG 100H
XRA A
STA 0FDEFH
JMP 0000
END
<control z> DO NOT PRESS ENTER!
e
ED PROFILE.SUB
i
PATCH
<control z> DO NOT PRESS ENTER!
e
(now insert the disc containing MAC.COM)
-22-
B:MAC PATCH
B:HEXCOM PATCH
ERA PATCH.HEX
ERA PATCH.SYM
ERA PATCH.PRN
ERA PATCH.ASM
5. It is possible to alter the CP/M+ disc to boot up without loading the BANK
program first. Type the following if you want your system disc altered
in this way:-
B:SAVE
B:SID C10CPM3.EMS
S1E0
C9
<control c> DO NOT PRESS ENTER!
C10CPM3.EMS
Y
100
6500
-23-