ugly color :-)

Source of 'dlg02_coder.php'

The central code of my AVR delay loop generators.

License: GPL. Yes. Use it. :-)

Some functions are very ugly, especially burn_level_2. I think I'll reinvent that wheel...

Have phun, tk.
<?

  
// Author: Tjabo Kloppenburg (tjabo at  unix-ag.org)
  // Date: 08.Dez2002
  // Version: 0.0.1 (without level 3)

  // Disclaimer: The license of this file is the GPL, so use the
  //             code and spread it.
  // If you find bugs or have a better idea for LEVEL2, please send
  // me an email.

  // In this file you find the following core functions:
  

  // Nice output of AVR Code:
  /*
  function getNewLabel( $prefix="L" ) {
  function printCodeLine( $label="", $code="", $comment="" ) {
  function printCommentLine( $comment="" ) {
  */

  // helper functons:
  /*
  function byte2hex( $b ) {
  */

  // how many bytes does the start/end code take?
  // "burn" because of the heat generated when doing active delays...
  /*
  function num_start_code_cycles( $num ) {  // RCALL
  function burn_start_code( $num ) {
  function num_end_code_cycles( $num ) {    // RET
  function burn_end_code( $num ) {
  */


  // Level0: NOPs, Level1: 1 register, Level2: 2 rgisters:
  /*
  function burn_level_0( $num ) {

  function level_1_get_cycles( $startvalue ) {
  function burn_level_1( $num ) {

  function level_2_get_cycles( $A, $B ) {
  function burn_level_2( $num ) {
  */



  // time burn functions, generation of delay loops:

  
function getNewLabel$prefix="L" ) {
    global 
$LABEL_NUMBER;
    
$LABEL_NUMBER += 1;
    
$tmp "" $prefix $LABEL_NUMBER;
    return 
$tmp;
  }


  function 
printCodeLine$label=""$code=""$comment="" ) {
    
$column1 10;
    
$column2 15;

    
$L1 "<font color='FF0000'>";
    
$L2 "</font>";
    
$C1 "<font color='009900'>";
    
$C2 "</font>";

    
$label $label == "" " " "$label:";

    while (
strlen($label) < $column1$label .= " ";
    while (
strlen($code)  < $column2$code  .= " ";

    
$tmp  "$L1$label$L2 $code";
    
$tmp .= ($comment == "") ? "\n" $C1;$comment$C2\n";
    print 
$tmp;
  }


  function 
printCommentLine$comment="" ) {
    
$C1 "<font color='009900'>";
    
$C2 "</font>";
    
$comment $comment == "" "\n" "$C1$comment$C2\n";
    print 
$comment;
  }



  function 
num_start_code_cycles$num ) {
    global 
$callmethod$pcwidth;
    if (
$callmethod == "rcall") {
      if ((
$pcwidth==16) && ($num >= 3))  {
        return 
3;
      }
      if ((
$pcwidth==22) && ($num >= 4))  {
        return 
4;
      }
    }
    return 
0;
  }

  function 
burn_start_code$num ) {
    global 
$callmethod$pcwidth;
    
$numcycles num_start_code_cycles$num );
    if (
$callmethod == "rcall") {
      
$n getNewLabel();
      
printCodeLine$n"""RCALL $n ($numcycles cycles / $pcwidth Bit PC)" );
      return 
$numcycles;
    }
    return 
0;
  }

  function 
byte2hex$b ) {
    return 
sprintf("%02X"$b);
  }


  function 
num_end_code_cycles$num ) {
    global 
$callmethod$pcwidth;
    if (
$callmethod == "rcall") {
      if (
$pcwidth==16) {
        return 
4;
      }
      elseif (
$pcwidth==22) {
        return 
5;
      }
      else {
        print 
"unknown pc width. in num_end_code_cycles()\n";
      }
    }
    return 
0;
  }


  function 
burn_end_code$num ) {
    global 
$callmethod$pcwidth;

    
$cycles_needed num_end_code_cycles$num );

    if (
$cycles_need >= $num ) {
      if (
$callmethod == "rcall") {
        
printCodeLine"""ret""return (" $cycles_needed " cycles, $pcwidth Bit PC)" );
        return 
$cycles_need;
      }
    }
    else {
      print 
"out of cylces, burn_end_code()\n";
      return 
0;
    }
    return 
0;
  }


  
