LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_math.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
22 #include "lms2012.h"
23 #include "c_math.h"
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 
29 //******* BYTE CODE SNIPPETS **************************************************
30 
46 void cMathAdd8(void)
47 {
48  DATA8 Tmp;
49 
50  Tmp = *(DATA8*)PrimParPointer();
51  Tmp += *(DATA8*)PrimParPointer();
52  *(DATA8*)PrimParPointer() = Tmp;
53 }
54 
55 
71 void cMathAdd16(void)
72 {
73  DATA16 Tmp;
74 
75  Tmp = *(DATA16*)PrimParPointer();
76  Tmp += *(DATA16*)PrimParPointer();
77  *(DATA16*)PrimParPointer() = Tmp;
78 }
79 
80 
96 void cMathAdd32(void)
97 {
98  DATA32 Tmp;
99 
100  Tmp = *(DATA32*)PrimParPointer();
101  Tmp += *(DATA32*)PrimParPointer();
102  *(DATA32*)PrimParPointer() = Tmp;
103 }
104 
105 
121 void cMathAddF(void)
122 {
123  DATAF Tmp;
124 
125  Tmp = *(DATAF*)PrimParPointer();
126  Tmp += *(DATAF*)PrimParPointer();
127  *(DATAF*)PrimParPointer() = Tmp;
128 }
129 
130 
146 void cMathSub8(void)
147 {
148  DATA8 Tmp;
149 
150  Tmp = *(DATA8*)PrimParPointer();
151  Tmp -= *(DATA8*)PrimParPointer();
152  *(DATA8*)PrimParPointer() = Tmp;
153 }
154 
155 
171 void cMathSub16(void)
172 {
173  DATA16 Tmp;
174 
175  Tmp = *(DATA16*)PrimParPointer();
176  Tmp -= *(DATA16*)PrimParPointer();
177  *(DATA16*)PrimParPointer() = Tmp;
178 }
179 
180 
196 void cMathSub32(void)
197 {
198  DATA32 Tmp;
199 
200  Tmp = *(DATA32*)PrimParPointer();
201  Tmp -= *(DATA32*)PrimParPointer();
202  *(DATA32*)PrimParPointer() = Tmp;
203 }
204 
205 
221 void cMathSubF(void)
222 {
223  DATAF Tmp;
224 
225  Tmp = *(DATAF*)PrimParPointer();
226  Tmp -= *(DATAF*)PrimParPointer();
227  *(DATAF*)PrimParPointer() = Tmp;
228 }
229 
230 
246 void cMathMul8(void)
247 {
248  DATA8 Tmp;
249 
250  Tmp = *(DATA8*)PrimParPointer();
251  Tmp *= *(DATA8*)PrimParPointer();
252  *(DATA8*)PrimParPointer() = Tmp;
253 }
254 
255 
271 void cMathMul16(void)
272 {
273  DATA16 Tmp;
274 
275  Tmp = *(DATA16*)PrimParPointer();
276  Tmp *= *(DATA16*)PrimParPointer();
277  *(DATA16*)PrimParPointer() = Tmp;
278 }
279 
280 
296 void cMathMul32(void)
297 {
298  DATA32 Tmp;
299 
300  Tmp = *(DATA32*)PrimParPointer();
301  Tmp *= *(DATA32*)PrimParPointer();
302  *(DATA32*)PrimParPointer() = Tmp;
303 }
304 
305 
321 void cMathMulF(void)
322 {
323  DATAF Tmp;
324 
325  Tmp = *(DATAF*)PrimParPointer();
326  Tmp *= *(DATAF*)PrimParPointer();
327  *(DATAF*)PrimParPointer() = Tmp;
328 }
329 
330 
346 void cMathDiv8(void)
347 {
348  DATA8 X,Y;
349 
350  X = *(DATA8*)PrimParPointer();
351  Y = *(DATA8*)PrimParPointer();
352  if (Y == 0)
353  {
354  if (X > 0)
355  {
356  X = (DATA8)DATA8_MAX;
357  }
358  if (X < 0)
359  {
360  X = (DATA8)DATA8_MIN;
361  }
362  }
363  else
364  {
365  X /= Y;
366  }
367  *(DATA8*)PrimParPointer() = X;
368 }
369 
370 
386 void cMathDiv16(void)
387 {
388  DATA16 X,Y;
389 
390  X = *(DATA16*)PrimParPointer();
391  Y = *(DATA16*)PrimParPointer();
392  if (Y == 0)
393  {
394  if (X > 0)
395  {
396  X = (DATA16)DATA16_MAX;
397  }
398  if (X < 0)
399  {
400  X = (DATA16)DATA16_MIN;
401  }
402  }
403  else
404  {
405  X /= Y;
406  }
407  *(DATA16*)PrimParPointer() = X;
408 }
409 
410 
426 void cMathDiv32(void)
427 {
428  DATA32 X,Y;
429 
430  X = *(DATA32*)PrimParPointer();
431  Y = *(DATA32*)PrimParPointer();
432  if (Y == 0)
433  {
434  if (X > 0)
435  {
436  X = (DATA32)DATA32_MAX;
437  }
438  if (X < 0)
439  {
440  X = (DATA32)DATA32_MIN;
441  }
442  }
443  else
444  {
445  X /= Y;
446  }
447  *(DATA32*)PrimParPointer() = X;
448 }
449 
450 
466 void cMathDivF(void)
467 {
468  DATAF X,Y;
469 
470  X = *(DATAF*)PrimParPointer();
471  Y = *(DATAF*)PrimParPointer();
472  X /= Y;
473  *(DATAF*)PrimParPointer() = X;
474 }
475 
476 
492 void cMathOr8(void)
493 {
494  DATA8 Tmp;
495 
496  Tmp = *(DATA8*)PrimParPointer();
497  Tmp |= *(DATA8*)PrimParPointer();
498  *(DATA8*)PrimParPointer() = Tmp;
499 }
500 
501 
517 void cMathOr16(void)
518 {
519  DATA16 Tmp;
520 
521  Tmp = *(DATA16*)PrimParPointer();
522  Tmp |= *(DATA16*)PrimParPointer();
523  *(DATA16*)PrimParPointer() = Tmp;
524 }
525 
526 
542 void cMathOr32(void)
543 {
544  DATA32 Tmp;
545 
546  Tmp = *(DATA32*)PrimParPointer();
547  Tmp |= *(DATA32*)PrimParPointer();
548  *(DATA32*)PrimParPointer() = Tmp;
549 }
550 
551 
567 void cMathAnd8(void)
568 {
569  DATA8 Tmp;
570 
571  Tmp = *(DATA8*)PrimParPointer();
572  Tmp &= *(DATA8*)PrimParPointer();
573  *(DATA8*)PrimParPointer() = Tmp;
574 }
575 
576 
592 void cMathAnd16(void)
593 {
594  DATA16 Tmp;
595 
596  Tmp = *(DATA16*)PrimParPointer();
597  Tmp &= *(DATA16*)PrimParPointer();
598  *(DATA16*)PrimParPointer() = Tmp;
599 }
600 
601 
617 void cMathAnd32(void)
618 {
619  DATA32 Tmp;
620 
621  Tmp = *(DATA32*)PrimParPointer();
622  Tmp &= *(DATA32*)PrimParPointer();
623  *(DATA32*)PrimParPointer() = Tmp;
624 }
625 
626 
642 void cMathXor8(void)
643 {
644  DATA8 Tmp;
645 
646  Tmp = *(DATA8*)PrimParPointer();
647  Tmp ^= *(DATA8*)PrimParPointer();
648  *(DATA8*)PrimParPointer() = Tmp;
649 }
650 
651 
667 void cMathXor16(void)
668 {
669  DATA16 Tmp;
670 
671  Tmp = *(DATA16*)PrimParPointer();
672  Tmp ^= *(DATA16*)PrimParPointer();
673  *(DATA16*)PrimParPointer() = Tmp;
674 }
675 
676 
692 void cMathXor32(void)
693 {
694  DATA32 Tmp;
695 
696  Tmp = *(DATA32*)PrimParPointer();
697  Tmp ^= *(DATA32*)PrimParPointer();
698  *(DATA32*)PrimParPointer() = Tmp;
699 }
700 
701 
717 void cMathRl8(void)
718 {
719  DATA8 Tmp;
720 
721  Tmp = *(DATA8*)PrimParPointer();
722  Tmp <<= *(DATA8*)PrimParPointer();
723  *(DATA8*)PrimParPointer() = Tmp;
724 }
725 
726 
742 void cMathRl16(void)
743 {
744  DATA16 Tmp;
745 
746  Tmp = *(DATA16*)PrimParPointer();
747  Tmp <<= *(DATA16*)PrimParPointer();
748  *(DATA16*)PrimParPointer() = Tmp;
749 }
750 
751 
767 void cMathRl32(void)
768 {
769  DATA32 Tmp;
770 
771  Tmp = *(DATA32*)PrimParPointer();
772  Tmp <<= *(DATA32*)PrimParPointer();
773  *(DATA32*)PrimParPointer() = Tmp;
774 }
775 
776 
925 void cMath(void)
926 {
927  DATAF X;
928  DATAF Y;
929  DATA8 X8;
930  DATA8 Y8;
931  DATA16 X16;
932  DATA16 Y16;
933  DATA32 X32;
934  DATA32 Y32;
935  DATA8 Cmd;
936  char Buf[64];
937  char *pBuf;
938 
939  Cmd = *(DATA8*)PrimParPointer();
940 
941  switch (Cmd)
942  {
943  case EXP :
944  {
945  X = *(DATAF*)PrimParPointer();
946  *(DATAF*)PrimParPointer() = expf(X);
947  }
948  break;
949 
950  case POW :
951  {
952  X = *(DATAF*)PrimParPointer();
953  Y = *(DATAF*)PrimParPointer();
954  *(DATAF*)PrimParPointer() = powf(X,Y);
955  }
956  break;
957 
958  case MOD8 :
959  {
960  X8 = *(DATA8*)PrimParPointer();
961  Y8 = *(DATA8*)PrimParPointer();
962  *(DATA8*)PrimParPointer() = X8 % Y8;
963  }
964  break;
965 
966  case MOD16 :
967  {
968  X16 = *(DATA16*)PrimParPointer();
969  Y16 = *(DATA16*)PrimParPointer();
970  *(DATA16*)PrimParPointer() = X16 % Y16;
971  }
972  break;
973 
974  case MOD32 :
975  {
976  X32 = *(DATA32*)PrimParPointer();
977  Y32 = *(DATA32*)PrimParPointer();
978  *(DATA32*)PrimParPointer() = X32 % Y32;
979  }
980  break;
981 
982  case MOD :
983  {
984  X = *(DATAF*)PrimParPointer();
985  Y = *(DATAF*)PrimParPointer();
986  *(DATAF*)PrimParPointer() = fmod(X,Y);
987  }
988  break;
989 
990  case FLOOR :
991  {
992  X = *(DATAF*)PrimParPointer();
993  *(DATAF*)PrimParPointer() = floor(X);
994  }
995  break;
996 
997  case CEIL :
998  {
999  X = *(DATAF*)PrimParPointer();
1000  *(DATAF*)PrimParPointer() = ceil(X);
1001  }
1002  break;
1003 
1004  case ROUND :
1005  {
1006  X = *(DATAF*)PrimParPointer();
1007  if (X < (DATAF)0)
1008  {
1009  *(DATAF*)PrimParPointer() = ceil(X - (DATAF)0.5);
1010  }
1011  else
1012  {
1013  *(DATAF*)PrimParPointer() = floor(X + (DATAF)0.5);
1014  }
1015  }
1016  break;
1017 
1018  case ABS :
1019  {
1020  X = *(DATAF*)PrimParPointer();
1021  *(DATAF*)PrimParPointer() = fabs(X);
1022  }
1023  break;
1024 
1025  case NEGATE :
1026  {
1027  X = *(DATAF*)PrimParPointer();
1028  *(DATAF*)PrimParPointer() = (DATAF)0 - X;
1029  }
1030  break;
1031 
1032  case TRUNC :
1033  {
1034  X = *(DATAF*)PrimParPointer();
1035  Y8 = *(DATA8*)PrimParPointer();
1036 
1037  if (Y8 > 9)
1038  {
1039  Y8 = 9;
1040  }
1041  if (Y8 < 0)
1042  {
1043  Y8 = 0;
1044  }
1045 
1046  snprintf(Buf,64,"%f",X);
1047 
1048  pBuf = strstr(Buf,".");
1049  if (pBuf != NULL)
1050  {
1051  pBuf[Y8 + 1] = 0;
1052  }
1053  sscanf(Buf,"%f",&X);
1054  *(DATAF*)PrimParPointer() = X;
1055  }
1056  break;
1057 
1058  case SQRT :
1059  {
1060  X = *(DATAF*)PrimParPointer();
1061  *(DATAF*)PrimParPointer() = sqrt(X);
1062  }
1063  break;
1064 
1065  case LOG :
1066  {
1067  X = *(DATAF*)PrimParPointer();
1068  *(DATAF*)PrimParPointer() = log10(X);
1069  }
1070  break;
1071 
1072  case LN :
1073  {
1074  X = *(DATAF*)PrimParPointer();
1075  *(DATAF*)PrimParPointer() = log(X);
1076  }
1077  break;
1078 
1079  case SIN :
1080  {
1081  X = *(DATAF*)PrimParPointer();
1082  X = DegToRad(X);
1083  X = sinf(X);
1084  *(DATAF*)PrimParPointer() = X;
1085  }
1086  break;
1087 
1088  case COS :
1089  {
1090  X = *(DATAF*)PrimParPointer();
1091  X = DegToRad(X);
1092  X = cosf(X);
1093  *(DATAF*)PrimParPointer() = X;
1094  }
1095  break;
1096 
1097  case TAN :
1098  {
1099  X = *(DATAF*)PrimParPointer();
1100  X = DegToRad(X);
1101  X = tanf(X);
1102  *(DATAF*)PrimParPointer() = X;
1103  }
1104  break;
1105 
1106  case ASIN :
1107  {
1108  X = *(DATAF*)PrimParPointer();
1109  X = asinf(X);
1110  X = RadToDeg(X);
1111  *(DATAF*)PrimParPointer() = X;
1112  }
1113  break;
1114 
1115  case ACOS :
1116  {
1117  X = *(DATAF*)PrimParPointer();
1118  X = acosf(X);
1119  X = RadToDeg(X);
1120  *(DATAF*)PrimParPointer() = X;
1121  }
1122  break;
1123 
1124  case ATAN :
1125  {
1126  X = *(DATAF*)PrimParPointer();
1127  X = atanf(X);
1128  X = RadToDeg(X);
1129  *(DATAF*)PrimParPointer() = X;
1130  }
1131  break;
1132 
1133  }
1134 
1135 }
1136 
1137 
1138 //*****************************************************************************
1139 
void cMathAnd16(void)
opAND16
Definition: c_math.c:592
void cMathSub16(void)
opSUB16
Definition: c_math.c:171
#define snprintf
Definition: c_input.c:141
#define DATA8_MIN
Definition: bytecodes.h:1497
void cMath(void)
opMATH
Definition: c_math.c:925
#define DATA32_MAX
Definition: bytecodes.h:1502
SWORD DATA16
VM Type for 2 byte signed value.
Definition: lmstypes.h:62
void cMathDiv16(void)
opDIV16
Definition: c_math.c:386
SLONG DATA32
VM Type for 4 byte signed value.
Definition: lmstypes.h:63
void cMathMulF(void)
opMULF
Definition: c_math.c:321
#define DATA16_MAX
Definition: bytecodes.h:1500
void cMathAdd8(void)
opADD8
Definition: c_math.c:46
void cMathAddF(void)
opADDF
Definition: c_math.c:121
void * PrimParPointer(void)
Get next encoded parameter from byte code stream.
Definition: lms2012.c:694
void cMathXor16(void)
opXOR16
Definition: c_math.c:667
void cMathRl32(void)
opRL32
Definition: c_math.c:767
void cMathOr8(void)
opOR8
Definition: c_math.c:492
#define DATA32_MIN
Definition: bytecodes.h:1501
void cMathAnd32(void)
opAND32
Definition: c_math.c:617
void cMathDivF(void)
opDIVF
Definition: c_math.c:466
void cMathXor8(void)
opXOR8
Definition: c_math.c:642
void cMathRl8(void)
opRL8
Definition: c_math.c:717
void cMathDiv32(void)
opDIV32
Definition: c_math.c:426
void cMathSub32(void)
opSUB32
Definition: c_math.c:196
void cMathOr32(void)
opOR32
Definition: c_math.c:542
void cMathMul8(void)
opMUL8
Definition: c_math.c:246
void cMathSub8(void)
opSUB8
Definition: c_math.c:146
void cMathDiv8(void)
opDIV8
Definition: c_math.c:346
void cMathMul16(void)
opMUL16
Definition: c_math.c:271
FLOAT DATAF
VM Type for 4 byte floating point value.
Definition: lmstypes.h:64
void cMathRl16(void)
opRL16
Definition: c_math.c:742
#define DegToRad(D)
Definition: c_math.h:25
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
#define DATA16_MIN
Definition: bytecodes.h:1499
void cMathMul32(void)
opMUL32
Definition: c_math.c:296
void cMathAnd8(void)
opAND8
Definition: c_math.c:567
void cMathAdd32(void)
opADD32
Definition: c_math.c:96
void cMathOr16(void)
opOR16
Definition: c_math.c:517
void cMathSubF(void)
opSUBF
Definition: c_math.c:221
void cMathAdd16(void)
opADD16
Definition: c_math.c:71
#define RadToDeg(R)
Definition: c_math.h:27
#define DATA8_MAX
Definition: bytecodes.h:1498
#define NULL
void cMathXor32(void)
opXOR32
Definition: c_math.c:692