// £123 | \ # various characters to persuade gedit to accept the file // takes a "mag tape" output file and extracts a loadable binary program // This program reads the mag tape (emulated in a file) generated by the Intercode Translator // and generates a loadable core image suitable to be loaded into leo3.c. // This image file is a plain text file, as detailed at the head of leo3.c. // Unless operating in quiet mode, there is a comment appended to each line // in which the absolute address is shown inside square brackets. // A comment such as "p = 4" means that the address part was augmented by the value of parameter 4. // There are switches: // -v verbose operation // -q quiet -- no comments in binary program // -b2340 specify base address of next chapter at 2340 -- can be used many times // - starts with chap 1 and includes the extra chapter // -M2 set modification group 2 -- only 0, 1, 2, 3 allowed, but 0 may be special // -x9 overlay chapter 9 on top of the penultimate initial chapter // -y12418 set the next chapter (e.g.10) to start at 12418 -- used with 08004 // Also 2 switches which may help in the running of programmes which are still in the process of copytyping // -o overlays go on top of this chapter // -i manual set of number of initial chapters -- used with incomplete progs // First param (after the switches) is the magtape file produced by Intercode Translator // For simple programs this can be MT-A2.leo, but for overlaid programs, // it seems to be better to used option 3 to opy the binary program to MT-A6.leo and use that. // Last parameter is the name of the binary program to generate // Author: David Holdsworth -- David.Holdsworth@bcs.org // Currently all rights are reserved, but this will be made available under the GNU public license. #include #include #include #include #ifndef O_BINARY #define O_BINARY 0 #endif char buff[999]; int store[8192]; char chval[256]; char alpha[256]; int tagnum = 7; // arbitrary values int modgrp = 1; // default modification group int chbase[15]; // start of each chapter int verbosity = 0; int maxpar, *param; int dvtype[65]; // device type configured for each route - end value to stop int reloc(int i, int v) // get relocation value -- lots of guesswork, but getting less { if ( i <= maxpar ) return param[i]; // big numbers are system calls, which currently are arranged to work with leo3.c // When we have a true master routine (MR) we can do the right thing if ( i == 256 ) // group4 -- I/O action { if ( v != 0x174000 ) // unexpected - i.e. not enter MR routine in emulator printf("Unexpected action for group 4: %05X %d/%d/%d %d\n", v, v>>16, (v>>15)&1, (v>>13)&3, v&017777); return 4; } if ( i == 1024 ) // overlay { if ( v != 0x174000 ) // unexpected - i.e. not enter MR routine in emulator printf("Unexpected action for overlay: %05X %d/%d/%d %d\n", v, v>>16, (v>>15)&1, (v>>13)&3, v&017777); return 5; } if ( i == 512 ) // ALARM { if ( v != 0x1A4000 ) // unexpected - i.e. not enter priority control printf("Unexpected action for alarm: %05X %d/%d/%d %d\n", v, v>>16, (v>>15)&1, (v>>13)&3, v&017777); return 1; } if ( i == 768 ) // unload { if ( v != 0x1A4000 ) // unexpected - i.e. not enter priority control printf("Unexpected action for unload: %05X %d/%d/%d %d\n", v, v>>16, (v>>15)&1, (v>>13)&3, v&017777); return 2; } if ( i == 1280 ) // enter MR for log output { if ( v != 0x174000 ) // unexpected - i.e. not enter MR routine in emulator printf("Unexpected action for overlay: %05X %d/%d/%d %d\n", v, v>>16, (v>>15)&1, (v>>13)&3, v&017777); return 154; } if ( verbosity != 0 ) fprintf(stdout, "Unknown parameter %d (%X)\n", i, i); return 0; // unknown } int readmt(int dv) // read block of data into store { int n = read(dv, store, sizeof(int)); static int bc = 0; int i; if ( n > 0 ) { n = store[0] & 0x7FF; // 11-bit count // printf("\nBlock %d, size = %d (prev = %d)", ++bc, n, store[0]>>11); i = read(dv, store, n * sizeof(int)); // for ( i = 0; i>8)&0xF00) | ((lsw>>4)&0xF0) | (lsw&0xF) | ((msw<<8)&0xF000) | ((msw<<4)&0xF0000); if ( (msw&0x30000) == 0x10000 ) // negative value { lsd ^= 0x100000; // printf("-ve value at word %d %06X %05X\n", p, msw, lsw); // exit(1); } return lsd; } int chap0[140]; // contents of chapter 0 void chap0alloc() // take data from the alloc block into chapter 0 { int w, i, nC, nR, nS; chap0[0] = fetchAlpha(5); // C = Floating point indicator (= 0 unless floating point is required). w = fetchAlpha(7); // C + 1 = Modification group indicator if ( w == 0 ) chap0[1] = 0; // ... (= 0 if mod. group is not ... else chap0[1] = modgrp; // ... required, otherwise allotted mod. group). chap0[2] = fetchAlpha(9); // C + 2 = Priority class (as specified on programme heading sheet). chap0[3] = fetchAlpha(11); // C + 3 = Total number of chapters chap0[4] = nC = fetchAlpha(13); // C + 4 = Number of chapters loaded initially (including the special chapter). chap0[5] = nR = fetchAlpha(15); // C + 5 = Number of files. i.e. routes chap0[6] = nS = fetchAlpha(17); // C + 6 = Number of transit areas (i.e. sections used in I/O). chap0[7] = 0; // C + 7 = Number of alternate routes. chap0[9] = w = fetchAlpha(23); // C + 9 = Chapter in which first instruction is located. chap0[8] = chbase[w] + fetchAlpha(21); // C + 8 = Entry point in absolute form. chap0[10] = tagnum; // C + 10 = Allocated tag number. chap0[11] = 0; // C + 11 = Trials indicator (= 15 for trial under P.T.S.). chap0[12] = fetchAlpha(39); // C + 12 = Programme identity number (decimal). chap0[13] = fetchAlpha(41); // C + 13 = Programme serial number (decimal). chap0[15] = 1; // C + 15 = Run and rerun number. chap0[16] = nC + nC; // C + 16' = 'Store modification register constant' (2 * number of // chapters initially /0). chap0[18] = (nR + nS) * 2; // C + 18' = 'Routes modification register constant' (2 * number of // routes + number of sections) /0). -- or should it be total no of sections? for ( i = 1; i<=nC; i++ ) // C + 20' = Allocated storage table. Entries are only held for initial { chap0[i+i+18] = chbase[i]; // to chapters (including the special chapter). Each entry chap0[i+i+19] = chbase[i]+2 // C + 32' occupies one long word of storage as below: + fetchAlpha(i+i+23); // Q10 Q6 Q5 Q1 } // |End of chapter + 2 | Start of chapter | } int chap0file(int i, int loc, int nC, int annex) // set up chapter zero info for file number i (counting from 0) // whose data is located starting at loc in store[] // and whose annex { int ww; // working location int fn; // file name int ft = fetchAlpha(loc+3); // file type // int route = i*9 + 9; // route number for this file - temp !!! int route = 0; // printf("!!! in there now\n"); if ( ft == 15 ) // dual input paper tape ft = 5; // we always use paper tape else if ( ft == 14 ) // special printer ft = 9; // we always Anelex else if ( ft == 19 ) // special printer ft = 9; // we always Anelex dvtype[64] = ft; // guarantees that we stop while ( dvtype[++route] != ft || store[64 + route] != 0 ) ; if ( route >= 64 ) { printf("No route found for type %d file %4X\n", ft, store[loc]); exit(1); } printf("Device type %d on route %d\n", ft, route); store[64 + route] = annex; // ASL param[nC+nC+i+1] = route; fn = store[loc]|0x4040; // C + 34' = Allocated routes and sections table. Each entry occupies if ( (fn&15) == 0 ) // to one long word of storage as below: fn -= 0x40; // 0 char // C + 64' Q10 Q9 Q6 Q5 Q3 and Q4 Q1 and Q2 chap0[35+i+i] = fn; // | |File identity | Route|128 or |Alloc. | // | | | Type |alloc. alt.|route no.| chap0[34+i+i] = // | | | |route no. | | (ft << 16) // The route numbers are held in channel and route form. All + 0x8000 + route; // entries except the alternate route (which is 128) and route // number are zero in the case of transit areas. ww = fetchAlpha(loc+5); // annex start -- N.B. printed manual has start and chapter no interchanged ww += chbase[fetchAlpha(loc+7)]; // seems there can be sign bit set for something not documented chap0[67+i+i] = // C + 66' = Annexe and section. An entry is held for each annexe or fetchAlpha(loc+9) + ww; // to section and an entry occupies one long word divided as chap0[66+i+i] = ww; // C + 96' below: return route; // Q10 Q6 Q5 Q1 } // |End of annexe | Start of annexe | int chap0tran(int i, int loc, int nC, int nR, int addr) // set up chapter zero info for transit area number i (counting from nR) // whose data is located starting at loc in store[] // See comments in chap0file for store details { int ww = fetchAlpha(loc+1); // start int offset = (i+nR)*2; // int route = 8 + i*9; // our transit area pseudo-route convention -- temp !!! int route = 0; // route 0 reserved for master // while ( store[64 + ++route] != 0 ) ; // check if this route is in use dvtype[64] = -1; // guarantees that we stop while ( dvtype[++route] >= 0 || store[64 + route] != 0 ) ; if ( route >= 64 ) { printf("No route found for transit area number %d\n", i); exit(1); } store[64 + route] = addr; // address of TA -- N.B. up above mag tape buffer area ww += chbase[fetchAlpha(loc+3)]; chap0[34+offset] = 0x8000 + route; chap0[67+offset] = fetchAlpha(loc+5) + ww; chap0[66+offset] = ww; offset = nC+nC+nR+i+i+1; // location in param space param[offset++] = route; param[offset] = route + 0x100040; return route; } void readconfig(int *map, int marker) // read peripheral configuration from routes.txt // types are stored in map with the value of marker added to each // values for unspecified routes are set to -1 { int i, j, t, r; FILE *fin = fopen("routes.txt", "r"); for ( i = 0; i<64; i++ ) map[i] = -1; if ( fin == NULL ) // look in parent directory fin = fopen("../routes.txt", "r"); if ( fin == NULL ) printf("No routes file found\n"); else { while ( fgets(buff, 50, fin) != NULL && memcmp(buff, "=======", 5) != 0 ) { i = atoi(buff); j = atoi(buff+2); t = atoi(buff+3); r = i*8 + j; map[r] = t + marker; if ( verbosity > 0 ) fprintf(stdout, "Device type %d configured on route %d/%d = %d\n", t, i, j, r); } } } main(int argc, char **argv) // this version reads a mag tape. { int fin; FILE *fout = stdout; int v, j, n; int curchap = -1; // this value should never be seen int i = 0; int mode = -1; // 0 = instructions, 1 = constants int addr = 0; int bc = 0; int fblk = -1; // expected location of file descriptor block int p; // parameter value int dbc = 0; // data block count within chapter int entAddr, entChap; int progID; int nR = 2; // number of routes int nS = 2; // number of transit areas int nC = 2; // number of chapters -- seems we need to allow for the extra chapter int totC = 2; // total number of chapters int hwm[15]; // top of each chapter -- used for managing overlays int nCman = -1; // for manually setting intial chap number -- used with incomplete progs int ovchap = -1; // for manually setting first overlaid chapter number -- incomplete progs ?? int xover = -1; // number of exception chapter which is to overlay the penultimate initial chapter int yover = -1; // base of next chapter, used in conjunction with -x - special for 08004 char *insfmt = "%d/%d/%d %d [%d] %06X p=%d\n"; // format for printing instructions for ( j = 0; j<15; j++ ) // fill up with default values chbase[j] = j*8192; // this only works for 1 proper chapter with 0 in div 0 and chap1 in div 1 n = 0; // chapter number pointer while ( ++i < argc && *(argv[i]) == '-' ) if ( (j = argv[i][1]) == 'v' ) if ( argv[i][2] == 0 ) verbosity ++; else verbosity = atoi(argv[i]+2); else if ( j == 'b' ) // base address of chapter -- can be used many times chbase[++n] = atoi(argv[i]+2); else if ( j == 'o' ) // overlays go on top of this chapter ovchap = atoi(argv[i]+2); else if ( j == 'q' ) // quiet -- no comments in binary program insfmt = "%d/%d/%d %d\n"; else if ( j == 'i' ) // manual set of initial chapter number -- used with incomplete progs nCman = atoi(argv[i]+2); else if ( j == 'x' ) // number of exception chapter which is to overlay the penultimate initial chapter xover = atoi(argv[i]+2); // used in 08004 which had two different areas of overlay else if ( j == 'y' ) // used with -x, base of chapter after -x chapter (big fudge for 08004) yover = atoi(argv[i]+2); // used in 08004 which had fancy last overlay else if ( j == 'M' ) // number of modification group, i.e. 0 to 3 modgrp = atoi(argv[i]+2); if ( argc < i+1 ) { fprintf(stderr, "Usage %s {-b} leo_MT output_file\n", *argv); exit(1); } readconfig(dvtype, 0); fin = open(argv[i], O_RDONLY + O_BINARY); if ( fin < 0 ) { perror(argv[i]); exit(1); } printf("File: %s\n", argv[i]); if ( argc < i + 2 ) fout = stdout; else fout = fopen(argv[i+1], "w"); if ( fout == NULL ) { perror(argv[i+1]); exit(1); } // give us some printable chars memset(alpha, '?', 256); // Alpha chars for printing file names for ( i = 1; i<10; i++ ) { alpha[i] = alpha[i+64] = i + '0'; alpha[i+16] = alpha[i+80] = i + 'A' - 1; alpha[i+32] = alpha[i+96] = i + 'I'; alpha[i+48] = alpha[i+112] = i + 'Q'; } alpha[48] = '0'; alpha[i+113] = '/'; memset(chap0, 0, 140 * sizeof(int)); // clear down chapter 0 n = readmt(fin); // first record while ( n > 0 ) { bc ++; // = fetchAlpha(1); if ( ((store[43] - 0x51636)&0x3F3F3) == 0 && ((store[42] - 0x36653)&0xF3F3F) == 0 ) { printf("%5d ALLOC block found\n", bc); fblk = bc + 114 - 75; printf(" Total chaps = %d (init %d) files(R) = %d Transit Areas = %d\n", totC = fetchAlpha(11), nC = fetchAlpha(13), nR = fetchAlpha(15), nS = fetchAlpha(17), fetchAlpha(19), fetchAlpha(21), fetchAlpha(23)); printf(" Enter at address %d in chapter %d\n", entAddr = fetchAlpha(21), entChap = fetchAlpha(23)); if ( nCman >= 0 ) // for early execution of an incomplete program nC = nCman; if ( totC != nC ) // there are overlaid chapters { n = nC; if ( ovchap >= 0 ) v = chbase[ovchap]; // first overlaid chapter else v = chbase[n-1]; // first overlaid chapter if ( verbosity != 0 ) printf(" Overlays based at %d\n", v); // assumes all overlays at the same base while ( ++n <= totC ) chbase[n] = v; // all overlay at the same address ..... if ( xover >= 0 ) // except this one which is over the previous initial chapter { chbase[xover] = chbase[nC-2]; if ( yover >= 0 ) chbase[xover+1] = yover; } } chap0alloc(); // take info from ALLOC block into chapter 0 if ( nCman >= 0 ) // for early execution of an incomplete program { nC = nCman; chap0[4] = nC; } maxpar = nS + nS + nR + nC + nC + 4; // create parameter array now that we know the size param = (int *)malloc((maxpar+1)*sizeof(int)); } else if ( ((store[7] - 0x59655)&0x3F3F3) == 0 && ((store[6] - 0x45577)&0xF3F3F) == 0 ) { if ( verbosity != 0 ) printf("%5d Found INDEX block %d - block size %d\n", bc, store[10]&0x3F, n); n = readmt(fin); bc ++; j = fetchAlpha(5); if ( verbosity != 0 ) printf("Prog %05X -- also %05X - block size %d\n", j, fetchAlpha(13), n); n = readmt(fin); bc ++; v = fetchAlpha(13); // printf("Prog %05X -- pass %05X - block size %d\n", fetchAlpha(9), v, n); if ( v == 0x71223 ) // must be PASS3 marker { progID = j; fprintf(fout, " PASS3 marker for program %05X\n", j); printf("%5d PASS3 marker for program %05X found\n", bc, j); } else if ( verbosity != 0 ) // must not be PASS3 marker printf("This is not the PASS3 marker %06X\n", v); } else if ( bc == fblk ) { int route; printf("%5d File details block (%d routes)\n", bc, nR); j = nR; memset(store+64, 0, 256*sizeof(int)); // put the data in its correct location - blocks are up to 54 if ( j >= 5 ) j = 4; for ( i = 0; i>1; // but it seems to be parameter number + 1 v = fetchAlpha(i*12+9); printf(" File %c%c type %d -- chap %d annex at %d length %d\n", alpha[(store[i*12+4]>>8)&127], alpha[store[i*12+4]&127], fetchAlpha(i*12+7), n, v, fetchAlpha(i*12+13) ); if ( i == 0 // do not know why this gets allocated to overlaid chap && n > nC ) // is this a bug or a feature that we do not know { printf(" Annex %d is in chapter %d - reallocated to %d\n", i, n, nC); n = nC; // this is a kludge of the very dirtiest kind !! } // printf("!!! enter chap0file\n"); route = chap0file(i, i*12+4, nC, chbase[n] + v); // annex assumed to live in owning chapter } if ( j != nR ) { n = readmt(fin); bc ++; for ( i = 4; i>1; // but it seems to be parameter number + 1 v = fetchAlpha(i*12-39); printf(" File %c%c type %d -- chap %d annex at %d length %d\n", alpha[(store[i*12-44]>>8)&127], alpha[store[i*12-44]&127], fetchAlpha(i*12-41), n, v, fetchAlpha(i*12-35) ); route = chap0file(i, i*12-44, nC, chbase[n] + v); // annex assumed to live in owning chapter } } n = readmt(fin); bc ++; // transit area details for ( i = 0; i>1; // no idea why chapter numbers appear to be doubled // printf("Chapter no of transit area %d halved to %d\n", i, n); if ( i == 0 // do not know why this gets allocated to overlaid chap && n > nC ) // is this a bug or a feature that we do not know -- see above about parameter + 1 { printf("Transit area %d is in chapter %d - reallocated to %d\n", i, n, nC); n = nC; // this is a kludge of the very dirtiest kind !! but may no longer happen } v = fetchAlpha(i*6+5) + chbase[n]; route = chap0tran(i, i*6+4, nC, nR, v); if ( verbosity != 0 ) printf(" TA start %d chap %d length %d on pseudo-route %d\n", v, n, fetchAlpha(i*6+9), route); } n = -3; // mark end of header info and inhibit next read } if ( ((store[13] - 0x53585)&0x3F3F3) == 0 && ((store[12] - 0x16773)&0xF3F3F) == 0 ) { printf("%5d CHAPTer %d start block (progid = %05X)\n", bc, fetchAlpha(5), fetchAlpha(9)); // should not see this } if ( n > 0 ) // more stuff to read n = readmt(fin); // so read it } if ( verbosity != 0 ) printf("%4d chapters\n%4d routes\n%4d transit areas", nC, nR, nS); // now to sort out the parameters -- see Appendix B of Vol III Translator // maxpar = nS + nS + nR + nC + nC + 4; // param = (int *)malloc((maxpar+1)*sizeof(int)); created as soon as alloc block found param[0] = 0; for ( i = 1; i<=nC; i++ ) { param[i+i-1] = chbase[i]; param[i+i] = chbase[i]&8191; } // for ( i = 1; i<=nR; i++ ) parameters for routes and sections are now done in // param[nC+nC+i] = i*9; chap0file and chap0tran // for ( i = 1; i<=nS; i++ ) // { param[nC+nC+nR+i+i-1] = i*9 - 1; // param[nC+nC+nR+i+i] = i*9 + 0x10003F; // } i = modgrp * 8; param[2*nC+nR+2*nS+1] = i; // 8 times mod group 1 param[2*nC+nR+2*nS+2] = i + 0x100002; param[2*nC+nR+2*nS+3] = i + 0x100004; param[2*nC+nR+2*nS+4] = i + 0x100006; buff[0] = ' '; buff[1] = '-'; for ( i = 0; i<10; i++ ) { if ( i <= maxpar ) fprintf(fout, "\n Param %d = %5d%c", i, param[i]&0xFFFFF, buff[param[i]>>20]); if ( i+10 <= maxpar ) fprintf(fout, " || Param %d = %5d%c", i+10, param[i+10]&0xFFFFF, buff[param[i+10]>>20]); if ( i+20 <= maxpar ) fprintf(fout, " || Param %d = %2d%c", i+20, param[i+20]&0xFFFFF, buff[param[i+20]>>20]); } chap0[14] = maxpar + 1; // C + 14 = Number of last parameter + 1. for ( i = 0; i<=maxpar; i++ ) // C + 98' = Parameter table. This table specifies the parameters to chap0[98+i] = param[i]; // to be added as the Master Programme loads the programme. // C + 138' fprintf(fout, "\n"); fprintf(fout, "\nLoading hardware route pointers for program ID %05X\n", progID); // load up the route and pseudo-route pointers store[63] = 0; // probably 0 already -- helps next loop for ( j = 64; j<128; j++ ) if ( store[j] != 0 ) { if ( store[j-1] == 0 ) // will need to set address for loading fprintf(fout, "L%d route %d/%d\n", j, (j&070)>>3, j&7); v = store[j]; fprintf(fout, "%d/%d/%d %d [%d] %06X\n", v>>16, (v>>15)&1, (v>>13)&3, v&017777, j, v); } j = -99; // last loaded location + 1 -- will not match initially while ( (n = readmt(fin)) > 0 ) { bc ++; // = fetchAlpha(1); if ( ((store[43] - 0x51636)&0x3F3F3) == 0 && ((store[42] - 0x36653)&0xF3F3F) == 0 ) { printf("%5d ALLOC block found in error\n", bc); printf(" FP = %d MR = %d priority = %d chaps = %d (init %d) files(R) = %d TAs = %d\n", fetchAlpha(5), fetchAlpha(7), fetchAlpha(9), fetchAlpha(11), nC = fetchAlpha(13), nR = fetchAlpha(15), nS = fetchAlpha(17), fetchAlpha(19), fetchAlpha(21), fetchAlpha(23)); } else if ( ((store[7] - 0x59655)&0x3F3F3) == 0 && ((store[6] - 0x45577)&0xF3F3F) == 0 ) { if ( verbosity != 0 ) printf("%5d Found INDEX block %d - block size %d\n", bc, store[10]&0x3F, n); n = readmt(fin); bc ++; if ( verbosity != 0 ) printf("Prog %05X -- also %05X - block size %d\n", fetchAlpha(5), fetchAlpha(13), n); n = readmt(fin); bc ++; if ( verbosity != 0 ) { printf("Prog %05X -- pass %05X - block size %d\n", fetchAlpha(9), v = fetchAlpha(13), n); if ( v == 0x71223 ) // must be PASS3 marker printf("This is the PASS3 marker\n"); else // must not be PASS3 marker printf("This is not the PASS3 marker %06X\n", v); } } else if ( ((store[13] - 0x13181)&0x3F3F3) == 0 && ((store[12] - 0x12733)&0xF3F3F) == 0 ) { if ( n != 54 ) { printf("Non-standard CHAPT block %d size %d\n", bc, n); exit(1); } n = fetchAlpha(5); // chapter number v = fetchAlpha(9); // prog ID fprintf(fout, "L%d loading chapter %d for program ID %05X\n", chbase[n], n, v); j = addr = chbase[n]; // base address of current chapter curchap = n; // used in next section dbc = 0; printf("%5d CHAPTer %d start at %d (progid = %05X)\n", bc, n, j, v); if ( j == yover ) // trickery needed here as this chapter is loaded by 08004 after chap 0 fiddle { param[3] = yover; param[4] = yover&8191; // ensure that addresses are fixed up properly printf(" parameters 3 and 4 reset to %d and %d\n", yover, param[4]); } } else if ( j >= 0 ) // data block { if ( dbc++ == 0 ) // first data block in chapter { v = fetchAlpha(7); // word 0 of the chapter if ( v != 0 ) { fprintf(fout, "X%d chapter 0 located at %d\n", j = chbase[curchap], v); for ( i = 0; i<140; i++ ) { v = chap0[i]; fprintf(fout, "%d/%d/%d %d [%d] %06X C + %d\n", v>>16, (v>>15)&1, (v>>13)&3, v&017777, j++, v, i); } v = fetchAlpha(7); // word 0 of the chapter fprintf(fout, "L%d extra chapter %d located at %d\n", j = chbase[curchap] + v - 1, curchap, v); printf("%5d Extra chapter %d located at %d (param = %d)\n", bc, curchap, j, fetchAlpha(5)); } else if ( curchap > nC ) // start of overlaid chapter { v = curchap - 1; // previous chapter being overlaid if ( curchap == nC + 1 ) // but it must have been chapter 0 v --; printf("%5d Overlaying chapter %d by %d\n", bc, v, curchap); fprintf(fout, "O%02d %5d %5d Overlaying chapter %d by %d\n", curchap - nC - 1, chbase[v], hwm[v], v, curchap); } } i = 0; while ( (i += 4) < 52 && (p = fetchAlpha(i+1)) != 0xF0000 ) { v = fetchAlpha(i+3); v += reloc(p, v); fprintf(fout, insfmt, v>>16, (v>>15)&1, (v>>13)&3, v&017777, j, v, p); j ++; } if ( p == 0xF0000 ) { hwm[curchap] = j; j = -100; } } } if ( totC > nC ) // Overlaid program -- need to do the last chapter { v = curchap; // previous chapter being overlaid if ( curchap == nC + 1 ) // but it must have been chapter 0 v --; printf("Overlaying last chapter %d\n", v); fprintf(fout, "O%02d %5d %5d Overlaying final chapter %d\n", curchap - nC, chbase[v], hwm[v], v); } fprintf(fout, "E%d entering at address %d in chapter %d\n", chap0[8], entAddr, entChap); // entAddr + reloc(entChap*2 - 1, 0), entAddr, entChap); close(fin); }