/* RT-11 Adapter Package for CP/M Rev. 1.0 -- July 1980 Rev. 1.1 -- March 1981 consisting of adding a valid system date word to all files placed on the RT-11 disk and putting the volume ID on a disk when the directory is initialized. This will keep RT-11 versions later than V02C from choking. copyright (c) 1980, William C. Colley, III Rev. 1.2 -- Craig Davenport - Incitec Ltd (Feb 1984) P O Box 140 Morningside, Qld 4170, Australia. -- Modified for Digital Research C compiler under CP/M-86 -- Assebmbly language routines added for BIOS calls etc. The main-line routine is here, as are the individual command processors. */ #include "B:RT11.H" #include "B:STDIO.H" #include "B:CTYPE.H" /* Main program.......... */ main() { char temp[20], t; int m, d, y; puts("\nRT-11 File I/O Package -- Rev. 1.2 -- Feb 1984\n"); puts("\nPut RT-11 disk into drive B, and CP/M disk into drive A.\n"); puts("THIS IS IMPORTANT. Hit CR when you're ready."); while(1) { gets(temp); if (temp[0] == '\0') break; puts("Are you sure?"); } puts("\nOK.\n"); BDOS(INIT_BDOS); /* Get system date word for later RT-11 versions. */ do { puts("Today's date (mm/dd/yy)? "); scanf("%2d/%2d/%2d",&m,&d,&y); } while (m == 0 || m > 12 || d == 0 || d > 31 || y < 72 || y > 99); sysdate = (m << 10) + (d << 5) + (y - 0110); while((t = getcom()) != 'Q') { switch (t) { case 'D': list_dir(); break; case 'E': erase_file(); break; case 'G': get_file(); break; case 'I': init_disk(); break; case 'P': put_file(); break; case 'R': rename_file(); break; case 'T': type_file(); break; default: puts("\nCommands available are:\n\n"); puts("(D)irectory list\n"); puts("(E)rase file on RT-11 disk\n"); puts("(G)et file from RT-11 disk\n"); puts("(I)initialize RT-11 disk\n"); puts("(P)ut file onto RT-11 disk\n"); puts("(R)ename file on RT-11 disk\n"); puts("(Q)uit program\n"); puts("(T)ype file on RT-11 disk\n"); putchar('\n'); break; } } puts("\nReinsert system disk and type any key."); getchar(); putchar('\n'); } /* Routine to erase a file on the RT-11 disk. */ erase_file() { int file_name[3]; if (!get_RT_name("File to erase? ",file_name)) return; if (!delete(file_name)) puts("Error -- file does not exist\n"); } /* Routine to rename a file on the RT-11 disk. */ rename_file() { int old_name[3], new_name[3]; if (!get_RT_name("Old name of file? ",old_name)) return; if (!get_RT_name("New name of file? ",new_name)) return; if (!rename(old_name,new_name)) puts("Error -- file does not exist\n"); } /* Routine to list the directory on the RT-11 disk. */ list_dir() { int t; char s[4], volume_id[512], temp[13]; temp[12] = '\0'; emt_375(BIOSREAD,1,1,volume_id); puts("\nVolume: "); putstr(temp,&volume_id[236*2]); puts(temp); puts(" Owner: "); putstr(temp,&volume_id[242*2]); puts(temp); usrcom(); puts("\n\nName .Ext Blks Date Start Extras\n\n"); do { while(*(dir_pointer + 1) != ENDSEG) { if (*(dir_pointer + 1) == PERM) { print_name(dir_pointer + 2); printf(" %3o ",_getword(dir_pointer,4)); if (t = _getword(dir_pointer,6) & 0x7fff) { getmon(t >> 10,s); printf("%2d-%s-%2d ",(t >> 5) & 037, s,(t & 037) + 0110); } else puts(" "); printf("%3o ",file_start); for (t = 0; t < directory.extra_bytes; t++) printf(" %3o",*(dir_pointer+t+14)); } else printf("< unused > %3o %3o", _getword(dir_pointer,4),file_start); incr1(); putchar('\n'); } } while (nxblk()); } /* Function to get a file from the RT-11 disk onto the CP/M disk. */ get_file() { char CP_file[20], xfer_buffer[512]; int t, RT_file[3], fd; if (!get_RT_name("RT-11 file name? ",RT_file)) return; puts("CP/M file name? "); gets(CP_file); if (CP_file[0] == '\0') sprint_name(RT_file,CP_file); if (!lookup(RT_file)) { puts("Error -- no source file\n"); return; } if ((fd = creat(CP_file)) == -1) { puts("Error -- could not create destination file\n"); return; } for (t = _getword(dir_pointer,4); t > 0; t--) { emt_375(BIOSREAD,file_start++,1,xfer_buffer); if (write(fd,xfer_buffer,512) != 512) { puts("Error -- CP/M disk full\n"); close(fd); return; } } close(fd); } /* Routine to type an RT-11 file on the console. */ type_file() { char c, xfer_buffer[512]; int file_name[3], i, j; if (!get_RT_name("File to type? ",file_name)) return; if (!lookup(file_name)) { puts("Error -- file does not exist\n"); return; } for (i = _getword(dir_pointer,4); i > 0; i--) { emt_375(BIOSREAD,file_start++,1,xfer_buffer); for (j = 0; j < 512; j++) { if ((c = xfer_buffer[j]) == '\0' || c == ('Z' - 64)) return; putchar(c); } } } /* Routine to put a file onto the RT-11 disk. */ put_file() { int RT_file[3], fd, size,numbyte; char CP_file[20], xfer_buffer[512]; puts("CP/M file name? "); gets(CP_file); if (CP_file[0] == '\0') return; if (!get_RT_name("RT-11 file name? ",RT_file)) return; if ((fd = open(CP_file,0)) == -1) { puts("Error -- could not open source file\n"); return; } size = filesize(CP_file); if ((file_start = enter(RT_file,size)) == 0) return; while (--size >= 0) { if ((numbyte=read(fd,xfer_buffer,512)) == -1) { puts("Error -- disk read on CP/M disk\n"); close(fd); return; } if (numbyte != 512) /* eof */ SETMEM(xfer_buffer+numbyte,512-numbyte,'Z'-64); emt_375(WRITE,file_start++,1,xfer_buffer); } close(fd); klose(RT_file); } /* Routine to initialize the directory on an RT-11 disk. */ init_disk() { char temp[50]; unsigned volume_id[256]; puts("Are you sure you want to do this (Y/N)? "); gets(temp); if (temp[0] != 'Y') { puts("\t.....Aborted\n"); return; } SETMEM(&directory,1024,0); puts("Number of directory segments (1 to 31)? "); while (1) { scanf("%d",&directory.total_segments); if (directory.total_segments > 0 && directory.total_segments < 32) break; puts("Say again? "); } puts("Extra bytes per directory entry? "); scanf("%d",&directory.extra_bytes); directory.highest_segment = 1; directory.first_block = (directory.highest_segment + 1) * 2 + 4; directory.entries[1] = EMPTY; _putword(directory.entries,4,488 - 2 * directory.total_segments); directory.entries[15 + directory.extra_bytes] = ENDSEG; segrw(WRITE,1); SETMEM(volume_id,512,' '); volume_id[0] = 0; volume_id[233] = 1; volume_id[234] = 6; volume_id[235] = 0107251; temp=""; puts("Volume ID (CR for default)? "); gets(temp); gets(temp); putstr(&volume_id[236], temp[0]==0 ? "RT11A" : temp); puts("Owner name (CR for default)? "); gets(temp); if (temp[0] != 0) putstr(&volume_id[242], temp); putstr(&volume_id[248], "DECRT11A"); emt_375(WRITE,1,1,volume_id); puts("\t.....Done\n"); } /* Internal function in initialize directory routine to put up to 12 characters from a string into the core image of the volume ID block (block 1 on the disk). Note that this routine is an addition at Ver 1.0. */ putstr(buffer,string) char *buffer, *string; { char i; for (i = 12; i > 0 && *string != '\0'; i--) { *buffer = toupper(*string); buffer+=1; string+=1; } }  .