Bank 7 corruption while loading in Plus2A mode

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
User avatar
jorgegv
Microbot
Posts: 112
Joined: Mon Aug 09, 2021 4:50 pm

Bank 7 corruption while loading in Plus2A mode

Post by jorgegv »

Hi guys, I have the following problem:
  • A 128K game works fine in 128K/Plus2 mode, but crashes in Plus2A mode.
  • The problem has been traced as a corruption of a single byte at position $D600 in Bank 7 (offset $2600 from $C000).
  • The data in that address is compressed, this change makes it decompress incorrectly, and ultimately crashes the game in Plus2A mode.
  • The detection has been done like this: game loaded in 128K mode, and just after loading the game (nothing is running), a snapshot is taken. The same, but in Plus2A mode, again a snapshot is taken.
  • When the interesting banks in both snapshots are compared there is a single byte different in BANK7, at address $E600.
  • Loading the game in Plus2A mode under Fuse and with a write breakpoint at BANK7, offset $2600, the breakpoint it is triggered during the load; it is shown that ROM3 is mapped, and it's forcibly writing to address $E600 (hardcoded in ROM), with BANK7 mapped. The instruction doing this is at address $389A in ROM3. This is what is corrupting the game.
  • Doing the same test but in 128 mode, with the same breakpoint, shows no writing at that address during the load (does not trigger the BP), and no corruption happens.
  • The basic loader is loading the banks by using a trivial bank switching routine in assembler at $8000. This routine only uses port 7FFD to switch banks, leaving port 1FFD untouched. Also, this routine takes into account the current BANKM value, and only modifies the bank number (3 low bits) leaving the remaining bits untouched. there
  • According to documentation, "Bank 7 contains editor scratchpads and +3DOS workspace" (https://worldofspectrum.org/faq/referen ... erence.htm)
Why would any ROM write directly to D600 in bank 7 during program load? ROM3 is supposed to be the 48 ROM, right? Any ideas?
zup
Manic Miner
Posts: 210
Joined: Wed Jul 08, 2020 8:42 am

Re: Bank 7 corruption while loading in Plus2A mode

Post by zup »

La RAM7 la utiliza el +3DOS para sus cosas. Una de las cosas que hace (durante las interrupciones) es controlar si debe detener el motor de la disquetera. Si el byte que apuntas no está a cero, lo decrementa (y si llega a cero, manda la orden para detener el motor de la disquetera).

La solución más obvia es cargar el juego con las interrupciones deshabilitadas. Aún así, si el juego habilita las interrupciones (sin usar su propia rutina), ese byte se decrementará. Otras soluciones pasarían por cargarlo con USR0 o hacer creer al Spectrum que está en modo 48k para que no decremente ese byte.

----------------------

+3DOS uses RAM7 for many things and during, interrupts, checks if disk drive motors should be stopped. If that byte is not zero, it decreases it (and when it reaches 0, it tries to stop the disk drive).

The obvious solution is disabling interrupts before loading the game. But if the game enables interrupts (without using their own routines), that byte would be decreased. Other solutions would be loading it using USR0 or make the Spectrum believe that it is in 48k mode so it doesn't decrease that byte.
User avatar
PROSM
Manic Miner
Posts: 476
Joined: Fri Nov 17, 2017 7:18 pm
Location: Sunderland, England
Contact:

Re: Bank 7 corruption while loading in Plus2A mode

Post by PROSM »

As zup says, the easiest way is to disable interrupts or use interrupt mode 2 with your own routine. If you need to use the ROM interrupt routine, and don't want to make the user have to load it in USR0 mode, then what you need to do as soon as your loader starts is switch to the 48K ROM (ROM3), and reset bit 4 of FLAGS ($5C3B).

On all other machines, this flag is reset by default. Amstrad appropriated this flag for the +2A/+3 to indicate whether +3DOS is active, and modified the 48K ROM accordingly, so if bit 4 is set, then it tries to runs the disk drive motor check, which ends up changing the value at $E600 in Bank 7.
All software to-date
Working on something, as always.
User avatar
jorgegv
Microbot
Posts: 112
Joined: Mon Aug 09, 2021 4:50 pm

Re: Bank 7 corruption while loading in Plus2A mode

Post by jorgegv »

I have tried fully disabling interrupts while loading, but I suspect the roms routines enable them again, because the corruption still happens.

I'll try to load forcing 48K ROM.
Timmy
Manic Miner
Posts: 230
Joined: Sat Apr 23, 2022 7:13 pm
Location: The Netherlands

Re: Bank 7 corruption while loading in Plus2A mode

Post by Timmy »

I remember hearing about not using Bank 7 for coding, but I really don't care about the details.

If I ever do 128K coding I might stop using Bank 7. Then again I'd just target the toastrack so I don't care about +3 corruptions.
User avatar
TomD
Manic Miner
Posts: 378
Joined: Tue Nov 13, 2018 9:47 am
Location: Leeds UK
Contact:

Re: Bank 7 corruption while loading in Plus2A mode

Post by TomD »

Yes the best way is to force 48k ROM with paging enabled, I've also found that writing a custom loader helps. You can still use the ROM routines so it works with the SD Card devices but it does help prevent these issues. For more info take a look at a utility I created which does this (https://tomdalby.com/other/zxstlc.html)

Worth adding that the tricky bit is when you need to 3DOS routines for loading from disk, but unless you plan a disk release you probably don't need to worry.

TomD
Retro enthusiast and author of Flynn's Adventure in Bombland, The Order of Mazes & Maze Death Rally-X. Check them out at http://tomdalby.com
User avatar
Einar Saukas
Bugaboo
Posts: 3138
Joined: Wed Nov 15, 2017 2:48 pm

Re: Bank 7 corruption while loading in Plus2A mode

Post by Einar Saukas »

User avatar
jorgegv
Microbot
Posts: 112
Joined: Mon Aug 09, 2021 4:50 pm

Re: Bank 7 corruption while loading in Plus2A mode

Post by jorgegv »

OK, thanks for the replies.

Someone pointed me to the Plus3 ROM disassembly which shows that the disk motor routine (the one that corrupts $E600) is only called if bit 4 of FLAGS is set (FLAGS is IY+1 when in BASIC).

So I just added

Code: Select all

	res 4,(iy+1)
to my bank switching routine, and voila, corruption is gone.
User avatar
jorgegv
Microbot
Posts: 112
Joined: Mon Aug 09, 2021 4:50 pm

Re: Bank 7 corruption while loading in Plus2A mode

Post by jorgegv »

Someone already had done it in this forums: viewtopic.php?p=63368#p63368
User avatar
jorgegv
Microbot
Posts: 112
Joined: Mon Aug 09, 2021 4:50 pm

Re: Bank 7 corruption while loading in Plus2A mode

Post by jorgegv »

PROSM wrote: Tue Feb 27, 2024 7:50 am As zup says, the easiest way is to disable interrupts or use interrupt mode 2 with your own routine. If you need to use the ROM interrupt routine, and don't want to make the user have to load it in USR0 mode, then what you need to do as soon as your loader starts is switch to the 48K ROM (ROM3), and reset bit 4 of FLAGS ($5C3B).

On all other machines, this flag is reset by default. Amstrad appropriated this flag for the +2A/+3 to indicate whether +3DOS is active, and modified the 48K ROM accordingly, so if bit 4 is set, then it tries to runs the disk drive motor check, which ends up changing the value at $E600 in Bank 7.
Sorry @PROSM I skimmed over your post, but you explained exactly the problem and solution.

Thanks, your answer was what I was looking for.
Post Reply