return OK;
}
+
+//
+// .if, Start conditional assembly
+//
+int d_if(void)
+{
+ WORD eattr;
+ VALUE eval;
+ SYM * esym;
+ IFENT * rif = f_ifent;
+
+ // Alloc an IFENTRY
+ if (rif == NULL)
+ rif = (IFENT *)malloc(sizeof(IFENT));
+ else
+ f_ifent = rif->if_prev;
+
+ rif->if_prev = ifent;
+ ifent = rif;
+
+ if (!disabled)
+ {
+ if (expr(exprbuf, &eval, &eattr, &esym) != OK)
+ return 0;
+
+ if ((eattr & DEFINED) == 0)
+ return error(undef_error);
+
+ disabled = !eval;
+ }
+
+ rif->if_state = (WORD)disabled;
+ return 0;
+}
+
+
+//
+// .else, Do alternate case for .if
+//
+int d_else(void)
+{
+ IFENT * rif = ifent;
+
+ if (rif->if_prev == NULL)
+ return error("mismatched .else");
+
+ if (disabled)
+ disabled = rif->if_prev->if_state;
+ else
+ disabled = 1;
+
+ rif->if_state = (WORD)disabled;
+ return 0;
+}
+
+
+//
+// .endif, End of conditional assembly block
+// This is also called by fpop() to pop levels of IFENTs in case a macro or
+// include file exits early with `exitm' or `end'.
+//
+int d_endif(void)
+{
+ IFENT * rif = ifent;
+
+ if (rif->if_prev == NULL)
+ return error("mismatched .endif");
+
+ ifent = rif->if_prev;
+ disabled = rif->if_prev->if_state;
+ rif->if_prev = f_ifent;
+ f_ifent = rif;
+ return 0;
+}
+
int d_dphrase(void);
int d_qphrase(void);
+int d_if(void);
+int d_else(void);
+int d_endif(void);
+
#endif // __DIRECT_H__
static SYM * curmac; // Macro currently being defined
static VALUE argno; // Formal argument count
-static LONG * firstrpt; // First .rept line
-static LONG * nextrpt; // Last .rept line
+static LLIST * firstrpt; // First .rept line
+static LLIST * nextrpt; // Last .rept line
static int rptlevel; // .rept nesting level
// Function prototypes
int ExitMacro(void)
{
WARNING(!!! Bad macro exiting !!!)
-
/*
This is a problem. Currently, the argument logic just keeps the current
arguments and doesn't save anything if a new macro is called in the middle
//
int defmac2(char * argname)
{
- SYM * arg;
-
if (lookup(argname, MACARG, (int)curmac->sattr) != NULL)
return error("multiple formal argument definition");
- arg = NewSymbol(argname, MACARG, (int)curmac->sattr);
+ SYM * arg = NewSymbol(argname, MACARG, (int)curmac->sattr);
arg->svalue = argno++;
return OK;
#else
if (curmac->lineList == NULL)
{
- curmac->lineList = malloc(sizeof(struct LineList));
+ curmac->lineList = malloc(sizeof(LLIST));
curmac->lineList->next = NULL;
curmac->lineList->line = strdup(ln);
curmac->last = curmac->lineList;
}
else
{
- curmac->last->next = malloc(sizeof(struct LineList));
+ curmac->last->next = malloc(sizeof(LLIST));
curmac->last->next->next = NULL;
curmac->last->next->line = strdup(ln);
curmac->last = curmac->last->next;
//
// Add lines to a .rept definition
//
-int defr1(char * ln, int kwno)
+int defr1(char * line, int kwno)
{
if (list_flag)
{
- listeol(); // Flush previous source line
- lstout('#'); // Mark this a 'rept' block
+ listeol(); // Flush previous source line
+ lstout('#'); // Mark this a 'rept' block
}
- switch (kwno)
+ if (kwno == 0) // .endr
{
- case 0: // .endr
if (--rptlevel == 0)
return 0;
-
- break;
- case 1: // .rept
- rptlevel++;
}
+ else if (kwno == 1) // .rept
+ rptlevel++;
+//DEBUG { printf(" defr1: line=\"%s\", kwno=%d, rptlevel=%d\n", line, kwno, rptlevel); }
+
+#if 0
//MORE stupidity here...
WARNING("!!! Casting (char *) as LONG !!!")
// Allocate length of line + 1('\0') + LONG
- LONG len = strlen(ln) + 1 + sizeof(LONG);
- LONG * p = (LONG *)malloc(len);
+ LONG * p = (LONG *)malloc(strlen(line) + 1 + sizeof(LONG));
*p = 0;
-
- strcpy((char *)(p + 1), ln);
+ strcpy((char *)(p + 1), line);
if (nextrpt == NULL)
- {
firstrpt = p; // First line of rept statement
- }
else
- {
*nextrpt = (LONG)p;
- }
nextrpt = p;
+#else
+ if (firstrpt == NULL)
+ {
+ firstrpt = malloc(sizeof(LLIST));
+ firstrpt->next = NULL;
+ firstrpt->line = strdup(line);
+ nextrpt = firstrpt;
+ }
+ else
+ {
+ nextrpt->next = malloc(sizeof(LLIST));
+ nextrpt->next->next = NULL;
+ nextrpt->next->line = strdup(line);
+ nextrpt = nextrpt->next;
+ }
+#endif
return rptlevel;
}
//
-// Define a .rept block, this gets hairy because they can be nested
+// Handle a .rept block; this gets hairy because they can be nested
//
-int DefineRept(void)
+int HandleRept(void)
{
VALUE eval;
rptlevel = 1;
LNCatch(defr1, "endr rept ");
+//DEBUG { printf("HandleRept: firstrpt=$%X\n", firstrpt); }
// Alloc and init input object
if (firstrpt)
{
//
// Hand off lines of text to the function 'lnfunc' until a line containing one
-// of the directives in 'dirlist' is encountered. Return the number of the
-// keywords encountered (0..n)
+// of the directives in 'dirlist' is encountered.
//
-// 'dirlist' contains null-seperated terminated keywords. A final null
-// terminates the list. Directives are compared to the keywords without regard
-// to case.
+// 'dirlist' contains space-separated terminated keywords. A final space
+// terminates the list. Directives are case-insensitively compared to the
+// keywords.
//
// If 'lnfunc' is NULL, then lines are simply skipped.
// If 'lnfunc' returns an error, processing is stopped.
//
static int LNCatch(int (* lnfunc)(), char * dirlist)
{
- char * p;
- int k;
-
if (lnfunc != NULL)
lnsave++; // Tell tokenizer to keep lines
- for(;;)
+ while (1)
{
if (TokenizeLine() == TKEOF)
{
// Test for end condition. Two cases to handle:
// <directive>
// symbol: <directive>
- p = NULL;
- k = -1;
+ char * p = NULL;
+ int k = -1;
if (*tok == SYMBOL)
{
+ // A string followed by a colon or double colon is a symbol and
+ // *not* a directive, see if we can find the directive after it
if ((tok[2] == ':' || tok[2] == DCOLON))
{
- if (tok[3] == SYMBOL) // label: symbol
+ if (tok[3] == SYMBOL)
p = string[tok[4]];
}
else
{
- p = string[tok[1]]; // Symbol
+ // Otherwise, just grab the directive
+ p = string[tok[1]];
}
}
if (p != NULL)
{
- if (*p == '.') // ignore leading '.'s
+ if (*p == '.') // Ignore leading periods
p++;
k = KWMatch(p, dirlist);
if (lnfunc != NULL)
k = (*lnfunc)(lnbuf, k);
- if (!k)
+ if (k == 0)
break;
}
//
-// See if the string `kw' matches one of the keywords in `kwlist'. If so,
-// return the number of the keyword matched. Return -1 if there was no match.
+// See if the string `kw' matches one of the keywords in `kwlist'. If so,
+// return the number of the keyword matched. Return -1 if there was no match.
// Strings are compared without regard for case.
//
static int KWMatch(char * kw, char * kwlist)
void InitMacro(void);
int ExitMacro(void);
int DefineMacro(void);
-int DefineRept(void);
+int HandleRept(void);
int InvokeMacro(SYM *, WORD);
#endif // __MACRO_H__
IFENT * ifent; // Current ifent
static IFENT ifent0; // Root ifent
-static IFENT * f_ifent; // Freelist of ifents
-static int disabled; // Assembly conditionally disabled
+IFENT * f_ifent; // Freelist of ifents
+int disabled; // Assembly conditionally disabled
int just_bss; // 1, ds.b in microprocessor mode
VALUE pcloc; // Value of "PC" at beginning of line
SYM * lab_sym; // Label on line (or NULL)
{
case MN_IF:
d_if();
- goto loop;
+ goto loop;
+
case MN_ELSE:
d_else();
goto loop;
+
case MN_ENDIF:
d_endif();
goto loop;
+
case MN_IIF: // .iif --- immediate if
if (disabled || expr(exprbuf, &eval, &eattr, &esym) != OK)
goto loop;
goto loop;
goto loop1;
+
case MN_MACRO: // .macro --- macro definition
if (!disabled)
{
}
goto loop;
+
case MN_EXITM: // .exitm --- exit macro
case MN_ENDM: // .endm --- same as .exitm
if (!disabled)
}
goto loop;
+
case MN_REPT:
if (!disabled)
{
goto loop;
}
- DefineRept();
+ HandleRept();
}
goto loop;
+
case MN_ENDR:
if (!disabled)
error("mis-nested .endr");
lab_sym = symbol;
+ // Yes, our CS professors told us to write checks for equality this way,
+ // but damn, it hurts my brain every time I look at it. :-/
if (0 == environment)
curenv++;
}
-//
-// .if, Start conditional assembly
-//
-int d_if(void)
-{
- IFENT * rif;
- WORD eattr;
- VALUE eval;
- SYM * esym;
-
- // Alloc an IFENTRY
- if ((rif = f_ifent) == NULL)
- rif = (IFENT *)malloc(sizeof(IFENT));
- else
- f_ifent = rif->if_prev;
-
- rif->if_prev = ifent;
- ifent = rif;
-
- if (!disabled)
- {
- if (expr(exprbuf, &eval, &eattr, &esym) != OK)
- return 0;
-
- if ((eattr & DEFINED) == 0)
- return error(undef_error);
-
- disabled = !eval;
- }
-
- rif->if_state = (WORD)disabled;
- return 0;
-}
-
-
-//
-// .else, Do alternate case for .if
-//
-int d_else(void)
-{
- IFENT * rif = ifent;
-
- if (rif->if_prev == NULL)
- return error("mismatched .else");
-
- if (disabled)
- disabled = rif->if_prev->if_state;
- else
- disabled = 1;
-
- rif->if_state = (WORD)disabled;
- return 0;
-}
-
-
-//
-// .endif, End of conditional assembly block
-// This is also called by fpop() to pop levels of IFENTs in case a macro or
-// include file exits early with `exitm' or `end'.
-//
-int d_endif (void)
-{
- IFENT * rif = ifent;
-
- if (rif->if_prev == NULL)
- return error("mismatched .endif");
-
- ifent = rif->if_prev;
- disabled = rif->if_prev->if_state;
- rif->if_prev = f_ifent;
- f_ifent = rif;
- return 0;
-}
-
#include "token.h"
// Exported variables
-extern IFENT * ifent;
extern const char comma_error[];
extern const char locgl_error[];
extern const char syntax_error[];
extern VALUE pcloc;
extern SYM * lab_sym;
extern LONG amsktab[];
+extern IFENT * ifent;
+extern IFENT * f_ifent;
+extern int disabled;
// Exported functions
void InitLineProcessor(void);
void Assemble(void);
-int d_if(void);
-int d_else(void);
-int d_endif(void);
#endif // __PROCLN_H__
default:
printf("-p: syntax error\n");
- ++errcnt;
+ errcnt++;
return errcnt;
}
if (pagelen < 10)
{
printf("-y: bad page length\n");
- ++errcnt;
+ errcnt++;
return errcnt;
}
#include <inttypes.h>
// Line lists
-struct LineList
+#define LLIST struct _llist
+LLIST
{
- struct LineList * next;
+ LLIST * next;
uint8_t * line;
};
#define SYM struct _sym
SYM
{
- SYM * snext; // * -> Next symbol on hash-chain
- SYM * sorder; // * -> Next sym in order of reference
- SYM * sdecl; // * -> Next sym in order of declaration
- uint8_t stype; // Symbol type
- uint16_t sattr; // Attribute bits
- uint32_t sattre; // Extended attribute bits
- uint16_t senv; // Enviroment number
- uint32_t svalue; // Symbol value
- uint8_t * sname; // * -> Symbol's print-name
- struct LineList * lineList; // * -> Macro's linked list of lines
- struct LineList * last; // * -> end of macro linked list
- uint32_t uid; // Symbol's unique ID
+ SYM * snext; // * -> Next symbol on hash-chain
+ SYM * sorder; // * -> Next sym in order of reference
+ SYM * sdecl; // * -> Next sym in order of declaration
+ uint8_t stype; // Symbol type
+ uint16_t sattr; // Attribute bits
+ uint32_t sattre; // Extended attribute bits
+ uint16_t senv; // Enviroment number
+ uint32_t svalue; // Symbol value
+ uint8_t * sname; // * -> Symbol's print-name
+ LLIST * lineList; // * -> Macro's linked list of lines
+ LLIST * last; // * -> end of macro linked list
+ uint32_t uid; // Symbol's unique ID
};
// Exported variables
inobj->inobj.ifile = ifile;
break;
+
case SRC_IMACRO: // Alloc and init an IMACRO
if (f_imacro == NULL)
imacro = malloc(sizeof(IMACRO));
inobj->inobj.imacro = imacro;
break;
+
case SRC_IREPT: // Alloc and init an IREPT
inobj->inobj.irept = malloc(sizeof(IREPT));
DEBUG { printf("alloc IREPT\n"); }
{
IMACRO * imacro = cur_inobj->inobj.imacro;
// LONG * strp = imacro->im_nextln;
- struct LineList * strp = imacro->im_nextln;
+ LLIST * strp = imacro->im_nextln;
if (strp == NULL) // End-of-macro
return NULL;
char * GetNextRepeatLine(void)
{
IREPT * irept = cur_inobj->inobj.irept;
- LONG * strp = irept->ir_nextln; // initial null
+// LONG * strp = irept->ir_nextln; // initial null
// Do repeat at end of .rept block's string list
- if (strp == NULL)
+// if (strp == NULL)
+ if (irept->ir_nextln == NULL)
{
DEBUG { printf("back-to-top-of-repeat-block count=%d\n", (int)irept->ir_count); }
irept->ir_nextln = irept->ir_firstln; // copy first line
return NULL;
}
- strp = irept->ir_nextln;
+// strp = irept->ir_nextln;
}
- strcpy(irbuf, (char *)(irept->ir_nextln + 1));
- DEBUG printf("repeat line='%s'\n", irbuf);
- irept->ir_nextln = (LONG *)*strp;
+// strcpy(irbuf, (char *)(irept->ir_nextln + 1));
+ strcpy(irbuf, irept->ir_nextln->line);
+ DEBUG { printf("repeat line='%s'\n", irbuf); }
+// irept->ir_nextln = (LONG *)*strp;
+ irept->ir_nextln = irept->ir_nextln->next;
return irbuf;
}
INOBJ * inobj = a_inobj(SRC_IFILE);
IFILE * ifile = inobj->inobj.ifile;
- ifile->ifhandle = handle; // Setup file handle
- ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices
- ifile->ifoldlineno = curlineno; // Save old line number
- ifile->ifoldfname = curfname; // Save old filename
- ifile->ifno = cfileno; // Save old file number
+ ifile->ifhandle = handle; // Setup file handle
+ ifile->ifind = ifile->ifcnt = 0; // Setup buffer indices
+ ifile->ifoldlineno = curlineno; // Save old line number
+ ifile->ifoldfname = curfname; // Save old filename
+ ifile->ifno = cfileno; // Save old file number
// NB: This *must* be preincrement, we're adding one to the filecount here!
- cfileno = ++filecount; // Compute NEW file number
- curfname = strdup(fname); // Set current filename (alloc storage)
- curlineno = 0; // Start on line zero
+ cfileno = ++filecount; // Compute NEW file number
+ curfname = strdup(fname); // Set current filename (alloc storage)
+ curlineno = 0; // Start on line zero
// Add another file to the file-record
FILEREC * fr = (FILEREC *)malloc(sizeof(FILEREC));
fr->frec_name = curfname;
if (last_fr == NULL)
- filerec = fr; // Add first filerec
+ filerec = fr; // Add first filerec
else
- last_fr->frec_next = fr; // Append to list of filerecs
+ last_fr->frec_next = fr; // Append to list of filerecs
last_fr = fr;
DEBUG { printf("[include: curfname: %s, cfileno=%u]\n", curfname, cfileno); }
//
int fpop(void)
{
- IFILE * ifile;
- IMACRO * imacro;
- LONG * p, * p1;
INOBJ * inobj = cur_inobj;
- if (inobj != NULL)
- {
- // Pop IFENT levels until we reach the conditional assembly context we
- // were at when the input object was entered.
- int numUnmatched = 0;
+ if (inobj == NULL)
+ return 0;
- while (ifent != inobj->in_ifent)
- {
- if (d_endif() != 0) // Something bad happened during endif parsing?
- return -1; // If yes, bail instead of getting stuck in a loop
+ // Pop IFENT levels until we reach the conditional assembly context we
+ // were at when the input object was entered.
+ int numUnmatched = 0;
- numUnmatched++;
- }
+ while (ifent != inobj->in_ifent)
+ {
+ if (d_endif() != 0) // Something bad happened during endif parsing?
+ return -1; // If yes, bail instead of getting stuck in a loop
- // Give a warning to the user that we had to wipe their bum for them
- if (numUnmatched > 0)
- warn("missing %d .endif(s)", numUnmatched);
+ numUnmatched++;
+ }
- tok = inobj->in_otok; // Restore tok and otok
- etok = inobj->in_etok;
+ // Give a warning to the user that we had to wipe their bum for them
+ if (numUnmatched > 0)
+ warn("missing %d .endif(s)", numUnmatched);
- switch (inobj->in_type)
- {
- case SRC_IFILE: // Pop and release an IFILE
- DEBUG { printf("[Leaving: %s]\n", curfname); }
+ tok = inobj->in_otok; // Restore tok and otok
+ etok = inobj->in_etok;
+
+ switch (inobj->in_type)
+ {
+ case SRC_IFILE: // Pop and release an IFILE
+ {
+ DEBUG { printf("[Leaving: %s]\n", curfname); }
- ifile = inobj->inobj.ifile;
- ifile->if_link = f_ifile;
- f_ifile = ifile;
- close(ifile->ifhandle); // Close source file
+ IFILE * ifile = inobj->inobj.ifile;
+ ifile->if_link = f_ifile;
+ f_ifile = ifile;
+ close(ifile->ifhandle); // Close source file
DEBUG { printf("[fpop (pre): curfname=%s]\n", curfname); }
- curfname = ifile->ifoldfname; // Set current filename
+ curfname = ifile->ifoldfname; // Set current filename
DEBUG { printf("[fpop (post): curfname=%s]\n", curfname); }
DEBUG { printf("[fpop: (pre) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); }
- curlineno = ifile->ifoldlineno; // Set current line#
- DEBUG printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno);
- cfileno = ifile->ifno; // Restore current file number
+ curlineno = ifile->ifoldlineno; // Set current line#
+ DEBUG { printf("cfileno=%d ifile->ifno=%d\n", (int)cfileno, (int)ifile->ifno); }
+ cfileno = ifile->ifno; // Restore current file number
DEBUG { printf("[fpop: (post) cfileno=%d ifile->ifno=%d]\n", (int)cfileno, (int)ifile->ifno); }
- break;
- case SRC_IMACRO: // Pop and release an IMACRO
- imacro = inobj->inobj.imacro;
- imacro->im_link = f_imacro;
- f_imacro = imacro;
- break;
- case SRC_IREPT: // Pop and release an IREPT
- DEBUG printf("dealloc IREPT\n");
- p = inobj->inobj.irept->ir_firstln;
+ break;
+ }
- while (p != NULL)
- {
- p1 = (LONG *)*p;
- p = p1;
- }
+ case SRC_IMACRO: // Pop and release an IMACRO
+ {
+ IMACRO * imacro = inobj->inobj.imacro;
+ imacro->im_link = f_imacro;
+ f_imacro = imacro;
+ break;
+ }
- break;
+ case SRC_IREPT: // Pop and release an IREPT
+ {
+ DEBUG { printf("dealloc IREPT\n"); }
+// LONG * p = inobj->inobj.irept->ir_firstln;
+ LLIST * p = inobj->inobj.irept->ir_firstln;
+
+ // Deallocate repeat lines
+ while (p != NULL)
+ {
+// Shamus: ggn confirmed that this will cause a segfault on 64-bit versions of
+// RMAC. This is just stupid and wrong anyway, so we need to fix crapola
+// like this...
+// LONG * p1 = (LONG *)*p;
+// p = p1;
+ free(p->line);
+ p = p->next;
}
- cur_inobj = inobj->in_link;
- inobj->in_link = f_inobj;
- f_inobj = inobj;
+ break;
+ }
}
+ cur_inobj = inobj->in_link;
+ inobj->in_link = f_inobj;
+ f_inobj = inobj;
+
return 0;
}
goto retry; // Try for more lines
else
{
- ifent->if_prev = (IFENT *) - 1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs
+ ifent->if_prev = (IFENT *)-1; //Signal Assemble() that we have reached EOF with unbalanced if/endifs
return TKEOF;
}
}
}
break;
+
// Macro-block:
// o Handle end-of-macro;
// o tag the listing-line with an at (@) sign.
case SRC_IMACRO:
if ((ln = GetNextMacroLine()) == NULL)
{
- if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc)
- goto retry; // Try for more lines...
+ if (ExitMacro() == 0) // Exit macro (pop args, do fpop(), etc)
+ goto retry; // Try for more lines...
else
- return TKEOF; // Oops, we got a non zero return code, signal EOF
+ return TKEOF; // Oops, we got a non zero return code, signal EOF
}
lntag = '@';
break;
+
// Repeat-block:
// o Handle end-of-repeat-block;
// o tag the listing-line with a pound (#) sign.
break;
}
- // Save text of the line. We only do this during listings and within
+ // Save text of the line. We only do this during listings and within
// macro-type blocks, since it is expensive to unconditionally copy every
// line.
if (lnsave)
strcpy(lnbuf, ln);
- // General house-keeping
+ // General housekeeping
tok = tokeol; // Set "tok" to EOL in case of error
tk = etok; // Reset token ptr
stuffnull = 0; // Don't stuff nulls
return error("goto not in macro");
IMACRO * imacro = cur_inobj->inobj.imacro;
- struct LineList * defln = imacro->im_macro->lineList;
+ LLIST * defln = imacro->im_macro->lineList;
// Attempt to find the label, starting with the first line.
for(; defln!=NULL; defln=defln->next)
WORD if_state; // 0:enabled, 1:disabled
};
-// Pointer to IFILE or IMACRO
+// Pointer to IFILE or IMACRO or IREPT
IUNION {
IFILE * ifile;
IMACRO * imacro;
// Ptr to IFILEs, IMACROs, and so on; back-ptr to previous input objects
INOBJ {
- WORD in_type; // 0=IFILE, 1=IMACRO ...
+ WORD in_type; // 0=IFILE, 1=IMACRO, 2=IREPT
IFENT * in_ifent; // Pointer to .if context on entry
INOBJ * in_link; // Pointer to previous INOBJ
TOKEN * in_otok; // Old `tok' value
TOKEN * in_etok; // Old `etok' value
- IUNION inobj; // IFILE or IMACRO ...
+ IUNION inobj; // IFILE or IMACRO or IREPT
};
// Information about a file
// Information about a macro invocation
IMACRO {
IMACRO * im_link; // Pointer to ancient IMACROs
- struct LineList * im_nextln; // Next line to include
+ LLIST * im_nextln; // Next line to include
WORD im_nargs; // # of arguments supplied on invocation
WORD im_siz; // Size suffix supplied on invocation
LONG im_olduniq; // Old value of 'macuniq'
// Information about a .rept invocation
IREPT {
- LONG * ir_firstln; // Pointer to first line
- LONG * ir_nextln; // Pointer to next line
+ LLIST * ir_firstln; // Pointer to first line
+ LLIST * ir_nextln; // Pointer to next line
VALUE ir_count; // Repeat count (decrements)
};
// Release Information
#define MAJOR 1 // Major version number
-#define MINOR 7 // Minor version number
-#define PATCH 2 // Patch release number
+#define MINOR 8 // Minor version number
+#define PATCH 0 // Patch release number
#endif // __VERSION_H__