Are the values of Z80 registers on ROM init meaningful?

Página 1/2
| 2

Por konamiman

Paragon (1141)

imagem de konamiman

18-07-2021, 18:19

I was pseudo-randomly browsing MSX code and I found this in Ducasp's WiFi driver:

INIT:
	ld	a,h	; Let's test if we are mirrored and being executed in wrong page
	cp	#40	; is MSB 0x40?
	ret	nz	; if not, return, it is a mirror

where INIT is the ROM startup routine, pointed at in the ROM header.

I'm really puzzled by that as I don't remember having seen any documentation stating that the Z80 registers have any meaningful value at ROM initialization time (certainly not in MSX2 Technical Handbook). By using a breakpoint in an emulator I see that when the Nextor ROM initialization routine runs, at address 40F6h, HL contains 4004h and DE contains 40F6h; so it seems it indeed works.

My question is: is this mirroring detection strategy standard? If not, is it at least reliable? In Nextor I'm using a way more complicated mechanism to prevent double initialization on mappers using pages 1 and 2 so it would be great if I could simplify it.

Entrar ou registrar-se para comentar

Por Metalion

Paragon (1430)

imagem de Metalion

19-07-2021, 10:32

(...)

EDIT : Sorry, after re-reading your post, I realized my answer was irrelevant

Por gdx

Enlighted (4634)

imagem de gdx

19-07-2021, 10:51

Standard or not, H cannot contain anything other than the MSB of the address at the time of the call to INIT.

however, it is better to use BIT 7,H to do the test.

Por Metalion

Paragon (1430)

imagem de Metalion

19-07-2021, 11:00

I just checked on an actual ROM, after ROM.INIT is called:
. ROM.INIT is contained in : DE,IX and HL'
. HL contains the address of the byte just after the stored address of ROM.INIT (ROM.STATEMENT word start address)

So if you have :

4000h   41h        ; 'A'
4001h   42h        ; 'B'
4002h   FFh
4003h   40h        ; ROM.INIT 40FFh

At start up, HL will be 4004h, and DE,IX,HL' will be 40FFh.

Por konamiman

Paragon (1141)

imagem de konamiman

19-07-2021, 11:03

Thanks for your answers. I wonder if it would be safe to use this as it's apparently not documented anywhere.

Por gdx

Enlighted (4634)

imagem de gdx

19-07-2021, 11:03

Yes, HL=4004h when init is at 4004h address and HL=8004h when init is at 8004h address.

Por theNestruo

Champion (308)

imagem de theNestruo

19-07-2021, 11:03

gdx wrote:

Standard or not, H cannot contain anything other than the MSB of the address at the time of the call to INIT.

Why?
First I though the same, because "the jump to INIT must have been a JP (HL)"... but then I realized that could have been JP (IX) and JP (IY), or even PUSH XX : RET (possible, but quite unlikely).
By looking at the BIOS disassembly and C-BIOS source code, it looks like the call is done using CALSLT/CLPRIM, that ends up using JP (IX), so the presence of the value in HL seems incidental...

But, again, this is undocumented behaviour, so I don't know if can be taken for granted. If anything, we could argue if the CALSLT documentation (that declares IX/IY as input parameter) can be read as "the called function will receive this as well"...

Por gdx

Enlighted (4634)

imagem de gdx

19-07-2021, 11:10

I just remember that by analyzing the routine, there is very little chance that it will be otherwise.

Por theNestruo

Champion (308)

imagem de theNestruo

19-07-2021, 11:14

gdx wrote:

I just remember that by analyzing the routine, there is very little chance that it will be otherwise.

Yes, seems similar to the VDP ports dilemma Smile

Por Metalion

Paragon (1430)

imagem de Metalion

19-07-2021, 11:39

gdx wrote:

Yes, HL=4004h when init is at 4004h address and HL=8004h when init is at 8004h address.

More precisely:
. HL contains 'header+4' : ROM.STATEMENT word stored address
. DE,IX and HL' contains ROM.INIT address

Por gdx

Enlighted (4634)

imagem de gdx

19-07-2021, 12:45

Maybe that was the reason. It's easier to add a value to HL than to BC or DE.
Anyway, I also checked on all emulated machines at the time and find no difference.

Página 1/2
| 2