/*****************************************************************************c * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 3-Dec-91 | [1.220] Created *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ste * last_da = NULL; ste * next_da = NULL; /**************************************************************************** * daop_da * Inputs: * int opindex: (not used) * int pass: 1 or 2 * Result: boolean * true if success * false if error * Effect: * Defines a storage area ****************************************************************************/ boolean daop_da(int opindex, int pass) { int noperands; int B; int L; char * p; int size; getlabelval * v; ste * sy; boolean rm = false; boolean gm = false; boolean clear = false; int ix = 0; int i; unsigned int addr; /* We have the following form: label DA nnnXmmm {,C | ,G | ,Ø ,Xn}* */ check_sym("Before DA"); noperands = scan_operands(); if(noperands == 0) { /* missing operand */ if(pass == 2) error(err_operand,"Missing operand to DA"); goto bad_exit; } /* missing operand */ p = strchr(operands[0],'X'); if(p == NULL) { /* no X */ if(pass == 2) error(err_operand,"Must be of form BXL; X is missing"); goto bad_exit; } /* no X */ *p = '\0'; B = atoi(operands[0]); L = atoi(p+1); *p = 'X'; for(i=1; i 16000) { /* bogus */ char msg[100]; sprintf(msg,"Size %dX%d exceeds 16000!",B,L); if(pass == 2) error(err_operand,msg); goto bad_exit; } /* bogus */ if(size+dot > 16000) { /* too big */ char msg[80]; sprintf(msg,"Memory overflow: DA %dX%d + %d",B,L,dot); if(pass == 2) error(err_operand,msg); goto bad_exit; } /* too big */ v = getlabel(); if(v != NULL) { /* we have a label */ if(v->left) { /* illegal */ if(pass == 2) error(err_label,"Indented label not allowed"); goto bad_exit; } /* illegal */ sy = lookup(v->name); if(sy == NULL) { /* not found */ sy = enter(v->name,addr); if(sy == NULL) { /* failed to allocate */ return false; } /* failed to allocate */ sy->B = B; sy->L = L; sy->W = (rm ? L+1 : L); sy->len = size; } /* not found */ else { /* multiply-defined? */ if(sy->val != addr) { /* is multiply defined */ sy->muldef = true; if(pass == 2) muldef(sy,NULL); } /* is multiply defined */ } /* multiply-defined? */ } /* we have a label */ else { /* we have no label */ if(pass == 2) error(err_label,"Label required for DA"); goto bad_exit; } /* we have no label */ if(clear) { /* clear it */ for(i=0; i= sy->L) { /* illegal val */ if(pass == 2) error(err_operand,"Value is outside record size"); goto bad_exit; } /* illegal val */ break; case 2: left = atoi(operands[0]); right = atoi(operands[1]); if(left < 0 || left >= sy->L) { /* illegal left */ if(pass == 2) error(err_operand,"Left field value outside record size"); goto bad_exit; } /* illegal left */ if(right < 0 || right >= sy->L) { /* illegal right */ if(pass == 2) error(err_operand,"Right field value outside record size"); goto bad_exit; } /* illegal right */ if(right < left) { /* inverse range */ if(pass == 2) error(err_operand,"Left of field must be < right of field"); goto bad_exit; } /* inverse range */ start = unindexed(last_da->val); for(i=start; i+left < start + sy->len; i+= sy->W) { /* place WMs */ unsigned loc; loc = check_memory(i+left); /* Note that we do not set the C_bits here because we only want to set a WM */ memory[loc] |= word_mark; } /* place WMs */ break; default: if(pass == 2) error(err_operand,"Too many operands on DA entry"); goto bad_exit; } /* how many? */ addr = right + last_da->val; /* Now process the label (if any) */ v = getlabel(); if(v != NULL) { /* process label */ sy = lookup(v->name); if(sy != NULL) { /* duplicate? */ if(pass == 1) { /* multiply-defined */ sy->muldef = true; } /* multiply-defined */ if(pass == 2 && sy->val != addr) { /* duplicate */ muldef(sy,NULL); } /* duplicate */ } /* duplicate? */ else { /* not dup */ sy = enter(v->name, addr); } /* not dup */ } /* process label */ if(pass == 2) { /* list it */ list_addr(addr); list_line(); emit_listing(); } /* list it */ next_da = last_da; return true; bad_exit: if(pass == 2) { /* list it */ list_addr(addr); list_line(); emit_listing(); } /* list it */ next_da = last_da; return false; } /**************************************************************************** * daop * Inputs: * int opindex: used to determine main or sub * int pass: 1 | 2 * Result: boolean * true if correct * false if error * Effect: * Processes a DA declaration or its subdeclaration ****************************************************************************/ boolean daop(int opindex, int pass) { switch(optable[opindex].opcode) { /* decode option */ case 0: /* 'DA' */ return daop_da(opindex,pass); case 1: /* subentry */ return daop_sub(opindex,pass); } /* decode option */ } /**************************************************************************** * fix_da * Result: void * * Effect: * Moves next_da to last_da and clears next_da * Notes: * A DA declaration always sets 'next_da' ****************************************************************************/ void fix_da() { last_da = next_da; next_da = NULL; }