Translating assembly to C - is this fragment written properly?

Thread Starter

metermannd

Joined Oct 25, 2020
343
I'm analyzing the firmware that was part of my project (the hardware part is on indefinite hold after I apparently blew up the unit).

One thing that has helped me get a better understanding is rewriting it into a different language (C++ in this case). Also, if I succeed in converting all ~7K of 68HC11 assembly into C, I can perhaps use a Teensy or something similar instead of the antiquated 8-bit era ICs I have / had in my current design.

Part of the interrupt involves continuously polling the output of the receiver stage and assembling the serial data data stream into bytes, and this next step involves comparing the current byte (byteLast) with the previous byte (byteOld) to calculate some values needed further down in the interrupt routine.

So, I did run this through an online C syntax checker / compiler and it seemed to 'take'. What I want to see is - one, to see if others can make sense of this, and two, if there may be a better way to handle the bit compare and loop instructions.

Code:
#include <stdio.h>

    int freq1[10] = {32,23,0,-23,-32,-23,0,23,32,23}; // freq lookup - fundamental
    int freq2[9] = {1,0,-1,0,1,0,-1,0,1}; // freq lookup - 2nd harmonic
    uint8_t byteLast, byteOld, accA, accB, temp1, valueIi, valueQi, valueI2i, valueQ2i;
    int idx;

//    Initialize variables
//    byteOld = previously processed byte
//    byteLast = recently collected byte to be processed
//    temp1 = scratchpad byte


int main()
{

nmi05:
    accA = byteOld;
    temp1 = byteLast;
    valueIi = 0;
    valueQi = 0;
    valueI2i = 0;
    valueQ2i = 0;
    idx = 8;

//    Roll temp1 into position
    temp1 = ((temp1 >> 1)|(temp1 << 7)); // ROR

//    We are looking for bit state transitions
//    If none, we skip and prepare for the next bit compare
nmi07:
    temp1 = ((temp1 << 1)|(temp1 >> 7)); // ROL

    accB = (accA ^ temp1); // XOR the two bytes
    if (accB > 0) {goto nmi10;} // is sign bit (bit 7) = 0?

//    Calculate Ii (fundamental, 0 degrees)
    accB = freq1[idx];
    if (accA < 0) {accB = (-accB);}
    valueIi = (valueIi + accB);

//    Calculate Qi (fundamental, 90 degrees)
    accB = freq1[idx+2];
    if (accA < 0) {accB = (-accB);}
    valueQi = (valueQi + accB);

//    Calculate I2i (2nd harmonic, 0 degrees)
    valueI2i = (valueI2i + freq2[idx]);

//    Calculate Q2i (2nd harmonic, 90 degrees)
    valueQ2i = (valueQ2i + freq2[idx+1]);

nmi10:
    accA = temp1;
    idx--;
    if (idx != 0) {goto nmi07;}

    byteOld = accA;

//  continue to integrator and vector math

}
 

MrChips

Joined Oct 2, 2009
30,706
If you need to create an iterative loop, here are two constructs:

while - do

while (condition)
{
};

do - while

do
{
}
while (condition);

In the first structure, the test is performed before executing the loop.
In the second structure the loop is always executed at least once.
 

ApacheKid

Joined Jan 12, 2015
1,533
...you should see what I started with.

I'll try and figure out how to do this without any goto statements then...
Goto is undesirable as nsaspook says, but its all you have in assembler for altering program flow, so its likely deeply ingrained in that original code.

I'd suggest leaving these in (for now) and getting a C copy of the original assembler, that works, once its working and tested then begin to restructure it. I suspect if you try to remove the goto too soon, you'll complicate the whole project. Also if the code was optimized initially the assembler may be more cryptic as a result and some of those goto statements might well be side effects of an optimization phase.

Whatever you do though this is likely pretty challenging work.
 

Thread Starter

metermannd

Joined Oct 25, 2020
343
What is the proper way to write the C++ equivalent of a Basic IF...THEN statement?

On the other hand, the more I look at certain parts of the interrupt code, the more I realize those parts I'm having the most difficulty properly translating into C++ are in fact the most critical pieces of the code.

