Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/engine/docalc.c
diff options
context:
space:
mode:
authorBernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
committer Bernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
commit1030dc837b10a03a02a85d5504cbeec168ce49e2 (patch)
tree698eefa87ac437deaf36a4141b326f8ce7986692 /src/engine/docalc.c
Import XaoS r489 (trunk after version 3.5)
Diffstat (limited to 'src/engine/docalc.c')
-rw-r--r--src/engine/docalc.c790
1 files changed, 790 insertions, 0 deletions
diff --git a/src/engine/docalc.c b/src/engine/docalc.c
new file mode 100644
index 0000000..9cacf27
--- /dev/null
+++ b/src/engine/docalc.c
@@ -0,0 +1,790 @@
+
+/* Hello reader!
+
+ * Are you sure you want read this? Its very cryptic and strange code. YOU
+ * HAVE BEEN WARNED! Its purpose is to genereate as fast as possible
+ * calculation loops for various formulas/algorithms. It uses lots of
+ * coprocesor magic. It is included from formulas.c
+ */
+
+#ifndef VARIABLES /*supply defaultd values */
+#define VARIABLES
+#endif
+#ifndef PRETEST
+#define PRETEST 0
+#endif
+#ifndef INIT
+#define INIT
+#endif
+#ifndef POSTCALC
+#define POSTCALC
+#endif
+#ifndef PRESMOOTH
+#define PRESMOOTH zre=rp+ip
+#endif
+#ifndef UFORMULA
+#define UFORMULA FORMULA
+#endif
+#ifndef UEND
+#define UEND
+#endif
+#ifndef SAVE
+#define SAVE
+#endif
+#ifndef SAVEVARIABLES
+#define SAVEVARIABLES
+#endif
+#ifndef RESTORE
+#define RESTORE
+#endif
+#ifndef RANGE
+#define RANGE 2
+#endif
+#ifndef __GNUC__
+#undef USEHACKS
+#endif
+#ifndef __i386__
+#undef USEHACKS
+#endif
+#ifdef NOASSEMBLY
+#undef USEHACKS
+#endif
+
+/* Prepare main loop */
+#ifndef NSFORMULALOOP
+#define NSFORMULALOOP(iter) \
+ do \
+ { /*try first 8 iterations */ \
+ FORMULA; \
+ iter--; \
+ } \
+ while (BTEST && iter)
+#endif
+#ifndef SFORMULALOOP
+#define SFORMULALOOP(iter) \
+ do \
+ { /*try first 8 iterations */ \
+ SAVEZMAG; \
+ FORMULA; \
+ iter--; \
+ } \
+ while (BTEST && iter)
+#endif
+#ifndef FORMULALOOP
+#ifdef SMOOTHMODE
+#define FORMULALOOP SFORMULALOOP
+#else
+#define FORMULALOOP NSFORMULALOOP
+#endif
+#endif
+
+#ifdef USEHACKS
+#ifdef RPIP
+#define I386HACK1 __asm__ ("#HACK1" : \
+ : \
+ "m" (szre), \
+ "m" (szim) \
+ );
+#define I386HACK __asm__ ("#HACK" : \
+ : \
+ "f" (zre), \
+ "f" (zim) \
+ );
+#else
+#define I386HACK __asm__ ("#HACK" : \
+ : \
+ "f" (zre), \
+ "f" (zim) \
+ );
+#endif
+#else
+#define I386HACK
+#define I386HACK1
+#endif
+
+#ifdef SMOOTHMODE
+#ifdef CUSTOMSAVEZMAG
+#define SAVEZMAG CUSTOMSAVEZMAG;
+#else
+#define SAVEZMAG szmag=rp+ip;
+#endif
+#else
+#define SAVEZMAG
+#endif
+
+#ifdef UNCOMPRESS
+/*uncompressed version of loop */
+#ifdef SMOOTHMODE
+static unsigned int FUNCTYPE
+SCALC(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+SCALC(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#else
+static unsigned int FUNCTYPE
+CALC(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned
+CALC(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#endif
+{
+ register unsigned int iter = cfractalc.maxiter;
+ number_t szre = 0, szim = 0;
+#ifdef RPIP
+ register number_t rp = 0, ip;
+#endif
+#ifdef SMOOTHMODE
+ number_t szmag = 0;
+#endif
+ SAVEVARIABLES VARIABLES;
+ INIT;
+ if (PRETEST)
+ iter = 0;
+ else {
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ if (iter < 16) {
+ I386HACK1;
+ I386HACK;
+
+ /*try first 8 iterations */
+ if (BTEST && iter) {
+ FORMULALOOP(iter);
+ }
+ /*
+ while (BTEST && iter)
+ {
+ SAVEZMAG;
+ FORMULA;
+ iter--;
+ } */
+ } else {
+ iter = 8 + (cfractalc.maxiter & 7);
+ I386HACK1;
+ I386HACK;
+
+ /*try first 8 iterations */
+ if (BTEST && iter) {
+ FORMULALOOP(iter);
+ }
+ /*
+ while (BTEST && iter)
+ {
+ SAVEZMAG;
+ FORMULA;
+ iter--;
+ } */
+ if (BTEST) {
+ iter = (cfractalc.maxiter - 8) & (~7);
+ iter >>= 3;
+ I386HACK1;
+ I386HACK; /*do next 8 iteration w/o out of bounds checking */
+ do {
+ /*hmm..we are probably in some deep area. */
+ szre = zre; /*save current possition */
+ szim = zim;
+ SAVE;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UFORMULA;
+ UEND;
+ iter--;
+ }
+ while (BTEST && iter);
+ if (!(BTEST)) { /*we got out of bounds */
+ iter <<= 3;
+ iter += 8; /*restore saved possition */
+ RESTORE;
+ zre = szre;
+ zim = szim;
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ I386HACK1;
+ I386HACK;
+ FORMULALOOP(iter);
+ /*
+ do
+ {
+ SAVEZMAG
+ FORMULA;
+ iter--;
+ }
+ while (BTEST && iter); */
+ }
+ } else
+ iter += cfractalc.maxiter - 8 - (cfractalc.maxiter & 7);
+ }
+ }
+#ifdef SMOOTHMODE
+ if (iter)
+ SMOOTHOUTPUT();
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ INOUTPUT();
+#else
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ OUTPUT();
+#endif
+}
+#else
+#ifdef SMOOTHMODE
+static unsigned int FUNCTYPE
+SCALC(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+SCALC(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#else
+static unsigned int FUNCTYPE
+CALC(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+CALC(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#endif
+{
+ register unsigned int iter = cfractalc.maxiter /*& (~(int) 3) */ ;
+#ifdef RPIP
+ register number_t rp, ip;
+#endif
+#ifdef SMOOTHMODE
+ number_t szmag = 0;
+#endif
+ VARIABLES;
+ INIT;
+ if (PRETEST)
+ iter = 0;
+ else {
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ if (BTEST && iter) {
+ FORMULALOOP(iter);
+ }
+ /*
+ while (BTEST && iter)
+ {
+ I386HACK;
+ SAVEZMAG
+ FORMULA;
+ iter--;
+
+ } */
+ }
+#ifdef SMOOTHMODE
+ if (iter)
+ SMOOTHOUTPUT();
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ INOUTPUT();
+#else
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ OUTPUT();
+#endif
+}
+#endif
+
+
+/*F. : Periodicity checking rountines. (16-02-97)
+ All comments preceded by F. are mine (Fabrice Premel premelfa@etu.utc.fr).
+ Tried to make code as efficient as possible.
+ Next to do is convert lim in a variable that would be updated sometimes
+ I'll try to make here a short explanation on periodicity checking :
+ first, we'll define 2 variables : whentosave and whenincsave, which are, respectively,
+ a measure of when we have to update saved values to be checked, and when to increase
+ interval between 2 updates, as if they're too close, we'll miss large periods.
+ We save Z at the beginning, and then we compare each new iteration with this Z, and if naerly
+ equal, we declare the suite to be periodic.
+ When ( iter mod whentosave ) == 0, we store a new value, and we repeat.
+
+ UNCOMPRESSed form is just an extension, with careful that if we only check whentosave
+ all 8 iterations, number of iterations must be well set at the begining.This is
+ done by adding a (iter&7) in the while statement preceeding then uncompressed
+ calculation. */
+
+/*F. : This is from then lim factor that depends all periodicity check spped : the bigger it is, the faster we
+ can detect periodicity, but the bigger it is, the more we can introduce errors.
+ I suggest a value of (maxx-minx)/(double)getmaxx for a classic Mandelbrot Set,
+ and maybe a lesser value for an extra power Mandelbrot.
+ But this should be calculated outter from here (ie each frame, for example), to avoid
+ new calculs */
+#ifdef PERI
+#define PCHECK (abs_less_than(r1 - zre, cfractalc.periodicity_limit) && abs_less_than(s1 - zim, cfractalc.periodicity_limit))
+
+#ifndef UNCOMPRESS
+
+#ifdef SMOOTHMODE
+static unsigned int FUNCTYPE
+SPERI(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+SPERI(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#else
+static unsigned int FUNCTYPE
+PERI(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+PERI(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#endif
+{
+ register unsigned int iter =
+ cfractalc.maxiter /*& (~(int) 3) */ , iter1 =
+ 8;
+ register number_t r1, s1;
+ int whensavenew, whenincsave;
+#ifdef RPIP
+ register number_t rp, ip;
+#endif
+#ifdef SMOOTHMODE
+ number_t szmag = 0;
+#endif
+ VARIABLES;
+ INIT;
+ if (PRETEST)
+ iter = 0;
+ else {
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ I386HACK;
+ if (iter < iter1)
+ iter1 = iter, iter = 8;
+
+ /*H. : do first few iterations w/o checking */
+ if (BTEST && iter1) {
+ FORMULALOOP(iter1);
+ }
+ /*
+ while (BTEST && iter1)
+ {
+ SAVEZMAG;
+ FORMULA;
+ iter1--;
+ } */
+ if (iter1) {
+ if (iter >= 8)
+ iter -= 8 - iter1;
+ goto end;
+ }
+ if (iter <= 8) {
+ iter = iter1;
+ } else {
+ iter -= 8;
+ r1 = zre;
+ s1 = zim;
+ whensavenew = 3; /*You should adapt theese values */
+ /*F. : We should always define whensavenew as 2^N-1, so we could use a AND instead of % */
+
+ whenincsave = 10;
+ /*F. : problem is that after deep zooming, peiodicity is never detected early, cause is is
+ quite slow before going in a periodic loop.
+ So, we should start checking periodicity only after some times */
+ while (BTEST && iter) {
+ SAVEZMAG;
+ FORMULA;
+ if ((iter & whensavenew) == 0) { /*F. : changed % to & */
+ r1 = zre;
+ s1 = zim;
+ whenincsave--;
+ if (!whenincsave) {
+ whensavenew = ((whensavenew + 1) << 1) - 1; /*F. : Changed to define a new AND mask */
+ whenincsave = 10;
+ }
+ } else {
+ if (PCHECK) {
+ PERIINOUTPUT();
+ }
+ }
+ iter--;
+
+ }
+ }
+ }
+ end:
+#ifdef SMOOTHMODE
+ if (iter)
+ SMOOTHOUTPUT();
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ INOUTPUT();
+#else
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ OUTPUT();
+#endif
+}
+
+#else
+
+/*F. : UNCOMPRESSed version. Note that whensavenew+1 should be a multiple of 8, else periodicity won't be able
+ to detect anything. */
+/*F. : this macros definitions are really strange, but after a while, it's good */
+
+#ifdef SMOOTHMODE
+static unsigned int FUNCTYPE
+SPERI(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+SPERI(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#else
+static unsigned int FUNCTYPE
+PERI(register number_t zre, register number_t zim, register number_t pre,
+ register number_t pim)
+CONSTF REGISTERS(3);
+REGISTERS(3)
+static unsigned int FUNCTYPE
+PERI(register number_t zre, register number_t zim,
+ register number_t pre, register number_t pim)
+#endif
+{
+ register unsigned int iter = cfractalc.maxiter /*& (~(int) 3) */ ;
+ register number_t r1 = zre, s1 = zim;
+ number_t szre = 0, szim = 0; /*F. : Didn't declared register, cause they are few used */
+ unsigned int whensavenew, whenincsave;
+#ifdef RPIP
+ register number_t rp = 0, ip;
+#endif
+#ifdef SMOOTHMODE
+ number_t szmag = 0;
+#endif
+ SAVEVARIABLES VARIABLES;
+ INIT;
+ if (PRETEST)
+ iter = 0;
+ else {
+ if (cfractalc.maxiter <= 16) {
+ I386HACK1;
+ /*I386HACK; */
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ /*F. : Added iter&7 to be sure we'll be on a 8 multiple */
+ if (BTEST && iter) {
+ FORMULALOOP(iter);
+ }
+ /*
+ while (BTEST && iter)
+ {
+ SAVEZMAG
+ FORMULA;
+ iter--;
+ } */
+ } else {
+ whensavenew = 7; /*You should adapt theese values */
+ /*F. : We should always define whensavenew as 2^N-1, so we could use a AND instead of % */
+
+ whenincsave = 10;
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ /*F. : problem is that after deep zooming, peiodicity is never detected early, cause is is
+ quite slow before going in a periodic loop.
+ So, we should start checking periodicity only after some times */
+ I386HACK1;
+ /*I386HACK; */
+ iter = 8 + (cfractalc.maxiter & 7);
+ while (BTEST && iter) { /*F. : Added iter&7 to be sure we'll be on a 8 multiple */
+ SAVEZMAG FORMULA;
+ iter--;
+ }
+ if (BTEST) { /*F. : BTEST is calculed two times here, isn't it ? */
+ /*H. : No gcc is clever and adds test to the end :) */
+ iter = (cfractalc.maxiter - 8) & (~7);
+ do {
+ szre = zre, szim = zim;
+ SAVE;
+ SAVEZMAG
+ /*I386HACK; */
+ I386HACK1;
+ FORMULA; /*F. : Calculate one time */
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ FORMULA;
+ if (PCHECK)
+ goto periodicity;
+ iter -= 8;
+ /*F. : We only test this now, as it can't be true before */
+ if ((iter & whensavenew) == 0) { /*F. : changed % to & */
+ r1 = zre, s1 = zim; /*F. : Save new values */
+ whenincsave--;
+ if (!whenincsave) {
+ whensavenew = ((whensavenew + 1) << 1) - 1; /*F. : Changed to define a new AND mask */
+ whenincsave = 10; /*F. : Start back */
+ }
+ }
+ }
+ while (BTEST && iter);
+ if (!BTEST) { /*we got out of bounds */
+ iter += 8; /*restore saved possition */
+ RESTORE;
+ zre = szre;
+ zim = szim;
+#ifdef RPIP
+ rp = zre * zre;
+ ip = zim * zim;
+#endif
+ I386HACK1;
+ /*I386HACK; */
+ FORMULALOOP(iter);
+ /*
+ do
+ {
+ SAVEZMAG
+ FORMULA;
+ iter--;
+ }
+ while (BTEST && iter); */
+ }
+ } else
+ iter += cfractalc.maxiter - 8 - (cfractalc.maxiter & 7);
+ }
+ }
+#ifdef SMOOTHMODE
+ if (iter)
+ SMOOTHOUTPUT();
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ INOUTPUT();
+#else
+ POSTCALC;
+ iter = cfractalc.maxiter - iter;
+ OUTPUT();
+#endif
+ periodicity:
+ PERIINOUTPUT();
+}
+
+/*else uncompress */
+#endif
+
+/*endif PERI */
+#undef PCHECK
+#endif
+
+#ifndef SMOOTHMODE
+#ifdef JULIA
+static void
+JULIA(struct image *image, register number_t pre, register number_t pim)
+{
+ int i, i1, i2, j, x, y;
+ unsigned char iter, itmp2, itmp;
+ number_t rp = 0, ip = 0;
+ register number_t zre, zim, im, xdelta, ydelta, range, rangep;
+ number_t xstep, ystep;
+ unsigned char *queue[QMAX];
+ unsigned char **qptr;
+ unsigned char *addr, **addr1 = image->currlines;
+#ifdef STATISTICS
+ int guessed = 0, unguessed = 0, iters = 0;
+#endif
+ VARIABLES;
+ range = (number_t) RANGE;
+ rangep = range * range;
+
+ xdelta = image->width / (RMAX - RMIN);
+ ydelta = image->height / (IMAX - IMIN);
+ xstep = (RMAX - RMIN) / image->width;
+ ystep = (IMAX - IMIN) / image->height;
+ init_julia(image, rangep, range, xdelta, ystep);
+ for (i2 = 0; i2 < 2; i2++)
+ for (i1 = 0; i1 < image->height; i1++) {
+ if (i1 % 2)
+ i = image->height / 2 - i1 / 2;
+ else
+ i = image->height / 2 + i1 / 2 + 1;
+ if (i >= image->height)
+ continue;
+ im = IMIN + (i + 0.5) * ystep;
+ for (j = (i + i2) & 1; j < image->width; j += 2) {
+ STAT(total2++);
+ addr = addr1[i] + j;
+ if (*addr != NOT_CALCULATED)
+ continue;
+ x = j;
+ y = i;
+ if (y > 0 && y < image->height - 1 && *(addr + 1) &&
+ x > 0 && x < image->width - 1) {
+ if ((iter = *(addr + 1)) != NOT_CALCULATED
+ && iter == *(addr - 1) && iter == addr1[y - 1][x]
+ && iter == addr1[y + 1][x]) {
+ *addr = *(addr + 1);
+ continue;
+ }
+ }
+ zim = im;
+ zre = RMIN + (j + 0.5) * xstep;
+ iter = (unsigned char) 0;
+ qptr = queue;
+ ip = (zim * zim);
+ rp = (zre * zre);
+ INIT;
+ while (1) {
+ if (*addr != NOT_CALCULATED
+#ifdef SAG
+ && (*addr == INPROCESS
+ || (*addr != (unsigned char) 1
+ && (itmp2 = *(addr + 1)) != NOT_CALCULATED
+ && ((itmp2 != (itmp = *(addr - 1))
+ && itmp != NOT_CALCULATED)
+ || (itmp2 !=
+ (itmp = *((addr1[y + 1]) + x))
+ && itmp != NOT_CALCULATED)
+ || (itmp2 !=
+ (itmp = *((addr1[y - 1]) + x))
+ && itmp != NOT_CALCULATED))))
+#endif
+ ) {
+ if (*addr == INPROCESS || *addr == INSET) {
+ *qptr = addr;
+ qptr++;
+ STAT(guessed++);
+ goto inset;
+ }
+ STAT(guessed++);
+ iter = *addr;
+ goto outset;
+ }
+#ifdef STATISTICS
+ if (*addr != NOT_CALCULATED)
+ unguessed++;
+#endif
+ if (*addr != INPROCESS) {
+ *qptr = addr;
+ qptr++;
+ *addr = INPROCESS;
+ if (qptr >= queue + QMAX)
+ goto inset;
+ }
+ STAT(iters++);
+ FORMULA;
+ ip = (zim * zim);
+ rp = (zre * zre);
+ if (greater_than(rp + ip, RANGE) || !(BTEST))
+ goto outset;
+ x = (int) ((zre - RMIN) * xdelta);
+ y = (int) ((zim - IMIN) * ydelta);
+ addr = addr1[y] + x;
+ if ((itmp = *(addr + 1)) != NOT_CALCULATED
+ && itmp == *(addr - 1) && itmp == addr1[y - 1][x]
+ && itmp == addr1[y + 1][x]) {
+ *addr = *(addr + 1);
+ }
+ }
+ inset:
+ while (qptr > queue) {
+ qptr--;
+ **qptr = INSET;
+ }
+ continue;
+ outset:
+ y = image->palette->size;
+ while (qptr > queue) {
+ qptr--;
+ iter++;
+ if ((int) iter >= y)
+ iter = (unsigned char) 1;
+ **qptr = iter;
+ }
+ }
+ }
+#ifdef STATISTICS
+ printf("guessed %i, unguessed %i, iterations %i\n", guessed, unguessed,
+ iters);
+ guessed2 += guessed;
+ unguessed2 += unguessed;
+ iters2 += iters;
+#endif
+}
+#endif
+#endif
+
+#undef FORMULALOOP
+#undef PCHECK
+#undef I386HACK
+#undef I386HACK1
+#undef SAVEZMAG
+#ifndef SMOOTHMODE
+#ifdef SMOOTH
+#define SMOOTHMODE
+#include "docalc.c"
+#endif
+#endif
+
+/*cleanup for next formula */
+#undef NSFORMULALOOP
+#undef SFORMULALOOP
+#undef PRESMOOTH
+#undef SMOOTH
+#undef SMOOTHMODE
+#undef RANGE
+#undef JULIA
+#undef PERI
+#undef SPERI
+#undef INIT
+#undef VARIABLES
+#undef PRETEST
+#undef BTEST
+#undef FORMULA
+#undef CALC
+#undef SCALC
+#undef RPIP
+#undef POSTCALC
+#undef UNCOMPRESS
+#undef SAVE
+#undef SAVEVARIABLES
+#undef RESTORE
+#undef USEHACKS
+#undef UFORMULA
+#undef UEND