/***************************************************************************** * Change Log * Date | Change *-----------+----------------------------------------------------------------- * 30-Nov-85 | [1.86] Created * 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] ignore C bit when moving data * 3-Dec-91 | [1.220] do not put anything in locations which do not * | have C_bits * 4-Dec-91 | [1.230] updated loader format to follow specs from * | Autocoder manual. * | Added procedure to set wordmarks in uninitialized space *****************************************************************************/ #include #include #include #include #include #include #include #include #include extern FILE * punch; extern boolean debug; extern unsigned start; int punched = 0; /* Write bootload card images, then dump memory #ifdef OBSOLETE 1111111111222222222233333333334444444444555555555566 1234567890123456789012345678901234567890123456786012345678901 ,008015,022029,036040N000000N0000001001 Ltttxxx,tt1tt2,tt3tt4,tt5tt6,tt7tt81001dddddddddddddddddddddddd...dddd Ltttxxx)tt1tt2,tt3tt4,tt5tt6,tt7tt81001dddddddddddddddddddddddd...dddd LtttxxxN000000N000000N000000N0000001001ddddddddddddddddddddddddd...ddd #endif 111111111122222222223333333333444444444455555555556666666666777777 123456789012345678901234567890123456789012345678601234567890123456789012345 * * * * * * * * * * * ,008015,022029,036040,047054,061068/039,072001N000000N000000N0000001040BOOTSTR .......................................Ltttxxx,tt1tt2,tt3tt4,tt5tt61040nnnn 1 1 1 1 1 1 1 1 1 1 1 ^ ^ ^ ^ ^ ^ ^ BOOT +8 +11 +15+18 +22+25 */ /* Starting data column and width */ #define DATA 1 #define DATA_WIDTH 39 /* Starting boot column */ #define BOOT 40 /* Place to put R BOOT instruction */ #define BOOTRB (BOOT+28) /* Number of wordmarks we can set */ #define NWM 6 #define NAM (NWM+2) struct {unsigned loc; unsigned char op; } wordmarks[NAM]; /* Address of hundreds position where cvbytes is done */ unsigned setmarks[NWM] = {BOOT+8,BOOT+11,BOOT+15,BOOT+18,BOOT+22,BOOT+25}; unsigned allmarks[NAM] = {BOOT+1, BOOT+4, BOOT+8,BOOT+11,BOOT+15,BOOT+18,BOOT+22,BOOT+25}; static char card[81]; /* card image (1-based) */ static char lastcard[81]; /* previous card (1-based) */ static char outcard[81]; /* ASCII card (0-based) */ static boolean has_lastcard = false; #ifdef OBSOLETE static char loader[] = ",008015,022029,036040N000000N0000001001"; #else static char loader[] = ",008015,022029,036040,047054,061068/039," "072001N000000N000000N0000001040BOOTSTRAP"; #endif void clearwm(void); /**************************************************************************** * loadcard * Effect: * Writes out the bootstrap loader card image(s) required ****************************************************************************/ void loadcard() { fprintf(punch,"%s\n",loader); punched++; } /**************************************************************************** * wcard * Result: void * * Effect: * If there is a card in 'lastcard', punches it out as a self-loading * card with a read-card-and-branch back to the bootstrap location * Takes the current card image and moves it to 'lastcard' ****************************************************************************/ void wcard() { if(has_lastcard) flushcard(i_R,BOOT); memcpy(lastcard,card,sizeof(card)); has_lastcard = true; } /**************************************************************************** * clearcard * Result: void * * Effect: * Clears the 'card' buffer to BCD spaces ****************************************************************************/ void clearcard() { int i; for(i=0;i<81;i++) card[i] = 0; /* BCD space */ } /**************************************************************************** * flushcard * Inputs: * unsigned char op: Operation for branch * unsigned branch: Place to branch to * Result: void * * Effect: * The buffer called 'lastcard' is written * Converts the BCD image in 'lastcard' to the output buffer 'outcard' * Right-blank-suppresses the result * Punches it and increments the punch count ****************************************************************************/ void flushcard(unsigned char op, unsigned branch) { int i; lastcard[BOOTRB] = op; cvbytes(&lastcard[BOOTRB+1],branch); for(i=0;i<80;i++) { /* write ascii */ outcard[i] = bcd_to_ascii(lastcard[i+1]); outcard[i+1] = '\0'; } /* write ascii */ /* Blank suppress */ for(i=79;i>0;i--) if(outcard[i] == ' ') outcard[i] = '\0'; else break; fprintf(punch,"%s\n",outcard); punched++; has_lastcard = false; } /**************************************************************************** * datacard * Inputs: * unsigned lb: Lower bound of memory image * unsigned ub: Upper bound of memory image * Result: unsigned * New lb location for next call * Effect: * Writes out boot records for data ****************************************************************************/ unsigned datacard(unsigned lb,unsigned ub) { unsigned i; int wmcnt; unsigned maxpos; int maxcard; if(debug) printf("datacard(%u,%u)\n",lb,ub); wmcnt = 0; /* Clear out the card and the wordmarks table */ clearwm(); clearcard(); for(i=0; lb + i < ub; i++) { /* skip over wm and uninit */ if(memory[lb+i] & C_bits) { /* real data */ lb = lb + i; break; } /* real data */ } /* skip over wm and uninit */ /* Normally, we get a free wordmark because we do an MLCWA instruction. Thus we can set 9 wordmarks (including the one set by the MLCWA). However, if no wordmark is to be set, we can set at most 6 more wordmarks, since we must consume two locations to clear the wordmark and of course we lose the one set by the MLCWA */ if(!WM(memory[lb]) ) { /* we must clear the wm */ wordmarks[wmcnt].loc = lb; wordmarks[wmcnt].op = i_CW; wordmarks[wmcnt+1] = wordmarks[wmcnt]; wmcnt += 2; } /* we must clear the wm */ for(i=0;i ub) break; if(WM(memory[lb+i]) && i > 0) { /* Can we set another word mark ? */ if(wmcnt >= NWM) break; /* No, quit loop */ /* Yes, record it */ wordmarks[wmcnt].loc = lb+i; wordmarks[wmcnt].op = i_SW; wmcnt++; } card[DATA+i] = BA8421M(memory[lb+i]); } /* move the next bunch of bytes into the record */ /* We now have the data in 'card' */ maxpos = lb+i; /* Maximum memory position valid in card, +1 */ maxcard = DATA+i; /* Maximum column position valid in card, +1 */ /* Print out the wordmark table */ if(debug) { /* display */ printf("wordmarks (%d) = ",wmcnt); for(i=0;i wmcnt, we have a non valid entry, so we skip it somehow. The way we skip an entry is either to duplicate the A address in the B address, or make the opcode a NOP, depending on whether we had an odd number or even number to set. Valid configurations are: ,AAABBB ; set wms in locations AAA and BBB ,AAAAAA ; set wm in location AAA N000000 ; no wordmark activity at all We get one wordmark for free, the one in the first location (column DATA), which we get via an MLCWA if we need it. We have to clear it if we don't want it. If we are setting an 'even' wordmark from our table, we first create a set-word-mark instruction (we store the opcode) We then assume the wordmark we are setting is the last, and set the A and B addresses identically. If we are setting an 'odd' wordmark from our table, we take advantage of the current instruction, and set its B-address. If we are at an even address and there are no more wordmarks to set, we put a NOP 0,0 instruction down. */ for(i=0;i ub) { /* transfer control */ card[DATA-4] = i_B; cvbytes(&card[DATA-3],start); } /* transfer control */ else { /* read next */ card[DATA-4] = i_R; cvbytes(&card[DATA-3],1); } /* read next */ /* And the initial load instruction */ card[BOOT] = i_MLCWA; cvbytes(&card[BOOT+4],maxpos-1); cvbytes(&card[BOOT+1],maxcard-1); /* At this point, the card image is complete, and the BCD image is found in 'card' */ wcard(); /* Skip over uninitialized storage */ while(maxpos <= ub && (memory[maxpos] & C_bits) == 0) maxpos++; if(debug) printf("<=datacard = %u\n",maxpos); return maxpos; } /**************************************************************************** * clearwm * Result: void * * Effect: * Clears the wordmarks table ****************************************************************************/ void clearwm(void) { int i; for(i=0;i= NAM) { /* dump current set */ dumpam(wmcnt); wmcnt = 0; } /* dump current set */ wmcnt++; wordmarks[wmcnt-1].op = i_SW; wordmarks[wmcnt-1].loc = lb; } /* uninit WM loc */ } /* scan */ dumpam(wmcnt); }