📄 sim1.c
字号:
/*****************************************************************//* *//* Machine Language Simulator *//* Version 3.0 *//* *//* by J. Glenn Brookshear *//* Marquette University *//* *//* Simulates the machine described in Appendix C *//* of the text Computer Science: An Overview. *//* Includes op-codes D and E (indirect addressing) *//* as described in Chapter 7. *//* *//* Last update: March 8, 2002 *//* *//*****************************************************************/#define ANSI 1 /* Set ANSI to 1 if this program is */ /* to be compiled on an ANSI C system. */ /* Set it to 0 if a (non ANSI) UNIX */ /* system is to be used. */ /* When the UNIX option is used, an */ /* empty file named SaveFile must be */ /* provided if no other SaveFile is */ /* present. */ /* This flag is used in deciding how */ /* to handle the deletion and renaming */ /* of files in the functions named */ /* save_program and delete_program. */#include<stdio.h>#include<stdlib.h>#include<string.h>#define true 1#define false 0char buf[80]; /* buffer for input from keyboard */long memory[16][16] = {0}; /* main memory */long reg[16] = {0}; /* registers */long pc = 0; /* program counter */long instr_reg = 0; /* instruction register */long op_code, operand_1, x, y; /* instruction components */long gethex(); /* utility function for reading */ /* hexadecimal values--avoids */ /* use of scanf(). */void identify(); /* identifies program on user */ /* screen when program starts. */void help(); /* functions for menu items */void display();void change_mem();void change_reg();void change_pc();void clear();void single_step();void run_to_halt();void process_file();void retrieve_program(); /* file manipulating functions */void save_program();void delete_program();void list_programs();void fetch(); /* steps in machine cycle */void decode();int execute();void add_float(); /* machine language instructions */void or();void and();void exclus_or();void rotate();void jump();/*******************************************************//* *//* main() displays the memory and register *//* contents on the screen and waits for *//* input from the keyboard. At that time *//* it calls the appropriate function to *//* perform the requested action. *//* *//*******************************************************/void main(){ identify(); display(); do { gets(buf); switch(buf[0]) { case 'M':case 'm': change_mem(); display(); break; case 'R':case 'r': change_reg(); display(); break; case 'P':case 'p': change_pc(); display(); break; case 'S':case 's': single_step(); display(); break; case 'G':case 'g': run_to_halt(); display(); break; case 'C':case 'c': clear(); display(); break; case 'F':case 'f': process_file(); display(); break; case 'H':case 'h':case '?': help(); display(); break; case 'Q':case 'q': break; } } while (buf[0] != 'Q' && buf[0] != 'q');}/*******************************************************//* *//* indentify() displays the program's identification *//* on the user's screen when the program begins. *//* *//*******************************************************/void identify(){long i, j; printf("\n\n\n\n\n\n\n\n\n"); printf("***************************************************\n"); printf(" **\n"); printf(" * Machine Simulator*\n"); printf(" * version 3.0*\n"); printf(" **\n"); printf(" * Simulates the machine described in Appendix C*\n"); printf(" * of the text Computer Science: An Overview.*\n"); printf(" **\n"); printf("***************************************************\n"); printf("\n\n\n\n\n\n\n\n"); for (i = 0; i < 65000; i++) for (j = 0; j < 200; j++) i = i;}/*******************************************************//* *//* help() presents an explanation of the options *//* on the main display menu. *//* *//*******************************************************/void help(){printf("\n\n\nOptions are as follows:\n\n"); printf(" M Change contents of memory cells.\n"); printf(" R Change contents of registers.\n"); printf(" P Change contents of program counter.\n"); printf(" C Clear memory or registers. (Options will begiven.)\n"); printf(" S Single step. (Execute a single machine cycle.)\n"); printf(" G Go. (Execute until a halt instruction is executed\n"); printf(" or until 500 machine cycles have beenexecuted.)\n"); printf(" F Obtain list of file options "); printf("(to save or retrieve programs).\n"); printf(" H Display this help screen.\n"); printf(" Q Terminate this simulation program.\n\n\n"); printf("\n**Type <Enter> to return to main display. "); gets(buf); printf("\n");}/*******************************************************//* *//* display() displays the machine state *//* and selection menu on the screen. *//* *//*******************************************************/void display(){ int i, j; printf("\n\n Main Memory\n\n"); for(i=0; i!=16; i++) { printf(" "); printf(" %X",i); } for(i=0; i!=16; i++) { printf("\n"); printf("%1X",i); for(j=0; j!=16; j++) if(memory[i][j] <= 15) /* Allow for leading 0s */ printf(" 0%X ",memory[i][j]); else printf(" %X ",memory[i][j]); } printf("\n\n"); for(i=0; i<16; i++) { if(i==8) {printf(" PC: "); if (pc <= 15) printf("0%X\n", pc); else printf("%X\n", pc); } printf("R%X:",i); if(reg[i] <= 15) printf("0%X ", reg[i]); else printf("%X ", reg[i]); } if (instr_reg == 0) printf(" IR: 0000\n"); else printf(" IR: %X\n", instr_reg); printf("\nType one of the following (H for help): "); printf("M, R, P, C, S, G, F, Q: ");}/*******************************************************//* *//* gethex() is used to read hexadecimal values *//* from the keyboard to avoid the lack of *//* control provided by scanf. *//* gethex() returns the value received when a *//* valid hexadecimal value is typed. Otherwise *//* it returns a -1 if only a RETURN was typed *//* or a -2 if any nonhexadecimal characters were *//* typed. *//* *//*******************************************************/long gethex(){long input = 0; long return_value; int valid = true; int i = 0; gets(buf); while (buf[i] != '\0') {switch (buf[i]) {case '0': input = input * 16 + 0; break; case '1': input = input * 16 + 1; break; case '2': input = input * 16 + 2; break; case '3': input = input * 16 + 3; break; case '4': input = input * 16 + 4; break; case '5': input = input * 16 + 5; break; case '6': input = input * 16 + 6; break; case '7': input = input * 16 + 7; break; case '8': input = input * 16 + 8; break; case '9': input = input * 16 + 9; break; case 'A':case 'a': input = input * 16 + 10; break; case 'B':case 'b': input = input * 16 + 11; break; case 'C':case 'c': input = input * 16 + 12; break; case 'D':case 'd': input = input * 16 + 13; break; case 'E':case 'e': input = input * 16 + 14; break; case 'F':case 'f': input = input * 16 + 15; break; default: valid = false; break; } i++; } if (valid == true && i != 0) /* Valid hexadecimal value */ return_value = input; if (valid == true && i == 0) /* Only a RETURN was typed */ return_value = -1; if (valid == false) /* Invalid input received */ return_value = -2; return(return_value);}/*******************************************************//* *//* change_mem() is used to change the contents *//* of consecutive memory cells. *//* *//*******************************************************/void change_mem(){long address, input; int a, b; do {printf("\n\nAddress of the cell to be changed (hexadecimal): "); address = gethex(); } while(address < 0 || address > 255); b = address % 16; a = address/16; printf("\n\n Cell Current New\n"); printf(" Address contents contents\n"); do {printf(" %X%X ", a, b); if (memory[a][b] <= 15) printf("0%X ", memory[a][b]); else printf("%X ", memory[a][b]); input = gethex(); if (0 <= input) if (input < 256) {memory[a][b] = input; if (b ==15) {b = 0; a++;} else b++; a = a % 16; } else {printf("\nInput value too large"); printf("\n(Type <Enter> to return to main display.)"); } if (input == -2) {printf("\n**Illegal input**"); printf("\n(Type <Enter> to return to main display."); } printf("\n"); } while (input != -1);}/*******************************************************//* *//* change_reg() is used to change *//* the contents of a register. *//* *//*******************************************************/void change_reg(){ long reg_num, value; char repeat = 'y'; while(repeat == 'y' || repeat == 'Y') {do {printf("\nRegister to change: "); reg_num = gethex(); if (reg_num < 0 || reg_num > 15) printf("\n**Illegal register number**"); } while(reg_num < 0 || reg_num > 15); do {printf("\nValue of register %X is: ", reg_num); printf("%X\n", reg[reg_num]); printf("New value for register %X: ", reg_num); value = gethex(); if (value < 0 || value > 255) printf("\n***Illegal register value***"); } while(value < 0 || value > 255); reg[reg_num] = value; printf("\nChange another register? (y/n): "); gets(buf); repeat = buf[0]; } printf("\n");}/*******************************************************//* *//* change_pc() is used to change the value of *//* the program counter. *//* *//*******************************************************/void change_pc(){do {printf("\nNew value of the program counter: "); pc = gethex(); if (pc < 0 || pc > 255) printf("\n**Invalid value for program counter**"); } while(pc < 0 || pc > 255); printf("\n");}/*******************************************************//* *//* clear() puts 0s in all memory cells or all *//* registers depending on the selection from *//* the keyboard. An invalid input from the *//* keyboard terminates the function with not *//* side effects. *//* *//*******************************************************/void clear(){ int i,j; printf("\nClear memory, registers, or both? (M, R, or B): "); gets(buf); if (buf[0] == 'M' || buf[0] == 'm') {for (i=0; i < 16; i++) for (j=0; j < 16; j++) memory[i][j] = 0; } if (buf[0] == 'R' || buf[0] == 'r') {for (i=0; i < 16; i++) reg[i] = 0; } if (buf[0] == 'B' || buf[0] == 'b') {for (i=0; i < 16; i++) for (j=0; j < 16; j++) memory[i][j] = 0; for (i=0; i < 16; i++) reg[i] = 0; } printf("\n");}/******************************************************//* *//* process_file() presents a menu of the file *//* processing options and branches to the *//* option selected. *//* *//******************************************************/void process_file(){printf("\n\nRetrieve a program, save a program, "); printf("\ndelete a program, or list available programs? "); printf("\n(R, S, D, or L): "); gets(buf); switch (buf[0]) {case 'R':case 'r': retrieve_program(); printf("\n"); break; case 'S':case 's': save_program(); break; case 'D':case 'd': delete_program(); break; case 'L':case 'l': list_programs(); break; default: printf("\n"); break; }}/*******************************************************//* *//* retrieve_program() retrieves the selected *//* machine language program (memory image) *//* from the file "SaveFile" and loads it into *//* the simulated memory. *//* *//*******************************************************/void retrieve_program(){ FILE *in_file; char input[80]; int i, j; long temp; int found = false; printf("\nType the name of the program to be retrieved: "); gets(buf); if ((in_file = fopen("SaveFile", "r")) == NULL) {printf("\nProgram file not available");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -