/* A mix of simple utility functions for dealing with paper tapes. param 1 is the mode -- i.e. selects which utility param 2 is an input file -- usually raw bytes from a paper tape reader param 3 is anothe file name -- wither an output file, or a file to be compared Mode k, show KDF9 as characters Mode r, reverse the order of the bytes -- used after reading a tape in reverse to detect misreads Other modes -- explanation (some) in the source text */ #include #include #include #include #define BUFF_SIZE 819200 #ifndef O_BINARY #define O_BINARY 0 #endif int verbose = 0; unsigned char buff[BUFF_SIZE], buff2[BUFF_SIZE]; /* KDF9 character code tables */ char ntab[] = " !\n!\t!!!!!!!!!!/0123456789_#;+-.!ABCDEFGHIJKLMNOPQRSTUVWXYZ!!~!!"; char stab[] = " !\n!\t!!!!!!!!!!:^[]<>=*%()_$;#*,!abcdefghijklmnopqrstuvwxyz!!~!!"; /* EDSAC 2 character code tables - sub10 is e and sub2 is # */ char ftab[] = "!f\r0r72s\n85/9(=ep43#6tn-1*)!.+ !"; char ltab[] = "!F\rORKUS\nLHAMZEDPGYWJTNBICX!VQ !"; void showchar(int c, char *buff) { int mask = 0x100; while ( (mask = mask >> 1) >= 0x8 ) if ( (c & mask) != 0 ) *(buff++) = 'o'; else *(buff++) = ' '; *(buff++) = '.'; while ( (mask = mask >> 1) > 0 ) if ( (c & mask) != 0 ) *(buff++) = 'o'; else *(buff++) = ' '; *(buff++) = ' '; if ( (c&0x7F) < ' ' ) c = ' '; *(buff++) = c & 0x7F; } main(argc, argv) int argc; char **argv; { char *mode; if ( argc < 3 ) printf("Usage: %s mode file1 file2", *argv ); else if ( *(mode = argv[1]) == 'r' ) /* reverse the order of the bytes */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int dvo = open(argv[3], O_WRONLY + O_TRUNC + O_CREAT + O_BINARY); int n, i, m, w; n = read(dvi, buff, BUFF_SIZE); if ( n > 0 && n < BUFF_SIZE ) // read all of file OK { m = n/2; for ( i = 0; i 0 && n < BUFF_SIZE ) // read all of file1 OK if ( m > 0 && m < BUFF_SIZE ) // read all of file2 OK { d1 = 0; d2 = 0; while ( buff[++d1] == 0 ) ; while ( buff2[++d2] == 0 ) ; printf("n = %d, d1 = %d :: m = %d, d2 = %d\n", n, d1, m, d2); while ( d1 < n && d2 < m && buff[d1++] == buff2[d2++] ) ; if ( d1 < n && d2 < m ) { d1 --; d2 --; printf("Mismatch d1 = %d, d2 = %d\n", d1, d2); printf("-------- %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", buff[d1-1]&255, buff[d1]&255, buff[d1+1]&255, buff[d1+2]&255, buff[d1+3]&255, buff[d1+4]&255, buff[d1+5]&255, buff[d1+6]&255, buff[d1+7]&255, buff[d1+8]&255); printf("-------- %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", buff2[d1-1]&255, buff2[d1]&255, buff2[d1+1]&255, buff2[d1+2]&255, buff2[d1+3]&255, buff2[d1+4]&255, buff2[d1+5]&255, buff2[d1+6]&255, buff2[d1+7]&255, buff2[d1+8]&255); } } printf("Ending code = %d/%d\n", n, m); } else if ( *mode == 'k' ) /* show KDF9 tapes as characters */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int dvo = open(argv[3], O_WRONLY + O_TRUNC + O_CREAT + O_BINARY); int n, i, m, w; char *tab; tab = ntab; // printf("%c %c %c %c %c\n", ntab[32], ntab[33], ntab[34], ntab[35], ntab[36]); // printf("%c %c %c %c %c\n", stab[32], stab[33], stab[34], stab[35], stab[36]); // printf("%c %c %c %c %c\n", tab[32], tab[33], tab[34], tab[35], tab[36]); n = read(dvi, buff, BUFF_SIZE); m = 0; if ( n > 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i %d\n", buff[i]&255, w); } write(dvo, buff, m); } } else if ( *mode == 'o' ) /* show KDF9 tapes as numbers */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int n, i, m, w; long ww; n = read(dvi, buff, BUFF_SIZE); m = 0; ww = 0; if ( n > 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i>16, (w>>8)&255, w&255); n += 4; w = (((buff[n]<<6) + buff[n+1]<<6) + buff[n+2]<<6) + buff[n+3]; printf(" %03o %03o %03o\n", w>>16, (w>>8)&255, w&255); } } } else if ( *mode == 'n' ) /* show numeric values of EDSAC 2 characters */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int n, i, m, w; n = read(dvi, buff, BUFF_SIZE); if ( n > 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i= '0' && w <= '9' ) { w -= '0'; // convert to binary value of digit if ( (ww = buff[i+1]) >= '0' && ww <= '9' ) { i ++; w = w*10 + ww - '0'; // convert 2-digit number } buff[m++] = w; } } write(dvo, buff, m); } } else if ( *mode == 'e' ) /* show EDSAC 2 tapes as characters */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int dvo = open(argv[3], O_WRONLY + O_TRUNC + O_CREAT + O_BINARY); int n, i, m, w; char *tab; tab = ftab; // printf("%c %c %c %c %c\n", ntab[32], ntab[33], ntab[34], ntab[35], ntab[36]); // printf("%c %c %c %c %c\n", stab[32], stab[33], stab[34], stab[35], stab[36]); // printf("%c %c %c %c %c\n", tab[32], tab[33], tab[34], tab[35], tab[36]); n = read(dvi, buff, BUFF_SIZE); m = 0; if ( n > 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i 0 && n < BUFF_SIZE ) // read all of file OK { for ( i = 0; i 0 && n < BUFF_SIZE ) // read all of file OK { i = 0; if ( buff[0] != 0x17 || buff[1] != 0x12 || buff[2] != 0x60 || buff[3] != 0x12 ) printf("This is probably not a binary paper tape program %02X %02X %02X %02X\n", buff[0], buff[1], buff[2], buff[3]); else { while ( (w = buff[i++])!=0x7D ) // process the A-block { w = (w&0x60)/2 + (w&0xF); buff[m++] = ntab[w]; } buff[m] = 0; // ensure string is terminated printf("A-block\n%s\n", buff); m = 0; while ( i>4; w = buff[i++]; w = (w&0x60)/2 + (w&0xF); buff[m++] = ww<<4 | w>>2; ww = buff[i++]; ww = (ww&0x60)/2 + (ww&0xF); buff[m++] = w<<6 | ww; } write(dvo, buff, m); if ( buff[44] != 0 || buff[45] != 8 ) printf("Beware, binary program starts at word %d\n", buff[44]<<8 | buff[45] ); } } printf("Ending code = %d/%d\n", n, m); } else if ( *mode == 'x' ) /* examine ignoring initial and final nulls */ { int dvi = open(argv[2], O_RDONLY + O_BINARY); int dv2 = open(argv[3], O_RDONLY + O_BINARY); int n, i, m, w, d1, d2; char chs[30] = " "; n = read(dvi, buff, BUFF_SIZE); m = read(dv2, buff2, BUFF_SIZE); if ( n > 0 && n < BUFF_SIZE ) // read all of file1 OK if ( m > 0 && m < BUFF_SIZE ) // read all of file2 OK { d1 = 0; d2 = 0; while ( buff[++d1] == 0 ) ; while ( buff2[++d2] == 0 ) ; printf("n = %d, d1 = %d :: m = %d, d2 = %d\n", n, d1, m, d2); while ( d1 < n && d2 < m && buff[d1++] == buff2[d2++] ) ; if ( d1 < n && d2 < m ) { d1 --; d2 --; printf("Mismatch d1 = %d, d2 = %d\n", d1, d2); chs[25] = 0; for ( i = -1; i<20; i++ ) { showchar(buff[d1+i], chs+2); showchar(buff[d2+i], chs+15); printf("%s\n", chs); } } } printf("Ending code = %d/%d\n", n, m); } else printf("Mode %s not recognised\n", mode); }