How are the values of EXPTBL initialized?

Par aoineko

Paragon (1140)

Portrait de aoineko

13-12-2021, 21:11

At a program start, the EXPTBL memory addresses (FCC1h~FCC4h) are initialized with a flag that tells if each of the 4 primary slots are expended or not. Where does this information come from?
Do you know how this information is retrieved by the MSX boot system?
I have the impression that it has something to do with the fact that the value of SLTSL is received inverted, but I am a bit lost. ^^

!login ou Inscrivez-vous pour poster

Par zeilemaker54

Champion (355)

Portrait de zeilemaker54

13-12-2021, 21:41

Search for CHKRAM here

Par aoineko

Paragon (1140)

Portrait de aoineko

13-12-2021, 23:50

I am not an expert in assembler. Can you confirm my understanding:

Once the main slot is selected in port A8h, we write to address FFFFh and the slot is expended if, when reading this same address, we get the inverse value. Is this correct? And logically, we get the same value if slot is not expended.

This means that there are 4 bytes somewhere that store the value of the expended slots of each primary slot, but where? Not in RAM, right?
Is it in a separate electronic component?

Par Grauw

Ascended (10821)

Portrait de Grauw

13-12-2021, 23:58

aoineko wrote:

Once the main slot is selected in port A8h, we write to address FFFFh and the slot is expended if, when reading this same address, we get the inverse value. Is this correct? And logically, we get the same value if slot is not expended.

That’s correct.

aoineko wrote:

This means that there are 4 bytes somewhere that store the value of the expended slots of each primary slot, but where? Not in RAM, right? Is it in a separate electronic component?

This address is a memory-mapped I/O register. Whatever value in RAM or ROM at 0FFFFH in any of the expanded slots can not be accessed, it is shadowed by this subslot selection register that’s built into in the expander. The specification requires that this register returns the complement of its value when it’s read, to allow detection.

Par aoineko

Paragon (1140)

Portrait de aoineko

14-12-2021, 00:07

Thank you Grauw for the explanations.

Your last sentence puts me in some doubt.
The FFFFh address is memory-mapped in all cases or only for extended slots? What happens if, for example, I access the FFFFh address of a cartridge in a non-extended slot 1. Do I get the value at this address or the value of the I/O register?

Par aoineko

Paragon (1140)

Portrait de aoineko

14-12-2021, 19:23

Can you confirm that non-expanded slots do not have a special mechanism related to the FFFFh address?

If a ROM/RAM is visible on page 3 in a non-expanded slot, I would retrieve the contents of the ROM/RAM at FFFFh by reading this address. Is this correct?

This means that in the case of a ROM (read only) in a non-expanded slot, I may read the invert of the value I would have tried to write (1 chance out of 256). So this method does not seem to be a safe way to know if a slot is expanded or not.

The method that would seem to be correct would be like:
- Put the primary slot in the register A8h page 3
- A = Read at FFFFh (and backup value to restore it later)
- B = Increment the value
- Write at FFFFh
- C = Read at FFFFh

If C == Invert(B) then the slot is extended
If C == B then the slot is not extended and contains RAM (to be restored)
Otherwise the slot is not extended and contains ROM

Does this make sense?

@zeilemaker54 : I can't follow the assembly code long enough to understand if that's what it does or not. :-/

Par zeilemaker54

Champion (355)

Portrait de zeilemaker54

15-12-2021, 20:41

aoineko wrote:

Can you confirm that non-expanded slots do not have a special mechanism related to the FFFFh address?

If a ROM/RAM is visible on page 3 in a non-expanded slot, I would retrieve the contents of the ROM/RAM at FFFFh by reading this address. Is this correct?

This means that in the case of a ROM (read only) in a non-expanded slot, I may read the invert of the value I would have tried to write (1 chance out of 256). So this method does not seem to be a safe way to know if a slot is expanded or not.

The method that would seem to be correct would be like:
- Put the primary slot in the register A8h page 3
- A = Read at FFFFh (and backup value to restore it later)
- B = Increment the value
- Write at FFFFh
- C = Read at FFFFh

If C == Invert(B) then the slot is extended
If C == B then the slot is not extended and contains RAM (to be restored)
Otherwise the slot is not extended and contains ROM

Does this make sense?

@zeilemaker54 : I can't follow the assembly code long enough to understand if that's what it does or not. :-/

The relevant code to check if the slot is expanded:
ld hl,0FFFFH
ld (hl),0F0H
ld a,(hl)
sub 00FH ; is slot expanded (writen value readback inverted) ?
jr nz,A0302 ; nope,
ld (hl),a
ld a,(hl)
inc a ; is slot expanded (writen value readback inverted) ?
jr nz,A0302 ; nope,

So 0F0H is written first and checked if 00FH is read back (so inverted)
Next 000H is written and checked if 0FFH is read back (so inverted again)
Note that if the slot is actually expanded, the last written 000H also selects secundairy slot 0 in all pages

And of course the correct primairy slot must be selected in page 3 which is the loop:
xor a ; start with primairy slot 0
ld c,a ; initialize expanded slot flags
A02E7: out (0A8H),a ; select primairy slot on page 2 and 3
..
..
A0335: in a,(0A8H)
add a,050H ; next primary slot page 2 and 3
jr nc,A02E7 ; all primary slots done ? nope, next

Par Grauw

Ascended (10821)

Portrait de Grauw

15-12-2021, 22:00

aoineko wrote:

Your last sentence puts me in some doubt.
The FFFFh address is memory-mapped in all cases or only for extended slots? What happens if, for example, I access the FFFFh address of a cartridge in a non-extended slot 1. Do I get the value at this address or the value of the I/O register?

The address FFFFH is only a memory-mapped register in case of expanded slots. If a non-expanded slot is selected in page 3, you will get the memory value at the address and not the register. This memory-mapped register is located in the expander (either internal or external), and not in the base configuration of the machine.

Because this logic is in the expander, it means that a base machine without expansion is cheaper to produce, since less logic is needed. This was especially relevant for the early MSX1 machines when ASICs like MSX-ENGINE weren’t available yet. The downside of having this logic in the expander is that it complicates the way to select the secondary slot; you have to do a little dance by temporarily selecting the expanded slot in page 3 in order to select the desired subslot for another page, while it could be simpler (and faster) had it been present as a built-in register.

Par aoineko

Paragon (1140)

Portrait de aoineko

15-12-2021, 23:34

Thanks Zeilemaker54 & Grauw for the explanations. It's crystal clear now. Smile

Par gdx

Enlighted (6440)

Portrait de gdx

16-12-2021, 08:56

There are all these explanations here:
https://www.msx.org/wiki/Slots#Programming

To access a secondary slot register via the FFFFh address, you must first select the corresponding primary slot in page 3 (C000h-FFFFh).