EOR: Some Special Uses
In my own personal, ongoing quest for doing things quicker or more RAM-efficiently with code, some time ago I blundered into some nice little hacks with the EOR instruction, the "Exclusive OR".
Some of my favourites are:
- A tiny EOR-based switch aka "alternator" for frame-skipping in raster interrupts.
- Using EOR for faster subtraction.
- Using EOR for faster addition.
Lets consider each of them in turn:
1. EOR-based alternator: At some point in many coding scenarios, you will probably want to perform certain tasks only on every other frame; it could be some game AI, it could be something like Toggleplexing, an audio effect, a scroll event or whatever; the key thing is that you need to do it every other frame.
For this, you could do as follows (which has probably been used by many coders since the 1980s, so it's not my invention!) inside one interrupt handler, so that it fires once every frame (i.e. screen refresh):
BNE ODDFRAME ; Branch to ODDFRAME every "odd" frame, whereas this BNE is ignored on every "even" frame
; EVENFRAME code goes here
All you have to do when setting this up at the start of the program is to ensure the variable ZPTOGGLE = either 0 or 1 and EOR will invert that value every frame, producing a 0,1,0,1,0,1,0,1,0 cycle ad infinitum.
SPECIAL NOTE: I like to use another way to perform the toggle logic that saves 1 cycle on both odd and even paths compared to the above, but it requires the use of self-modifying code and consumes more RAM for the logic... this is scheduled for inclusion in the next Newsletter for subscribers.
2. EOR for faster subtraction: Normally you would subtract using SEC and SBC, such as per the following example:
SBC BITTABLE,Y ; where BITTABLE,Y is known to hold only values less than #%00011111
That takes 2 + 2 + 4* cycles = 8-9 cycles, the actual number depending on whether or not the page boundary is crossed by the SBC,Y operation; and if we say, by way of illustration, that the value in BITTABLE,Y = #%00001111 (15 in decimal), the result will be #%00010000, i.e, 31 - 15 = 16.
So if we can safely predict the range of the value being subtracted, we could use EOR to do the subtraction like this:
EOR #%00011111 ; Shorthand for subtracting BITTABLE,Y from #%00011111
The same calculation (with the same result, obviously!) now takes 4* + 2 cycles = 6-7 cycles, the actual number depending on whether or not the page boundary is crossed by the LDA,Y operation, with the extra bonus of the carry flag remaining unaltered by the calculation!
Again, the idea of using EOR for this kind of subtraction is not my invention and it's probably impossible to know who did it first, but it's slick and saves 2 precious CPU cycles and 1 byte of RAM from the standard way of subtracting.
(Incidentally, this forms part of the landscape damage encoding routine in Parallaxian, in which trees set on fire by bombing are still on fire next time they scroll on to the screen).
3. EOR for faster addition: Just as you can use EOR for fast subtraction if the constraints of that subtraction are first known and understood, so you can also use it for some fast addition, with the same fundamental proviso.
For example, let's say you want to add any number less than #$F0 (in decimal, 128 or, in binary #%10000000) to #$F0; normally, you would use CLC and ADC to do the following (we should keep it all in binary to help understand what's happening with the various bits):
That gives a result of #%10001010 (138 in decimal) in the A-reg and takes 2 + 2 + 2 = 6 cycles, but consider that the following will give you the same result:
...which puts #%10001010 (138 in decimal) in the A-reg but takes only 2 + 2 = 4 cycles, with the saving still applying over different addressing modes if you replace like with like and, as with the EOR subtraction, you walk out of the calculation with the carry flag unaffected!
Of course, that's only the tip of the iceberg in terms of what can be done with EOR; for example, you can use it to save space in the VIC bank if you have a sprite that has a flickering flame such as that used by Parallaxian's "Backfire" enemy.
So instead of keeping the full definitions for the craft with and without the flame showing, you only need one and use EOR to manually draw / clear the sprite data for the flame
on alternating frames.
Another nice use for EOR I came across was where you can use it to obfuscate code, as per the final example on this Dustlayer post about Bit Manipulation.
Finally, there are some helpful generic, non-C64-related tools online that will allow you to perform tests using the big 3 logical operators of AND, ORA and EOR (which sometimes is known as XOR), such as this one: bitwise-calculator.
Illegal Opcode SAX/AXS: A Practical Use
Interested in coding on the C64? Check out this Kindle e-book on Amazon (and yes, I get a tiny pittance if you buy via the banner below):
PS: Don't forget to check the home page regularly for more articles like this and visit the Everything64 Forum to comment further.
And of course, kindly follow me on Twitter and subscribe to my YouTube channel!
Help Make Parallaxian Happen
If you really want to help get Parallaxian finished, kindly support the continuation of its development via one of the options below, so that I can devote the necessary time to it; it's a truly huge project and although the toughest technical challenges have been completed, there remains a lot of hard work to get it over the finishing line.
Way #1: Start Your Amazon Sessions via Kodiak64.com (Costs You Nothing!)
This one should be the easiest because it's a painless and indirect way to help me for something you would be doing anyway, regardless of my request for help.
So how does it work?
Well, it makes no difference what you're buying on Amazon... whether it's a garden gnome for your dad, jewellery for your wife, the new C64 Maxi for yourself or an obscure first edition by an even more obscure 17th century Belgian poet for someone you very much dislike.
The point is, if you buy anything on Amazon, even your groceries, I will automatically receive a commission as long as your Amazon session begins as a click on an Amazon product banner on this website or just on any generic Amazon link on this website (such as those listed below):
So, you would make your daily visit to Kodiak64.com to check out what's new and then, while you're here, enter Amazon via one of those links to order whatever you were planning on buying anyway, thus doing your bit to advance Parallaxian's development.
Way #2: Purchase Merch from the Kodiak64 Shop
Hosted externally (for now) on Teespring, the features limited edition C64-related merchandise, for which I have mostly set my margin at 15% of the retail price (to keep it as low as worthwhile).
I intend to change designs every month to keep things fresh, albeit with the core themes remaining Commodore 64 centric.
Way #3: PayPal Donation
Finally, at the highest rung of the altruism ladder among the 3 options, maybe you could consider a small, recurring monthly donation (and depending on your tax situation, you might even be able to designate it as a charitable donation rather than let the taxman have it).
And don't worry, you can cancel at any time... but in the meantime, it would be a welcome contribution, however petite.
Oh, and as a special thank you, all who do this will be credited in the game (unless you opt out of it if you have the same kind of incognito hermit tendencies I do).