void log_msg(enum log_level level, const char* who, const char* format, ...) { if (level == DEBUG_MSG) { if (opt_debug == 0) return; if (cpu_dev.dctrl == 0 && opt_debug < 1) // todo: should CPU control all debug settings? return; } // Make sure all messages have a prior display of the IC if (!ignore_IC && (PPR.IC != last_IC || PPR.PSR != last_IC_seg)) { last_IC = PPR.IC; last_IC_seg = PPR.PSR; char *tag = "Debug"; // char *who = "IC"; // out_msg("\n%s: %*s %s %*sIC: %o\n", tag, 7-strlen(tag), "", who, 18-strlen(who), "", PPR.IC); char icbuf[80]; addr_modes_t addr_mode = get_addr_mode(); ic2text(icbuf, addr_mode, PPR.PSR, PPR.IC); // out_msg("\n"); // out_msg("%s: %*s IC: %s\n", tag, 7-strlen(tag), "", icbuf); msg(DEBUG_MSG, NULL, "\n", NULL); char buf[80]; sprintf(buf, "%s: %*s IC: %s\n", tag, 7 - (int) strlen(tag), "", icbuf); msg(DEBUG_MSG, NULL, buf, NULL); } va_list ap; va_start(ap, format); #if 0 char *tag = (level == DEBUG_MSG) ? "Debug" : (level == INFO_MSG) ? "Info" : (level == NOTIFY_MSG) ? "Note" : (level == WARN_MSG) ? "WARNING" : (level == ERR_MSG) ? "ERROR" : "???MESSAGE"; msg(tag, who, format, ap); #else msg(level, who, format, ap); #endif va_end(ap); }
int scan_seg(uint segno, int msgs) { // See descripton at _scan_seg(). uint saved_seg = TPR.TSR; fault_gen_no_fault = 1; addr_modes_t amode = get_addr_mode(); set_addr_mode(APPEND_mode); int saved_debug = opt_debug; opt_debug = 0; t_stat ret = _scan_seg(segno, msgs); if (ret > 1 && msgs) out_msg("xseginfo: Error processing request.\n"); opt_debug = saved_debug; TPR.TSR = saved_seg; fault_gen_no_fault = 0; set_addr_mode(amode); return ret; }
void doFault(DCDstruct *i, _fault faultNumber, _fault_subtype subFault, char *faultMsg) { //if (faultNumber < 0 || faultNumber > 31) if (faultNumber & ~037) // quicker? { printf("fault(out-of-range): %d %d '%s'\r\n", faultNumber, subFault, faultMsg ? faultMsg : "?"); return; } dps8faults *f = &_faults[faultNumber]; if (bFaultCycle) // if already in a FAULT CYCLE then signal trouble faule f = &_faults[FAULT_TRB]; else { // TODO: safe-store the Control Unit Data (see Section 3) into program-invisible holding registers in preparation for a Store Control Unit (scu) instruction, } int fltAddress = rFAULTBASE & 07740; // (12-bits of which the top-most 7-bits are used) word24 addr = fltAddress + f->fault_address; // absolute address of fault YPair bFaultCycle = true; // enter FAULT CYCLE word36 faultPair[2]; core_read2(addr, faultPair, faultPair+1); // In the FAULT CYCLE, the processor safe-stores the Control Unit Data (see Section 3) into program-invisible holding registers in preparation for a Store Control Unit (scu) instruction, then enters temporary absolute mode, forces the current ring of execution C(PPR.PRR) to 0, and generates a computed address for the fault trap pair by concatenating the setting of the FAULT BASE switches on the processor configuration panel with twice the fault number (see Table 7-1). This computed address and the operation code for the Execute Double (xed) instruction are forced into the instruction register and executed as an instruction. Note that the execution of the instruction is not done in a normal EXECUTE CYCLE but in the FAULT CYCLE with the processor in temporary absolute mode. addr_modes_t am = get_addr_mode(); // save address mode PPR.PRR = 0; set_addr_mode(ABSOLUTE_mode); t_stat xrv = doXED(faultPair); bFaultCycle = false; // exit FAULT CYCLE if (xrv == CONT_TRA) longjmp(jmpMain, JMP_TRA); // execute transfer instruction set_addr_mode(am); // If no transfer of control takes place, the processor returns to the mode in effect at the time of the fault and resumes normal sequential execution with the instruction following the faulting instruction (C(PPR.IC) + 1). if (xrv == 0) longjmp(jmpMain, JMP_NEXT); // execute next instruction else if (0) // TODO: need to put test in to retry instruction longjmp(jmpMain, JMP_RETRY); // retry instruction // printf("fault(): %d %d %s (%s) '%s'\r\n", f->fault_number, f->fault_group, f->fault_name, f->fault_mnemonic, faultMsg ? faultMsg : "?"); // // if (f->fault_group == 7 && i && i->a) // return; // // return; // longjmp(jmpMain, JMP_NEXT); // causes cpuCycles to not count the current instruction // // pending_fault = true; // bool retry = false; // // int fltAddress = rFAULTBASE & 07740; // (12-bits of which the top-most 7-bits are used) // fltAddress += 2 * f->fault_number; // // f->fault_pending = true; // this particular fault is pending, waiting for processing // // _processor_addressing_mode modeTemp = processorAddressingMode; // // processorAddressingMode = ABSOLUTE_MODE; // word24 rIC_temp = rIC; // // t_stat ret = doFaultInstructionPair(i, fltAddress); // // f->fault_pending = false; // pending_fault = false; // // processorAddressingMode = modeTemp; // // // XXX we really only want to do this in extreme conditions since faults can be returned from *more-or-less* // // XXX do it properly - later.. // // if (retry) // longjmp(jmpMain, JMP_RETRY); // this will retry the faulted instruction // // if (ret == CONT_TRA) // longjmp(jmpMain, JMP_TRA); }
void read_file(char *filename,struct Process **pproc) { FILE *fp; char *endfile,line[MAXSTR],*p,save_token[MAXSTR]; int label_bool=0,line_count=0,num_code=0,n_args; struct instruction_node *new_instr; struct Process *proc; struct expr_node *new_expr; proc=(struct Process*)malloc(sizeof(struct Process)); if(proc==NULL) die("errore nell'allocare struct Process"); proc->pt=NULL; proc->pc=NULL; proc->prev=NULL; proc->next=NULL; proc->processID=get_processID(); fp=fopen(filename,"r"); if(fp==NULL) die("error opening file"); proc->pc=(struct process_construct*)malloc(sizeof(struct process_construct)); if(proc->pc==NULL) die("errore nell'allocare process_construct"); proc->pc->first=NULL; proc->pc->last=NULL; proc->pc->len=0; proc->pc->org[0]='\0'; proc->pc->vt_first=NULL; proc->pc->vt_last=NULL; while((endfile=fgets(line,MAXSTR,fp))!=NULL) { line_count++; p=&line[0]; if(*p==';') continue; p=skip_space(p); if(*p=='\n') continue; p=get_token(p); p=skip_space(p); if((strcmp(my_token,"org"))==0) { p=get_word(p);strncpy(proc->pc->org,my_token,MAXSTR); if(*p!='\n') {sprintf(save_token,"parse error at line %d. not an end line after the org argument",line_count);die(save_token);} continue; } if((strcmp(my_token,"end"))==0) { p=skip_space(p); if(*p!='\n') {sprintf(save_token,"parse error after 'end' at line %d.",line_count);die(save_token);} break; } if((strcmp(my_token,"assert"))==0) { take_assert(p); new_expr=(struct expr_node*)malloc(sizeof(struct expr_node)); if(new_expr==NULL) {printf("at line %d, ",line_count);die("error allocating new_expr");} p=skip_space(p); p=get_b_arg(&new_expr,p,line_count); insert_in_vt(ASSERT_STR,new_expr,line_count,proc); continue; } if(*p==':') { insert_label(my_token,num_code,line_count,proc);p=skip_space(++p); if(*p=='\n') continue; p=get_token(p); } n_args=is_instr(my_token,line_count); if(n_args!=-1) { new_instr=(struct instruction_node*)malloc(sizeof(struct instruction_node)); if(new_instr==NULL) {printf("at line %d , ",line_count);die("error allocating new_instr");} strncpy(new_instr->instr,my_token,MAXSTR); new_instr->num_node=num_code++; new_instr->line_count=line_count; new_instr->prev=NULL; new_instr->next=NULL; new_instr->code=NULL; new_instr->left=NULL; new_instr->right=NULL; new_instr->laddr[0]='#';new_instr->laddr[1]='\0'; new_instr->raddr[0]='#';new_instr->raddr[1]='\0'; strcpy(new_instr->modifier,"NULL"); if(*p=='.'){ p=get_word(++p);is_modifier(my_token,line_count); strncpy(new_instr->modifier,my_token,MAXMOD); } p=skip_space(p); if(n_args>0) { p=get_addr_mode(p); //$ by default. the result is in my_token new_instr->laddr[0]=my_token[0]; new_instr->laddr[1]='\0'; //p=get_token(p); //new_instr->left=(struct expr_node*)malloc(sizeof(struct expr_node)); //if(new_instr->left==NULL){ //printf("at line %d , ",line_count);die("error alocating left expr");} p=get_arg(&new_instr->left,p,line_count); p=skip_space(p); if(n_args>1) { if(*p!=',') {printf("at line %d , ",line_count);die("a comma expected (,)");} p=skip_space(++p); p=get_addr_mode(p); //$ by default. the result is in my_token new_instr->raddr[0]=my_token[0]; new_instr->raddr[1]='\0'; //p=get_token(p); //new_instr->right=(struct expr_node*)malloc(sizeof(struct expr_node)); //if(new_instr->right==NULL){ //printf("at line %d , ",line_count);die("error allocating right expr");} p=get_arg(&new_instr->right,p,line_count); p=skip_space(p); } } if(*p!='\n') {printf("at line %d , ",line_count);die("not an ending line after command");} //add the node add_node(new_instr,proc); continue; } strncpy(save_token,my_token,MAXSTR); p=get_token(p); if((strcmp(my_token,"equ"))==0) { new_expr=(struct expr_node*)malloc(sizeof(struct expr_node)); if(new_expr==NULL) {printf("at line %d, ",line_count);die("error allocating new_expr");} p=skip_space(p); p=get_arg(&new_expr,p,line_count); insert_in_vt(save_token,new_expr,line_count,proc); continue; } } fclose(fp); proc->pc->len=num_code; add_proc(proc); *pproc=proc; }