#include #include #include "glovar.h" /*****************************************************************/ /* Computing Science MSc Dissertation */ /* `newogg' oggin Interpreter */ /* By Lydia L W Wong (C) August 1990 */ /* University of Stirling */ /*****************************************************************/ /* this file called newm.c contains the main body of the program,*/ /* which invokes, controls and terminates the program. */ /*****************************************************************/ /* group 1 mnemonics */ char grp1code[10][4]={"lda","sta","ldi","add","sub", "cmp","and","ora","jsr","jmp"}; /* addressing modes */ char fourmodes[4][10]={"immediate","direct","indirect","indexed"}; /* group 2 mnemonics */ char grp2code[16][4]={"stp","rts","asr","asl","neg","psh","pul", "clr","inc","trp","rtt","sti","rir","spi","lsr","lsl"}; /* group 3 mnemonics */ char grp3code[8][4]={"beq","bne","bgt","bge","blt","ble","bcs","bcc"}; extern void Caseerror(); /* function for output error message */ /*****************************************************************/ /* copy data 'datain' in decimal to location 'address' of memory.*/ /* set 'error' to true if access location out of range. */ /*****************************************************************/ void writecycle(address, datain, error) int address; /* location number */ int datain; /* data copied to memory */ boolean *error; /* true = access location over range */ { (*error) = (boolean)((address < 0) || (address > 1023)); if (!(*error)) mm.A[address] = datain; } /*****************************************************************/ /* read and convert a file in octal characters to decimal and */ /* place the converted file in main memory. */ /*****************************************************************/ void readfile(datafile) char *datafile; /* file read in */ { int count; /* counter of For loop */ int data; /* data of file read in */ int blockaddress; /* block address of file read in */ int blocksize; /* block size of block being read */ boolean errorstatus; /* true == access location over range*/ FILE *fp; fp = fopen(datafile, "r"); if (fp == NULL) { printf("\n"); perror(datafile); /* Prints the error message */ terminate(); /* Terminates program */ } fscanf(fp, "%6o", &blockaddress); pc = blockaddress; do { fscanf(fp, "%6o", &blocksize); for (count = 1;count <= blocksize ; count++) { fscanf(fp, "%6o", &data); writecycle(blockaddress, data, &errorstatus); if (errorstatus) erroradd(blockaddress); blockaddress = blockaddress + 1; } } while (fscanf(fp, "%6o", &blockaddress) != EOF); } /*****************************************************************/ /* initialise global registers and processor status word. */ /*****************************************************************/ void initialise() { mdr = 0; acc = 0; sp = 1024; ir = 0; temp = 0; psw.c = 0; psw.n = 0; psw.z = 0; psw.v = 0; } /*****************************************************************/ /* copy data from main memory of location 'address' to 'data' and*/ /* set 'error' true if access location over range. */ /*****************************************************************/ void readcycle(address, data, error) int address; /* location number */ int *data; /* data copied from memory */ boolean *error; /* true == access location over range */ { (*error) = (boolean)((address < 0) || (address > 1023)); if (!(*error)) (*data) = mm.A[address]; } /*****************************************************************/ /* input an integer 'data' from main program; compute value of */ /* 'operand', function code bits and return value of bits 12-14 */ /* to rmdr; determine instruction group 'opg'. */ /*****************************************************************/ void decoding(data, opg, rmdr, operand) int data; /* value of instruction */ instructiongroup *opg; /* instruction group */ int *rmdr; /* value of bits 12-14 */ int *operand; /* value of operand bits */ { if (data < 4096) /* if bit 12-15 not set */ (*opg) = group2; else { (*operand) = data % 1024; data = data - (*operand); if (data >= 32768) /* if bit 15 set */ { (*rmdr) = (data % 32768) / 4096; switch ((*rmdr)) { case 0: case 7: (*opg) = group3; break ; case 1: case 2: case 3: case 4: case 5: case 6: (*opg) = group1; break ; default: /* Should never get here */ Caseerror(Line); } } else (*opg) = group1; } } /*****************************************************************/ /* convert integers to 16-bit ogginwords. */ /*****************************************************************/ void integertooggin(source, oggin) int source; /* integer input value */ ogginword *oggin; /* 16-bit value in ogginword */ { register int i; /* counter of For loop */ for (i = 0;i<= 15 ; i++) oggin->A[i] = 0; i = 0; do { oggin->A[i] = source % 2; source = source / 2; i = i + 1; } while (!(source == 0)); } /*****************************************************************/ /* convert values in ogginwords to integers. */ /*****************************************************************/ void oggintointeger(source, result) ogginword source; /* value in ogginword */ int *result; /* value in integer */ { register int i; /* counter of For loop */ (*result) = 0; for (i = 15; i>=0 ; i--) (*result) = ((*result) * 2) + source.A[i]; } /*****************************************************************/ /* add two variables 'p' and 'q' bit by bit and place the result */ /* in 'r'; determine if carry bit set. */ /*****************************************************************/ void addword(p, q, r) ogginword p, q; /* two values to be added */ ogginword *r; /* result of addition. */ { p_status c_bit; /* processor status word */ register int i; c_bit.c = 0; for (i = 0; i<=15 ; i++) { r->A[i] = (p.A[i] + q.A[i] + c_bit.c) % 2; c_bit.c = (p.A[i] + q.A[i] + c_bit.c) / 2; } if (c_bit.c == 1) psw.c = 1; else psw.c = 0; } /*****************************************************************/ /* convert ones to zeros and zeros to ones bit by bit of 'result'*/ /* and return the converted value to 'result' again. */ /*****************************************************************/ void onescomplement(result) ogginword *result; /* value before and after one's complement */ { register int i; /* counter of For loop */ for (i = 0; i<=15; i++) { if (result->A[i] == 0) result->A[i] = 1; else result->A[i] = 0; } } /*****************************************************************/ /* two's complement the value in `source' by first one's */ /* complementing it and then adding one; and place the result to */ /* 'source' again. */ /*****************************************************************/ void twoscomplement(source) ogginword *source; /* value before and after two's complement */ { ogginword result; /* value after two's complement */ register int i; ogginword one; /* value of 1 in ogginword */ for (i = 0; i<=15 ; i++) result.A[i] = 0; one.A[0] = 1; for (i = 1; i<=15 ; i++) one.A[i] = 0; onescomplement(source); addword((*source), one, &result); (*source) = result; } /*****************************************************************/ /* decide status of N,Z bits according to 'resultofoperation' and*/ /* convert it back to integer and return to 'holder'. */ /*****************************************************************/ void pc_nz_bits(resultofoperation,holder) int *holder; /* register for holding final result */ ogginword resultofoperation; /* input value in ogginword */ { if (resultofoperation.A[15] == 1) psw.n = 1; else psw.n = 0; oggintointeger(resultofoperation, holder); if (holder == 0) psw.z = 1; else psw.z = 0; pcnew = pc + 1; } /*****************************************************************/ /* convert an integer to octal characters and the octal string as*/ /* an array of char. */ /*****************************************************************/ octalcode writeoct(datain) int datain; /* integer value */ { int i; /* index of array */ int no; /* remainder of division */ octalcode oct; /* result of converted value */ strncpy(oct.A, "000000", sizeof(oct.A)); i = 6; do { no = datain % 8; oct.A[i - 1] = no + (unsigned)('0'); datain = datain / 8; i = i - 1; } while (!(datain == 0)); return(oct); } /* ** Start of program code */ main(argc,argv) int argc; /* argument counter */ char *argv[]; /* argument variables */ { char *datafile; /* name of data file */ if ( argc < 2) { printf("Usage: %s datafile\n",argv[0]); exit(1); } if ( argc > 2 ) { printf("Only one file is allowed\n"); exit(1); } datafile = argv[1]; title(); sleep(2); message(); initscr(); mvaddstr(0,1, "pc= instr= acc= sp="); mvaddstr(0,45,"index= CNZV= pc<-"); refresh(); readfile(datafile); buildwin(); buildpad(); initialise(); inst_cycle(); terminate(); } /* ** End of program newm.c */