jetsetdanny Posted July 3, 2023 Report Share Posted July 3, 2023 I have the following question in relation to something I am working on right now: In the original "Manic Miner" (BB version), the code starting at #9077 plays a celebratory sound effect. As per SkoolKid's disassembly: The code at #9077 - #9079 prepares C and D for the celebratory sound effect by setting them to 0. However, I believe they are already set to 0 after the previous portion of the code is executed, so this instruction seems to be unnecessary. Freeing up three bytes in this particular spot would be of great use to me. However, I am not 100% sure that it is safe to eliminate the instruction in question; in other words, I'm not 100% sure that C and D are *always* set to 0 at this point anyway (without this instruction in place). Could someone have a look at the code and either confirm or deny that this instruction can be safely eliminated? Any thoughts on this will be greatly appreciated 🙂 . Spider 1 Quote Link to comment Share on other sites More sharing options...
Spider Posted July 3, 2023 Report Share Posted July 3, 2023 I would say it is safe to do so. I checked and with a breakpoint before that instruction BC is or always appears to be zero and the only way without cheating to get to this section of code is at the end of Final Barrier minus 'teleporter' (which I usually NOP out) Its really as I see it more interested in making sure C is zero. As a test, insert a breakpoint at 36981 (#9075h) the LD (HL),0 instruction just before we get here. I tested it by first merely NOP'ing out the three bytes that make up the LD BC,0 instruction then as a further test I tried them at 255/#FF by a LD BC, 65535 The sound was not (or not to my hearing) effected in any way. It is a loop for the sound nothing more and the following on code will use BC for the LDIR instruction anyways. Also tested by setting the PC to the start of the 'congrats' sound effect, which produced the same. EDIT... They say a picture is worth a thousand (#3E8? 😄 ) words or bytes... I too am 'up to something' with this. It should of been done two weeks ago but what with this and that (real life) etc. Quote Link to comment Share on other sites More sharing options...
jetsetdanny Posted July 4, 2023 Author Report Share Posted July 4, 2023 Thanks, Andy! 👍 Yes, I know BC is 0000 just before we get there, that's why I think it's safe to eliminate the instruction in question. However, I haven't tried to "backtrack the history" of BC before #9075, i.e. to see when it becomes 0000 and what makes it become 0000, which is why I asked the question. Having a closer look at it now, I can see that C is set to 00 by the instruction at 903E. At this point (when the game is stopped) B is also 00 (when I checked, but I'm not sure if always). Afterwards, before getting to the celebratory sound, the program draws Willy and the Swordfish graphics and sets attributes for them. As far as I understand the situation, this portion of the code is always executed in the same way (it does not depend in any way on what the player does, as there is no room for any input related to the player's actions or inaction), so the end result always has to be the same. Since C is set to 00 by the instruction at 903E and evidently is also (perhaps: remains, or perhaps: is again) 00 when we get to 9077, after the sprite-printing/attribute-setting code at 903E - 9076 has run its course, I am not really worried about C. I'm more (potentially) worried about B, which apparently is 00 at 903E and continues to be 00 at 9077 (which is great!), but I don't know when and "in what circumstances" it becomes 00 *before* we get to 903E. In other words, I don't have a 100% certainty that I can discard a scenario in which for some reason B would be something else than 00 when we arrive at 903E. Actually, writing these words, I believe I have actually come up with a solution for my uncertainty 🙂 . I do have one spare byte in that general area (thanks to an optimisation which can be applied in relation to the sprite-printing code). So if - taking advantage of that one spare byte - I change the LD C,00 instruction at 903E to LD BC,0000 instruction, I won't have to worry any more, because BC will definitely be 0000 at 903E (no matter what happens before), and if it remains 0000 at 9077, after the sprite-printing/attribute-setting code at 903E - 9076 has run its course, the instruction setting it to 0000 at 9077 can be safely eliminated, because there is no way BC at this point could be anything else than 0000. I believe this solves my problem, but please correct my reasoning if it's flawed in any way 🙂 . Spider 1 Quote Link to comment Share on other sites More sharing options...
Spider Posted July 4, 2023 Report Share Posted July 4, 2023 I typed up some notes without internet access (before I saw your reply) However, change the LD BC , 0 to something else (higher value so both B and C are set) such as LD BC , 32768 or LD BC , 65535 , then try your routine. May need to know if you're invoking it elsewhere Quote Assuming we completed final barrier acceptably , just after the check for demo mode / cheat mode so we're at 36926: At this point B is already at 0 and C is 1 , likely (not looked) from the sprite drawing routine 36926 LD C , 0 , (not sure why as XOR C is one byte however carry flag is reset) Now C is zero 36928 to 36982 is the piece of code to draw the S.F and attributes , none of this uses BC so it remains at 0 36983 starts the sound effect Unless one can invoke the routine during play, although I did set the PC to be 36986 (skipping the LD BC 0) midpoint in playing Central Cavern. If you want to try it more, change the instruction at 34814 which reads JP Z , 34252 to be JP Z , 36986 (Skipping the LD BC , 0 instruction) now when you press BREAK it will go there instead. POKE 34815 , 122 POKE 34816 , 144 Quote Link to comment Share on other sites More sharing options...
IRF Posted July 10, 2023 Report Share Posted July 10, 2023 (edited) Danny, your original query mentioned the C and D registers both being set to #00. But D is set to #32, just after BC are set to #0000. Judging by subsequent posts though, I think you meant to refer to B and C in the first place? Andy, you suggested that XOR C will set C to zero via a single byte command. That is not the case - that trick only works with XOR A. Danny, there is no direct use of B in the preceding code (#903E-#9076), but that code contains two CALLs to the sprite-drawing subroutine (#8FF4), wherein B is assigned a value of #10. So there is no point setting B to zero at #903E - it would be undone at #9046 (and then again at #904F)! Fortunately for your purposes though, there is a DJNZ loop at the end of that subroutine (at #9024), and that loop by definition will not come to an end until B has reached zero. So B (and C) will always hold the value zero by the time flow of execution reaches #9077. 😊 Edited July 13, 2023 by IRF Spider and jetsetdanny 2 Quote Link to comment Share on other sites More sharing options...
IRF Posted July 10, 2023 Report Share Posted July 10, 2023 Having said that, the code without the command to set initial values for BC at the start would be quite 'brittle' (to quote Andrew Broad in another context). ie it would not be a well-designed bit of code if it were exported elsewhere, where it might run into problems. Spider 1 Quote Link to comment Share on other sites More sharing options...
Spider Posted July 11, 2023 Report Share Posted July 11, 2023 On 7/10/2023 at 3:33 PM, IRF said: Andy, you suggested that XOR C will set C to zero via a single byte command. That is not the case - that trick only works with XOR A. I perhaps should of looked closer, sorry. My fault as I thought for a moment "I ought to look that up in the reference to be sure" , but I knew it would interefe with the Carry flag. 22 hours ago, IRF said: Having said that, the code without the command to set initial values for BC at the start would be quite 'brittle' (to quote Andrew Broad in another context). ie it would not be a well-designed bit of code if it were exported elsewhere, where it might run into problems. I did ponder that, It is good practise to know their state upon entering, however setting them at random values aka LD BC , 65535 (B=255 + C=255) did not appear to break the sound. But I do agree. IRF 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted July 11, 2023 Report Share Posted July 11, 2023 (edited) XOR C doesn't change the value in C, it only changes the value of A. (And the Flag register - as you say, it resets the Carry Flag.) Edited July 12, 2023 by IRF Spider and jetsetdanny 1 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted July 13, 2023 Report Share Posted July 13, 2023 (edited) Of course, if we know that C=0 throughout, then those two two-byte commands LD (HL), #00 at #9072 and #9074 can each be replaced by a single byte LD (HL), C. (Unless that's the optimisation which Danny already identified, as he referred to in the third post of this thread?) Edited July 13, 2023 by IRF jetsetdanny 1 Quote Link to comment Share on other sites More sharing options...
IRF Posted July 13, 2023 Report Share Posted July 13, 2023 (edited) At #904C, H already holds the value #40, so the three-byte LD HL, #40B3 can be replaced with a two-byte LD L, #B3 (I suspect that might be the one that @jetsetdanny already came up with?) Edited August 5, 2023 by IRF Spider 1 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.