// 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)
]