/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 27-Nov-85 | [1.22] Created * 30-Nov-85 | [1.57] Handle indexing * 30-Nov-85 | [1.86] Call datacard to dump memory to output device * 4-Dec-85 | [1.104] recognize ' for @ * 13-Dec-85 | [1.166] Removed cvbytes to separate module * 13-Dec-85 | [1.166] Undid previous change * 24-Nov-91 | [1.177] memory.h => automem.h * 24-Nov-91 | [1.177] converted to C6.0 * 24-Nov-91 | [1.177] mach.h => machmem.h * 3-Dec-91 | [1.220] use symbolic NOPERANDS since some pseudo-ops * | have more than 3 * 3-Dec-91 | [1.220] use C_bits to determine valid memory locations * 4-Dec-91 | [1.230] use isdata to determine valid memory locations * 22-Dec-91 | [1.259] cvbytes: set C_bits *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include char operands[NOPERANDS][81]; extern char line[81]; extern int dot; extern boolean debug; extern char * valstr(); extern unsigned start; #define isdata(x) ( ( (x) & (word_mark | C_bits) ) != 0 ) #define barewm(x) ( ( (x) & word_mark && !((x) & C_bits) ) ) /**************************************************************************** * scan_operands * Result: int * Number of operands found (0,1,2,3,...,NOPERANDS) * Effect: * Loads the operands[i] fields with the operands * * Operand form value * 0 * d 1 * A 1 * A, 2 * A,d 2 * A,B 2 * A,B, 3 * A,B,d 3 ****************************************************************************/ int scan_operands() { int i; int operand; char * pos = &line[OPERAND_START]; char * epos = &line[80]; boolean more; int noperands; int len; more = true; noperands = 0; for(operand=0;operand0) noperands++; more = false; scanned = true; pos++; break; case ',': scanned = true; pos++; noperands++; break; default: operands[operand][dpos] = *pos; dpos++; pos++; } /* decode */ operands[operand][dpos] = '\0'; /* Operand is empty to start */ #if 0 printf("operands[%d][%d] = \"%s\"\n",operand,dpos,operands[operand]); #endif } /* scan this operand */ } /* scan one operand */ return noperands; } /**************************************************************************** * cvbytes * Inputs: * char * dest: Place to put converted bytes * unsigned val: Value to convert * Effect: * 3 bcd characters representing the value are placed in dest[0..2] * Clobbers any WM or data flags ****************************************************************************/ void cvbytes(char * dest,unsigned val) { unsigned baseval; baseval = base(val); /* base address value */ if(debug) printf("cvbytes(0x%x,%u (%s))\n",dest,val,valstr(val)); if(val == expr_bad) { /* had error */ dest[0] = dest[1] = dest[2] = ascii_to_bcd('.') | C_bits; return; } /* had error */ dest[2] = (char) (val % 10); /* low order bcd char is units */ if(dest[2] == '\0') dest[2] = 10; /* 8-2 for 0 */ #if debug_cvbytes printf("dest[2]=%d (%c)\n",dest[2],bcd_to_ascii(dest[2])); #endif dest[1] = (char) ((baseval / 10) % 10); if(dest[1] == '\0') dest[1] = 10; /* 8-2 for 0 */ #if debug_cvbytes printf("dest[1]=%d (%c)\n",dest[1],bcd_to_ascii(dest[1])); #endif dest[0] = (char) ((baseval / 100) % 10); if(dest[0] == '\0') dest[0] = 10; /* 8-2 for 0 */ #if debug_cvbytes printf("dest[0]=%d (%c)\n",dest[0],bcd_to_ascii(dest[0])); #endif /* That takes care of the easy stuff! 000..999 now stored */ /* Now do decoding for 1000..3999 (A,B,AB = 1,2,3 on tens) and for 4000-15000 (A,B,AB = 1,2,3 * 4000 on units ) and index registers range hundreds units 000- 999 - - 1000- 1999 A - 2000- 2999 B - 3000- 3999 AB - 4000- 4999 - - 5000- 5999 A A 6000- 6999 B A 7000- 7999 AB A 8000- 8999 - - 9000- 9999 A B 10000-10999 B B 11000-11999 AB B 12000-12999 - - 13000-13999 A AB 14000-14999 B AB 15000-15999 AB AB */ switch((baseval/1000) % 4) { /* hundreds zone */ case 0: break; case 1: dest[0] |= A_bits; break; case 2: dest[0] |= B_bits; break; case 3: dest[0] |= BA_bits; break; } /* hundreds zone */ switch((baseval/4000) % 4) { /* units zone */ case 0: break; case 1: dest[2] |= A_bits; break; case 2: dest[2] |= B_bits; break; case 3: dest[2] |= BA_bits; break; } /* units zone */ /* Now decode the index value */ switch(ixreg(val)) { /* index */ case 0: break; case 1: dest[1] |= A_bits; break; case 2: dest[1] |= B_bits; break; case 3: dest[1] |= BA_bits; break; } /* index */ dest[0] |= C_bits; dest[1] |= C_bits; dest[2] |= C_bits; } /**************************************************************************** * debug_write_operand * Inputs: * unsigned val: Value which was to be converted * char * bytes: Byte array written * Effect: * displays debug info ****************************************************************************/ void debug_write_operand(unsigned val,char * bytes) { #if debug_cvbytes int i; printf("write_operand(%s) => \"",valstr(val)); for(i=0;i<3;i++) printf("%c",bcd_to_ascii(bytes[i])); printf("\" ("); for(i=0;i<3;i++) printf("\\%03o",bytes[i]); printf(")\n"); #endif } /**************************************************************************** * write_operand * Inputs: * unsigned val: Value to write as operand, uses encoded X1,X2,X3 * Effect: * Writes 3 characters in memory at "dot", advances dot ****************************************************************************/ void write_operand(unsigned val) { char bytes[4]; int i; cvbytes(bytes,val); debug_write_operand(val,bytes); for(i=0;i<3;i++) { /* deposit */ memory[dot] = C_bits | bytes[i]; dot++; } /* deposit */ } /**************************************************************************** * write_dchar * Inputs: * char d: d-char value, in bcd * Effect: * Writes the d-char at dot ****************************************************************************/ void write_dchar(char d) { memory[dot] = C_bits | d; dot++; } /**************************************************************************** * dump_memory * Effect: * Dumps memory to output device ****************************************************************************/ void dump_memory() { int i; int lb; int ub; int nlb; for(lb=1;lb<16000;lb++) if(memory[lb]&C_bits) break; for(ub=15999;ub>0;ub--) if(memory[ub]&C_bits) break; printf("loc data %d..%d\n",lb,ub); printf("----- ----\n"); if(!WM(memory[lb])) printf("%5d: ",lb); for(i=lb;i<=ub;i++) { /* dump memory */ if(WM(memory[i])) { /* new field */ printf("\n%5d: ",i); } /* new field */ printf("%c",bcd_to_ascii(memory[i])); } /* dump memory */ printf("\n"); } /**************************************************************************** * punch_card * Effect: * Punches cards on virtual card punch ****************************************************************************/ void punch_cards() { int i; int lb; int ub; int nlb; for(lb=1;lb<16000;lb++) if(memory[lb] & C_bits) break; for(ub=15999;ub>0;ub--) if(memory[ub] & C_bits) break; loadcard(); nlb = lb; while(nlb <= ub) { /* write card */ nlb = datacard(nlb,ub); } /* write card */ /* Now find all locations which have WM bits but no C_bits (so we want to set wms without disturbing the data which might have been already placed) */ for(lb=1;lb<16000;lb++) if(barewm(memory[lb])) break; for(ub=15999;ub>0;ub--) if(barewm(memory[ub])) break; if(ub >= lb) wmcard(lb,ub); flushcard(i_B,start); }