[Home]Vitenka/ICFP

www.vitenka.com | ToothyWiki | Vitenka | RecentChanges | Login | Webcomic

// Nasty mostly C hack.  Relies on 32bit architecture in a few places it shouldn't, probably.  Also, no way to get input or load the first program.  About half an hours coding, needs debugging.  Can't be bothered :)

uint32 gpr[8];
uint32 valueOnScreen? = 0xffffffff;
uint32 finger = 0;
uint32 progamLength;
uint32 numArrays = 0;

struct arrayInfo
{
	uint32* ptr;
uint32 id;
uint32 size;
arrayInfo* prev;
arrayInfo* next;
};

enum rval_t
{
	OK,
FAIL,
HALT
}

arrayInfo* head = NULL;

rval_t CopyArray?( uint32 dest, uint32 src )
{
	FreeArray?( dest );
arrayInfo srcInfo;
rval_t rval = GetArrayInfo?( src, &srcInfo );
if ( OK != rval )
{
return rval;
}
if ( 0 == dest )
{
// special fast stuff for program
free( program );
progamLength = srcInfo.size;
program = malloc( sizeof(uint32) * progamLength );
assert( program );
memcpy( destInfo.ptr, srcInfo.ptr, progamLength * sizeof(uint32) );
return OK;
}
else
{
uint32 destId = AllocateArray?( srcInfo.size );
arrayInfo destInfo;
rval = GetArrayInfo?( destId, &destInfo );
assert( OK==rval );
assert( destInfo.size == srcInfo.size );
destInfo.id = dest;
memcpy( destInfo.ptr, srcInfo.ptr, srcInfo.size * sizeof(uint32) );
}
return OK;
}

rval_t GetArrayInfo?( uint32 id, arrayInfo* array );
{
	assert( array );

	if ( 0==id )
{
array->ptr = program;
array->id = 0;
array->size = programLength;
array->prev = NULL;
array->next = NULL;
return OK;
}

	arrayInfo* ptr = head;
while ( ptr )
{
if ( id == ptr->id )
{
array->ptr = ptr->ptr;
array->id = ptr->id;
array->size = ptr->size;
array->prev = ptr->prev;
array->next = ptr->next;
return OK;
}
ptr = ptr->next;
}
return FAIL;
}

uint32 GetUniqueId?()
{
	uint32 id = numArrays;
arrayInfo array;
rval_t rval;
rval = GetArrayInfo?( id, &array );
while ( OK == rval )
{
id = (0xffffffff == id)? 1 : id+1;
rval = GetArrayInfo?( id, &array );
}
return id;
}

uint32 AllocateArray?( uint32 size )
{
	numArrays++;
uint32* ptr = malloc ( sizeof(uint32) * size);
assert( ptr );
memset( ptr, sizeof(uinte32)*size);
id = GetUniqueId?();
arrayInfo* info = new arrayInfo
assert( info );
info->ptr = ptr;
uint32 id;
info->id = id;
info->size = size;
info->next = head;
info->prev = NULL;
if ( head )
{
head->prev = info;
}
head = info;
return id;
}

rval_t FreeArray?( uint32 id )
{
	arrayInfo array;
rval_t rval = GetArrayInfo?( id, &array );

	if( 0 == id )
{
return FAIL;
}

	if ( OK != rval )
{
return rval;
}
if ( array->prev )
{
array->prev->next = array->next;
}
if ( array->next )
{
array->next->prev = array->prev;
}
free( array->ptr );
if ( array->prev )
{
free( array->prev->next );
}
else if ( array->next )
{
free( array->next->prev );
}
else
{
free ( head );
head = NULL;
}
return OK;
}

uint32 GetInput?()
{
	// TODO: return an input value - 0-255, or -1 if EOF
return valueOnScreen?;
}

void Display( uint32 value )
{
	assert( value< 256 );
printf( "%c", (char) value );
valueOnScreen? = value;
}

rval_t GetArray?( uint32 id, uint32 offset, uint32* value )
{
	assert( value );

	if ( 0 == id )
{
if ( progamLength <= offset )
{
return FAIL;
}
*value = program[offset];
return OK;
}

	arrayInfo array = GetArrayInfo?( id );

	if ( !array.ptr || array.size <= offset )
{
return FAIL;
}

	*value = array.ptr[offset];
return OK;
}

rval_t SetArray?( uint32 id, uint32 offset, uint32 value )
{

	if ( 0 == id )
{
if ( progamLength <= offset )
{
return FAIL;
}
program[offset] = value;
return OK;
}

	arrayInfo array = GetArrayInfo?( id );

	if ( !array.ptr || array.size <= offset )
{
return FAIL;
}

	array.ptr[offset] = value;
return OK;
}

rval_t ExecutePlatter?( uint32 value )
{
	uint32 opcode = (value & 0xE0000000) >> 28;

	uint32 set_a_id = (value & 0x01C000000) >> 25;
uint32 c_id = (value & 0x7);
uint32 b_id = (value & 0x38) >> 3;
uint32 a_id = (value & 0x1C) >> 6;

	uint32 a = gpr[a_id];
uint32 b = gpr[b_id];
uint32 c = gpr[c_id];

	uint32 temp = 0;
rval_t rval = OK;

	switch ( opcode )
{
case 0:
gpr[set_a_id] = (0==c) ? a : b;
break;
case 1:
rval = GetArray?( B, C, &temp );
gpr[set_a_id] = (OK == rval) temp : gpr[set_a_id];
break;
case 2:
rval = SetArray?( a, b, c );
break;
case 3:
gpr[a_id] = b + c; // mod32 done by c for us.
break;
case 4:
gpr[a_id] = b * c; // mod32 done by c for us.
break;
case 5:
gpr[a_id] = b / c; // mod32 done by c for us.
break;
case 6:
gpr[a_id] = ~(b&c);
break;
case 7:
return HALT;
case 8:
gpr[b_id] = AllocateArray?( c );
break;
case 9:
return FreeArray?( c );
break;
case 10:
if ( c > 255 )
return FAIL;
Display( c );
break;
case 11:
gpr[c_id] = GetInput?();
break;
case 12:
CopyArray?( 0, b );
finger = c;
// (obvious enhancement: array0 := B, then make a copy into B)
break;
case 13:
gpr[set_a_id] = value & 0x1ffffff;
break;
default:
return FAIL;
}
return rval;
}


void main( uint32* zero, uint32 zeroLength )
{
	assert( zero );
program = zero;
prgramLength = zeroLength;
rval_t rval = OK;
while ( OK == rval )
{
uint32 value = 0;
if ( OK != GetArray?( 0, finger, &value ) )
{
rval = FAIL;
break;
}
finger++;
rval = ExecutePlatter?( value );
}

	if ( HALT == rval )
{
printf ( "HALTED" );
}
else
{
printf( "FAILED" );
}
}

www.vitenka.com | ToothyWiki | Vitenka | RecentChanges | Login | Webcomic
This page is read-only | View other revisions | Recently used referrers
Last edited January 28, 2007 4:44 pm (viewing revision 2, which is the newest) (diff)
Search: