Research / Megadrive Programming / Logical operations Before we start with logical operations, I will show some more Bcc instructions as I promised. Apart from data registers, address registers and program counter, there's an another register (last one, I promise) called SR (status register). We are now only interested in 5 bits of it, named CCR (flag register). Everything moved to CCR will be copied in the lower byte of SR (this works in reverse). Anyway, CCR consists of 5 bits, which are flags. These flags are set or cleared when certain thing is being done with registers, or an instruction is called. These flags are: - C Flag (carry) - 9th bit of adding, shifting and bit rotation. - V Flag (overflow) - It'll be set when result can't be represented. Eg. when you add $01 (byte) to $7F (byte), the result is $80 and V flag will be set - Z Flag (zero) - Will be set when the result is zero. - N Flag (negative) - Will be set if the highest bit of result is set (in two complement it's the sign bit, so the signed negative) - X Flag (extended) - A copy of C flag. But what these things have to do with CMP and Bcc? In C, this code: something == 1 will return 1 if it's true. Now, when you compare two values, Z flag is set when they are the same or is cleared when they're different. BEQ branches if Z flag is set and BNE will branch if Z flag is cleared. So... BEQ and BNE can be used not only when comparing two values. Look at that example: moveq #0,d0 It will branch, because the result of setting d0 to 0 is 0 and Z flag is set. And BEQ branches if Z flag is set. This comes in handy if you want to test if a number is null or not. Here's a list of Bcc instructions: instr conditions flags required Enough of these branches, let's learn about bits... I really hope you know what bits and bytes are. If you don't, a byte consists of 8 bits, which can be either 1 (set) or 0 (cleared). Number 7 is 111 binary. You can do fun stuff with bits. Eg. the keys pressed on joypad are all stored in one byte. Each bit of this byte represents a key: 7 6 5 4 3 2 1 0 The lowest bit is up, bit 1 is down etc... Now if you want to know if B is pressed, what should you do? You should use the AND instruction. AND operation compares all bits of two values and sets a bit in a new one if this bit was set in both of the values. I'm not an expert of logical operations so you can laugh =P Example: Value 1: 10101100 Take a look at this code: move.b ($FFFFF604).w,d0 ;$FFFFF604 is the joypad output in Sonic 1 Imagine we press B, Up and Start. And instruction will look like that: SACBRLDU The result is not zero so it won't branch! Nifty, isn't it? There are other: or.b #$8,d0 OR sets the result bit if value 1 bit OR value 2 bit is set. Value 1: 00100100 Next: eor.b #$24,d0 EOR sets the result bit if one and ONLY one bit is set in value bits (like x86 xor). Value 1: 00101110 And next: not.b d0 NOT clears the bit if it was set and sets the bit if it was cleared. (changes all bits) Before: 01001001 And now on with bit shifting. This operation moves bits by an ammount to the right or to the left. Eg. we'll shift a value 3 times to the right: Before: 00101000 So after this it'll be: 00000101 Bit shifting is fun because one shift to the left multiples a number by 2 and one shift to the right divides it by 2. The instructions: lsl.b #3,d0 LSL shifts x bits to the left, LSR shifts x bits to the right. There's also bit rotating: rol.b #1,d0 It'll rotate a number one bit to the left: Before: 10101010 It works the same to the right. The last part of bits: bset #1,d0 ;sets bit 1 of d0 homework: move.b #$4,d0 Now your homework is to guess if it is going to branch or not. Bit operations are boring at first but you'll get used to them... Back | Printer friendly << 3. Compares, branches... | 5. Editing the game code >> |