// -------------------------------------------------
  // -------------------------------------------------
  // Level 0 construction:
    /*
           nop  [nop...]
           ...
    */
  
function burn_level_0$num ) {
    
printCodeLine"""""$num NOPs:" );
    for (
$i 1$i <= $num$i++ ) {
      
printCodeLine"""nop""" );
    }
    return 
$num;
  }


  
// -------------------------------------------------
  // -------------------------------------------------
  // Level 1 construction:
    /*
           ldi Rxx, $xx
       L0: dec Rxx
           brne L0
           ...
    */

  // -------------------------------------------------
  
function level_1_get_cycles$startvalue ) {
    if (
$startvalue == 1) {
      return 
3;
    }
    return ( 
+ (($startvalue 1) * 3) + 2);
  }
  
// -------------------------------------------------

  
function burn_level_1$num ) {
    global 
$registers;

    if (
count($registers) == 0) {
      return 
0;
    }

    if ((
$num >= 3) && ($num <= ( (254*3) + 255*))) {

      
// find start value for loop:
      
$found false;
      
$test  256;
      while ((! 
$found ) && ($test >= 1)) {
        
$can_do level_1_get_cycles$test );
        
$found = ( $can_do <= $num );
        if (!
$found) { $test -= 1; }
      }

      if (
$found) {
        
$val  = ($test == 256) ? $test;
        
$val2 byte2hex$val );

        
$Rxx $registers[0];

        
$n getNewLabel();
        
printCodeLine"""ldi $Rxx, \$$val2"" = $val (decimal)" );
        
printCodeLine$n"dec $Rxx"         ""                  );
        
printCodeLine"""brne $Rxx$n"    "loop" );

        return 
round(level_1_get_cycles$test ));
      }

    }
    return 
0;
  }
  
// -------------------------------------------------
  // -------------------------------------------------

  // Level 2 construction:
    /*
           ldi Rxx, $xx   1
       L0: ldi Ryy, $yy   1    ___
       L1: dec Ryy        1     |
           brne L1        2/1  _|_1 X
           dec Rxx        1
           brne L0        2/1
           ...
    */

  // -------------------------------------------------
  
function level_2_get_cycles$A$B ) {
    
// $A = $A == 0 ? 256 : $A;
    // $B = $B == 0 ? 256 : $B;

    // annahme: A  != 1 und B != 1:
    
$X = (($A 1)*(1+2)) + (1+1);
    
$Y + (($B 1)*(1+$X+1+2)) + (1+$X+1+1);

    return 
$Y;
  }
  
// -------------------------------------------------


  
function burn_level_2$num ) {
    global 
$registers;

    
$bestes_a 1;
    
$bestes_b 1;
    
$bestes_unter_diff 50000;
    
$found false;

    for (
$i 1$i <= 256$i++) {
      
$j 1;
      
$abbruchJ false;
      while ((
$j <= 256) && (! $abbruchJ )) {
        
$Y level_2_get_cycles$i$j );
        if (
$Y <= $num) {
          if ((
$num $Y) < $bestes_unter_diff) {
            
$bestes_a $i;
            
$bestes_b $j;
            
$bestes_unter_diff $num $Y;
            
$found true;
          }
        }
        else {
          
$abbruchJ true;
        }
        
$j += 1;
      }
    }
    if (
$found) {
      
$gain level_2_get_cycles$bestes_a$bestes_b );
      
printCommentLine"LEVEL 2 LOOP: gain=$gain");

      
$val1  = ($bestes_a == 256) ? $bestes_a;
      
$val2  = ($bestes_b == 256) ? $bestes_b;

      
$val1h byte2hex$val1 );
      
$val2h byte2hex$val2 );

      
$Rxx $registers[0];
      
$Ryy $registers[1];

      
$n getNewLabel();
      
$m getNewLabel();

      
printCodeLine"""ldi $Rxx, \$$val1h"" \$$val1h = $val1 (decimal)" );
      
printCodeLine$n"ldi $Ryy, \$$val2h"" \$$val2h = $val2 (decimal)" );
      
printCodeLine$m"dec $Ryy""" );
      
printCodeLine"""brne $m"" );
      
printCodeLine"""dec $Rxx""" );
      
printCodeLine"""brne $n"" );
      return 
$gain;
    }

    return 
0;
  }

  
// -------------------------------------------------
  // -------------------------------------------------

?>