/*******************************************************************************************
 *
 *  Definitions used when calling MMBasic Interpreter API Functions from CFunctions
 *  For MMBasic V5.3
 *
 *  This file is public domain and may be used without license.
 *
 *
 ******************************************************************************************/


//Addresses in the API Table for the pointers to each function

#define Vector_CurrentCpuSpeed    (*(int*)0x9D000000)       // CurrentCpuSpeed
#define Vector_uSec               (*(int*)0x9D000004)       // void uSec(unsigned int us)
#define Vector_putConsole         (*(int*)0x9D000008)       // void putConsole(int c)
#define Vector_getConsole         (*(int*)0x9D00000C)       // int getConsole(void)
#define Vector_ExtCfg             (*(int*)0x9D000010)       // void ExtCfg(int pin, int cfg, int option)
#define Vector_ExtSet             (*(int*)0x9D000014)       // void ExtSet(int pin, int val)
#define Vector_ExtInp             (*(int*)0x9D000018)       // int ExtInp(int pin)
#define Vector_PinSetBit          (*(int*)0x9D00001C)       // void PinSetBit(int pin, unsigned int offset)
#define Vector_PinRead            (*(int*)0x9D000020)       // int PinRead(int pin)
#define Vector_GetPortAddr        (*(int*)0x9D000024)       // unsigned int *GetPortAddr(int pin, unsigned int offset)
#define Vector_GetPinBit          (*(int*)0x9D000028)       // int GetPinBit(int pin)
#define Vector_MMPrintString      (*(int*)0x9D00002C)       // void MMPrintString(char* s)
#define Vector_IntToStr           (*(int*)0x9D000030)       // void IntToStr(char *strr, long long int nbr, unsigned int base)
#define Vector_FloatToStr         (*(int*)0x9D000034)       // void FloatToStr(char *p, float f, int m, int n, char ch)
#define Vector_CheckAbort         (*(int*)0x9D000038)       // void CheckAbort(void)
#define Vector_GetMemory          (*(int*)0x9D00003C)       // void *GetMemory(size_t msize);
#define Vector_GetTempMemory      (*(int*)0x9D000040)       // void *GetTempMemory(int NbrBytes)
#define Vector_FreeMemory         (*(int*)0x9D000044)       // void FreeMemory(void *addr)
#define Vector_DrawRectangle      *(unsigned int *)(int*)0x9D000048          // void DrawRectangle(int x1, int y1, int x2, int y2, int c)
#define Vector_DrawBitmap         *(unsigned int *)(int*)0x9D00004C          // void DrawBitmap(int x1, int y1, int width, int height, int scale, int fg, int bg, unsigned char *bitmap )
#define Vector_DrawLine           (*(int*)0x9D000050)       // void DrawLine(int x1, int y1, int x2, int y2, int w, int c)
#define Vector_FontTable          (*(int*)0x9D000054)       // const unsigned char *FontTable[FONT_NBR]
#define Vector_FMul               (*(int*)0x9D000058)       // float FMul(float a, float b)
#define Vector_FAdd               (*(int*)0x9D00005C)       // float FAdd(float a, float b)
#define Vector_FSub               (*(int*)0x9D000060)       // float FSub(float a, float b)
#define Vector_FDiv               (*(int*)0x9D000064)       // float FDiv(float a, float b)
#define Vector_FCmp               (*(int*)0x9D000068)       // int   FCmp(float a,float b)
#define Vector_FSin               (*(int*)0x9D00006C)       // float sinf(float)
#define Vector_FLog               (*(int*)0x9D000070)       // float logf(float)
#define Vector_FPow               (*(int*)0x9D000074)       // float powf(float, float)
#define Vector_atanf              (*(int*)0x9D000078)       // float atanf(float)
#define Vector_FloatToInt         (*(int*)0x9D00007C)       // long long int FloatToInt(float)
#define Vector_IntToFloat         (*(int*)0x9D000080)       // float IntToFloat(long long int a)
#define Vector_CFuncmSec          (*(int*)0x9D000084)       // CFuncmSec
#define Vector_ExtCurrentConfig   (*(int*)0x9D000088)       // int ExtCurrentConfig[NBRPINS + 1];
#define Vector_CFuncRam           (*(int*)0x9D00008C)       // StartOfCFuncRAM
#define Vector_Option             (*(int*)0x9D000090)       // Option
#define Vector_HRes               (*(int*)0x9D000094)       // HRes
#define Vector_VRes               (*(int*)0x9D000098)       // VRes
#define Vector_LoadFloat          (*(int*)0x9D00009C)       // float LoadFloat(unsigned long)
#define Vector_SoftReset          (*(int*)0x9D0000A0)       // void SoftReset(void)
#define Vector_CFuncInt           (*(int*)0x9D0000A4)       // CFuncInt
#define Vector_ScrollLCD          *(unsigned int *)(int*)0x9D0000A8          // void scrollLCD
#define Vector_CFuncT1            (*(int*)0x9D0000AC)       // CFuncT1
#define Vector_CFuncT5            (*(int*)0x9D0000B0)       // CFuncT5
#define Vector_ExecuteProgram     (*(int*)0x9D0000B4)       // void ExecuteProgram(char *fname)
#define Vector_SaveProgramToFlash (*(int*)0x9D0000B8)       // void SaveProgramToFlash(char *pm, int msg)
#define Vector_error              (*(int*)0x9D0000BC)       // void error(char *msg)
#define Vector_ProgFlash          (*(int*)0x9D0000C0)       // ProgFlash
#define Vector_ClearProgram       (*(int*)0x9D0000C4)       // void ClearProgram(void)
#define Vector_llist              (*(int*)0x9D0000C8)       // char *llist(char *b, char *p)
#define Vector_CFuncInt2          (*(int*)0x9D0000CC)       // CFuncInt2
#define Vector_vartbl             (*(int*)0x9D0000D0)       // vartbl
#define Vector_varcnt             (*(int*)0x9D0000D4)       // varcnt
#define Vector_GetTouchAxis       *(unsigned int *)(int*)0x9D0000D8       // GetTouchAxis
#define Vector_DrawBuffer         *(unsigned int *)(int*)0x9D0000DC       // void DrawBuffer(int x1, int y1, int x2, int y2, char *c)
#define Vector_ReadBuffer         *(unsigned int *)(int*)0x9D0000E0       // void ReadBuffer(int x1, int y1, int x2, int y2, char *c)


