Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
279 lines
6.7 KiB
C++
279 lines
6.7 KiB
C++
|
|
/*{{{ comment*/
|
|
/*
|
|
|
|
File names.c
|
|
|
|
This module contains functions to move from
|
|
i860 pointer <--> i860 name
|
|
This is primarily for SuperVision distributed rendering systems
|
|
where the same data item will be held in different places on different
|
|
boards
|
|
|
|
Phil Atkin
|
|
|
|
(c) Division Ltd. 1991
|
|
*/
|
|
|
|
/*}}} */
|
|
/*{{{ discussion*/
|
|
/*
|
|
|
|
In superVision we have a problem that the same data item will not
|
|
appear in the same place on different processors. We need to implement
|
|
a naming system which allows us to uniquely identify a piece of data
|
|
and find its location in memory. There are two strategies for this - we
|
|
either try to maintain as many REAL pointers as we can in the i860 and
|
|
resort to names only across the dView/i860 boundary, OR we swallow the big
|
|
pill and use names EVERYWHERE, including the internal linked lists. Currently
|
|
we load no more than 400 instances (the corridor maze demo). If I build a
|
|
hash table of 512 locations, at the moment no programs will need to indirect
|
|
more than once to get the physical location from the name.
|
|
OK, that's decided it - ALL references to dView-visible items will be by NAME.
|
|
|
|
Internal linked lists will be maintained as pointers. The dpl processor
|
|
ignores the NEXT field anyway, so the only problem then is heirarchy.
|
|
|
|
IMPACTS
|
|
-------
|
|
|
|
Backward compatibility
|
|
----------------------
|
|
|
|
NULL needs to be an invalid name.
|
|
Walking linked lists, we need to go nameToAddress() on each item.
|
|
|
|
heirachy
|
|
--------
|
|
|
|
In heirarchies, the link, next and daddy fields are NAMES. Therefore
|
|
heirarchy stuff needs nameToAddress() in the loop.
|
|
|
|
Creation
|
|
--------
|
|
|
|
We get a new name. Add it to the hash table, and hand the pointer back
|
|
to the dView.
|
|
|
|
Deletion
|
|
--------
|
|
|
|
Do what we do now, but in addition delete any hash-table storage.
|
|
|
|
|
|
|
|
I believe we NEVER need to go addressToName()
|
|
|
|
|
|
*/
|
|
/*}}} */
|
|
/*{{{ includes*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "dpltypes.h"
|
|
/*}}} */
|
|
/*{{{ local typedefs*/
|
|
#define max_pages 512
|
|
#define mask_pages ((max_pages)-1)
|
|
|
|
typedef struct s_ypage {
|
|
struct s_ypage *next;
|
|
int name;
|
|
dpl_type name_type;
|
|
void *address;
|
|
} yellowPage;
|
|
/*}}} */
|
|
/*{{{ statics*/
|
|
static yellowPage *yellowPages [max_pages];
|
|
|
|
static int init=0;
|
|
|
|
/*}}} */
|
|
/*{{{ externally visible*/
|
|
|
|
/* the first name handed out is 1 */
|
|
|
|
int allocatedNames=1;
|
|
/*}}} */
|
|
|
|
/*{{{ void checkNull ( void *p, char *s )*/
|
|
void checkNull ( void *p, char *s )
|
|
{
|
|
if (p==NULL) {
|
|
printf( "NULL pointer in %s\n", s );
|
|
fflush(stdout);
|
|
exit (666);
|
|
}
|
|
/*
|
|
else
|
|
printf ( "ok pointer in %s\n", s );
|
|
*/
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ int initNames ()*/
|
|
int initNames ()
|
|
{
|
|
int i;
|
|
/* printf ("initNames\n"); */
|
|
if (init==0) {
|
|
for (i=0; i<max_pages; i++) {
|
|
yellowPages[i]=NULL;
|
|
}
|
|
init=1;
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ addName ( int item_name, void *location, dpl_type type )*/
|
|
static void
|
|
addName ( int item_name, void *location, dpl_type type )
|
|
{
|
|
yellowPage *head=yellowPages[item_name&mask_pages], *node=head;
|
|
/*
|
|
printf ("add name address 0x%x name %d type %s\n",
|
|
location, item_name, type_to_string(type));
|
|
*/
|
|
/* find somewhere to put this item */
|
|
if (head == NULL) {
|
|
/* nothing in this hash entry, create first location */
|
|
head=(yellowPage *) malloc ( sizeof (yellowPage));
|
|
checkNull ( head, "createName");
|
|
head->address=location;
|
|
head->name=item_name;
|
|
head->name_type=type;
|
|
head->next=NULL;
|
|
yellowPages[item_name&mask_pages] = head;
|
|
}
|
|
else {
|
|
/* find tail of list */
|
|
while (node->next != NULL) {
|
|
node=node->next;
|
|
}
|
|
node->next=(yellowPage *) malloc ( sizeof (yellowPage));
|
|
node=node->next;
|
|
checkNull ( node, "createName");
|
|
node->address=location;
|
|
node->name=item_name;
|
|
node->name_type=type;
|
|
node->next=NULL;
|
|
}
|
|
/* printf ("newName returning %d\n", item_name ); */
|
|
return ( item_name );
|
|
}
|
|
/*}}} */
|
|
/*{{{ int newName ( void *location, dpl_type type )*/
|
|
int newName ( void *location, dpl_type type )
|
|
{
|
|
/* printf ("newName %d\n", item_name ); */
|
|
if (location == NULL)
|
|
return 0;
|
|
else {
|
|
int item_name=allocatedNames++;
|
|
|
|
addName ( item_name, location, type );
|
|
|
|
return ( item_name );
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ int deleteName ( int item_name, dpl_type type )*/
|
|
int deleteName ( int item_name, dpl_type type )
|
|
{
|
|
yellowPage *head=yellowPages[item_name&mask_pages],
|
|
*node=head,
|
|
*prev=NULL;
|
|
|
|
while (node->name != item_name) {
|
|
prev=node;
|
|
node=node->next;
|
|
|
|
if (node==NULL) {
|
|
printf ("Name 0x%x (%s) not found\n",
|
|
item_name, type_to_string(type) );
|
|
exit (666);
|
|
}
|
|
}
|
|
|
|
if (type != (-1)) {
|
|
if (node->name_type != type ) {
|
|
printf ("deleteName: name 0x%x wrong type, expected %s found %s\n",
|
|
item_name, type_to_string(type),
|
|
type_to_string(node->name_type) );
|
|
exit (666);
|
|
}
|
|
}
|
|
|
|
if (prev == NULL) {
|
|
yellowPages[item_name&mask_pages] = node->next;
|
|
free ( node );
|
|
}
|
|
else {
|
|
prev->next=node->next;
|
|
free (node);
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ void *nameToAddress ( int item_name, dpl_type type )*/
|
|
void *nameToAddress ( int item_name, dpl_type type )
|
|
{
|
|
yellowPage *head;
|
|
|
|
if (item_name == 0) return NULL;
|
|
|
|
|
|
for (head=yellowPages[item_name&mask_pages];head;head=head->next) {
|
|
if (head->name == item_name) {
|
|
if (head->name_type == type) {
|
|
return head->address;
|
|
}
|
|
else if (type == (dpl_type) (-1)) {
|
|
return head->address;
|
|
}
|
|
else {
|
|
printf ("nameToAddress: name 0x%x wrong type, expected %s found %s address 0x%x\n",
|
|
item_name, type_to_string(type),
|
|
type_to_string(head->name_type),
|
|
head->address);
|
|
printf ("allocatedNames = %d\n", allocatedNames );
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
/*}}} */
|
|
/*{{{ int addressToName ( void *item, dpl_type type )*/
|
|
int addressToName ( void *item, dpl_type type )
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<(mask_pages)+1; i++ ) {
|
|
yellowPage *head=yellowPages[i];
|
|
|
|
while (head) {
|
|
if (head->address == item) {
|
|
if (type == (-1))
|
|
return head->name;
|
|
else if (head->name_type == type)
|
|
return head->name;
|
|
else
|
|
printf ("found item 0x%x name 0x%x, wrong type\n",
|
|
item, head->name );
|
|
}
|
|
head=head->next;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
/*}}} */
|
|
/*{{{ int check_name ( int name)*/
|
|
int check_name ( int name)
|
|
{
|
|
return ((name < 0) || (name > allocatedNames));
|
|
}
|
|
/*}}} */
|
|
|
|
|