//
// Decoder
//
// An Objective-C class for simulating a digital decoder.
//


#import "Decoder.h"
#import "compmath.h"


@implementation Decoder


- initNumBits:(int)nbits			// numbits inputs, 2^numbits outputs.
	in:innode				// Input Node.
	out:outnode				// Node of outputs.
{
    [super init];
    
    if(nbits < 1) {
        fprintf(stderr, "Decoder: Attempt to create Decoder with less than 1 input bit!\n");
	exit(-2);
    }
    
    multioutput = NO;				// Single output.
    
    numbits = nbits;
    numouts = pow2(numbits);
    
    INITDEVTYPE("Decoder");
    
    TESTNODE("IN", innode, numbits);
    TESTNODE("OUT", outnode, numouts);
    
    IN = innode;
    OUT = outnode;
    
    temp = (bit *)malloc(numouts * sizeof(bit));
    
    return self;
}


- initNumBits:(int)nbits
	in:innode
	outs:(id *)outarray
{
    int		i;
    char	nodenum[20];
    
    [super init];
    
    multioutput = YES;
    
    if(nbits < 1) {
        fprintf(stderr, "Decoder: Attempt to create Decoder with %d inputs!\n", nbits);
	exit(-1);
    }
    
    numbits = nbits;
    numouts = pow2(numbits);
    
    INITDEVTYPE("Decoder");
    
    TESTNODE("IN", innode, numbits);
    IN = innode;
    
    outputs = (id *)malloc(numouts * sizeof(id));
    
    for(i = 0; i < numouts; i++) {
        sprintf(nodenum, "OUT[%d]", i);
        TESTNODE(nodenum, outarray[i], 1);
        outputs[i] = outarray[i];
    }
	
    temp = (bit *)malloc(numbits * sizeof(bit));		// Temporary answer storage.
    
    return self;
}


- free
{
    if(!multioutput) {
	free(temp);
    }
    else {
        free(outputs);
    }
    
    return [super free];
}


- cycle
{
    int index, i;
    bit	tempbit;
    bit *inbits = [IN getBits];
    
    
    index = 0;
 	   
    for(i = 0; i < numbits; i++) {			// Calculate index of high output:
	index = index * 2;				//   * Shift index right; and
	index = index + inbits[i];			//   * Add current bit.
    }
    
    if(!multioutput) {
	for(i = 0; i < numouts; i++) {
	    temp[i] = (i == index);				// Set all but index = 0.
	}
    
	[OUT setBits:temp];
    }
    else {
        for(i = 0; i < numouts; i++) {
	    tempbit = (i == index);
	    [outputs[i] setBits:&tempbit];
	}
    }
    
    return self;
}


@end


//
// End of file.
//