view buffer.c @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents 76568becd6d6
children
line wrap: on
line source

#include "datum.h"
#include "vis_threading.h"
#include "structs.h"
#include <string.h>

//TODO: Make some kind of "notifier" lock that takes some kind of callback
//to be called when the lock becomes free

typedef struct
{
	int offset;
	char * buffer;
	int size;
	VIS_CRITICAL_SECTION(lock)
} fixed_buffer;
	
int vis_buffer_new(datum ** params, queue_entry * entry)
{
	int size = params[0]->c.integers.num_a;
	fixed_buffer * buf;
	release_ref(params[0]);
	params[0] = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer) + size, entry->instance->def->program);
	buf = params[0]->c.generic.data;
	buf->offset = 0;
	buf->buffer = ((char *)buf) + sizeof(fixed_buffer);
	buf->size = size;
	VIS_InitializeCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_lock(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	VIS_EnterCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_unlock(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	VIS_LeaveCriticalSection(buf->lock);
	return 0;
}

int vis_buffer_putbyte(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	char byte = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		buf->buffer[buf->offset++] = byte;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writebyte(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	char byte = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		buf->buffer[buf->offset] = byte;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_putshort(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	short * wordbuf;
	short word = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		wordbuf = (short *)buf->buffer;
		wordbuf[buf->offset >> 1] = word;
		params[1] = NULL;
		buf->offset += 2;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writeshort(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	short * wordbuf;
	short word = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		wordbuf = (short *)buf->buffer;
		wordbuf[buf->offset >> 1] = word;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_putlong(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	long * longbuf;
	long lword = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		longbuf = (long *)buf->buffer;
		longbuf[buf->offset >> 2] = lword;
		params[1] = NULL;
		buf->offset += 4;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_writelong(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	long * longbuf;
	long lword = params[1]->c.integers.num_a;
	release_ref(params[1]);
	if(buf->offset < buf->size)
	{
		longbuf = (long *)buf->buffer;
		longbuf[buf->offset >> 2] = lword;
		params[1] = NULL;
	}
	else
	{
		params[1] = params[0];
		params[1] = NULL;
	}
	return 0;
}

int vis_buffer_reset(datum ** params, queue_entry * entry)
{
	fixed_buffer * buf = params[0]->c.generic.data;
	buf->offset = 0;
	return 0;
}

#if defined(SEGA) | defined(NINTENDO_DS)
int vis_buffer_fromaddress(datum ** params, queue_entry * entry)
{
	char buffer;
	datum * out;
	int size = params[1]->c.integers.num_a;
	fixed_buffer * buf;
	release_ref(params[1]);
	out = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer), entry->instance->def->program);
	buf = out->c.generic.data;
	buf->offset = 0;
	buf->buffer = (char *)(params[0]->c.integers.num_a);
	buf->size = size;
	VIS_InitializeCriticalSection(buf->lock);
	release_ref(params[0]);
	params[0] = out;
	return 0;
}
#endif