IRF Posted September 18, 2017 Report Share Posted September 18, 2017 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 DI87C7 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.) Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted September 18, 2017 Report Share Posted September 18, 2017 (edited) 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 October 22, 2017 by IRF Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted September 26, 2017 Report Share Posted September 26, 2017 (edited) 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 February 27, 2018 by IRF jetsetdanny and Spider 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted October 4, 2017 Report Share Posted October 4, 2017 (edited) 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 attributesEXPANSION 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 October 4, 2017 by IRF Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted October 4, 2017 Report Share Posted October 4, 2017 The code as listed was not tested (otherwise the mistake would have been obvious on first run). Yes the RRCA should have been RLCA .... IRF and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted October 4, 2017 Report Share Posted October 4, 2017 Thanks for confirmation. I was going to test it out as is, just to see how it messes with some familiar layouts - I still might, just for fun... Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
Norman Sword Posted October 4, 2017 Report Share Posted October 4, 2017 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. jetsetdanny, IRF and Spider 3 Quote Link to comment Share on other sites More sharing options...
IRF Posted October 4, 2017 Report Share Posted October 4, 2017 (edited) Yes, you have to be very careful to 'follow the rules' when it comes to flags. I came a cropper a while back when I (falsely) assumed that a DEC A [or DEC L] command would set the Carry flag when A is decremented from #00 to #FF. Edited October 5, 2017 by IRF jetsetdanny 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted October 26, 2017 Report Share Posted October 26, 2017 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). jetsetdanny 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted November 3, 2017 Report Share Posted November 3, 2017 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!) Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.