Math and Logical Commands
Now, let's see how we can alter the bit 'n' bytes instead of just moving 'em around. The math/arithmetic commands lets you calculate and manipulate the bytes, either directly in the memory, or in the registers. For instance, in the first example we had a command called INC $D020 which made the border color flicker. This command means "increment $D020" and as you might have guessed, it adds 1 to the given address. If the content of the address has reached maximum ($FF/255) it just restarts from 0. A related command is DEC, which works the same way, just other way around, which means it decrements the value by 1, and restarts from $FF if the value was allready 0. Let's have another color flicker example...INC $D020
This time it just flickers between two colors, since it first adds 1 and then subtracts 1.
You can also inc/dec the X and Y registers (but not A for some strange reason.) This is done with these commands: INX, DEX, INY, and DEY. So we could also make color flicker this way...
This just looks a bit different since it's slower first to move the color value into the X register, then increment it, and then move it back to the memory address.
Ok, say you want to increment a byte by 27. Then you could ofcuz just write an INC command 27 times. But a smarter way would be to use the command ADC (add with carry) which can add any given number to the accumulator. The following piece of code adds 27 to the address $0400, which by the way is the char in the upper left corner of the screen, so you should see some kind of change there...
As you might have guessed 1B is the hex value for 27. What you might not have guessed is that CLC means clear carry flag. We will get into flags later, but intil now you just have to remember to clear carry before adding, and set carry before subtracting. Here's an example of the latter...
SEC means set carry and SBC means subtract with carry. Like most other commands ADC and SBC has lots of different addressing modes. For example ADC $1234 which means add the value found in address $1234 to A. So it does not affect the address, only A. To make it affect the address you must STA it afterwards. Remember the relative addressing mode? It also works for ADC/SBC - eg. ADC $1234,X
If we can add and subtract, can we then multiply and divide too? Not quite, I'm afraid. It's only a C64, you know! But we can push all the bits in a byte left or right, which is alsmost the same as multiplying or dividing by 2. For instance LSR $0400 shifts the bits in address $0400 to the right, so if you had the value 6 there it will now be 3. However, if you LSR it again it will now be 1, because the rightmost bit is thrown away. ASL $0400 will shift them left which is the same as multiplying by 2. So the original value was 100 it will now be 200. This trick also has its limitations since a byte can only be 255 at max, so if you try to ASL a value greater than 127 (hex 7F) you will not get a correct result. You can ASL/LSR as many times as you want, and thereby multiply/divide by 2,4,8,16...
If you wanna multiply/divide by other values it's a bit trickier. The following code uses a combination of ASL and ADC to multiply by 3...
As you can see we can also just type ASL without any address. This means that it's A that's shifted left. I think I'll explain the previous example a bit more so it's clear what happens for everyone. Let's say the value of $5000 is 4, and then let's see what happens with the accumulator...
LDA $5000 A=4
ADC $5000 A=12 (or $0C in hex)
If you want to play around with this some more you can use the mon command M which lets you view the content of the memory. For example M 5000 lists the 8 bytes from $5000 to $5007. Then you can change the values, and after pressing return it will take effect. For example you can change the value of $5000 to 04, then run the previous piece of code, and then type M 5000 again to see if it has changed to 0C.
For any Comments or Questions please contact us.