Question about Bank 2

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
XoRRoX
Manic Miner
Posts: 233
Joined: Wed Jul 11, 2018 6:34 am

Question about Bank 2

Post by XoRRoX »

Hello,

I've just recently started to mess about with 128k bank switching.

Am I correct when I say that Bank 0 is the default Bank paged at boot and can thus be freely translated (for my understanding) as "main memory"?

Regarding Bank 2: in the docs it says "also at 0x8000", which I discover to mean that everything you write to 49152 and up, will also appear at 32768 and up.

What surprises me though is that it seems that when switching back to Bank 0, whatever was also written to 32768 and up is not restored?

To test things, I created the following BASIC file:

Code: Select all

10 CLEAR 32767
15 REM Currently in Bank 0 - "Main Memory"
20 REM Print values at 32768 & 49152
30 GO SUB 160

40 REM Switch to bank 2
50 LET a=2+16
60 GO SUB 130

65 REM Put a value in bank, which will also be placed at shadow main RAM
70 POKE 49152,255

75 REM Print values at 32768 & 49152
80 GO SUB 160

85 REM Switch to bank 0 - main memory
90 LET a=0+16
100 GO SUB 130

105 REM Print values at 32768 & 49152
110 GO SUB 160
120 STOP

130 POKE 23388,a: OUT 32765,a
150 RETURN 

160 PRINT "23388: ";PEEK 23388: PRINT "32768: ";PEEK 32768: PRINT "49152: ";PEEK 49152: PRINT 
170 RETURN
Which outputs:

Code: Select all

23388: 16
32768: 0
49152: 0
 
23388: 18
32768: 255
49152: 255
 
23388: 16
32768: 255
49152: 0
When having switched to Bank 0, and thus having paged out Bank 2, I expect for the last value @ 32768 to be not 255 but 0 again.

What is going on here? :roll: :)

PS: the way I discovered this is because I had corruption of my code between 32768-49152, when writing to 49152-65535.
Hadn't the corruption not been in text printed on screen but somewhere in my code area, I'd probably never have discovered why my code would crash...
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Why you expect that value @32768 will change back to 0 ? You changed it to 255 (via mirror @49152) and never rewrite to anything else.
Proud owner of Didaktik M
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: Question about Bank 2

Post by Nienn Heskil »

XoRRoX wrote: Fri Jul 10, 2020 9:37 am in the docs it says "also at 0x8000"
That's just a fancy way of saying, 'we've also given some sort of "bank numbers" to the regular 48K memory areas you're used to, just to mess with you'. :)

When you switch the banks using port #7FFD on a 128K, it only affects what is mapped at [#C000;#FFFF]. But [#8000;#BFFF] is always bank 2, and [#4000;#7FFF] is always bank 5.
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Nienn Heskil wrote: Fri Jul 10, 2020 9:57 am
XoRRoX wrote: Fri Jul 10, 2020 9:37 am in the docs it says "also at 0x8000"
That's just a fancy way of saying, 'we've also given some sort of "bank numbers" to the regular 48K memory areas you're used to, just to mess with you'. :)
No it's not. It is really what it says: you have 128k of memory, accessible through three 16K windows , first two windows are fixed, third can be selected to view any of eight 16K pages.
Proud owner of Didaktik M
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: Question about Bank 2

Post by Nienn Heskil »

catmeows wrote: Fri Jul 10, 2020 10:05 am
Nienn Heskil wrote: Fri Jul 10, 2020 9:57 am That's just a fancy way of saying, 'we've also given some sort of "bank numbers" to the regular 48K memory areas you're used to, just to mess with you'. :)
No it's not. It is really what it says: you have 128k of memory, accessible through three 16K windows , first two windows are fixed, third can be selected to view any of eight 16K pages.
How do I access the 128K of memory through the first two windows if they are fixed..? I'm sorry, that makes no sense. You're saying something similar to, "Any customer can have a car painted any color that he wants so long as it is black".
AndyC
Dynamite Dan
Posts: 1406
Joined: Mon Nov 13, 2017 5:12 am

Re: Question about Bank 2

Post by AndyC »

