127 lines
3.5 KiB
C
127 lines
3.5 KiB
C
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// bios - Holds BIOS image and can retrieve environment data
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef EMU_COMPILE
|
|
#error "Hi I forgot to set EMU_COMPILE"
|
|
#endif
|
|
|
|
#include "bios.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
static uint8 *image = {0};
|
|
static uint32 image_size = 0;
|
|
|
|
uint8* EMU_CALL bios_get_image_native(void) { return image; }
|
|
uint32 EMU_CALL bios_get_imagesize(void) { return image_size; }
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Static init
|
|
//
|
|
void EMU_CALL bios_set_image(uint8 *_image, uint32 _size) {
|
|
#ifdef EMU_BIG_ENDIAN
|
|
uint32 i;
|
|
for (i = 0; i < _size; i += 4) {
|
|
uint8 a = _image[i + 0];
|
|
uint8 b = _image[i + 1];
|
|
_image[i + 0] = _image[i + 3];
|
|
_image[i + 1] = _image[i + 2];
|
|
_image[i + 2] = b;
|
|
_image[i + 3] = a;
|
|
}
|
|
#endif
|
|
image = _image;
|
|
image_size = _size;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Find environment variables
|
|
// Returns nonzero on error
|
|
//
|
|
sint32 EMU_CALL bios_getenv(
|
|
const char *name,
|
|
char *dest,
|
|
sint32 dest_l
|
|
) {
|
|
uint8 *romnative = bios_get_image_native();
|
|
uint8 whole_env_area[129];
|
|
uint8 *env;
|
|
const uint8 *banner = (const uint8 *) "Highly Experimental";
|
|
sint32 banner_l = (sint32) strlen((char *)banner);
|
|
sint32 name_l = (sint32) strlen(name);
|
|
sint32 i;
|
|
|
|
for(i = 0; i < 128; i++) {
|
|
sint32 byteofs = 0x80 + (i ^ (EMU_ENDIAN_XOR(3)));
|
|
whole_env_area[i] = romnative[byteofs];
|
|
}
|
|
whole_env_area[128] = 0;
|
|
|
|
env = whole_env_area;
|
|
|
|
if(!dest_l) return 1;
|
|
if(memcmp(env, banner, banner_l)) return 1;
|
|
env += banner_l;
|
|
|
|
for(;;) {
|
|
sint32 isquote = 0;
|
|
uint8 *varnamestart;
|
|
uint8 *varnameend;
|
|
uint8 *varvalstart;
|
|
uint8 *varvalend;
|
|
sint32 varnamelen;
|
|
sint32 varvallen;
|
|
// find a variable name
|
|
for(;; env++) { uint8 c = *env; if(!c) return 1; if(c != ' ') break; }
|
|
varnamestart = env;
|
|
// find where it ends
|
|
for(;; env++) { uint8 c = *env; if(!c) return 1; if(c == '=') break; }
|
|
varnameend = env;
|
|
// eat trailing spaces
|
|
while(
|
|
(varnameend > varnamestart) &&
|
|
(varnameend[-1] == ' ')
|
|
) varnameend--;
|
|
// skip equals sign
|
|
env++;
|
|
// compute length
|
|
varnamelen = (sint32)(varnameend - varnamestart);
|
|
// find the value
|
|
for(;; env++) { uint8 c = *env; if(!c) return 1; if(c != ' ') break; }
|
|
varvalstart = env;
|
|
// if it's a quote, handle it as such
|
|
if(*env == '\"') { varvalstart++; env++; isquote = 1; }
|
|
// seek to the end of the value
|
|
for(;; env++) {
|
|
uint8 c = *env;
|
|
if(!c) break;
|
|
if(isquote && c == '\"') break;
|
|
if((!isquote) && c == ' ') break;
|
|
}
|
|
varvalend = env;
|
|
// skip trailing quote if it's there
|
|
if(isquote && *env == '\"') env++;
|
|
// compute length
|
|
varvallen = (sint32)(varvalend - varvalstart);
|
|
|
|
// now, if this is the variable name we want...
|
|
if(varnamelen == name_l && !memcmp(varnamestart, name, name_l)) {
|
|
// return it in the destination buffer
|
|
if(varvallen > (dest_l - 1)) varvallen = (dest_l - 1);
|
|
if(varvallen) memcpy(dest, varvalstart, varvallen);
|
|
dest[varvallen] = 0;
|
|
return 0;
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|