This is Memory.m in view mode; [Download] [Up]
//
// Memory
//
// An Objective-C class for simulating main memory subsystems for computer simulations.
// The memory has n-bit words, and m-bit addresses.
//
// Can be used for main RAM memory, ROM, Cache memory, and microstore.
//
#import "Memory.h"
#import "compmath.h"
#import "utility.h"
@implementation Memory
- initType:(int)atype // Type of memory.
dataBits:(int)dbits // Number of bits in a memory word.
addressBits:(int)abits // Number of bits in an address.
physical:(int)nwords // Amount of memory actually in subsystem.
wait:(int)wcycles // Number of cycles memory access takes.
datain:din // Node for data in.
addrin:ain // Node for address in.
ready:rout // Node for ready signal out.
dataout:dout // Node for data out.
exception:eout // Node for exception signal out.
enable:e // Node for enable.
rw:rw // Node for read/write select.
{
switch(atype) {
case MEM_RAM:
case MEM_ROM:
type = atype;
break;
default:
fprintf(stderr, "Memory: Attempt to create memory of invalid type %d!\n", atype);
exit(-1);
break;
}
if(dbits < 1) {
fprintf(stderr, "Memory: Attempt to create Memory with less than one bit per word!\n");
exit(-2);
}
databits = dbits;
if(abits < 1) {
fprintf(stderr, "Memory: Attempt to create Memory with less than one address bit!\n");
exit(-3);
}
addressbits = abits;
if(nwords < 1) {
fprintf(stderr, "Memory: Attempt to create Memory with less than one word!\n");
exit(-4);
}
numwords = nwords;
if(wcycles < 0) {
fprintf(stderr, "Memory: Attempt to create Memory with less than zero wait cycles!\n");
exit(-5);
}
wait = wcycles;
INITDEVTYPE("Memory");
TESTNODE("DATAIN", din, databits);
TESTNODE("ADDRIN", ain, addressbits);
TESTNODE("READY", rout, 1);
TESTNODE("DATAOUT", dout, databits);
TESTNODE("EXC", eout, 1);
TESTNODE("ENABLE", e, 1);
TESTNODE("RW", rw, 1);
DATAIN = din;
ADDRIN = ain;
READY = rout;
DATAOUT = dout;
EXC = eout;
ENABLE = e;
RW = rw;
lastenable = 0;
lastrw = 0;
lastaddrin = 0;
lastdatain = 0;
cyclenum = 0;
numbits = numwords * databits;
data = (bit *)malloc(numbits * sizeof(bit));
return self;
}
- free
{
free(data);
return [super free];
}
- cycle // Execute one cycle
{
bit enablebit = *([ENABLE getBits]);
bit rwbit = *([RW getBits]);
bit *indata = [DATAIN getBits];
bit *inaddr = [ADDRIN getBits];
long addr = bits2long(inaddr, addressbits);
long curdata = bits2long(indata, databits);
bit one = 1;
bit zero = 0;
bit curexc = *([EXC getBits]);
int i;
if(type == MEM_ROM) {
[DATAOUT setBits:&(data[addr * databits])];
return self;
}
if(enablebit)
if(cyclenum < wait) { // If not ready, simply block.
cyclenum++;
return self;
}
else {
cyclenum == 0;
[READY setBits:&one];
if(*[RW getBits]) { // If we are writing,
for(i = 0; i < databits; i++) // copy input data to memory.
data[addr * databits + i] = indata[i];
}
else { // Else, we are reading, so
[DATAOUT setBits:&(data[addr * databits])]; // set DATAOUT to the word.
}
}
else {
cyclenum = 0;
return self;
}
return self;
}
- loadAt:(int)addr fromFile:(FILE *)aFile // Load some data into the memory.
{
int curaddr;
char linebuffer[256];
int i;
curaddr = addr;
while(readline(aFile, linebuffer) == 0) {
for(i = 0; i < databits; i++) {
if(linebuffer[databits - i - 1] == '0') {
data[curaddr * databits + i] = 0;
}
else {
data[curaddr * databits + i] = 1;
}
}
curaddr++;
}
return self;
}
- dumpWord:(int)addr toFile:(FILE *)aFile
{
int i;
int sum;
for(i = (databits - 1); i >= 0; i--) { // Dump binary form.
fprintf(aFile, "%d", data[addr * databits + i]);
}
fprintf(aFile, " : 0x"); // Dump hex form.
sum = 0;
for(i = (databits - 1); i >= 0; i--) {
switch(i % 4) {
case 0:
sum += data[addr * databits + i];
fprintf(aFile, "%X", sum);
sum = 0;
break;
case 1:
sum += 2 * data[addr * databits + i];
break;
case 2:
sum += 4 * data[addr * databits + i];
break;
case 3:
sum += 8 * data[addr * databits + i];
break;
}
}
return 0;
}
- dumpStart:(int)start // Dump a portion of memory to a file.
stop:(int)stop
toFile:(FILE *)aFile
{
int curaddr;
if(start < 0) {
fprintf(stderr, "Memory: Cannot dump memory below 0!\n");
return nil;
}
if(stop < start) {
fprintf(stderr, "Memory: Dump stop address must not be less than start address!\n");
return nil;
}
if(aFile != stdout) {
fprintf(stdout, "Dumping memory [%d..%d]...\n", start, stop);
}
fprintf(aFile, "\n\nMemory content : \n\n");
for(curaddr = start; curaddr <= stop; curaddr++) { // For all words in range:
fprintf(aFile, "%p: ", curaddr); // Dump the address.
[self dumpWord:curaddr toFile:aFile]; // Dump the word.
fprintf(aFile, "\n"); // Dump end of line.
}
return self;
}
@end
//
// End of file.
//These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.