Значок ресурса

SuperCAT

Нет прав на скачивание
Автор: Toni Baker
Год: 1987
Издатели: ZX Computing
Языки: 🇬🇧 Английский
Формат: 📼 TAP лента
Требования: 🖥️ ZX Spectrum 128K

Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing

Скриншоты:
0025962-run-1.png


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.
Автор
Verter_bot
Загрузки
0
Просмотры
9
Расширение
zip
Размер
827 байт
Хэш
9ab0c9e077cc1315395cb6dbb7b5d74d
Первый выпуск
Последнее обновление

Оценки

0.00 звезд(ы) 0 оценок
Назад
Вверх