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.