Nienn Heskil wrote: Fri Jul 10, 2020 11:05 am
catmeows wrote: Fri Jul 10, 2020 10:05 am No it's not. It is really what it says: you have 128k of memory, accessible through three 16K windows , first two windows are fixed, third can be selected to view any of eight 16K pages.
How do I access the 128K of memory through the first two windows if they are fixed..? I'm sorry, that makes no sense. You're saying something similar to, "Any customer can have a car painted any color that he wants so long as it is black".
There are eight 16K banks of memory. The first two windows will always show the same two banks (2 & 5). Changes made in that part of the address space will therefore always affect those banks. The third window can show any of the eight banks, giving access to the full 128K through a 16K window.

If you access bank 2 through the third, pagable window, then you will see exactly the same changes reflected in that bank via the lower window, i.e. changing the byte at #C000 will appear to change the same value at #4000. Likewise changing the byte at #4000 will change the value also seen at #C000.
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Well, that is little bit complicated.

As everybody knows, Z80 can address 65536 bytes using 16-bit address bus. So CPU just says: "hey, mem, please could you give me byte at XXXX ?" And memory answers: "Sure, here it is." Right ?
Except this is not how it is working. Because you have ROM memory, which is different chip than RAM memory chip. So how it really works ?

In ZX, you have CPU, ULA, memory and some glue logic. Except I have just said, that you have CPU, ULA, ROM, RAM and some glue logic. What is the glue logic for ? It does a lot of things and one of that things is that it decodes memory (together with ULA).

ZX Spectrum 16K has two memory chips: 16K ROM and 16K RAM. Whenever CPU asks something from memory, the address is taken.
If address is from range $0000 - $3FFF, which means the two highest bits of address are '00' (i.e. address 00xxxxxx xxxxxxxx), it is the ROM chip what is activated and the lower 14 bits are used to address a byte from 16K of ROM.
If address is from range $4000 - $7FFF, which mean two highest bits of address are '01', it is the 16K RAM what is activated and the lower 14 bits are used to point into 16K RAM chip.

ZX Spectrum 48K has three memory chips: 16K ROM, 16K RAM and 32K RAM. Address decoding is same for 16K model, but if adresss is in range $8000-$FFFF, (i.e. highest bit is '1') then it is the 32K RAM chip activated and lower 15 bits are used to point 32K RAM.

ZX Spectrum 128 has again three memory chips: 32K ROM and two 64K RAM chips. Which means there is no such thing like good old 48K memory. Let's name the RAM chips A and B. For access to $4000 - $7FFF, fixed position on chip A is accessed, just 16K window. For access to $8000 - $BFFF, fixed position on chip B is accessed, just 16K window.
And now, for access to $C000 - $FFFF, the address is computed from lower 14bits on address bus and the page bits in ULA - that three paging bits select which of the chips A and B is used, and where is the 16K window on chip.

Note that 3 ULA bits + 14 address bus bits are together 17 bits and that is why you can address 128K instead of 64K.
Proud owner of Didaktik M
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: Question about Bank 2

Post by Nienn Heskil »

AndyC wrote: Fri Jul 10, 2020 11:39 am The first two windows will always show the same two banks (2 & 5). Changes made in that part of the address space will therefore always affect those banks.
In which case, why even bring that up? /o This is, at best, obscure implementation details that has no practical meaning from a programmer's perspective. You can just say '16384-49151 behaves exactly the same as on a 48K, and 49152-65535 is your actual bank paging window' and be done with it.

Information noise is a problem with much documentation and especially articles out there. Care must be taken to make sense while keeping things human-readable, if we want anything more than explaining topics to those who already know them (hi wikipedia).
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Nienn Heskil wrote: Fri Jul 10, 2020 12:09 pm
AndyC wrote: Fri Jul 10, 2020 11:39 am The first two windows will always show the same two banks (2 & 5). Changes made in that part of the address space will therefore always affect those banks.
In which case, why even bring that up? /o This is, at best, obscure implementation details that has no practical meaning from a programmer's perspective. You can just say '16384-49151 behaves exactly the same as on a 48K, and 49152-65535 is your actual bank paging window' and be done with it.

Information noise is a problem with much documentation and especially articles out there. Care must be taken to make sense while keeping things human-readable, if we want anything more than explaining topics to those who already know them (hi wikipedia).
Consider this pseudocode:

Code: Select all

.ORG $8000
 select bank  2
 ld hl, $C000
 ld de, $C001
 ld bc, 16382
 ld (hl), OPCODE_RST0
 ldir
 ret
 
What you think will happen ? Do you think this code will ever return to caller ? Overwritting memory pointed by program counter is not an obscure implementation detail.
Proud owner of Didaktik M
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: Question about Bank 2

