Jump to content
Jet Set Willy & Manic Miner Community

The AND, OR and XOR instructions


jetsetdanny

Recommended Posts

  • 1 month later...

I have to say I'm quite impressed with John Elliott's cunning use of an XOR followed by an AND command, in the 'Move the Horizontal Guardians' code in JSW64, in order to determine when to reverse the guardians' direction of movement.

 

The traditional JSW code uses an AND gate - to pick the lowest five bits of Byte 2 of the guardian definition, and then compares it against the minimum or maximum x-coordinate (Byte 6 or Byte 7 respectively) using a CP command.

 

However, that isn't possible in JSW64, because the highest three bits of Byte 7 are used as flags for Fast and Slow horizontal guardians.  So an XOR command, and then an AND gate, is used as an alternative way to compare selected bits (0-4) for comparison - after that pair of operations, the zero flag is set if (and only if) the values stored in the lowest five bits of the pair of bytes under consideration, exactly match.

 

This isn't really related to AND, OR or XOR, but it's another impressive little trick of John Elliott's that I thought was worth mentioning somewhere:

 

In the code that moves Skylabs in the JSW64 game engine, there's a cunning use of the CCF command (Complement the Carry Flag), as part of a code-efficient way of handling Skylabs that move upwards.

 

******

 

And on the subject of variations on classic Manic Miner 'specials' in JSW64, I haven't seen it explicitly pointed out anywhere in the manual or anywhere else, but it is perfectly possible to have an Angry Eugene that moves upwards until it stops (rather than downwards as in the original MM).

Link to comment
Share on other sites

I guess you could modify the code in the MM game engine.

 

First thoughts: swap around the DEC A and INC A at #8E07 and #8E12 respectively, and then modify the y-coordinate at which Eugene comes to a halt (#8E14).

 

I have a further suggestion for a modification to Eugene - in fact suggestions for all four 'special' MM guardians, in the JSW64 game engine - but they will have to wait for a future post, when I have the time.

Edited by IRF
Link to comment
Share on other sites

  • 1 month later...

I have to say I'm quite impressed with John Elliott's cunning use of an XOR followed by an AND command, in the 'Move the Horizontal Guardians' code in JSW64, in order to determine when to reverse the guardians' direction of movement.

 

The traditional JSW code uses an AND gate - to pick the lowest five bits of Byte 2 of the guardian definition, and then compares it against the minimum or maximum x-coordinate (Byte 6 or Byte 7 respectively) using a CP command.

 

However, that isn't possible in JSW64, because the highest three bits of Byte 7 are used as flags for Fast and Slow horizontal guardians.  So an XOR command, and then an AND gate, is used as an alternative way to compare selected bits (0-4) for comparison - after that pair of operations, the zero flag is set if (and only if) the values stored in the lowest five bits of the pair of bytes under consideration, exactly match.

 

EDIT: To clarify, load Guardian Definition byte 2 into A, XOR with Guardian Definition Byte 7, then AND #1F.  The Z flag will be set iff the x-coordinates match.

 

Geoff Mode's 'Move the guardians' routine actually takes the above approach further, in order to update the animation frame of a guardian, and the x-coordinate of horizontal/diagonal guardians.

 

In these circumstances, part of a guardian definition byte needs to be updated without altering the rest of the byte.  That's easy for a single flag - just toggle the relevant bit (e.g. Bit 7 of Byte 0 which specifies the direction - use XOR 80).

 

However, when a variable uses more than a single bit, it gets more complicated.  One example would be the two bits that determine a guardian's current frame of animation, which sits within the same definition byte (Byte 0) as the guardian type (lowest bits) as well as its direction flag.  Another example is a guardian's x-coordinate, which shares a definition byte (Byte 2) with the Base sprite.

 

The more familiar approach (to me at least) is to:

 

- load the byte that you're updating into the A register,

- do an AND for the bits you don't want to alter,

- save the output into another variable such as C,

- load the value you want for the bits you do want to update to A,

- do an OR C to merge the two elements,

- and then reload the output of that back into the definition byte.

 

Geoff used the sequence XOR - AND - XOR, which I think is more efficient(?), to update only the parts of a byte that need updating, and leave the rest of the byte unchanged.  The operand of both XOR commands being the guardian definition byte under consideration, whilst the operand of the AND command selects only the bits that you want to update.

 

e.g. to update a guardian's x-coordinate, he uses:

 

[A register holds the new value of the guardian's x-coordinate, in Bits 0-4; whilst Bits 5-7 are initially blank]

XOR (IX+$02)

AND #1F          for updating Bits 0-4

XOR (IX+$02)

[Then load A back into (IX+$02)]

 

The end result is that the x-coordinate of the guardian is updated, but its Base Sprite is unaltered.

Edited by IRF
Link to comment
Share on other sites

  • 3 weeks later...

I've just come to realise why a certain aspect of the MM/JSW code is the way it is.

 

The convention when copying data from one place to another is to use HL (or the indexed equivalents, IX or IY) to point at the data that you're copying, and DE as the addresses to which the values are copied.  (DE presumably signifying 'DEstination'?)

 

That's how LDIR loops operate, and also how the 'Print a message' and 'Print a single character' routines work.

 

But in the case of the 'Draw a sprite' routine at #9456, it is the other way round - DE points at the sprite graphic data, whilst the address to which to draw each byte, in turn, is defined via HL.

 

The reason for this is that the test for pixel collisions uses an AND (HL) instruction.  Furthermore, if no collision occurs, then the process of merging the sprite being drawn with the existing background graphic is done via an OR (HL) instruction.

 

There are no such equivalent Z80 commands involving the DE register-pair. i.e. there are no AND (DE) or OR (DE) commands in the Z80 instruction set.

 

So that is why the DE and HL register-pairs are used in the way that they are by the 'Draw a sprite' routine.

Edited by IRF
Link to comment
Share on other sites

  • 1 month later...
  • 1 month later...

I'm quite pleased with my successful implementation of the patch to 'Draw the Ropes', so that each rope's exact pixel-position can be specified on an individual basis.

 

Firstly, the use of the XOR command to separate out, in a byte-efficient manner, the two components of a rope's definition byte 2 (i.e. the starting column in Bits 0-4, and the pixel-position in Bits 5-7).

 

Secondly, the use of the SCF and RRA commands and a DJNZ loop, to convert Bits 5-7 in order to infill the appropriate pixel (set the correct single bit), in the graphic byte where the top segment of rope appears.

 

I'll type up a disassembly when I get a chance. :)

Link to comment
Share on other sites

  • 3 weeks later...

Looking at the 'Game Over' routine, I believe that the problem we once encountered in implementing certain INK colours for the Barrel (some choices for which were influenced by the chosen INK colour for the Foot/Willy) could be eliminated by simply replacing the value '#FA' at #8CB0 with '#F8'. i.e. the AND gate at #8CAF should only select the Barrel's PAPER/BRIGHT/FLASH bits (3-7), leaving the OR gate at #8CB1 to fully control the Barrel's INK bits (0-2).

Edited by IRF
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.