-
Notifications
You must be signed in to change notification settings - Fork 0
/
execute.c
executable file
·303 lines (271 loc) · 9.43 KB
/
execute.c
1
#define EXECUTE_C#include "vax_to_68000.h"#include "globals.h"#include "instrs.h"#include "mmemory.h"#include "vax.h"#include "execute.h"#include "docmds.h"#include "exception.h"/******************************************************************************//* *//* I N S T R U C T I O N P R I N T E R *//* *//******************************************************************************/#pragma segment EXECUTEvoid execute( void ){register long argno;register long mode; /* mode */long r; /* register currently dealing with*/register long d; /* assembled byte, word, long or float */register char *ap; /*pointer to argument discription part of the optab entry for this instruction*/OPTAB ip; /*pointer to the optab entry for this instruction*/long ins;address address; /*address of operand*/long index; /*index to add to address*/long indexed; old_pc = PC; if(TP == 1) { exception(FAULT,V_TP,"tp",0,0); return; } TP = T; nf_temp_reg = TEMPREGS & REG_MASK; /*base for tempory registers*/ ins = bget(PC); /*get instruction*/ if(exceptions_on == 0) /*Must have had a page fault*/ return; PC++; ip = optab + ioptab[ ins ]; /*set up pointer to op table entry for instruction*/ ap = ip->argtype; /*set up pointer to op table entry for the argument type*/ for ( argno = 0; argno < ip->nargs; argno++, ap++ ) { /*for each arg expected*/ indexed = index = 0; top: if ( *ap & ACCB ) /* branch displacement */ mode = 0xAF + ( (*ap & NIBBLE_MASK) << 5 ); /*will give modes of AF for byte -> A with PC (F) as reg CF for word -> C with PC (F) as reg EF for long -> E with PC (F) as reg */ else { mode = bget( PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC++; } if ( mode & 0300 ) { /* not short literal */ r = ( mode & NIBBLE_MASK ); mode >>= 4; switch ( mode ) { case 4: /* [ r ] */ if(indexed || r == 15) /*not allowed to use pc as index reg*/ { exception(FAULT,V_RAM,"Reseverd Address Mode Fault",0,0); return; } index = vax_regs[r].contents.as_ulong * v_size_of[*ap & NIBBLE_MASK]; /*Indexed Register.*/ indexed = 1; goto top; case 5: /* r */ if(indexed || (*ap & ACCA)) { exception(FAULT,V_RAM,"Reseverd Address Mode Fault",0,0); return; } address = REGBASE + r; /*a dummy address for the register*/ break; /*The register contains the value required*/ case 6: /* ( r ) */ address = vax_regs[r].contents.as_ulong + index; /*Register defered.*/ break; case 7: /* -( r ) */ if(r == 15) /*not allowed to use PC as -(r) register*/ { exception(FAULT,V_RAM,"Reseverd Address Mode Fault",0,0); return; } vax_regs[r].contents.as_ulong -= v_size_of[*ap & NIBBLE_MASK];/*Auto Decr*/ address = vax_regs[r].contents.as_ulong + index; /*Auto decrecrement.*/ break; case 9: /* *( r )+ or PC Absolute*/ address = get(vax_regs[r].contents.as_address) + index; if(exceptions_on == 0) /*Must have had a page fault*/ return; vax_regs[r].contents.as_ulong += 4; break; case 8: /* ( r )+ or PC immediate*/ address = vax_regs[r].contents.as_ulong + index; vax_regs[r].contents.as_ulong += v_size_of[*ap & NIBBLE_MASK]; break; case 0xB: /* byte displacement defferred */ d = (long) vax_fetchb(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC++; address = get(d + vax_regs[r].contents.as_address) + index; if(exceptions_on == 0) /*Must have had a page fault*/ return; break; case 0xA: /* byte displacement */ d = (long) vax_fetchb(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC++; address = d + vax_regs[r].contents.as_ulong + index; break; case 0xD: /* word displacement deferred */ d = (long) vax_fetchw(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC += 2; address = get(d + vax_regs[r].contents.as_address) + index; if(exceptions_on == 0) /*Must have had a page fault*/ return; break; case 0xC: /* word displacement */ d = (long) vax_fetchw(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC += 2; address = d + vax_regs[r].contents.as_ulong + index; break; case 0xF: /* long displacement deferred */ d = vax_fetchl(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC += 4; address = get(d + vax_regs[r].contents.as_address) + index; if(exceptions_on == 0) /*Must have had a page fault*/ return; break; case 0xE: /* long displacement */ d = vax_fetchl(PC); if(exceptions_on == 0) /*Must have had a page fault*/ return; PC += 4; address = d + vax_regs[r].contents.as_ulong + index; break; } /* end of the mode switch */ } else { /* short literal */ if(indexed || (*ap & (ACCA | ACCW)) ) /*Not permitted with short literals*/ { exception(FAULT,V_RAM,"Reseverd Address Mode Fault",0,0); return; } if ( (*ap & NIBBLE_MASK) == TYPF || (*ap & NIBBLE_MASK) == TYPD ) { /*floating literal*/ address = REGBASE + nf_temp_reg; temp_regs[nf_temp_reg++].contents.as_ulong = e2f(flt_imm[ mode ]); } else { /* short literal */ address = REGBASE + nf_temp_reg; temp_regs[nf_temp_reg++].contents.as_ulong = mode; } } opaddr[argno] = address; } new_pc = PC; ip->ins_fnc(ip->iname);}void fix_registers(void){address the_old_pc;register long argno;register long mode; /* mode */long r; /* register currently dealing with*/register char *ap; /*pointer to argument discription part of the optab entry for this instruction*/OPTAB ip; /*pointer to the optab entry for this instruction*/long ins;long indexed; the_old_pc = old_pc; if(TP == 1 || the_old_pc == PC) { /*Would have caused a Trace FAULT*/ return; } ins = bget(the_old_pc++); /*get instruction*/ ip = optab + ioptab[ ins ]; /*set up pointer to op table entry for instruction*/ ap = ip->argtype; /*set up pointer to op table entry for the argument type*/ for ( argno = 0; argno < ip->nargs; argno++, ap++ ) {/*for each arg expected*/ indexed = 0; top: if ( *ap & ACCB ) /* branch displacement */ mode = 0xAF + ( (*ap & NIBBLE_MASK) << 5 ); /*will give modes of AF for byte -> A with PC (F) as reg CF for word -> C with PC (F) as reg EF for long -> E with PC (F) as reg */ else { if(the_old_pc == PC) return; mode = bget( the_old_pc++); } if ( mode & 0300 ) { /* not short literal */ r = ( mode & NIBBLE_MASK ); mode >>= 4; if(the_old_pc >= PC) return; switch ( mode ) { case 4: /* [ r ] */ if(indexed || r == 15) /*not allowed to use pc as index reg*/ { /*Would have caused a FAULT*/ return; } indexed = 1; goto top; case 5: /* r */ if(indexed || (*ap & ACCA)) { /*Would have caused a FAULT*/ return; } break;/*The register contains the value required*/ case 6: /* ( r ) */ break; case 7: /* -( r ) */ if( r == 15) return; vax_regs[r].contents.as_ulong += v_size_of[*ap & NIBBLE_MASK];/*Auto Decr*/ break; case 9: /* *( r )+ or PC Absolute*/ if( r != 15 ) vax_regs[r].contents.as_ulong -= 4; else vax_regs[15].contents.as_ulong += 4; break; case 8: /* ( r )+ or PC immediate*/ if( r != 15 ) vax_regs[r].contents.as_ulong -= v_size_of[*ap & NIBBLE_MASK]; else vax_regs[15].contents.as_ulong += v_size_of[*ap & NIBBLE_MASK]; break; case 0xB: /* byte displacement defferred */ case 0xA: /* byte displacement */ the_old_pc++; break; case 0xD: /* word displacement deferred */ case 0xC: /* word displacement */ the_old_pc += 2; break; case 0xF: /* long displacement deferred */ case 0xE: /* long displacement */ the_old_pc += 4; break; } /* end of the mode switch */ } else { /* short literal */ if(indexed || (*ap & (ACCA | ACCW)) ) /*Not permitted with short literals*/ { /*Would have caused a FAULT*/ return; } } }}