Post by Nienn Heskil »

catmeows wrote: Fri Jul 10, 2020 12:23 pm
Nienn Heskil wrote: Fri Jul 10, 2020 12:09 pm In which case, why even bring that up? /o This is, at best, obscure implementation details that has no practical meaning from a programmer's perspective. You can just say '16384-49151 behaves exactly the same as on a 48K, and 49152-65535 is your actual bank paging window' and be done with it.

Information noise is a problem with much documentation and especially articles out there. Care must be taken to make sense while keeping things human-readable, if we want anything more than explaining topics to those who already know them (hi wikipedia).
Consider this pseudocode:

Code: Select all

.ORG $8000
 select bank  2
 ld hl, $C000
 ld de, $C001
 ld bc, 16382
 ld (hl), OPCODE_RST0
 ldir
 ret
 
What you think will happen ? Do you think this code will ever return to caller ? Overwritting memory pointed by program counter is not an obscure implementation detail.
Correct. But the number/size/inner workings of 'imaginary fixed windows' absolutely are.

As long as one remembers that: '[#8000;#BFFF] is always bank 2, and [#4000;#7FFF] is always bank 5' - it should be alright. :)
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Yes, I agree. Everything works as on 48K as long you don't touch paging. The trap/advantage is that you can mirror pages 2, 5 also at $C000 which may cause some confusion. The rest are really implementation details, for case anyone is interested how it really works.
Back to original problem.

XoRRox -
at start of your program the RAM paging is set up as follows: 16384: fixed bank 5, 32768: fixed bank 2, 49152: selected bank 0
then you page in bank 2 to 49152-> 16384: fixed bank 5, 32768: fixed bank 2, 49152: selected bank 2
by writing to 49152 you defacto write to first byte of page 2 - thats why you see value 255 at 32768 and 49152.
then you page in bank 0 again -> 16384: fixed bank 5, 32768: fixed bank 2, 49152: selected bank 0
So now 32768 still shows first byte of bank 2, and 49152 shows first byte of bank 0.
You changed first byte of page 2, that is why you still see 255 at 32768. But ou never changed first byte of page 0, so it correctly shows 0.
Proud owner of Didaktik M
XoRRoX
Manic Miner
Posts: 233
Joined: Wed Jul 11, 2018 6:34 am

Re: Question about Bank 2

Post by XoRRoX »

catmeows wrote: Fri Jul 10, 2020 9:55 am Why you expect that value @32768 will change back to 0 ? You changed it to 255 (via mirror @49152) and never rewrite to anything else.
Well, normally with the other banks 0, 1, 3, 4 & 6, when you page to a different bank, all of its contents is

Well, normally when one switches between banks, all data gets swapped.
I thought of bank 2 (and possibly 7) as direct mirrors at both regions @ 32768 and 49152. So like the same RAM is paged at 2 locations at the same time.

So my thinking was something like:

Code: Select all

- page-in bank 7:
  - switch away current bank with all of its 16k of data.
  - map bank 7 to region 32768 & 49152

- page-in other bank:
  - switch away bank 7's 16k of data
  - map bank x's to region 49152

If it's not like that, does that mean that if you have code/assets in 32768-49151 that you don't want to be destroyed, you can only use Bank 7 to read from, not write anything to it?
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

XoRRoX wrote: Fri Jul 10, 2020 12:56 pm
catmeows wrote: Fri Jul 10, 2020 9:55 am Why you expect that value @32768 will change back to 0 ? You changed it to 255 (via mirror @49152) and never rewrite to anything else.
Well, normally with the other banks 0, 1, 3, 4 & 6, when you page to a different bank, all of its contents is

Well, normally when one switches between banks, all data gets swapped.
I thought of bank 2 (and possibly 7) as direct mirrors at both regions @ 32768 and 49152. So like the same RAM is paged at 2 locations at the same time.

So my thinking was something like:

Code: Select all

- page-in bank 7:
  - switch away current bank with all of its 16k of data.
  - map bank 7 to region 32768 & 49152
you can page only to 49152, 32768 is always same

Code: Select all

- page-in other bank:
  - switch away bank 7's 16k of data
  - map bank x's to region 49152

