Conditional branches - from assembly to Arduino

I’m working on rewriting some 6801 assembly into something I can pour into an Arduino, and a hiccup that has turned up pertains to some conditionals. I know how to rephrase BNE (!=), BEQ (==), BLE (<=), etc…

but the ones that have me scratching my head use the 9th bit carry flag (BCC / BCS) or where the result is plus or minus (BPL / BMI).

Any thoughts?

what do you mean with "to Arduino". Are you writing in assembly language for the 328P or in C++ ?

here is the summary of the conditional branch for the 328P (see page 10)

What I mean is I have some assembly code I want to rewrite into C++.

He's writing a Motorola 68,000 emulator.

And in that light..

Do you have the registers and flags set up as variables? Because that's what you would be testing against..

-jim lee

conditional branches are usually generated from status bits (Negative, Overflow, Carry bit,...) set by previous arithmetic operations. For exemple after most instructions that have a value result, the ‘negative’ flag will contain bit 7 of that result and this is what is checked by BMI
=>You need to understand what the previous operation was. (Could be a multi byte division algorithm or something more complex than initially meet the eyes)

the ones that have me scratching my head use the 9th bit carry flag (BCC / BCS)

C/C++ does not have access to the Carry Flag. The usual workaround is to use a larger variable (int instead of byte) and check the 9th bit. This is comparatively inefficient :frowning:

or where the result is plus or minus (BPL / BMI).

BPL/BMI usually work out as similar to “<” or “>=”, perhaps with unsigned variables vs signed, depending on the previous operation.

PS:

He’s writing a Motorola 68,000 emulator.

6801 is NOT a 68000

1. Assembly instruction can directly test the carry-bit being prduced after the addition of two unsigned number. C language can not do it. For example:

byte x1 = 0xF0;
byte x2 = 0x23;
byte x3 = x1 + x2;  //x3 = 0x13

2. In order to catcah/preserve the MSBit of the result, you need to do like this (as mentioned in Post#5):

unsigned int x3 = (unsigned int)x1 + (unsigned int)x2; //x3 = 0x0113 = 0000 0001 0001 0011

3. Now, you can do the following conditional branching by testing bit-8 of x3:

if(bitRead(x3, 8) == HIGH)
{
     //do this
}
else
{
      //do tthat
}

that’s low level. understanding why BCC (for example) was written or generated in the first place might help get better code.

for example (6502)

        LDA #0      ;Initialize REM to 0
        STA REM
        STA REM+1
        LDX #16     ;There are 16 bits in NUM1
L1      ASL NUM1    ;Shift hi bit of NUM1 into REM
        ROL NUM1+1  ;(vacating the lo bit, which will be used for the quotient)
        ROL REM
        ROL REM+1
        LDA REM
        SEC         ;Trial subtraction
        SBC NUM2
        TAY
        LDA REM+1
        SBC NUM2+1
        [color=red]BCC L2      ;Did subtraction succeed?[/color]
        STA REM+1   ;If yes, save it
        STY REM
        INC NUM1    ;and record a 1 in the quotient
L2      DEX
        BNE L1

initially you can see BCC as a test on the subtraction but that’s an example that divides the two-byte number NUM1 by the two-byte number NUM2, leaving the quotient in NUM1 and the remainder in REM

So maybe the better code in C/C++ will just use NUM1 / NUM2 or NUM1 % NUM2

this sound similar to how C is not suited for fixed point arithmetic that many DSPs are well suited for

a different approach/algorithm is needed for C-code or a C++ class is needed to emulate the lower level processor op-codes

I think the first sentence in reply #7 nails it. You need to do some reverse engineering to at least partially reconstruct the original code.

yes. depends on it's purpose. is it simply used to propagate a bit into the next most significant byte of a multi byte value or is is being used in a barrel shift operation.

the first case is handled by C using standard math operations, but there's no standard C operation that implements a barrel shift.

You could post the code and hope that people enjoy a challenge...

aarg:
I think the first sentence in reply #7 nails it. You need to do some reverse engineering to at least partially reconstruct the original code.

And given that you’ve recently “[become] able to understand how one can stick new numbers in a given variable on the fly” it seems like

you should slow your roll a bit there and just learn C or C++. Srsly, you are embracing yourself with these kinda questions.

a7

alto777:
Srsly, you are embracing yourself with these kinda questions.

not sure I get what you are saying

For the most part, the BCC / BCS branches in the code in question act on the result of bit-wise shifts, likely to check the results of one set of inputs as the test progresses.

I see what westfw is talking about - I’m thinking the answer may have to be testing whether or not the result is greater than 256 after a shift to the left or if there is a remainder of 0.5 after a shift to the right. Either that or replace it with in-place bit testing.

The BPL / BMI operations seem to follow math operations.

This code is getting to be like an onion. Figure something out and there’s another layer of complexity visible in the code that hasn’t been translated yet.

I would be more than happy to post the code - but I understand this forum is picky on attachments… even then, the question would be whether to post the full low-level code or the current mix I have so far.

alto: Directed to whom?

alto777:
And given that you’ve recently “[become] able to understand how one can stick new numbers in a given variable on the fly” it seems like

you should slow your roll a bit there and just learn C or C++. Srsly, you are embracing yourself with these kinda questions.

a7

HOW DO YOU EXPECT SOMEONE TO LEARN IF THEY DO NOT ASK QUESTIONS?

MY INTENT WAS TO SEE OUT HOW LOW-LEVEL OPERATIONS LIKE THE ONES ASKED ABOUT ARE HANDLED IN C OR IF I NEED TO DIG DEEPER INTO THE CODE TO FIGURE OUT WHAT IS HAPPENING IN ORDER TO BE ABLE TO DO A PROPER REWRITE.

ONCE I HAVE A BETTER UNDERSTANDING ON WHAT TRANSLATES DIRECTLY AND WHAT NEEDS TO BE REWRITTEN FIRST, THEN MY PLAN WAS TO START OVER FROM THE TOP AND LEARN TO WRITE A PROPER PROGRAM IN C.

/bullhorn

There is no need to shout

would be more than happy to post the code - but I understand this forum is picky on attachments

Meh. Not that picky about attachments. More "annoyed when people include code in the text of their post without using code tags (which means that they didn't read the instructions)" or "annoyed when people attach code that was short enough to have appeared in-line in their post" or "really annoyed when people post pictures of code."

Go ahead and attach your ASM code (as a .txt file)
If it's short enough, just put it inside code tags.

Shouting aside, you're putting the cart before the horse.

The point of high(er)-level languages is that you don't concern yourself with low-level constructs (did that last instruction set the carry and the half-carry? Do I jump on carry clear or carry set?), leaving you to concentrate on what the code has to do, not how it is to be done.

If you want to recode in C/C++, don't read the assembler code, read the comments next to them - they should be telling you what the code has to do.

If you don't want to recode, use C/C++ to write a 680x emulator (I know there's a 6502 emulator, there may well be a 680x one) and simply run the original code under emulation.

The only time I've ever seen a practical translation approach was a project I once worked on where the source (a lot of source) was all written in 6809 assembler, and the plan was to move it to Macro-11. An automatic translator was written (Macro-11 looks a lot like a superset of 6809 ASM), but there was still a lot of manual work to do. The approach was ultimately abandoned, but it took up a lot of time and money.