Автор: Toni Baker
Год: 1987
Издатели: ZX Computing
Языки:
Английский
Формат:
TAP лента
Требования:
ZX Spectrum 128K
Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing
Скриншоты:
Год: 1987
Издатели: ZX Computing
Языки:
Формат:
Требования:
Ссылки:
Скриншоты:
INTO THE 128
by Toni Baker
from ZX Computing May 1987
Toni Baker begins a series exploring the secrets
of the 128, and starts by proving that you can
switch between 48 and 128K modes at will.
[The RANDOMIZE USR 32814 function to switch to 128 mode doesn't work. ]
[I've tried entering 48k mode from the menu, from the SPECTRUM command,]
[and from RANDOMIZE USR 32781 (which works); but whichever way I get to]
[48k mode, trying to enter 128k mode with RANDOMIZE USR 32814 always ]
[crashes. The call address 32814(802Eh) is correct and the code matches]
[the listing, so there must be an error in the listing. JimG]
Welcome to the first of a new five part series [only two parts were
printed, as ZX Computing ceased publication after the June 1987 issue]
on the 128K versions of the Spectrum (ie. both the Spectrum 128 and
the 128+2) from a machine code perspective. In this series I intend to
cover all aspects of the new machines where they differ from the old
16K and 48K machines. I'll be going through all the special features
and explaining how you can access them from machine code.
First of all, the most obvious feature of the 128 is its large memory.
In fact it now has 32K of ROM and 128K of RAM, making 160K in all -
quite a phenomenal amount really. This memory is organised in what are
called pages, a page being simply a chunk of continuous memory. On the
128 there are two pages of ROM and eight pages of RAM, and each page
contains exactly 16K of memory. Hence we have 2*16 = 32K of ROM, and
8*16 = 128K of RAM altogether.
Traditional machine codists will be aware that on the 48K Spectrum the
memory was continuous and occupied all addresses from 0000 to FFFF
inclusive (with 0000 to 3FFF being ROM and the rest RAM). It is clear,
however, that if we want to address more memory than was allowed on
the 48K then four hexadecimal digits is simply not enough. To address
the vast banks of memory on the 128 we need not four but FIVE
hexadecimal digits, so we can have addresses like 12345h or 7CDEF. To
see how all this works let's first look at the ROM.
A ROM with a view
There are two pages of ROM, and each page contains 16K. The first page
is numbered (not surprisingly) from 00000 to 03FFF inclusive. This is
known as ROM zero, and may be colloquially referred to as "The NEW
ROM". When the machine is first switched on or the RESET button
pressed then control begins at the very start, at address 00000. This
"New ROM" is in fact totally new and is not present on 16K and 48K
machines.
The second page of ROM is numbered from 10000h to 13FFF. This is
called ROM one, and is sometimes referred to as "The OLD ROM".
Although a few changes have been made this is, essentially, the
original ROM which was present on 16K and 48K machines. Notice that
the numbering of the ROMs is not continuous (ie. there is a gap
between the end of ROM 0 (03FFF) and the start of ROM 1 (10000h)).
The next task is to see how all this ties in with machine code. You
are probably aware that all machine code instructions are designed for
an address range using only four hex digits, not five. For instance
CALL xxxx is allowed but CALL xxxxx is not. Instructions like LD
A,(HL) or JP (HL) may at first glance seem like a way round the
problem, but then you have to remember that HL itself (as with all
register pairs) can only hold values between 0000 and FFFF, which
leaves us back at square one.
The solution is actually very simple. An instruction like CALL 1234h
can mean either CALL 01234h or CALL 11234h depending on which of the
ROMs is paged in. You can visualise this by imagining that only one of
the two ROMs is allowed in at a time. Either of the ROMs (but never
both) may be present in memory at any one time. If ROM 0 is present
then we say that ROM 0 is paged in. If ROM 1 is present then we say
that ROM 1 is paged in. Whichever of the ROMs is paged in (since one
of them must be at all times) is referred to as the current ROM, or
the current ROM page. Thus the current ROM will invariably be either 0
or 1 - this supplies the first digit [of] all ROM addresses. The
remaining four digits may be handled in machine code as normal.
Since there are only two ROMs and no more, addresses such as A1234
cannot exist. I have, however, heard of the Shadow ROM of the ZX
Interface One being referred to as ROM two, in which case maybe
addresses 20000h to 21FFF could refer to the Shadow ROM, but this is
non-standard so I won't go into it in any detail.
On the RAM PAGE
Having dealt with ROM addresses it is now time to deal with RAM.
Addresses in RAM are all between 0000 and FFFF, and as with the ROMs,
only one page of RAM may be paged in at any one time. The pages of RAM
are numbered from zero to seven, so this means that RAM addresses all
lie in one of the ranges 0C000 to 0FFFF, 1C000 to 1FFFF, 2C000 to
2FFFF, 3C000 to 3FFFF, 4C000 to 4FFFF, 5C000 to 5FFFF, 6C000 to 6FFFF,
or 7C000 to 7FFFF. Whichever of the RAM pages is paged in is referred
to as the current RAM, or the current RAM page. The current RAM page
wIll be a digit between 0 and 7 - this supplies the first digit of all
RAM addresses, The remaining four digits may be handled in machine
code as normal.
Having established that all addresses between x0000 and x3FFF are in
ROM, and that all addresses xC000 to xFFFF are in RAM, (where x refers
to the relevant page number) this leaves us with a gap. What about
addresses 4000 to BFFF?
The answer is a kind of shorthand. The address range between 4000h and
BFFF is split up into two 16K chunks, ie. 4000h to 7FFF and 8000h to
BFFF. The first chunk is shorthand for RAM page five, and the second
chunk is shorthand for RAM page two.
In other words, 4000h means precisely the same thing as 5C000. (Also,
5000h means 5D000, 6000h means 5E000 and 7000h means 5F000, etc). This
means that, in effect, page five is permanently paged in, though with
a modified addresses range.
In similar fashion, 8000h means the same thing as 2F000, etc. So page
two is also effectively permanently paged in, again with a modified
address range.
As well as being a shorthand method of accessing two of the eight RAM
pages, we also now have an illusion of continuity - and this is the
marvellous trick which makes the 128 compatible with the 48K machine.
You see, we now have the situation whereby every single (four digit)
address from 0000 all the way up to FFFF now actually means something.
At every such address there is memory available, with 0000 to 3FFF
being ROM and the rest being RAM. We now have the appearance of a
continuous stretch of RAM from 4000h all the way up to FFFF. This is a
48K illusion, but it makes the thing compatible with other Spectrums,
and is jolly useful for machine codes.
Page to Page
The next thing you'll need to know is how to change pages; that is,
how to specify which ROM page and which RAM page is to be paged in.
The answer comes in the form of an OUT instruction. Output port number
7FFD is the key to the thing. You can think of it almost like an extra
register or memory location, in that it can store a value between 00
and FF. Like a memory location you can assign it with a new value,
but, unlike a memory location it is impossible ever to read its value.
There is essentially only one way of writing to this port in machine
code. The sequence of instructions:
LD BC,7FFD
LD A,??
OUT (C),A
(You can of course swap the order of the first two instructions).
It is this port which PAGES IN the various ROM and RAM pages. Take a
look at figure One. This shows the meanings of the individual bits of
port 7FFD. As you can see, bits two to zero specify the RAM page while
bit four specifies the ROM page. I'll come to the meanings of the
other bits later on.
There is, of course, one major problem with port 7FFD. Because you
cannot read from this port it is impossible to actually determine
which ROM or RAM page is currently paged in at any moment in time. For
this reason the Spectrum 128 keeps a back-up copy of the value of port
7FFD in one of its new system variables. The system variable is called
BANK-M. Its address is 5B5C. Because of this back-up copy reading
(BANK-M) will tell you what is paged in and what isn't. It also means,
however, that whenever you change page by writing to port 7FFD then
you must also store the value in BANK-M, or else the ROM may cause a
crash.
In fact, the Spectrum 128's interrupt routines (which lie at addresses
00038 and 10038) actually require that bit four (at least) of BANK-M
be accurate. This means that interrupts must be disabled whilst
changing ROMs. Furthermore, on leaving the interrupt routine the value
in (BANK-M) is output to port 7FFD, so if they didn't match before,
they certainly will afterwards. The upshot of all this is that if you
want to change RAM page (or screen - but more of that later) then
either interrupts must be disabled throughout the change, or (BANK-M)
must be loaded first and port 7FFD loaded second. If you get this the
wrong way round then you'll get a crash the first time an interrupt
occurs between the two instructions.
Screen display
As with the 48K Spectrum the screen is stored at address 4000h. As
I've already stated this is the same thing as 5C000 (ie. address C000
on RAM page five). The Spectrum 128, however, has not one but two
screens, though this isn't obviously mentioned in the instruction
manual.
Both of the 128's screens are memory mapped, but obviously only one of
them can ever be visible on the TV at any one time. The normal screen
which appears all of the time under normal circumstances is called
SCREEN ZERO, but there is also an alternative screen, called SCREEN
ONE, which is stored at address 7C000 (ie. address C000 on RAM page
seven).
If one of these screens is visible on the TV then it is said to be
ACTIVE. Normally screen zero is active at all times and screen one is
never active; however, you can change this from machine code by
setting bit three of (BANK-M) and output port 7FFD (see Figure 1
[IN1_1.GIF]). What's more, it makes no difference if a different RAM
page is paged in. For instance, screen one is stored on RAM page
seven. Suppose we made screen one active by setting bit three of
(BANK-M) and subsequently outputting the value to port 7FFD. This
would mean that the contents of screen one would be visible on the TV.
The pixels of screen one are stored at addresses 7C000 to 7D7FF;
whilst the attributes are stored at addresses 7D800 to 7DAFF. It is
clear that page seven must be paged in, in order to change the
contents of screen one. However, it is not necessary for page seven to
be paged in, in order for screen one to be active. Any RAM page may be
paged in, and screen one would still be visible as long as it remained
active. Only by activating screen zero can screen one be made to
vanish from the TV.
Surprisingly, it turns out that you can change the current screen in
BASIC without having to use machine code at all. The BASIC instruction
POKE 23388,24 will activate screen one, whereas POKE 23388,16 will
activate screen zero (and so deactivate screen one). If you try this
then all you'll get is a black TV picture since all the attribute
bytes contain zero. Unfortunately, it is not possible to print
anything onto screen one from BASIC - machine code is a must here.
Still - the technique can be useful. If your BASIC program contains
the three instructions:
POKE 23388,24: LOAD SCREEN$: POKE 23388,16
Then the TV will appear to go blank whilst a file is loaded from tape.
When the loading is complete the finished picture will appear on the
TV instantaneously!
Another useful point to note is that any error report message
generated by a BASIC program (including 0:OK) will automatically
re-activate screen zero, so if you forget to switch screen one off
then the Speccy will do it for you.
Port
There is one more bit from port 7FFD which is used. This is bit five,
which in 128K mode must always be RESET. If this bit is set then the
machine "locks" in 48K configuration (ie. with ROM 1 permanently paged
in, RAM page zero permanently paged in, and screen zero permanently
active). Setting bit five of (BANK-M), however, is not in itself
sufficient to enter 48K mode, because the machine stack will contain a
few "return addresses" which were intended to refer to ROM 0, and once
the machine is locked ROM 0 cannot be paged in.
The 128 contains two new BASIC commands - PLAY and SPECTRUM. The more
complicated PLAY I shall leave until part five of this series, but
SPECTRUM I can deal with now. The effect of typing the command
SPECTRUM is twofold: firstly, the machine goes into 48K mode; and
secondly the error report 0:OK is produced, stopping any program in
its tracks.
Page thirty of the Spectrum 128+2 manual tells us, and I quote, "Once
in 48K BASIC mode, there is no way back to 128 BASIC mode apart from
resetting the +2 (or switching off, then on again)." The same is also
true of the ordinary Spectrum 128. The program which accompanies this
article, however, will do just that! It is now possible to switch
between 48K mode and 128K mode at will! Here's how it's done.
Mode switching
First, switch the machine on (or reset it) and select "128 BASIC" from
the main menu. You may then type SPECTRUM if you wish, but the program
will not work if you select "48 BASIC" from the main menu. CLEAR 32767
will ensure that the program remains safely above RAMTOP. LOAD the
program which I have listed. You now have two additional commands at
your disposal:
RANDOMIZE USR 32781
is similar to the command SPECTRUM, in that it will cause the machine
to enter 48K mode. However, it will do so without generating the
report 0:OK, so that program execution may continue from the next
statement. To complement this the command
RANDOMIZE USR 32814
will re-enter 128K mode, and will again continue from the next BASIC
statement. Whilst all this sounds nice and cozy, please bear in mind
that there are rules to follow: NEVER use the command COPY whilst in
48k mode; NEVER use LPRINT or otherwise print to channel "P" (normally
stream three) whilst in 48K mode; and NEVER place any code into the
printer buffer. The reason for these restrictions is that the printer
buffer is used by the Spectrum 128 to store new system variables and
subroutines. Corrupting the printer buffer would truly make a return
to 128K mode impossible.
This new arrangement, however, has tremendous advantages for people
who own a Spectrum 128 with a real printer plugged into the RS232
socket - especially if they don't own an Interface One - for it now
becomes possible to use the printer in 48K mode after all.
Firstly you must set the BAUD rate. This can only be done in 128K mode
using the command FORMAT "P",N. Then you can type either SPECTRUM or
RANDOMIZE USR 32781 to enter 48K mode, Now to print anything onto your
printer all you have to do is include the following statements in your
program:
RANDOMIZE USR 32814: LPRINT (anything): RANDOMIZE USR 32781
As it happens, the program is relocatable too, except that there is
one absolute reference to the label SWAP-2, and another to label
P-128. Both of these must be changed if you wish to relocate the
program.
There is just one other aspect I want to discuss in this article. The
Plus 2 comes complete with two little joystick sockets, and it is
useful to know how to read the joysticks from machine code. To read
from JOYSTICK 1 you must input a byte from port EEFE. Figure 2
[IN1_2.GIF] will show you how to interpret that byte. Each bit will
normally be set, but will be reset if the joystick is in use and
corresponds to the correct direction.
To read the JOYSTICK 2 you must input a byte from port F7FE. Figure 2
will again show you how to interpret that byte. The machine code
sequence LD BC,F7FE / IN A,(C) will input the byte into the A
register.
In the next article in this series I shall tell you all about page
codes, and the Spectrum's "Silicon disc" file storage system. See you
then.
by Toni Baker
from ZX Computing May 1987
Toni Baker begins a series exploring the secrets
of the 128, and starts by proving that you can
switch between 48 and 128K modes at will.
[The RANDOMIZE USR 32814 function to switch to 128 mode doesn't work. ]
[I've tried entering 48k mode from the menu, from the SPECTRUM command,]
[and from RANDOMIZE USR 32781 (which works); but whichever way I get to]
[48k mode, trying to enter 128k mode with RANDOMIZE USR 32814 always ]
[crashes. The call address 32814(802Eh) is correct and the code matches]
[the listing, so there must be an error in the listing. JimG]
Welcome to the first of a new five part series [only two parts were
printed, as ZX Computing ceased publication after the June 1987 issue]
on the 128K versions of the Spectrum (ie. both the Spectrum 128 and
the 128+2) from a machine code perspective. In this series I intend to
cover all aspects of the new machines where they differ from the old
16K and 48K machines. I'll be going through all the special features
and explaining how you can access them from machine code.
First of all, the most obvious feature of the 128 is its large memory.
In fact it now has 32K of ROM and 128K of RAM, making 160K in all -
quite a phenomenal amount really. This memory is organised in what are
called pages, a page being simply a chunk of continuous memory. On the
128 there are two pages of ROM and eight pages of RAM, and each page
contains exactly 16K of memory. Hence we have 2*16 = 32K of ROM, and
8*16 = 128K of RAM altogether.
Traditional machine codists will be aware that on the 48K Spectrum the
memory was continuous and occupied all addresses from 0000 to FFFF
inclusive (with 0000 to 3FFF being ROM and the rest RAM). It is clear,
however, that if we want to address more memory than was allowed on
the 48K then four hexadecimal digits is simply not enough. To address
the vast banks of memory on the 128 we need not four but FIVE
hexadecimal digits, so we can have addresses like 12345h or 7CDEF. To
see how all this works let's first look at the ROM.
A ROM with a view
There are two pages of ROM, and each page contains 16K. The first page
is numbered (not surprisingly) from 00000 to 03FFF inclusive. This is
known as ROM zero, and may be colloquially referred to as "The NEW
ROM". When the machine is first switched on or the RESET button
pressed then control begins at the very start, at address 00000. This
"New ROM" is in fact totally new and is not present on 16K and 48K
machines.
The second page of ROM is numbered from 10000h to 13FFF. This is
called ROM one, and is sometimes referred to as "The OLD ROM".
Although a few changes have been made this is, essentially, the
original ROM which was present on 16K and 48K machines. Notice that
the numbering of the ROMs is not continuous (ie. there is a gap
between the end of ROM 0 (03FFF) and the start of ROM 1 (10000h)).
The next task is to see how all this ties in with machine code. You
are probably aware that all machine code instructions are designed for
an address range using only four hex digits, not five. For instance
CALL xxxx is allowed but CALL xxxxx is not. Instructions like LD
A,(HL) or JP (HL) may at first glance seem like a way round the
problem, but then you have to remember that HL itself (as with all
register pairs) can only hold values between 0000 and FFFF, which
leaves us back at square one.
The solution is actually very simple. An instruction like CALL 1234h
can mean either CALL 01234h or CALL 11234h depending on which of the
ROMs is paged in. You can visualise this by imagining that only one of
the two ROMs is allowed in at a time. Either of the ROMs (but never
both) may be present in memory at any one time. If ROM 0 is present
then we say that ROM 0 is paged in. If ROM 1 is present then we say
that ROM 1 is paged in. Whichever of the ROMs is paged in (since one
of them must be at all times) is referred to as the current ROM, or
the current ROM page. Thus the current ROM will invariably be either 0
or 1 - this supplies the first digit [of] all ROM addresses. The
remaining four digits may be handled in machine code as normal.
Since there are only two ROMs and no more, addresses such as A1234
cannot exist. I have, however, heard of the Shadow ROM of the ZX
Interface One being referred to as ROM two, in which case maybe
addresses 20000h to 21FFF could refer to the Shadow ROM, but this is
non-standard so I won't go into it in any detail.
On the RAM PAGE
Having dealt with ROM addresses it is now time to deal with RAM.
Addresses in RAM are all between 0000 and FFFF, and as with the ROMs,
only one page of RAM may be paged in at any one time. The pages of RAM
are numbered from zero to seven, so this means that RAM addresses all
lie in one of the ranges 0C000 to 0FFFF, 1C000 to 1FFFF, 2C000 to
2FFFF, 3C000 to 3FFFF, 4C000 to 4FFFF, 5C000 to 5FFFF, 6C000 to 6FFFF,
or 7C000 to 7FFFF. Whichever of the RAM pages is paged in is referred
to as the current RAM, or the current RAM page. The current RAM page
wIll be a digit between 0 and 7 - this supplies the first digit of all
RAM addresses, The remaining four digits may be handled in machine
code as normal.
Having established that all addresses between x0000 and x3FFF are in
ROM, and that all addresses xC000 to xFFFF are in RAM, (where x refers
to the relevant page number) this leaves us with a gap. What about
addresses 4000 to BFFF?
The answer is a kind of shorthand. The address range between 4000h and
BFFF is split up into two 16K chunks, ie. 4000h to 7FFF and 8000h to
BFFF. The first chunk is shorthand for RAM page five, and the second
chunk is shorthand for RAM page two.
In other words, 4000h means precisely the same thing as 5C000. (Also,
5000h means 5D000, 6000h means 5E000 and 7000h means 5F000, etc). This
means that, in effect, page five is permanently paged in, though with
a modified addresses range.
In similar fashion, 8000h means the same thing as 2F000, etc. So page
two is also effectively permanently paged in, again with a modified
address range.
As well as being a shorthand method of accessing two of the eight RAM
pages, we also now have an illusion of continuity - and this is the
marvellous trick which makes the 128 compatible with the 48K machine.
You see, we now have the situation whereby every single (four digit)
address from 0000 all the way up to FFFF now actually means something.
At every such address there is memory available, with 0000 to 3FFF
being ROM and the rest being RAM. We now have the appearance of a
continuous stretch of RAM from 4000h all the way up to FFFF. This is a
48K illusion, but it makes the thing compatible with other Spectrums,
and is jolly useful for machine codes.
Page to Page
The next thing you'll need to know is how to change pages; that is,
how to specify which ROM page and which RAM page is to be paged in.
The answer comes in the form of an OUT instruction. Output port number
7FFD is the key to the thing. You can think of it almost like an extra
register or memory location, in that it can store a value between 00
and FF. Like a memory location you can assign it with a new value,
but, unlike a memory location it is impossible ever to read its value.
There is essentially only one way of writing to this port in machine
code. The sequence of instructions:
LD BC,7FFD
LD A,??
OUT (C),A
(You can of course swap the order of the first two instructions).
It is this port which PAGES IN the various ROM and RAM pages. Take a
look at figure One. This shows the meanings of the individual bits of
port 7FFD. As you can see, bits two to zero specify the RAM page while
bit four specifies the ROM page. I'll come to the meanings of the
other bits later on.
There is, of course, one major problem with port 7FFD. Because you
cannot read from this port it is impossible to actually determine
which ROM or RAM page is currently paged in at any moment in time. For
this reason the Spectrum 128 keeps a back-up copy of the value of port
7FFD in one of its new system variables. The system variable is called
BANK-M. Its address is 5B5C. Because of this back-up copy reading
(BANK-M) will tell you what is paged in and what isn't. It also means,
however, that whenever you change page by writing to port 7FFD then
you must also store the value in BANK-M, or else the ROM may cause a
crash.
In fact, the Spectrum 128's interrupt routines (which lie at addresses
00038 and 10038) actually require that bit four (at least) of BANK-M
be accurate. This means that interrupts must be disabled whilst
changing ROMs. Furthermore, on leaving the interrupt routine the value
in (BANK-M) is output to port 7FFD, so if they didn't match before,
they certainly will afterwards. The upshot of all this is that if you
want to change RAM page (or screen - but more of that later) then
either interrupts must be disabled throughout the change, or (BANK-M)
must be loaded first and port 7FFD loaded second. If you get this the
wrong way round then you'll get a crash the first time an interrupt
occurs between the two instructions.
Screen display
As with the 48K Spectrum the screen is stored at address 4000h. As
I've already stated this is the same thing as 5C000 (ie. address C000
on RAM page five). The Spectrum 128, however, has not one but two
screens, though this isn't obviously mentioned in the instruction
manual.
Both of the 128's screens are memory mapped, but obviously only one of
them can ever be visible on the TV at any one time. The normal screen
which appears all of the time under normal circumstances is called
SCREEN ZERO, but there is also an alternative screen, called SCREEN
ONE, which is stored at address 7C000 (ie. address C000 on RAM page
seven).
If one of these screens is visible on the TV then it is said to be
ACTIVE. Normally screen zero is active at all times and screen one is
never active; however, you can change this from machine code by
setting bit three of (BANK-M) and output port 7FFD (see Figure 1
[IN1_1.GIF]). What's more, it makes no difference if a different RAM
page is paged in. For instance, screen one is stored on RAM page
seven. Suppose we made screen one active by setting bit three of
(BANK-M) and subsequently outputting the value to port 7FFD. This
would mean that the contents of screen one would be visible on the TV.
The pixels of screen one are stored at addresses 7C000 to 7D7FF;
whilst the attributes are stored at addresses 7D800 to 7DAFF. It is
clear that page seven must be paged in, in order to change the
contents of screen one. However, it is not necessary for page seven to
be paged in, in order for screen one to be active. Any RAM page may be
paged in, and screen one would still be visible as long as it remained
active. Only by activating screen zero can screen one be made to
vanish from the TV.
Surprisingly, it turns out that you can change the current screen in
BASIC without having to use machine code at all. The BASIC instruction
POKE 23388,24 will activate screen one, whereas POKE 23388,16 will
activate screen zero (and so deactivate screen one). If you try this
then all you'll get is a black TV picture since all the attribute
bytes contain zero. Unfortunately, it is not possible to print
anything onto screen one from BASIC - machine code is a must here.
Still - the technique can be useful. If your BASIC program contains
the three instructions:
POKE 23388,24: LOAD SCREEN$: POKE 23388,16
Then the TV will appear to go blank whilst a file is loaded from tape.
When the loading is complete the finished picture will appear on the
TV instantaneously!
Another useful point to note is that any error report message
generated by a BASIC program (including 0:OK) will automatically
re-activate screen zero, so if you forget to switch screen one off
then the Speccy will do it for you.
Port
There is one more bit from port 7FFD which is used. This is bit five,
which in 128K mode must always be RESET. If this bit is set then the
machine "locks" in 48K configuration (ie. with ROM 1 permanently paged
in, RAM page zero permanently paged in, and screen zero permanently
active). Setting bit five of (BANK-M), however, is not in itself
sufficient to enter 48K mode, because the machine stack will contain a
few "return addresses" which were intended to refer to ROM 0, and once
the machine is locked ROM 0 cannot be paged in.
The 128 contains two new BASIC commands - PLAY and SPECTRUM. The more
complicated PLAY I shall leave until part five of this series, but
SPECTRUM I can deal with now. The effect of typing the command
SPECTRUM is twofold: firstly, the machine goes into 48K mode; and
secondly the error report 0:OK is produced, stopping any program in
its tracks.
Page thirty of the Spectrum 128+2 manual tells us, and I quote, "Once
in 48K BASIC mode, there is no way back to 128 BASIC mode apart from
resetting the +2 (or switching off, then on again)." The same is also
true of the ordinary Spectrum 128. The program which accompanies this
article, however, will do just that! It is now possible to switch
between 48K mode and 128K mode at will! Here's how it's done.
Mode switching
First, switch the machine on (or reset it) and select "128 BASIC" from
the main menu. You may then type SPECTRUM if you wish, but the program
will not work if you select "48 BASIC" from the main menu. CLEAR 32767
will ensure that the program remains safely above RAMTOP. LOAD the
program which I have listed. You now have two additional commands at
your disposal:
RANDOMIZE USR 32781
is similar to the command SPECTRUM, in that it will cause the machine
to enter 48K mode. However, it will do so without generating the
report 0:OK, so that program execution may continue from the next
statement. To complement this the command
RANDOMIZE USR 32814
will re-enter 128K mode, and will again continue from the next BASIC
statement. Whilst all this sounds nice and cozy, please bear in mind
that there are rules to follow: NEVER use the command COPY whilst in
48k mode; NEVER use LPRINT or otherwise print to channel "P" (normally
stream three) whilst in 48K mode; and NEVER place any code into the
printer buffer. The reason for these restrictions is that the printer
buffer is used by the Spectrum 128 to store new system variables and
subroutines. Corrupting the printer buffer would truly make a return
to 128K mode impossible.
This new arrangement, however, has tremendous advantages for people
who own a Spectrum 128 with a real printer plugged into the RS232
socket - especially if they don't own an Interface One - for it now
becomes possible to use the printer in 48K mode after all.
Firstly you must set the BAUD rate. This can only be done in 128K mode
using the command FORMAT "P",N. Then you can type either SPECTRUM or
RANDOMIZE USR 32781 to enter 48K mode, Now to print anything onto your
printer all you have to do is include the following statements in your
program:
RANDOMIZE USR 32814: LPRINT (anything): RANDOMIZE USR 32781
As it happens, the program is relocatable too, except that there is
one absolute reference to the label SWAP-2, and another to label
P-128. Both of these must be changed if you wish to relocate the
program.
There is just one other aspect I want to discuss in this article. The
Plus 2 comes complete with two little joystick sockets, and it is
useful to know how to read the joysticks from machine code. To read
from JOYSTICK 1 you must input a byte from port EEFE. Figure 2
[IN1_2.GIF] will show you how to interpret that byte. Each bit will
normally be set, but will be reset if the joystick is in use and
corresponds to the correct direction.
To read the JOYSTICK 2 you must input a byte from port F7FE. Figure 2
will again show you how to interpret that byte. The machine code
sequence LD BC,F7FE / IN A,(C) will input the byte into the A
register.
In the next article in this series I shall tell you all about page
codes, and the Spectrum's "Silicon disc" file storage system. See you
then.