If it's not like that, does that mean that if you have code/assets in 32768-49151 that you don't want to be destroyed, you can only use Bank 7 to read from, not write anything to it?
32768-49151 is absolutely safe as long you don't page in bank 2. You can safely write to banks 0,1,3,4,6,7 and your code bellow 49152 will not change.
Proud owner of Didaktik M
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Image
Proud owner of Didaktik M
AndyC
Dynamite Dan
Posts: 1406
Joined: Mon Nov 13, 2017 5:12 am

Re: Question about Bank 2

Post by AndyC »

Nienn Heskil wrote: Fri Jul 10, 2020 12:09 pm quote]
You can just say '16384-49151 behaves exactly the same as on a 48K, and 49152-65535 is your actual bank paging window' and be done with it.
Except it doesn't.

Consider what happens if you page Bank 2 or 5 in at the high address and then write to it. This changes memory in the 16384-49152 range, which wouldn't happen on a 48K ever.

It gets more important when you consider the +2A/+3 extended banking schemes where it's possible to page other RAM combinations into that address space as well.

Looking at the memory map as a series of 16K banks selected from 128K of RAM and 32k (or 64K) of ROM, with certain model specific limitations on what can be paged where, is a more coherent model overall. It's even valid for 48K mode.
XoRRoX
Manic Miner
Posts: 233
Joined: Wed Jul 11, 2018 6:34 am

Re: Question about Bank 2

Post by XoRRoX »

So my statement
if you have code/assets in 32768-49151 that you don't want to be destroyed, you can only use Bank 2 to read from, not write anything to it?
is correct then? (sorry, earlier I accidentally wrote / instead of 2).

The thing is that only Banks 0 & 2 are uncontented across all Spectrum models which may be needed for time-critical routines such as sample playback.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2641
Joined: Mon Nov 13, 2017 3:16 pm

Re: Question about Bank 2

Post by Ast A. Moore »

XoRRoX wrote: Fri Jul 10, 2020 2:30 pm The thing is that only Banks 0 & 2 are uncontested across all Spectrum models which may be needed for time-critical routines such as sample playback.
You could incorporate a machine detection routine into your code, and then page in any bank you need depending on what Spectrum model your code is running on.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Nienn Heskil
Microbot
Posts: 132
Joined: Tue Jun 09, 2020 6:14 am
Contact:

Re: Question about Bank 2

Post by Nienn Heskil »

AndyC wrote: Fri Jul 10, 2020 1:54 pm
Nienn Heskil wrote: Fri Jul 10, 2020 12:09 pm quote]
You can just say '16384-49151 behaves exactly the same as on a 48K, and 49152-65535 is your actual bank paging window' and be done with it.
Except it doesn't.

Consider what happens if you page Bank 2 or 5 in at the high address and then write to it. This changes memory in the 16384-49152 range, which wouldn't happen on a 48K ever.

It gets more important when you consider the +2A/+3 extended banking schemes where it's possible to page other RAM combinations into that address space as well.

Looking at the memory map as a series of 16K banks selected from 128K of RAM and 32k (or 64K) of ROM, with certain model specific limitations on what can be paged where, is a more coherent model overall. It's even valid for 48K mode.
I've addressed that above. It's easier to remember that in the 128K 'scheme of things', one is assigned bank 2, and the other bank 5. As a general rule, that doesn't change in any way, and is mostly all there is to it for practical purposes. Properties such as mirroring the same data at two address ranges naturally follow from this; you can get down to electron level and whatnot if you want, but you don't have to.

+2A/+3 - perhaps. But at least in my mind I view that paging mode as something completely unrelated. It's just... weird, and arbitrary. There's just a couple of fixed page combinations available, a number of which don't quite make sense on a Spectrum. IIRC, it cannot even be used together with #7FFD (although I might be wrong).
catmeows
Manic Miner
Posts: 718
Joined: Tue May 28, 2019 12:02 pm
Location: Prague

Re: Question about Bank 2

Post by catmeows »

Ast A. Moore wrote: Fri Jul 10, 2020 2:33 pm
XoRRoX wrote: Fri Jul 10, 2020 2:30 pm The thing is that only Banks 0 & 2 are uncontested across all Spectrum models which may be needed for time-critical routines such as sample playback.
You could incorporate a machine detection routine into your code, and then page in any bank you need depending on what Spectrum model your code is running on.
Or you can use banks 0,2 only and use rest of free memory as RAMDISK. RAMDISK can be accessed from BASIC.
Proud owner of Didaktik M
Post Reply