//Macros to call each function.

#define CurrentCpuSpeed                 (*(unsigned int *) Vector_CurrentCpuSpeed)
#define uSec(a)                         ((void (*)(unsigned int )) Vector_uSec) (a)
#define putConsole(a)                   ((void (*)(char)) Vector_putConsole) (a)
#define getConsole()                    ((int (*)(void)) Vector_getConsole) ()
#define ExtCfg(a,b,c)                   ((void (*)(int, int, int)) Vector_ExtCfg) (a,b,c)
#define ExtSet(a,b)                     ((void(*)(int, int)) Vector_ExtSet) (a,b)
#define ExtInp(a)                       ((int(*)(int)) Vector_ExtInp) (a)
#define PinSetBit(a,b)                  ((void(*)(int, int)) Vector_PinSetBit) (a,b)
#define PinRead(a)                      ((int(*)(int)) Vector_PinRead) (a)
#define GetPortAddr(a,b)                ((volatile unsigned int * (*)(int,int)) Vector_GetPortAddr) (a,b)
#define GetPinBit(a)                    ((int (*)(int)) Vector_GetPinBit) (a)
#define MMPrintString(a)                ((void (*)(char*)) Vector_MMPrintString) (a)
#define IntToStr(a,b,c)                 ((void (*)(char *, long long int, unsigned int)) Vector_IntToStr) (a,b,c)
#define FloatToStr(a,b,c,d,e)           ((void (*)(char *, float, int, int, char)) Vector_FloatToStr) (a,b,c,d,e)
#define CheckAbort()                    ((void (*)(void)) Vector_CheckAbort) ()
#define GetMemory(a)                    ((void* (*)(int)) Vector_GetMemory) (a)
#define GetTempMemory(a)                ((void* (*)(int)) Vector_GetTempMemory) (a)
#define FreeMemory(a)                   ((void (*)(void *)) Vector_FreeMemory) (a)
#define DrawRectangle(a,b,c,d,e)        ((void (*)(int,int,int,int,int)) (*(unsigned int *)Vector_DrawRectangle)) (a,b,c,d,e)
#define DrawRectangleVector             (*(unsigned int *)Vector_DrawRectangle)
#define DrawBitmap(a,b,c,d,e,f,g,h)     ((void (*)(int,int,int,int,int,int,int, char*)) (*(unsigned int *)Vector_DrawBitmap)) (a,b,c,d,e,f,g,h)
#define DrawBitmapVector                (*(unsigned int *)Vector_DrawBitmap)
#define DrawLine(a,b,c,d,e,f)           ((void (*)(int,int,int,int,int,int)) Vector_DrawLine) (a,b,c,d,e,f)
#define FontTable                       (void*)((int*)(Vector_FontTable))
#define FMul(a,b)                       ((float (*)(float, float)) Vector_FMul) (a,b)
#define FAdd(a,b)                       ((float (*)(float, float)) Vector_FAdd) (a,b)
#define FSub(a,b)                       ((float (*)(float, float)) Vector_FSub) (a,b)
#define FDiv(a,b)                       ((float (*)(float, float)) Vector_FDiv) (a,b)
#define FCmp(a,b)                       ((int (*)(float, float)) Vector_FCmp) (a,b)
#define FSin(a)                         ((float (*)(float)) Vector_FSin) (a)
#define FLog(a)                         ((float (*)(float)) Vector_FLog) (a)
#define FPow(a,b)                       ((float (*)(float, float)) Vector_FPow) (a,b)
#define atanf(a)                        ((float (*)(float)) Vector_atanf) (a)
#define FloatToInt(a)                   ((long long (*)(float)) Vector_FloatToInt) (a)
#define IntToFloat(a)                   ((float (*)(long long)) Vector_IntToFloat) (a)
#define CFuncmSec                       (*(unsigned int *) Vector_CFuncmSec)
#define ExtCurrentConfig                ((int *) Vector_ExtCurrentConfig)
#define CFuncRam                        ((int *) Vector_CFuncRam)
#define Option                          ({struct option_s *optionstructurepointer; optionstructurepointer=(void *)(unsigned int)Vector_Option;})
#define HRes                            (*(unsigned int *) Vector_HRes)
#define VRes                            (*(unsigned int *) Vector_VRes)
#define LoadFloat(a)                    ((float (*)(unsigned int)) Vector_LoadFloat) (a)
#define SoftReset()                     ((void (*)(void)) Vector_SoftReset) ()
#define CFuncInt                        (*(unsigned int *) Vector_CFuncInt)
#define ScrollLCD(a)                    ((void (*)(int)) (*(unsigned int *)Vector_ScrollLCD)) (a)
#define CFuncT1                         (*(unsigned int *) Vector_CFuncT1)
#define CFuncT5                         (*(unsigned int *) Vector_CFuncT5)
#define GetTouchAxisVector              (*(unsigned int *)Vector_GetTouchAxis)
#define GetTouchAxis                    ((int (*)(int)) (*(unsigned int *)GetTouchAxisVector)) (a)
#define DrawBuffer(a,b,c,d,e)           ((void (*)(int , int , int , int , char * ))Vector_DrawBuffer)) (a,b,c,d,e)
#define DrawBufferVector                (*(unsigned int *)Vector_DrawBuffer)
#define ReadBuffer(a,b,c,d,e)           ((void (*)(int,int,int,int,int,int,int, char*)) (*(unsigned int *)Vector_ReadBuffer)) (a,b,c,d,e)
#define ReadBufferVector                (*(unsigned int *)Vector_ReadBuffer)

