/* file VINIT.C ** ** By: Adam Bridge ** Multiware, Inc. ** Box 161 ** 139 G Street ** Davis, CA 95616 ** ** (916)756-3291 ** ** This file holds the initialization portions of the code. This ** should always be memory resident. Therefore it should be in the ** root module when used in an overlay environment. This is required ** because of the reference to vrtgbl.c which contains the global ** definitions of the static data structures. ** ** REV 1281.041 */ #include #include #include #include /* include the file of initializers */ /* VALLOC() is the routine called to allocate memory. It is a very simple ** routine which increases the size of the system break until no more more ** of the desired size can be found. It returns null when this occurs. This ** is a temporary routine until NALLOC() is adopted. ** sbreak() is an RT11 specific routine which is a part of the Whitesmiths ** RT11 library. It adjusts the top of the user area, algebraically up ** by the specified arguement. It returns the address of the start of the ** new area or NULL if there wasn't enough room in the system for the ** requested space. */ PAGE_PTR valloc() { IMPORT TEXT *sbreak(); FAST TEXT *p; p = sbreak(P_SIZE); return(p); } /* VINIT() creates the linked list of pages that are managed in ** main memory by the virtual routines. When VINIT() is called ** one page has already been associated with its respective root module. ** The function then requests valloc() to provide it with one page of ** space. It then inserts that page at the head of the linked list, ** between the root and the previously allocated page. This eliminates ** the requirement to traverse the linked list to find the end. ** Pages are allocated to each member of the ROOT array based upon existance ** of a non-NULL pointer to the first page of that arrays linked list. */ VOID vinit() { IMPORT PAGE_PTR valloc(); IMPORT struct rt ROOT[]; IMPORT LONG ticks(); IMPORT VOID snap_shot(); FAST PAGE_PTR p; FAST COUNT i; FOREVER { for ( i = 0; i < 5; i++ ) { if ( ROOT[i].frst_page == NULL ) continue; p = ROOT[i].frst_page; if ( (ROOT[i].frst_page = valloc()) == NULL) { ROOT[i].frst_page = p; goto ext; } ROOT[i].frst_page->nxt_page = p; p = ROOT[i].frst_page; p->acc_time = ticks(); p->blk_num = 0; ROOT[i].n_pages++; } } ext: ; } /* VDIM(name, number, dispos, f_size, d_size) associates a file structure ** with the virtual array facility. Name is a pointer to a string containing ** a valid RT11 filename. If the filename is wrong a fatal exit is taken. ** dispos has the values NEW, OLD, SCRATCH. In the case of NEW the file ** is created to have f_size elements of d_size bytes per element. ** OLD files are considered to already exist on the system. The file is ** opened for reading and writing. It is a fatal error to try to open ** an OLD file that doesn't exist. f_size is ignored for OLD files. ** SCRATCH files are created and opened and deleted upon program exit. ** f_size is a LONG integer giving the size of a virtual array in the ** number of data items. d_size is the number of bytes per data item. ** d_size is restricted to being an integer divider of BLK_SIZE which ** is 512 bytes per block. This restriction is enforced to prevent data ** from crossing block boundaries. number is the virtual array which vdim ** is associating name with. ** ** RETURNS: VDIM returns YES if a file was successfully connected to ** a virtual array. NO is returned if there was difficulty. ** Sometimes a fatal error exit from the program is taken if ** the difficulty is extreme. ** ** WARNING: Passing VDIM only a device name has the interesting and ** potentially useful side effect of performing a non-file ** structured lookup on the device in question. This can ** allow the user to casually destroy such valuable items as ** directories or copies of the operating system. It also ** gives the user an easy way to peek at the contents of a ** disk surface. Be warned. */ BOOL vdim(name, number, dispos, f_size, d_size) FAST COUNT number; TEXT *name; COUNT dispos, d_size; LONG f_size; { IMPORT PAGE_PTR valloc(); COUNT i; COUNT dblk[4]; ROOT[number].n_blks = (int)(( f_size * d_size )/ BLK_SIZE) + 1; ROOT[number].size = d_size; f_to_50(dblk, name); if ( dblk[0] == 0 ) dblk[0] = rad50("dk ",3); switch (dispos) { case NEW: while((i=u_enter(ROOT[number].chan,dblk,ROOT[number].n_blks,NULL))<0) { error = i & BYTMASK; if (error == 0) { ROOT[number].chan++; continue; } else trouble(CREATERR); } ROOT[number].dispos = KEEP; break; case OLD: while ( (i = lookup(ROOT[number].chan, dblk, NULL)) < 0 ) { error = i & BYTMASK; if (error == 0) { ROOT[number].chan++; continue; } else trouble(OPENERR); } ROOT[number].dispos = KEEP; break; case SCRATCH: while ( (i = u_enter ( ( ROOT[number].chan & BYTMASK ),\ dblk,ROOT[number].n_blks,NULL)) < 0 ) { error = i & BYTMASK; if (error == 0) { ROOT[number].chan++; continue; } else trouble(CREATERR); } ROOT[number].dispos = DESTROY; break; default: trouble(VDIM); break; } if ( (ROOT[number].frst_page = valloc()) == NULL) trouble(ROOM); else { ROOT[number].n_pages = 1; ROOT[number].frst_page->nxt_page = NULL; ROOT[number].frst_page->acc_time = ticks(); ROOT[number].frst_page->blk_num = 0; } return(YES); }