Jump to content
Jet Set Willy & Manic Miner Community

Free space and code optimisation in "JSW"


jetsetdanny

Recommended Posts

Geoff Mode dispenses with most of the 'Game has just loaded' routine at #8400.  The entry point into the game is simply set to #87C6, where only the absolutely essential stuff is done:

 

87C6 F3       DI
87C7 31FF5B   LD   SP, #5BFF

 

(Although I think that will leave the address #5BFF unused, with the first entry onto the stack being placed at #5BFD-FE.  Using LD SP, #5C00 instead would prevent such a 'gap' being left at the base of the stack.)

Link to comment
Share on other sites

Four bytes can be freed up in the Move Willy (1) routine, at #8E2D-#8E35, by replacing the individual checks for Jumping Animation Counter values of #10 (16) and #0D (13), with a single check:

 

CP #09

JP C, ##8FBC

 

That way, when Willy is in the 'ascent' phase of a jump (Jumping Animation Counter = 01 to 08), the program bypasses the check for Left-Right movement keys (Move Willy (2)), and proceeds to Move Willy (3) to move him sideways (if appropriate).

 

Now, the checks for jump-counter values of #10 (16) or #0D (13) ensure that Willy can only land (safely or otherwise), or gain traction on, a standonable block when he is cell-row aligned (i.e. when his sprite occupies two rows).  But that task is immediately replicated in the original code by the check at #8E39.  So the individual checks for jump-counter values of 16 and 13 aren't actually necessary!

 

******

 

P.S. If you simply NOP out #8E2A to #8E35, then Willy can perform a quirky 'step-up jump', which allows him to land on a platform one or two rows above his sprite without overshooting it and landing during the descent phase.  This can enable him to land on a Water cell platform that is located in cell-row 2, without breaching past the top of the current room and ending up in the room above!  (Think of this like climbing up, rather than jumping up, a ladder.)

Edited by IRF
Link to comment
Share on other sites

  • 2 weeks later...

I believe that you can save two bytes at #8DD7, one byte each at #8EDA and #8FA5, and two bytes at #8FC6.

 

This can be achieved by deleting the BIT 7, A instructions, and then changing the conditionality of the subsequent jumps/returns, from JP Z/JR Z/RET Z to JP P/RET P.

 

EDIT: In the case of #8FA5, it needs to be a JP M.

 

******

 

I can't see any reason why the RLC A at #8F14 couldn't be a RLCA instead, saving one byte.

Edited by IRF
Link to comment
Share on other sites

If I may be so bold, I feel that I must query something from one of Norman Sword's earlier posts.

 

The two RRCA instructions, highlighted in bold in the quote below, should actually be two RLCA instructions?  (Assuming that the room layout data is stored in the same way that it is in original JSW. i.e. with Bits 6 and 7 of each compressed room layout byte corresponding to the leftmost of the four room cells that are defined by that particular layout byte, Bits 4/5 relating to the next room cell along, then Bits 2/3, and finally Bits 0 and 1 corresponding to the rightmost room cell in that group of four cells.)

 

Two RLCA operations would rotate two bits of the Accumulator into Bits 0 and 1, ready for selection by the subsequent AND #03 gate, in the correct order to consider the four cells from left to right in turn (before moving on to consider the next cluster of four room cells to the right).

 

 


ROOM ATTRIBUTE FIX and SPACE SAVER

 

org     8d33h

 

; start is 8d33h 36147

 

......

 

Draw_Room

        ld      de,8000h        ;room definition
        ld      HL,L5E00h       ;5e00h the room attributes
EXPANSION
        ld      b,4             ;four cells per byte
        ld      a,(DE)
exp
        rrca
        rrca

        ld      c,a              ;temp save "a"
        and     3              ; values 00b,01b,10b,11b  (types)
        ld      (hl),a          ; write the type into the cell
        ld      a,c             ;restore "a"
        inc     l
        djnz    exp           ; repeat for the byte (4 cells)
        inc     de
        jr      nz,EXPANSION    ; first 256 done
        inc     h               ; this second check is done twice in the 512 loop
        bit     5,h
        jr      z,EXPANSION

 

http://jswmm.co.uk/topic/185-free-space-and-code-optimisation-in-jsw/?p=6101

 

Otherwise, it's an excellent bit of optimisation.

Edited by IRF
Link to comment
Share on other sites

        inc     l
        djnz    exp           ; repeat for the byte (4 cells)
        inc     de
        jr      nz,EXPANSION    ; first 256 done
 

be careful of any slight editing you might be tempted to do. The routine as shown was modified to use different data (the overall routine works).

 

I have for example listed four instructions from the routine. Of note the first instruction sets the zero flag, the last instruction of the four acts on the zero flag set by the inc L.  

 

Note that the DJNZ and the INC DE do not change the zero flag. 

Link to comment
Share on other sites

  • 3 weeks later...

Talking of the effects of various operations on the flags, I've just noticed that the ADD command, applied to a 16-bit register-pair, doesn't set the Zero flag even if the output rolls over to zero (0000).

 

However, the ADC command does set the Zero flag in that circumstance, although you may need to do an XOR A beforehand to reset the Carry Flag (like the 'Move Willy' routine does when using the SBC command - there being no such thing as a 16-bit SUB).

Link to comment
Share on other sites

  • 2 weeks later...

The LD BC command at #8C8E only actually needs to be a LD C (one byte shorter), since the B register is redefined after that before B is used.

 

****

 

In the 'Lose a life' routine, at #8C19, there is the sequence:

 

LD C,E

RRC C

RRC C

RRC C

 

It occurred to me that this can be replaced by the following, which saves two bytes (net):

 

LD A,E

RRCA

RRCA

RRCA

LD C,A

 

After I came up with the above, something else then occurred to me. Immediately afterwards, at #8C20, there is an OR #10 command which SkoolKid identifies as (currently) being redundant (since it is immediately followed by an XOR A, which resets A to zero).

 

However, if the above approach is used, then perhaps the intention of the OR #10 in Matthew's original code might be fulfilled (note that the OR gate has to be placed before A is loaded into C):

 

LD A,E

RRCA

RRCA

RRCA

OR #10

LD C,A

 

This has the effect of slightly lengthening the sound effect when Willy is killed, and the sound has a little more 'depth' to it. It is an extremely subtle effect - only really noticeable if you play modified and unmodified files in tandem, killing Willy in each file in turn.

 

However, if you study the possible values that are held by the C register as the 'death sneeze' progresses, I am convinced that this was the original purpose of that OR #10 command!

 

To recap: the 'death' sound effect loop is repeated eight times, as A descends through consecutive values from #47 (01000111b) to #40 (01000000b). Each time, the duration of the note is assigned to the C register (copied from A, via E) using the above operations. This yields the following values of C:

 

#E8 (11101000b)

#C8 (11001000b)

#A8 (10101000b)

#88 (10001000b)

#68 (01101000b)

#48 (01001000b)

#28 (00101000b)

#08 (00001000b)

 

Note how Bit 4 of C always holds zero for each possible value of C. The OR #10 command sets Bit 4 of A, which would slot in perfectly in between the highest three bits and the always-set Bit 3.

 

If this was the intention, then Matthew may have made the mistake of assuming that OR #10 would set Bit 4 of C in that context - something which can be achieved by my suggested tweaks to the code. (Although doing so will negate the two-byte saving that was my original aim when I started playing around with this part of the code!)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.