// NOTE:  The argument to RunBasicSub is a string specifying the name of the BASIC subroutine to be executed.
//        It MUST be terminated with TWO null chars.
#define RunBasicSub(a)                  ((void (*)(char *)) Vector_ExecuteProgram) (a)

#define SaveProgramToFlash(a,b)         ((void (*)(char *, int)) Vector_SaveProgramToFlash) (a,b)
#define error(a)                        ((void (*)(char *)) Vector_error) (a)
#define ProgFlash                       ((int *) Vector_ProgFlash)
#define ClearProgram()                  ((void (*)(void)) Vector_ClearProgram) ()
#define llist(a,b)                      ((char * (*)(char *, char *)) Vector_llist) (a,b)
#define CFuncInt2                       (*(unsigned int *) Vector_CFuncInt2)

// the structure of the variable table, passed to the CFunction as a pointer Vector_vartbl which is #defined as vartbl
#define MAXVARLEN           32                  // maximum length of a variable name
#define MAXDIM              8                   // maximum nbr of dimensions to an arraystruct
struct s_vartbl {                                      // structure of the variable table
    char name[MAXVARLEN];                       // variable's name
    char type;                                  // its type (T_NUM, T_INT or T_STR)
    char level;                                 // its subroutine or function level (used to track local variables)
    short int dims[MAXDIM];                     // the dimensions. it is an array if the first dimension is NOT zero
    unsigned char size;                         // the number of chars to allocate for each element in a string array
    union u_val {
        float f;                                // the value if it is a float
        long long int i;                        // the value if it is an integer
        float *fa;                              // pointer to the allocated memory if it is an array of floats
        long long int *ia;                      // pointer to the allocated memory if it is an array of integers
        char *s;                                // pointer to the allocated memory if it is a string
    } val;
};

