MDFS::Software.JSW.JGH.Pause/htm | Search |
LDIR
clearing the BC
register, and then later code assumes it still holds the address of the
keyboard and tries to IN A,(C)
from it. The resultant
IN 0
crashes the Interface 1, as shown in the following
disassembly:
8B00: INC HL ; Increment pointer to attributes LD A,H ; Get high byte CP &5B ; Has it passed end of screen at &5AFF? JR NZ,&8AF3 ; Loop for 24 screen lines RET 8B07: LD HL,&9A00 ; Restore attributes of bottom third LD DE,&5A00 LD BC,&0100 ; Copy from &9A00 to &5A00 LDIR ; BC now holds zero! LD A,(&80DE) ; Get border colour OUT (&FE),A ; Set border 8B17: LD A,(&85D1) ; Get a variable CP &FF ; Is it &FF - lost a life? JP Z,&8C01 ; Jump to lose a life LD B,&BF ; BC now holds &BF00 instead of &BFFE LD HL,&85E2 IN A,(C) ; Read from port 0 and crashMany published bugfixes patch the code with a call elsewhere to set the registers correctly. Unfortunately, not only is that not neccessary, most of the published bugfixes actually crash the game in a different way. As Andrew Broad has pointed out, many bugfixes put in a call to &FFF0. Unfortunately, that is the data area for room 63, and if room 63 is ever used, it either corrupts the room data or corrupts the pause bugfix.
Bugfix 1
None of this is needed. The simplest fix is to realise that if the bottom
third of the screen does not have it's colours changed during the pause at
&8B00, then the attributes do not need to be restored at &8B07.
This can be done by looping until &5A instead of &5B and replacing
the LDIR
with LD C,&FE
to restore C correctly:
Original code: Changed to: 8B02 FE 5B CP &5B 8B02 FE 5A CP &5A 8B10 ED B0 LDIR 8B10 0E FE LD C,&FEThis can be done with
POKE 35587,90:POKE 35600,14:POKE 35601,254
.
Bugfix 2
When typing up my commented JSW disassembly I realised that there is
another way to fix the pause bug, while allowing the bottom third of
the screen to change colour while pausing. The code at &8B17 checks
if A holds &FF with CP &FF
. As A is not then used this
can be replaced with INC A
with the same Z/NZ flag effects,
and is one byte shorter. This means there is enough space to replace the
LD B,&BF
with LD BC,&BFFE
:
Original code: Changed to: 8B1A FE FF CP &FF 8B1A 3C INC A 8B1C CA 01 8C JP Z,&8C01 8B1B CA 01 8C JP Z,&8C01 8B1F 06 BF LD B,&BF 8B1E 01 FE BF LD BC,&BFFEThis can be done with:
POKE 35610,60:POKE 35611,202:POKE 35612,1 POKE 35613,140:POKE 35614,1:POKE 35615,254and can be applied to the original JSW48 code with the Pause.hex hex patchfile. This is now my preferred pause bugfix.