python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

vm/mem.c

Committer:
va009039
Date:
2016-04-14
Revision:
15:94ca5c8003e5
Parent:
0:65f1469d6bfb

File content as of revision 15:94ca5c8003e5:

/*
# This file is Copyright 2002 Dean Hall.
# This file is part of the PyMite VM.
# This file is licensed under the MIT License.
# See the LICENSE file for details.
*/


#undef __FILE_ID__
#define __FILE_ID__ 0x0D


/**
 * \file
 * \brief VM Memory
 *
 * VM memory operations.
 * Implementations and stubs for getByte and memCopy functions.
 * Functions to load object images from static memory.
 */


#include "pm.h"


uint16_t
mem_getWord(PmMemSpace_t memspace, uint8_t const **paddr)
{
    /* PyMite is little endian; get low byte first */
    uint8_t blo = mem_getByte(memspace, paddr);
    uint8_t bhi = mem_getByte(memspace, paddr);

    return (uint16_t)(blo | (bhi << (int8_t)8));
}


uint32_t
mem_getInt(PmMemSpace_t memspace, uint8_t const **paddr)
{
    /* PyMite is little endian; get low word first */
    uint16_t wlo = mem_getWord(memspace, paddr);
    uint32_t whi = mem_getWord(memspace, paddr);

    return (uint32_t)(wlo | (whi << (int8_t)16));
}


#ifdef HAVE_FLOAT
float
mem_getFloat(PmMemSpace_t memspace, uint8_t const **paddr)
{
    union
    {
        char c[4];
        float f;
    }
    v;

#ifdef PM_FLOAT_BIG_ENDIAN
    /* If the architecture is Big Endian, reverse the bytes of the float */
    v.c[3] = mem_getByte(memspace, paddr);
    v.c[2] = mem_getByte(memspace, paddr);
    v.c[1] = mem_getByte(memspace, paddr);
    v.c[0] = mem_getByte(memspace, paddr);

#else
    v.c[0] = mem_getByte(memspace, paddr);
    v.c[1] = mem_getByte(memspace, paddr);
    v.c[2] = mem_getByte(memspace, paddr);
    v.c[3] = mem_getByte(memspace, paddr);

#ifndef PM_FLOAT_LITTLE_ENDIAN
#warning Neither PM_FLOAT_LITTLE_ENDIAN nor PM_FLOAT_BIG_ENDIAN is defined \
         for this platform; defaulting to little endian.
#endif
#endif

    return v.f;
}
#endif /* HAVE_FLOAT */


void
mem_copy(PmMemSpace_t memspace,
         uint8_t **pdest, uint8_t const **psrc, uint16_t count)
{
    /* Copy memory from RAM */
    if (memspace == MEMSPACE_RAM)
    {
        sli_memcpy(*pdest, *psrc, count);
        *psrc += count;
        *pdest += count;
        return;
    }

    /* Copy memory from non-RAM to RAM */
    else
    {
        uint8_t b;

        for (; count > 0; count--)
        {
            b = mem_getByte(memspace, psrc);
            **pdest = b;
            (*pdest)++;
        }
        return;
    }
}


uint16_t
mem_getStringLength(PmMemSpace_t memspace, uint8_t const *const pstr)
{
    uint8_t const *psrc;

    /* If source is in RAM, use a possibly optimized strlen */
    if (memspace == MEMSPACE_RAM)
    {
        return sli_strlen((char const *)pstr);
    }

    /* Otherwise calculate string length */
    psrc = pstr;
    while (mem_getByte(memspace, &psrc) != (uint8_t)0);
    return psrc - pstr - 1;
}


PmReturn_t
mem_cmpn(uint8_t *cname, uint16_t cnamelen, PmMemSpace_t memspace,
         uint8_t const **paddr)
{
    uint16_t i;
    uint8_t b;

    /* Iterate over all characters */
    for (i = 0; i < cnamelen; i++)
    {
        b = mem_getByte(memspace, paddr);
        if (cname[i] != b)
        {
            return PM_RET_NO;
        }
    }
    return PM_RET_OK;
}