// InterDisk.bcpl // Copyright Xerox Corporation 1979 //This is a little module that Lyle Ramshaw wrote to allow Oedit to // reference disk files on any Diablo or Trident drive, without // worrying about details like whether they had been Init'ed or not, // and whether or not they needed fancy microcode. //The primary exported procedures are SetUpInterDisk(zone), which // takes a zone for disk space as the argument, and sets up the // InterDisk static data structures. You should allow 1024*number // of Trident files + (~125)*number of Trident drives + 256*number // of Diablo files + (~100)*[DP1 open? 1, 0] + slop. //After executing SetUpInterDisk, you can use InterDiskOpenFile instead // of OpenFile, and it will parse the drive specifications on the // file names, init the drive if necessary, and then open the file. //InterDiskOpenFile only pays attention to its first three arguments. //The zone argument to SetUpInterDisk is used for all space requirements. // When you have either already opened a file on a Trident drive, or // you know that you will never use any Trident drive, you may call // the routine OverwriteLoadRam, and it will do a SetEndCode to // get back the space taken up by LoadRam and TriconMC. A system using this // feature should end its load command with "LoadRam TriconMC" in that // order. get "streams.d" get "altodefs.d" external [ //the exported procedures SetUpInterDisk InterDiskOpenFile OverwriteLoadRam ] external [ //from BFS package BFSInit BFSClose //from TFS package TFSInit TFSClose TFSSilentBoot LoadRam DiskRamImage TFSSwatContextProc //from the OS lvUserFinishProc lvSwatContextProc SetEndCode CallSwat OpenFile Allocate sysDisk Wl Ws ] static [ savedUFP; savedSCP ] static [ triDisks; diDisk1; diskZone ] structure UnPacked: [ Type bit 1 //0 for Diablo, 1 for Trident Num bit 15 ] manifest [ Diablo = 0; Trident = 1 ] structure [ Left byte Right byte ] structure Packed: [ blank bit 11 FileSys bit 2 //For T-300's, says which file system Num bit 3 ] structure Str: [ Len byte Char↑1,255 byte ] let SetUpInterDisk(zone) be [ //assign zone to static variable, to remember it diskZone = zone //set up disk objects to be 0, since no disks Init'ed triDisks = Allocate(zone, 32) for i=0 to 31 do triDisks!i=0 diDisk1=0 ] and OverwriteLoadRam() be SetEndCode(LoadRam) and InterDiskOpenFile(name, ksType, itemSize) = valof [ let nameWordLength = (name>>Str.Len/2) + 1 let nameCopy = Allocate(diskZone, nameWordLength) AssignStr(nameCopy, name) let drive=ParseDriveSpec(nameCopy) if drive eq -1 then resultis 0 if drive eq 0 then resultis //means use DP0 = sysDisk OpenFile(nameCopy,ksType,itemSize,0,0,0,diskZone,0,sysDisk) let type = drive<<UnPacked.Type let num = drive<<UnPacked.Num switchon type into [ case Diablo: if num ne 1 then resultis 0 if diDisk1 eq 0 then InitDP1() resultis OpenFile(nameCopy,ksType,itemSize,0,0,0,diskZone,0,diDisk1) case Trident: [ let triDrive, fileSys = num<<Right, num<<Left if (triDrive ls 0) % (triDrive gr 7) then resultis 0 if (fileSys ls 0) % (fileSys gr 2) then resultis 0 let packed = 0 packed<<Packed.FileSys = fileSys packed<<Packed.Num = triDrive if triDisks!packed eq 0 then InitTridentDrive(num, packed) resultis OpenFile(nameCopy,ksType,itemSize,0,0,0,diskZone,0,triDisks!packed) ] ] ] and InitDP1(num) be [ let res = BFSInit(diskZone, true, 1) if res eq 0 then Bitch("Couldn't operate DP1.") diDisk1 = res ] and InitTridentDrive(unpacked, packed) be [ test @lvUserFinishProc eq Finish ifso [ let res = TFSInit(diskZone, true, unpacked) if res eq 0 then [ let message = "Couldn't operate TPn." message>>Str.Char↑20 = (unpacked<<Right) + $0 Bitch(message) ] triDisks!packed = res ] ifnot //Time to load the RAM with the Trident microcode [ let load = LoadRam(DiskRamImage, true) let AltoVersion=(table [ #61014; #1401 ] )() let eng=AltoVersion<<VERS.eng if (eng le 3) & (load ls 0) then Bitch("Couldn't load the RAM.") //otherwise, assume that correct microcode is loaded on a //Dolphin or Dorado, and pluge on savedUFP = @lvUserFinishProc @lvUserFinishProc = Finish savedSCP = @lvSwatContextProc @lvSwatContextProc = TFSSwatContextProc InitTridentDrive(unpacked, packed) ] ] and Bitch(msg) be [ Wl(msg) let AltoVersion=(table [ #61014; #1401 ] )() test AltoVersion<<VERS.eng ge 4 ifso Ws("Correct microcode loaded? ") ifnot Ws("Therefore, farewell! ") abort ] //The following routine reads the "DP1:" portion of the file name and ParseDriveSpec(str) = valof [ let colonIndex = Contains(str, $:) test colonIndex ifnot [ //default drive is DP0=sysDisk resultis 0 ] ifso [ let res, num = nil, nil if colonIndex ls 3 then resultis -1 if (str>>Str.Char↑2 ne $P)&(str>>Str.Char↑2 ne $p) then resultis -1 num = 0 for i=3 to colonIndex-1 do num = (num lshift 3) + str>>Str.Char↑i - $0 res<<UnPacked.Num = num switchon str>>Str.Char↑1 into [ case $D: case $d: res<<UnPacked.Type = Diablo RemoveDriveSpec(str, colonIndex) resultis res case $T: case $t: res<<UnPacked.Type = Trident RemoveDriveSpec(str, colonIndex) resultis res default: resultis -1 ] ] ] and RemoveDriveSpec(str, index) be [ str>>Str.Len = str>>Str.Len - index for i=1 to str>>Str.Len do str>>Str.Char↑i = str>>Str.Char↑(i+index) ] and Contains(str, char) = valof [ for i=1 to str>>Str.Len do if str>>Str.Char↑i eq char then resultis i resultis 0 ] and AssignStr(str1, str2) be [ str1>>Str.Len = str2>>Str.Len for i=1 to str1>>Str.Len do str1>>Str.Char↑i = str2>>Str.Char↑i ] and Finish() be [ for i=0 to 31 do if triDisks!i then TFSClose(triDisks!i) if diDisk1 then BFSClose(diDisk1) @lvUserFinishProc = savedUFP @lvSwatContextProc = savedSCP TFSSilentBoot() ]