// the variable table
#define vartbl                          (*(struct s_vartbl *) Vector_vartbl)

// number of variables defined (eg, largest index into the variable table)
#define varcnt                          (*(unsigned int *) Vector_varcnt)


//  Useful macros

#define DrawPixel(x, y, c)     DrawRectangle(x, y, x, y, c)
#define PIC32MX470F512H_DEVID  0x0580A053
#define PIC32MX470F512L_DEVID  0x0580B053
#define PIC32MX170F256B_DEVID  0x06610053
#define PIC32MX270F256B_DEVID  0x06600053
#define PIC32MX170F256D_DEVID  0x0661A053
#define PIC32MX270F256D_DEVID  0x0660A053
#define DEVID                  (*(volatile unsigned int *)0xBF80F220)
#define HAS_28PINS             ((DEVID & 0xfffffff) == PIC32MX170F256B_DEVID || (DEVID & 0xfffffff) == PIC32MX270F256B_DEVID)
#define HAS_44PINS             ((DEVID & 0xfffffff) == PIC32MX170F256D_DEVID || (DEVID & 0xfffffff) == PIC32MX270F256D_DEVID)
#define HAS_64PINS             (DEVID & 0xfffffff) == PIC32MX470F512H_DEVID
#define HAS_100PINS            (DEVID & 0xfffffff) == PIC32MX470F512L_DEVID
#define NBRPINS                ({int j=28; if(HAS_44PINS)j=44; if(HAS_64PINS)j=64;if(HAS_100PINS)j=100; j ;})

// Types used to define a variable in the variable table (vartbl).   Often they are ORed together.
// Also used in tokens and arguments to functions
#define T_NOTYPE       0                            // type not set or discovered
#define T_NBR       0x01                            // number (or float) type
#define T_STR       0x02                            // string type
#define T_INT       0x04                            // 64 bit integer type
#define T_PTR       0x08                            // the variable points to another variable's data
#define T_IMPLIED   0x10                            // the variables type does not have to be specified with a suffix
#define T_CONST     0x20                            // the contents of this variable cannot be changed


