I will try to explain the present issues of ESXDOS:
ESXDOS forces the machine to boot straight into USR 0 mode. This is not bad. You still have access to 128K memory, AY, etc.
However, there are games that load blocks into different memory banks. To do this, they have to page in each bank, load something in it, then go to the next page, and at the end, jump to the start of the game.
To change the bank to page in, the loader should issue an OUT to port 32765, but this port is write only, so most of them use the value of sysvar BANKM as a starting value. They do something like this, for example to page in bank 4
Código: Seleccionar todo
ld a,(BANKM)
and 0f8h
or 4
ld (BANKM),a
ld bc,7ffdh
out (c),a
This works well provided that BANKM (at 23388) has a value that match the one presently stored in register 7FFDh, but ESXDOS changes that value and doesn't update BANKM. And even if it would do, the normal 48K reset procedure that is called after ESXDOS initialization would reset BANKM again, as it falls under the printer buffer area, which is zeroed as a part of the initialization routine.
What if a loader uses BANKM and this is set to zero? Well, that would mean that the moment the loader issues an OUT with the updated value (as in the previous code), ROM 0 (or ROM 2 on +2A/+3 systems) will be paged in, losing the BASIC runtime, the loading routine, etc, resulting in a hang or reboot.
Fortunately, we know that the value ESXDOS writes to 7FFDh is always the same: 10h. So the idea is to give loaders that same value. This is why we do a POKE 23388,16 just before doing a LOAD ""
This procedure works for almost all games that present this issue. There are some others that don't work even with the POKE. These games usually have their loaders written in BASIC and rely on the system interrupt handler to perform the actual OUT. While in 128K BASIC, the maskable interrupt handler reads the value at BANKM and out's it to port 7FFDh, so to page in a certain bank, say bank 4, one just have to do a POKE 23388,16+4: PAUSE 1 (to ensure an interrupt happens before going on with the rest of the program). These games will need a true 128K environment in order to load.
Ideally, the NMI.SYS routine should check whether it is running on a 128K machine or +2A/+3 machine, and after mounting the tape, page in ROM 0 writting to appropiate registers and jump to a point in which the loader has just been called from the start menu. That is, it should do something similar to what Carmeloco program does.
Not so ideally, but easier to implement is that NMI.SYS pokes the memory address at 23388 with the value 16 just before jumping to the point in ROM 3 which the loading is initiated.