// EraseDisk.bcpl - Procedures for making a basic OS disk and // extending a file system. // Copyright Xerox Corporation 1979, 1980, 1982 // Last modified March 15, 1982 4:16 PM by Boggs get "AltoFileSys.d" get "Disks.d" get "BFS.d" get "Streams.d" get "SysDefs.d" get "SysInternals.d" get "AltoDefs.d" get "BcplFiles.d" external [ // outgoing procedures EraseDisk; ExtendDisk // incoming procedures BFSInit; BFSNewDisk; BFSExtendDisk; BFSTryDisk AssignDiskPage; ReleaseDiskPage; BFSClose CreateSysDisk; OpenFile PositionPage; WriteBlock Gets; Closes; Resets Ws; Wo; Wss; GetString; YesNo Idle // incoming statics sysZone; sysDisk sysFont; sysFontSize SysErr; keys; CursorLink ] //---------------------------------------------------------------------------- let EraseDisk() be //---------------------------------------------------------------------------- // First create a virgin Alto file system using BFSNewDisk, // then install the Alto OS files. [ Ws(" Type the name of a host from which I can get Alto programs: ") let hostName = vec 20; GetString(hostName) Ws(" Type the name of the directory where Alto programs are kept.") Ws("*N If the host is an IFS or Maxc, this should probably be 'Alto'") Ws("*N If the host is just another random Alto, type <return>: ") let directory = vec 20; GetString(directory) // Ask user about what size disk he'd like to have. let nDisks, dirLen = 1, 5000 if BFSTryDisk(1, 0) then [ Ws(" Use both of the disks? ") if YesNo() then [ nDisks = 2; dirLen = dirLen*2 ] ] let nTracks = 203 if BFSTryDisk(0, 203) then [ Ws(" Use all 406 cylinders of the disk? ") if YesNo() then [ nTracks = 406; dirLen = dirLen*2 ] ] let nSectors = BFSmNSectors if BFSTryDisk(0, 0, 13) then [ Ws(" Use all 14 sectors of the disk? ") if YesNo() then nSectors = 14 ] if nDisks eq 1 & nTracks eq 203 then [ Ws(" Do you want a big SysDir? ") if YesNo() then dirLen = dirLen*2 ] // Now give the user time to reconsider and/or change disks. Ws(" If you wish to change disks, please do so now.*N") Ws(" When the disk is ready, type OK to proceed, A to abort: ") [ let c = Gets(keys) if c eq $A % c eq $a then [ Ws("*n"); return ] unless c eq $O % c eq $o then loop Ws("O") c = Gets(keys) if c eq $K % c eq $k then break ] repeat Ws("K") // EraseDisk (cont'd) // Assertion: the only way out of here now is out the bottom. let savedSysErr = SysErr; SysErr = EraseSysErr let savedIdle = Idle; Idle = EraseIdle CursorLink = false // We should handle fail returns here... BFSNewDisk(sysZone, 0, nDisks, nTracks, dirLen, nSectors) sysDisk = BFSInit(sysZone, true, 0) // Make some files at advertised disk addresses // The -1 is for the leader page: the boot disk address is page 1 of a file. // Dumper.boot under the "DU" keys ReleaseDiskPage(sysDisk, AssignDiskPage(sysDisk, 4608-2)) Closes(OpenFile("Dumper.boot")) // DMT.boot under the "D" key ReleaseDiskPage(sysDisk, AssignDiskPage(sysDisk, 3072-2)) Closes(OpenFile("DMT.boot")) ReleaseDiskPage(sysDisk, AssignDiskPage(sysDisk, 0)) // Patch FTP back to remove crock about page count (see Install.bcpl) ftpOs>>SV.H.length = ftpOs>>SV.H.length-2 // Write the HiddenFTP.run inside the OS onto Executive.run. // When we finish, "Executive.run" (really HiddenFTP) will be // invoked with a command line to go get the real FTP and Exec. let s = OpenFile("Executive.Run") PositionPage(s, 135) //as of 5/5/79 it was 101 pages long Resets(s) WriteBlock(s, ftpOs, ftpOs!-1) Closes(s) // Write FTP.Run from the copy saved in memory. This is used to // get the Executive and the full function version of FTP. s = OpenFile("Ftp.Run") PositionPage(s, 200) //as of 5/5/79 it was 176 pages long Resets(s) WriteBlock(s, ftpOs, ftpOs!-1) //HiddenFTP Closes(s) // Restore FTP to buggered status (see Install.bcpl) ftpOs>>SV.H.length = ftpOs>>SV.H.length+2 // FTP command line to retrieve the Exec and FTP s = OpenFile("Com.cm", ksTypeWriteOnly, charItem) Wss(s, "Ftp.Run "); Wss(s, hostName) if directory>>STRING.length ne 0 then [ Wss(s, " Directory/c "); Wss(s, directory) ] Wss(s, " Retrieve/c Executive.Run Ftp.run") Closes(s) // Make the current font be SysFont.al on the new disk s = OpenFile("SysFont.Al") WriteBlock(s, sysFont-2, sysFontSize) Closes(s) // Create Swatee. This is used by Swat, the Mesa Debugger, // Bravo, Empress, and others who need a large temporary file. s = OpenFile("Swatee") PositionPage(s, 375b+3) Closes(s) // Flush DiskDescriptor BFSClose(sysDisk) SysErr = savedSysErr Idle = savedIdle CursorLink = true Ws("*N*N*N*N*N*N*N*N") ] //---------------------------------------------------------------------------- and ExtendDisk() be //---------------------------------------------------------------------------- [ CreateSysDisk() if sysDisk>>BFSDSK.nDisks eq 2 then [ BFSClose(sysDisk); return ] let nTracks = BFSTryDisk(0, 203)? BFS44NTracks, BFS31NTracks let nDisks = BFSTryDisk(1, 0)? 2, 1 if nDisks ne sysDisk>>BFSDSK.nDisks then [ Ws(" Use both of the disks? ") unless YesNo() do nDisks = 1 ] if nTracks ne sysDisk>>BFSDSK.nTracks then [ Ws(" Use all 406 cylinders of the disk? ") unless YesNo() do nTracks = BFS31NTracks ] // Give user chance to reconsider... Ws(" Are you sure? Type OK to proceed, A to abort: ") [ let c = Gets(keys) if c eq $A % c eq $a then [ Ws("*n"); BFSClose(sysDisk); return ] unless c eq $O % c eq $o then loop Ws("O") c = Gets(keys) if c eq $K % c eq $k then break ] repeat Ws("K...") let savedSysErr = SysErr; SysErr = EraseSysErr let savedIdle = Idle; Idle = EraseIdle CursorLink = false BFSExtendDisk(sysZone, sysDisk, nDisks, nTracks) BFSClose(sysDisk) SysErr = savedSysErr Idle = savedIdle CursorLink = true Ws("Done!*N") ] //---------------------------------------------------------------------------- and EraseSysErr(p, nil, nil, nil, nil, nil; numargs na) be //---------------------------------------------------------------------------- [ Ws("*NSysErr during EraseDisk or ExtendDisk") for i = 1 to na do [ Wo((lv p)!(i-1)); Ws(" ") ] // To debug, insert a disk with Dumper.boot on it, and DumperBoot p = Gets(keys) repeatuntil p eq $*n //"DU" won't proceed it ] //---------------------------------------------------------------------------- and EraseIdle() be //---------------------------------------------------------------------------- [ let MulDiv = table [ 055001B // sta 3 savedPC,2 155000B // mov 2 3 111000B // mov 0 2 102460B // mkzero 0 0 061020B // mul 031403B // lda 2 3 3 061021B // div 077400B // Swat 121000B // mov 1 0 171000B // mov 3 2 035001B // lda 3 savedPC,2 001401B // jmp 1,3 ] @cursorX = 200 + 200*diskAddress>>DA.disk @cursorY = diskAddress>>DA.track ls 0? 0, 20 + MulDiv(808-40-16, diskAddress>>DA.track, 406) ]