#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 newg2.c contains a package of functions to */ /* decode and execute function codes which belong to group 2. */ /*****************************************************************/ extern void Caseerror(); /* function for output error message */ extern void nonrecognise(); /* another function for error message*/ extern char grp2code[][4]; /* group 2 mnemonics */ /*****************************************************************/ /* input value of instruction from dogroup2; decode it and return*/ /* function code to code; execute the job of code. */ /*****************************************************************/ void degrp2(data, code, signal) int data; /* integer value of instruction */ ingroup2 *code; /* function code of group 2 */ int signal; /* signal lookahead if 1 */ { switch (data % 1024) { case 0: (*code) = stp; break ; case 1: (*code) = rts; break ; case 2: (*code) = asr; break ; case 3: (*code) = asl; break ; case 4: (*code) = neg; break ; case 5: (*code) = psh; break ; case 6: (*code) = pul; break ; case 7: (*code) = clr; break ; case 8: (*code) = inc; break ; case 9: (*code) = trp; break ; case 10: (*code) = rtt; break ; case 11: (*code) = sti; break ; case 12: (*code) = rir; break ; case 13: (*code) = spi; break ; case 14: (*code) = lsr; break ; case 15: (*code) = lsl; break ; default: nonrecognise(pc+signal,data,2); } } /*****************************************************************/ /* load V-bit with the exclusive OR of the N-bit and the C-bit. */ /*****************************************************************/ void load_v_bit() { if (psw.n == psw.c) psw.v = 0; else psw.v = 1; } /*****************************************************************/ /* 'pop' value from stack and place it to pcnew; highlight winn. */ /*****************************************************************/ void rts_group2() { location = sp; pcnew = mm.A[sp]; sp = sp + 1; mvwprintw(comm_win,0,1,"return from subroutine to "); mvwprintw(comm_win,1,1,"location %o.",pcnew); wstandout(winn); } /*****************************************************************/ /* push value of acc to stack; convert acc to ogginword to decide*/ /* status of N,Z bits; highlight wina and set pcnew to pc + 1. */ /*****************************************************************/ void psh_group2() { ogginword resultofoperation;/* value of acc in 16 bits */ sp = sp - 1; mm.A[sp] = acc; location = sp; integertooggin(acc, &resultofoperation); pc_nz_bits(resultofoperation,&acc); /* also pcnew = pc + 1 */ wstandout(wina); mvwprintw(comm_win,0,1,"push value of acc to stack %o",location); } /*****************************************************************/ /* 'pop' value from stack and store it in acc; convert acc to */ /* decide N,Z bits; highlight wina and set pcnew to pc + 1. */ /*****************************************************************/ void pul_group2() { ogginword resultofoperation;/* value of acc in 16 bits */ acc = mm.A[sp]; location = sp; sp = sp + 1; integertooggin(acc, &resultofoperation); pc_nz_bits(resultofoperation,&acc); wstandout(wina); mvwprintw(comm_win,0,1,"'pop' data from stack %o",location); mvwprintw(comm_win,1,1,"to acc."); } /*****************************************************************/ /* convert value of acc to ogginword and return result to result-*/ /* ofoperation; place bit 0 in C-bit and shift bit 15 to bit 1 */ /* one place right; decide N,Z bits and set pcnew to pc + 1. */ /*****************************************************************/ void asr_group2() { register int i; ogginword resultofoperation;/* value of acc in 16 bits */ integertooggin(acc, &resultofoperation); psw.c = resultofoperation.A[0]; for (i = 0; i<=14 ; i++) resultofoperation.A[i] = resultofoperation.A[i + 1]; pc_nz_bits(resultofoperation,&acc); load_v_bit(); mvwprintw(comm_win,0,1,"acc shifted right 1 place."); mvwprintw(comm_win,1,1,"Bit 15 is replicated."); mvwprintw(comm_win,2,1,"bit 0 shifted to C bit."); } /*****************************************************************/ /* convert acc to ogginword and place result in resultofoperation*/ /* put value of bit 15 in C-bit; pad bit 0 with 0; shift bit 0 to*/ /* bit 14 one place left; decide N,Z bits and set pcnew to pc + 1*/ /*****************************************************************/ void asl_group2() { register int i; ogginword resultofoperation;/* value of acc in 16 bits */ integertooggin(acc, &resultofoperation); psw.c = resultofoperation.A[15]; for (i = 14; i>=0 ; i--) resultofoperation.A[i + 1] = resultofoperation.A[i]; resultofoperation.A[0] = 0; pc_nz_bits(resultofoperation,&acc); load_v_bit(); mvwprintw(comm_win,0,1,"acc shifted left 1 place."); mvwprintw(comm_win,1,1,"Bit 0 padded with 0."); mvwprintw(comm_win,2,1,"Bit 15 shifted to C bit."); } /*****************************************************************/ /* convert acc to ogginword and put result in resultofoperation; */ /* negate resultofoperation using two's complement; decide */ /* N,Z bits and set pcnew to pc + 1; highlight acc. */ /*****************************************************************/ void neg_group2() { int i; ogginword resultofoperation;/* value of acc in 16 bits */ int oldacc; /* acc before negated */ oldacc = acc; integertooggin(acc, &resultofoperation); twoscomplement(&resultofoperation); pc_nz_bits(resultofoperation,&acc); if ((acc != 0) && (oldacc == acc)) psw.v = 1; else psw.v = 0; if (acc == 0) psw.c = 0; else psw.c = 1; mvwprintw(comm_win,0,1,"Negate accumulator contents."); wstandout(wina); } /*****************************************************************/ /* convert acc to ogginword and place result in resultofoperation*/ /* place C-bit to ctemp; C-bit takes the value of bit 0; shift */ /* bit 15 to bit 1 right one place; put ctemp in bit 15; decide */ /* status of N,Z bits and set pcnew to pc + 1. */ /*****************************************************************/ void lsr_group2() { register int i; p_status ctemp; /* processor status word */ ogginword resultofoperation;/* value of acc in 16 bits */ integertooggin(acc, &resultofoperation); ctemp.c = psw.c; psw.c = resultofoperation.A[0]; for (i = 0; i<=14; i++) resultofoperation.A[i] = resultofoperation.A[i + 1]; resultofoperation.A[15] = ctemp.c; pc_nz_bits(resultofoperation,&acc); load_v_bit(); mvwprintw(comm_win,0,1,"acc rotated right 1 place."); mvwprintw(comm_win,1,1,"C-bit loaded into bit 15."); mvwprintw(comm_win,2,1,"bit 0 loaded into C-bit."); } /*****************************************************************/ /* add 1 to ir; convert ir to ogginword and decide status of N,Z */ /* bits; and set pcnew to pc + 1. */ /*****************************************************************/ void inc_group2() { ogginword resultofoperation;/* value of acc in 16 bits */ ir = ir + 1; integertooggin(ir, &resultofoperation); pc_nz_bits(resultofoperation,&ir); mvwprintw(comm_win,0,1,"IR <- IR + 1"); } /*****************************************************************/ /* set acc to 0 and set Z to 1 and other psw flags to 0 */ /*****************************************************************/ void clr_group2() { acc = 0; psw.c = 0; psw.n = 0; psw.z = 1; psw.v = 0; mvwprintw(comm_win,0,1,"zero accumulator."); pcnew = pc + 1; } /*****************************************************************/ /* input an integer, decode it to get values of C,N,Z,V bits. */ /*****************************************************************/ void pull_psw(contents) int contents; /* value of psw in integer */ { psw.c = (contents % 16) / 8; psw.n = (contents % 8) / 4; psw.z = (contents % 4) / 2; psw.v = (contents % 2); } /*****************************************************************/ /* convert processor status word to integer. */ /*****************************************************************/ int push_psw() { int psw_in; /* integer value of psw */ psw_in = 0; if (psw.c == 1) psw_in = psw_in + 8; if (psw.n == 1) psw_in = psw_in + 4; if (psw.z == 1) psw_in = psw_in + 2; if (psw.v == 1) psw_in = psw_in + 1; return(psw_in); } /*****************************************************************/ /* push psw and pc + 1 to stack; load pc with trap routine addr */ /* and new processor status word from locations 10 and 11 octal. */ /*****************************************************************/ void trp_group2() { sp = sp -1; mm.A[sp] = push_psw(); location = sp; sp = sp - 1; mm.A[sp] = pc + 1; loca_1 = sp ; pcnew = mm.A[8]; pull_psw(mm.A[9]); mvwprintw(comm_win,0,1,"perform a synchronous trap "); mvwprintw(comm_win,1,1,"push current psw to %4o",location); mvwprintw(comm_win,2,1,"push return address to %4o",loca_1); mvwprintw(comm_win,3,1,"obtain new pc and psw from"); mvwprintw(comm_win,4,1,"locations 10 and 11 "); } /*****************************************************************/ /* 'pop' return address from stack to pc and restore old psw. */ /*****************************************************************/ void rtt_group2() { int rtt_psw; /* value of psw in integer */ pcnew = mm.A[sp]; location = sp; sp = sp + 1; rtt_psw = mm.A[sp]; pull_psw(rtt_psw); loca_1 = sp; mvwprintw(comm_win,0,1,"return from trap"); mvwprintw(comm_win,1,1,"pop return address from "); mvwprintw(comm_win,2,1,"location %4o to pc",location); mvwprintw(comm_win,3,1,"pop psw from location"); mvwprintw(comm_win,4,1,"%4o to psw",loca_1); } /*****************************************************************/ /* push value of index register to stack; convert ir to ogginword*/ /* and decide status of N,Z bits; set pcnew to pc + 1. */ /*****************************************************************/ void sti_group2() { ogginword resultofoperation;/* value of acc in 16 bits */ sp = sp - 1; mm.A[sp] = ir; location = sp; integertooggin(ir,&resultofoperation); pc_nz_bits(resultofoperation,&ir); mvwprintw(comm_win,1,1,"store index register"); mvwprintw(comm_win,2,1,"to stack %o",location); } /*****************************************************************/ /* restore value of index register from stack; decide N,Z bits */ /* and set pcnew to pc + 1. */ /*****************************************************************/ void rir_group2() { ogginword resultofoperation;/* value of acc in 16 bits */ ir = mm.A[sp]; location = sp; sp = sp + 1; integertooggin(ir,&resultofoperation); pc_nz_bits(resultofoperation,&ir); mvwprintw(comm_win,1,1,"restore data from stack"); mvwprintw(comm_win,2,1,"%o to index register",location); } /*****************************************************************/ /* move stack pointer to index register; set pcnew to pc + 1. */ /*****************************************************************/ void spi_group2() { ir = sp; psw.n = 0; psw.z = 0; psw.v = 0; pcnew = pc + 1; mvwprintw(comm_win,1,1,"move stack pointer %o",sp); mvwprintw(comm_win,2,1,"to index register."); wstandout(wins); } /*****************************************************************/ /* convert acc to ogginword and place result in resultofoperation*/ /* put C-bit in ctemp.c; put bit 15 in C-bit; shift bit 0 to */ /* bit 14 one place left; decide N,Z bits and set pcnew to pc + 1*/ /*****************************************************************/ void lsl_group2() { register int i; p_status ctemp; /* processor status words */ ogginword resultofoperation;/* value of acc in 16 bits */ integertooggin(acc,&resultofoperation); ctemp.c = psw.c; psw.c = resultofoperation.A[15]; for (i=14; i>=0; i--) resultofoperation.A[i+1] = resultofoperation.A[i]; resultofoperation.A[0] = ctemp.c; pc_nz_bits(resultofoperation,&acc); load_v_bit(); mvwprintw(comm_win,0,1,"acc rotated left 1 place."); mvwprintw(comm_win,1,1,"bit 15 loaded into C-bit."); mvwprintw(comm_win,2,1,"C-bit loaded into bit 0."); } /*****************************************************************/ /* input function code from dogroup2; execute the code. */ /*****************************************************************/ void exgrp2(code) ingroup2 code; /* function code of group 2 */ { switch (code) { case stp: pcnew = pc + 1; mvwprintw(comm_win,1,1,"halt processor "); break ; case rts: rts_group2(); break ; case psh: psh_group2(); break ; case pul: pul_group2(); break ; case asr: asr_group2(); break ; case asl: asl_group2(); break ; case neg: neg_group2(); break ; case lsr: lsr_group2(); break ; case lsl : lsl_group2(); break; case clr: clr_group2(); break ; case inc: inc_group2(); break ; case trp : trp_group2(); break; case rtt : rtt_group2(); break; case sti : sti_group2(); break; case rir : rir_group2(); break; case spi : spi_group2(); break; default: Caseerror(Line); } } /*****************************************************************/ /* input value of instruction from inst(); decode it and */ /* return the code to code2; execute the code and move data */ /* needed to assl_win and comm_win. */ /*****************************************************************/ void dogroup2(data, code2,signal,end) int data; /* value of instruction */ ingroup2 *code2; /* function code of group 2 */ int signal; /* value either 1 or 0 */ { ingroup2 g2; /* function code of group 2 */ octalcode str; /* octal no. output as a string */ ogginword binary;/* binary no. in 16 bits */ int i; /* counter of For loop */ degrp2(data, &(*code2),signal); if (signal == 1) mvwprintw(assl_win,2,0,"%s",grp2code[*code2]); else { exgrp2((*code2)); wattron(assl_win,A_STANDOUT); mvwprintw(assl_win,1,0,"%s",grp2code[*code2]); wattroff(assl_win,A_STANDOUT); mvwprintw(expl_win,2,0,"%s",grp2code[*code2]); mvwprintw(expl_win,4,0,"%s","none"); mvwprintw(expl_win,5,0,"%s","none"); if (((*code2) == asl) || ((*code2) == asr) || ((*code2) == lsr) || ((*code2) == lsl) || ((*code2)== clr) || ((*code2) == neg)) { integertooggin(oldacc,&binary); mvwprintw(comm_win,3,1,"OLDacc :"); for (i=15; i>=0; i--) mvwprintw(comm_win,3,10+15-i,"%1d",binary.A[i]); integertooggin(acc,&binary); mvwprintw(comm_win,4,1,"NEWacc :"); for (i=15; i>=0; i--) mvwprintw(comm_win,4,10+15-i,"%1d",binary.A[i]); } } } /* ** End of newg2.c */