... the wind is fading from the sails on this project...
 

Thread Starter

metermannd

Joined Oct 25, 2020
343
I get the part where if ( a == 1 ) { b = 2 } else { c = 3 }, but what about redirecting program flow based on the status of certain variables? i.e., if uutType == 1, go to test_35, else start with test_15... sorry for being clear as mud :-\
 

click_here

Joined Sep 22, 2020
548
It sounds like what you are after is the "conditional branching" instructions - It basically means branch if the bit of the CCR is set.

For a==b you would do an XOR or Subtraction between a and b, then BNE (branch if the result is not zero)

All options... (source)
"BEQ: Branch if Equal to Zero
Branch is made if Z flag is 1 (indicating a zero result).
BNE: Branch if Not Equal to zero:
Branch is made if Z flag is 0 (indicating a non-zero result).
BCC: Branch if Carry is Clear
Branch is made if C flag is 0, indicating that a carry did not result from the last operation.
BCS: Branch if Carry is Set
Branch is made if C flag is 1, indicating carry occurred.
BLO: Branch if Lower
Branch is made if result of subtraction was less than zero. This instruction works correctly when using unsigned data.
BGE: Branch if Greater Than or Equal
Branch is made if result of subtraction is greater than or equal to zero. This instruction works correctly only when using unsigned data"
 

click_here

Joined Sep 22, 2020
548
I reread your question and concluded that meowsoft's interpretation of your question was incorrect.

You want to know how to turn that assembly code that you posted and you are having trouble turning it into C++

Compare these 2 codes...
Code:
point1:
 ...
if(apple == 0)
    goto point1;
and
Code:
do
{
  ...
}
while(apple == 0);
Functionality they are equivalent

Also have a look at these 2 codes...
Code:
if (accB > 0) {goto nmi10;} // is sign bit (bit 7)
...
nmi10:
and...
Code:
if (accB <= 0)  
{
    ...
}
 

click_here

Joined Sep 22, 2020
548
Code:
    idx = 8;
    ....
nmi07:
    ....
    idx--;
    if (idx != 0) {goto nmi07;}
Although it's not 100% in the correct form (more like a do/while instead of a while), in this specific case you could use a 'for' loop (because it explicitly sets idx before the loop so it doesn't need to be tested before the first pass)

Code:
for(idx = 8; idx != 0; idx--)
{
    ...
}

A 'for' statement should look like:
Code:
//for(i = 0; i != 8; i++)
i = 0;
while(i != 8)
{

    i++;
}
... and if you want to see a 'goto' statement that behaves a 'while' statement, you'd do something like this...
Code:
startloop:  if(i == 8) goto endloop;
  
  ...

  goto startloop;
endloop:
So a 'for' loop would be
Code:
i = 0;
startloop:  if(i == 8) goto endloop;
  
  ...
  i++
  goto startloop;
endloop:
It is also worth looking into some of the reasons why using a goto statement is a terrible idea.
 

nsaspook

Joined Aug 27, 2009
13,079
So a 'for' loop would be
Code:
i = 0;
startloop:  if(i == 8) goto endloop;
 
  ...
  i++
  goto startloop;
endloop:
It is also worth looking into some of the reasons why using a goto statement is a terrible idea.
Here, a goto statement is a terrible idea but it's not always bad code structure when used as a C exception handling mechanism. Gotos are not the problem. The compiler and linker are perfectly capable is using it to optimize source code to efficient machine code. Programmers who abuse gotos as a substitute for structured source code are the problem.

https://www.cprogramming.com/tutorial/goto.html
 

MrChips

Joined Oct 2, 2009
30,706
The first step would be to attempt to convert this into a flow chart.
Start by determining the flow of control. For now, ignore any details encoded in blocks of sequential code.

Here is my start.

flowchart_1.jpg
It contains three exits from the ISR (interrupt service routine) via RTI (return from interrupt). This violates one of the cardinal rules of structured programming, that is, there must be a single entry point and a single exit point from any function or subroutine. Keep this in mind because in porting the ASM code to a HLL (high level language) a goal would be to adhere to the rules of structured programming.
 
Top