1

I have a variable:

  ushort statusRegister;

This variable tracks the result of various computations by way of the setting or clearing of its individuals bits. The bits are defined as:

  • Bit0 = carry
  • Bit1 = overflow
  • Bit2 = Zero
  • Bit3 = Sign
  • Bit4 = IRQ
  • Bit5 = Aux Carry
  • Bit6 = 1 Not used
  • Bit7= 1 not used

Given the following:

   Ushort  varA = 0x8B;
   Ushort varb = 0x24;
   Ushort result = varA + varB;

How do I set or clear these individual bits given the result of the computation? I can't figure out how to determine if the computation caused a bit carry or half carry or if an overflow occurred.

Thanks for any advice

  • C# does not expose primitive info like if there was a carry or not. If you want to know you are going to have to do some extra math after you have the result to figure out if the carry happened or not. Not posting as an answer because I have no idea what that math would be. – Scott Chamberlain Jun 15 '16 at 17:40

1 Answers1

0

Here is the answer after extra discussion. Much simpler after taking into account the feedback.

However, I just focused on the carry bit as an example of how to address each bit in your statusRegister. Not sure if you need us to expand on the other bits.

So updating the register would be something like:

bool carry = result < Math.Max(varA, varB);
statusRegister |= (ushort)((carry) ? 0x1 : 0x0); //set the carry bit

Depending on your situation you may or may not need to clear the status register between iterations. If so, you could so something like:

statusRegister &= 0xFFFE; //clear the carry bit first
statusRegister |= (ushort)((carry) ? 0x1 : 0x0); //then set the carry bit
Ayo I
  • 7,722
  • 5
  • 30
  • 40
  • 1
    Why so complicated? Carry is just `result < varA`. Similar for half-carry, just mask first – harold Jun 15 '16 at 18:28
  • @user497745 No, not an assignment, I kinda wish it were, maybe then I would know what the heck I am into. I am trying to write a MC6808 Virtual Machine. I have an old (1985) robot that uses the MC68008 as its brains. I appreciate your response and will try it out but I am having lots of difficultly wrapping my head around all of that logic, especially your carry var. Can you elaborate? If not I will figure it out in due time. –  Jun 15 '16 at 19:44
  • @Harold I really appreciate the simplicity of your answer. From what I gather anytime the result is less than varA a carry results? Does this hold true for any value? And you chose varA in your response what impact does varB play. What about subtraction? –  Jun 15 '16 at 19:51
  • 1
    @KenM `result < varB` is the [same](http://haroldbot.nl/?q=let+x+%3D+a+%2B+b+in+%28x+%3C+a%29+%3D%3D+%28x+%3C+b%29) condition. In fact you can compare against `min(a, b)` or `max(a, b)` as well, all of them mean that a 1 must have "fallen off the end", it's the only way the sum of two unsigned things can become less than either of the summands. You can write subtraction in terms of addition, you may have to flip the resulting carry, depending on your target CPU, I'm not sure what 68k requires. – harold Jun 15 '16 at 20:32
  • @Harold Ok. I think you're right. I started down that path mentally, but wasn't sure if there are any edge cases to worry about where the wraparound results in the value being less than one but not the other. Is that what you're implying by the max(a,b)? Because yes! `carry = result < max(vara,varb)` would work. – Ayo I Jun 15 '16 at 22:36
  • It does work, but I'm not sure why you went with that one. I mean, `result < varA` is even simpler. It has a sort of asymmetric feel about it I suppose.. The point I wanted to make with the min/max was that since both work, it apparently doesn't matter which we choose, so we could just choose A (or B), regardless of whether it's the minimum of the maximum it's always going to be at least one of them. – harold Jun 16 '16 at 22:45
  • Yes, you must be exploiting a mathematical property that I'm not aware of. I guess I'd have to think about it a bit more. `carry = result < max(varA,varB)` is easy to prove mathematically that it must, by definition, be correct. You're probably right that `carry = result < varA` and `carry = result < varB` also have a proof to prove their correctness, but without fully understanding the proof I just didn't want to recommend it. – Ayo I Jun 17 '16 at 19:05
  • Fair enough. The region between `min(a, b)` and `max(a, b)` is actually unreachable, you can't end up there without overflowing (obviously without overflow `result >= max(a, b)`) but also not *with* overflowing because the maximum addend is equivalent to -1, so if you try to "overflow as far as possible" in an attempt to get into that unreachable region, you'd get stuck one below the border. So anything in between the min and max can be used as threshold, including the end points, even without knowing which endpoint you're using. – harold Jun 17 '16 at 19:43
  • Or less generally and more asymmetrically, we just added a non-negative number to `a`, so the result has to be at least `a`. If it isn't, that can only have happened through wrapping. (the same argument works for `b` of course) – harold Jun 17 '16 at 19:47
  • @harold Very interesting. Yep. The first proof makes sense. I'll have to remember that for the future. – Ayo I Jun 17 '16 at 19:55