1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-05 13:24:11 +01:00
LibrePilot/flight/libraries/PyMite/vm/mem.c

155 lines
3.4 KiB
C
Raw Normal View History

/*
# This file is Copyright 2003, 2006, 2007, 2009, 2010 Dean Hall.
#
# This file is part of the PyMite VM.
# The PyMite VM is free software: you can redistribute it and/or modify
# it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2.
#
# The PyMite VM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# A copy of the GNU GENERAL PUBLIC LICENSE Version 2
# is seen in the file COPYING in this directory.
*/
#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, uint8_t cnamelen, PmMemSpace_t memspace,
uint8_t const **paddr)
{
uint8_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;
}