/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 27-Nov-85 | [1.20] Created * 4-Dec-85 | [1.104] star is set to dot-1 * 4-Dec-85 | [1.113] Accept = for # * 11-Dec-85 | [1.164] Reject any characters not in the bcd character set. * 20-Dec-85 | [1.170] Give error if unrecognized operand for DCW * 20-Dec-85 | [1.171] Issue error only on pass 1 * 24-Nov-91 | [1.177] converted to C6.0 * 24-Nov-91 | [1.177] memory.h => automem.h, avoid conflict with ANSI * | name * 24-Nov-91 | [1.177] mach.h => machmem.h * 3-Dec-91 | [1.220] store C_bit with all stored data so that we * | can tell difference between initialized and passed-over storage * 3-Dec-91 | [1.220] use CHAR_GM for groupmark * 22-Dec-91 | [1.257] allow & for signed constant * 22-Dec-91 | [1.257] handle symbolic addresses e.g. DCW +FOO *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /**************************************************************************** * signed_const * Inputs: * int sign: <0 for minus bits * >0 for plus bits * =0 for no bits * boolean need_wm: true if wm required, false otherwise * int pass: Pass number * Effect: * Declares a signed constant. This may be of the form * +nnn or -nnn for digits, or +NAME or -NAME for address * values ****************************************************************************/ static void signed_const(int sign,boolean need_wm,int pass) { /* operands[0] is our constant */ char str[80]; int width; int val; int twidth; int i; if(sign==0) strcpy(str,operands[0]); else strcpy(str,&operands[0][1]); if(isalpha(str[0])) { /* name */ ste * sy; char msg[80]; int loc = dot; unsigned int addr; if(!expr(str, &addr, true, expr_lit_illegal, pass, false)) { /* failed */ dot += 3; /* names take up 3 characters */ return; } /* failed */ if(pass == 2) { /* lay it down */ unsigned ho = dot; if(sign < 0) addr = comp16K(addr); write_operand(addr); if(need_wm) memory[ho] |= word_mark; } /* lay it down */ return; } /* name */ width = strlen(str); /* simple syntax check: twidth == width? */ val = atoi(str); #if 0 /* rewrite for C6.0 */ if(twidth != width) { /* bogus */ error(err_operand,"Illegal characters in numeric constant"); } /* bogus */ #endif for(i=0;i 63 || bcd < 0) { /* illegal character */ error(err_operand,"Illegal BCD character in literal"); bcd = 0; /* Make it a space */ } /* illegal character */ memory[loc] = C_bits | bcd; } /* store number */ if(need_wm) { /* store WM */ unsigned loc; loc = check_memory(dot); memory[loc] |= word_mark; } /* store WM */ if(sign < 0) { /* store minus */ unsigned loc; loc = check_memory(dot + width - 1); memory[loc] |= B_bits; } /* store minus */ else if(sign > 0) { /* store plus */ unsigned loc; loc = check_memory(dot + width - 1); memory[loc] |= BA_bits; } /* store plus */ dot += width; } /**************************************************************************** * dc * Inputs: * int pass: Pass number we are on * boolean need_wm: True to put wordmark in field * False for no word mark * Result: int * Amount of dot offset * Effect: * Defines storage with or without word mark as indicated ****************************************************************************/ static int dc(int pass,boolean need_wm) { int val; int noperands; boolean GMWM = false; int cnt; int i; int old_dot = dot; int offset = 0; /* Check the operand. If a literal, declare that space. If an expression, allocate that much space */ check_sym("dc - before scan"); noperands = scan_operands(); check_sym("dc - after scan"); if(noperands == 0) { /* bogus */ if(pass==1) error(err_operand,"DC/DCW requires operand"); if(pass == 2) { /* list it */ list_line(); emit_listing(); } /* list it */ return 0; } /* bogus */ if(noperands == 2) { /* want GMWM? */ if(strcmp(operands[1],"G") == 0) GMWM = true; else { /* bogus */ if(pass==1) error(err_operand,"DC/DCW must have only one operand"); if(pass == 2) { /* list it */ list_line(); emit_listing(); } /* list it */ return 0; } /* bogus */ } /* want GMWM? */ /* Valid values are: ok +ddd (ddd digits) stores that many digits with AB bits on L/O ok -ddd (ddd digits) stores that many digits with B bit on L/O ok ddd (ddd digits) stores that many digits with no zones on L/O ok #dd (dd digits) stores that many spaces ok @...@ stores alpha constant nyi +expr stores address constant ,G indicates GM/WM must follow */ switch(operands[0][0]) { /* decode constant */ case '#': /* space: #dd */ case '=': check_sym("processing # in dc"); val = atoi(&operands[0][1]); #if 0 /* rewrite for C6.0 */ if(cnt != strlen(operands[0])-1) { /* bad characters */ if(pass==1) error(err_operand,"Bad characters in # value"); /* return; */ } /* bad characters */ #endif if(val+dot > 16000) { /* too big */ char msg[80]; sprintf(msg,"Memory overflow: #%d + %d",val,dot); if(pass==2) error(err_operand,msg); return 0; } /* too big */ for(i=0;i16000) { /* overflow */ if(pass==1) error(err_operand,"Memory overflow"); return 0; } /* overflow */ for(i=1;i