Pause bugfix for JSW48 |
MDFS::Software.JSW.JGH.Docs.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:
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 ; HL=>music flags 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 Pause2.hex hex patchfile.
Bugfix 3
SkoolKid spotted an even more efficient bugfix, just
requiring three pokes. Instead of reading from the corrupted BC, port &FE is
read directly, with A preloaded with the high byte of the address.
Original code: Changed to: 8B1F 06 BF LD B,&BF 8B1F 3E BF LD A,&BF ; 'h'-'enter' 8B21 21 E2 85 LD HL,MFLAGS 8B21 21 E2 85 LD HL,MFLAGS 8B24 ED 78 IN A,(C) 8B24 DB FE IN A,(&FE) ; Read keyboard rowThis can be done with:
POKE 35615,62:POKE 35620,219:POKE
35621,254
and can be applied with the
Pause.hex hex patch file.