//***************************************************************************************************
// Constants and definitions copied from the Micromite MkII and Micromite Plus source
//***************************************************************************************************

#define MAXVARLEN 32        // maximum length of a variable name
#define MAXSTRLEN 255       // maximum length of a string
#define STRINGSIZE 256      // must be 1 more than MAXSTRLEN to accomodate the byte representing the length of the string
#define MAXDIM 8            // maximum nbr of dimensions to an array

//The Option structure
struct option_s {
    char Autorun;
    char Tab;
    char Invert;
    char Listcase;
    char Height;
    char Width;
    int  PIN;
    int  Baudrate;
    int  ColourCode;

    // display related
    char DISPLAY_TYPE;
    char DISPLAY_ORIENTATION;

    // touch related
    char TOUCH_CS;
    char TOUCH_IRQ;
    char TOUCH_SWAPXY;
    int  TOUCH_XZERO;
    int  TOUCH_YZERO;
    float TOUCH_XSCALE;
    float TOUCH_YSCALE;

    // for the SPI LCDs
    char LCD_CD;
    char LCD_CS;
    char LCD_Reset;

// Note the next options are only applicable to the MM+

    char SerialCon;
    char SDCARD_CS;
    char SD_CD;
    char SD_WP;
    char DISPLAY_BL;
    char DISPLAY_CONSOLE;
    char DefaultFont;
    char KeyboardConfig;
    char TOUCH_Click;


// To enable older CFunctions to run any new options *MUST* be added at the end of the list
    unsigned int ProgFlashSize;    // used to store the size of the program flash (also start of the LIBRARY code)
    char pins[4];                  // general use storage for CFunctions that need to record the pins for a parallel port
};


// Define the offsets from the PORT address
// these are used by GetPortAddr(a,b)
#define ANSEL               -8
#define ANSELCLR            -7
#define ANSELSET            -6
#define ANSELINV            -5
#define TRIS                -4
#define TRISCLR             -3
#define TRISSET             -2
#define TRISINV             -1
#define PORT                0
#define PORTCLR             1
#define PORTSET             2
#define PORTINV             3
#define LAT                 4
#define LATCLR              5
#define LATSET              6
#define LATINV              7
#define ODC                 8
#define ODCCLR              9
#define ODCSET              10
#define ODCINV              11
#define CNPU                12
#define CNPUCLR             13
#define CNPUSET             14
#define CNPUINV             15
#define CNPD                16
#define CNPDCLR             17
#define CNPDSET             18
#define CNPDINV             19
#define CNCON               20
#define CNCONCLR            21
#define CNCONSET            22
#define CNCONINV            23
#define CNEN                24
#define CNENCLR             25
#define CNENSET             26
#define CNENINV             27
#define CNSTAT              28
#define CNSTATCLR           29
#define CNSTATSET           30
#define CNSTATINV           31

// configurations for an I/O pin
// these are used by ExtCfg(a,b,c)
#define EXT_NOT_CONFIG      0       // Not Configured
#define EXT_ANA_IN          1       // Analogue Input
#define EXT_DIG_IN          2       // Digital Input
#define EXT_FREQ_IN         3       // Frequency Measurement Input
#define EXT_PER_IN          4       // Period measurement Input
#define EXT_CNT_IN          5       // Pulse Counting Input
#define EXT_INT_HI          6       // Generate Interrupt on RISING edge
#define EXT_INT_LO          7       // Generate Interrupt on FALLING edge
#define EXT_DIG_OUT         8       // Digital Output
#define EXT_OC_OUT          9       // Digital Output with Open Collector
#define EXT_INT_BOTH        10      // Generate Interrupt on BOTH Falling and Rising edges
#define EXT_RESERVED        100     // this pin is reserved and SETPIN and PIN cannot be used
#define EXT_BOOT_RESERVED   101     // this pin is reserved at boot

