// FtpInit.bcpl -- Initialization for the Run file version
// Copyright Xerox Corporation 1979, 1980, 1981, 1982
// Last modified October 10, 1982  10:43 PM by Boggs

get "Pup0.decl"
get "Pup1.decl"
get "Streams.d"
get "AltoDefs.d"
get "AltoFileSys.d"

external
[
// outgoing procedure
InitFtp

// incoming procedures
InitFtpPList; InitFtpUtil; InitPupLevel1; SetAllocation
InitSysFont; InitComCm; InitDisplay; InitLog
MakeBar; MakeTitle; FTPShowDisplayStream
MyFrame; Enqueue; Unqueue; CallSwat; SysErr; Closes
InitializeZone; Allocate; Free; FunnyAllocate
TFSInit; TFSSwatContextProc
PupChecksum; UPupChecksum; InitBcplRuntime; LoadRam
InitializeContext; CallContextList
Overlay

// outgoing statics
stackSize; savedAllocate
ftpDisk; ctxQ; initCode
savedSwatContextProc

ramFlag; errorFlag; debugFlag; tfsFlag; logFlag
userFlag; serverFlag; telnetFlag; cliFlag

// incoming statics
sysFont; fontHeight; lastShownStream; currentYPos
serverDsp; userDsp; telnetDsp; userDspLen; telnetCode
sysZone; lvSysZone; sysDisk
FtpRamImage; dPSIB; overlayStream
lvSwatContextProc; tfsUnit
]

static
[
stackSize; initDone = false
ftpDisk; ctxQ; initCode
savedSwatContextProc; savedAllocate

ramFlag = true; errorFlag = true; debugFlag = false
logFlag = false; cliFlag = false; tfsFlag = false
userFlag = true; serverFlag = true; telnetFlag = true
]

manifest
[
// order of overlay segments after resident code
// must match order in load command file
ram = 1
server = 2
user = 3
keyboard = 4
commandLine = 5
telnet = 6
tfs = 7
tfsInit = 8
init = 9

stackLimit = 335b
numPBIs = 12

servDspSLC = 100  //server window size
userDspSLC = 200  //user window size

black = true
white = false
]

//-----------------------------------------------------------------------------------------
let InitFtp() be
//-----------------------------------------------------------------------------------------
[
// cursor
@mouseX, @mouseY = 260, 25
for i = 0 to 7 do cursorBitMap!i = 177400b
for i = 8 to 15 do cursorBitMap!i = 377b

// sysZone
let freeBegin = @stackLimit
let freeEnd = MyFrame()-200
@stackLimit = freeEnd
test freeEnd-freeBegin gr 0
   ifso sysZone = InitializeZone(freeBegin, freeEnd-freeBegin, SysErr,
    (debugFlag? SysErr, 0))
   ifnot sysZone = InitializeZone(freeEnd-77777b, 77777b, SysErr,
    (debugFlag? SysErr, 0))
savedAllocate = sysZone!0; sysZone!0 = FunnyAllocate
@lvSysZone = sysZone

// contexts
ctxQ = Allocate(sysZone, 2); ctxQ!0 = 0
let initCtx = InitializeContext(Allocate(sysZone, 1500), 1500, InitCtx)
Enqueue(ctxQ, initCtx)
CallContextList(ctxQ!0) repeatuntil initDone
Unqueue(ctxQ, initCtx)
Free(sysZone, initCtx)
]

//-----------------------------------------------------------------------------------------
and InitCtx(ctx) be
//-----------------------------------------------------------------------------------------
[
if ramFlag % tfsFlag then
   [
   let p = Overlay(ram)
   ramFlag = LoadRam(FtpRamImage, true) ge 0
   Free(sysZone, p)
   if ramFlag then
      [
      PupChecksum = UPupChecksum
      InitBcplRuntime()
      ]
   ]
stackSize = tfsFlag? 2400, 1200

// disk
ftpDisk = sysDisk

// Pup package
InitPupLevel1(sysZone, ctxQ, numPBIs)
let fakeSoc = dPSIB - offset PupSoc.psib/16
SetAllocation(fakeSoc, numPBIs-4, numPBIs-5, numPBIs-5)

// Ftp subsystem
InitSysFont()
InitDisplay()
InitComCm()

// server
serverFlag = serverFlag & not cliFlag
if serverFlag then
   [
   MakeTitle("   FTP Server")
   serverDsp = MakeBar(white, (servDspSLC/(2*fontHeight))*fontHeight)
   FTPShowDisplayStream(serverDsp)
   Overlay(server)
   ]

// user
if userFlag then
   [
   MakeTitle("   FTP User")
   Overlay(user)
   userDspLen = 3500
   let slc = userDspSLC
   unless serverFlag % tfsFlag do
      [ userDspLen = userDspLen + 5000; slc = slc + servDspSLC ]
   unless (telnetFlag & not cliFlag) % tfsFlag do
      [ userDspLen = userDspLen + 1500; slc = 780-currentYPos ]
   userDsp = MakeBar(white, (slc/(2*fontHeight))*fontHeight)
   FTPShowDisplayStream(userDsp)
   test cliFlag
      ifso [ Overlay(commandLine); unless logFlag do logFlag = true ]
      ifnot Overlay(keyboard)
   InitLog()
   ]

// telnet
telnetFlag = telnetFlag & not cliFlag & not tfsFlag
if telnetFlag then
   [
   MakeTitle("   Telnet User")
   telnetDsp = MakeBar(white, ((780-currentYPos)/(2*fontHeight))*fontHeight)
   FTPShowDisplayStream(telnetDsp)
   telnetCode = Overlay(telnet)
   ]
FTPShowDisplayStream(MakeBar(black, 1))

// FtpInit (cont'd)

// Trident
if tfsFlag then
   [
   Overlay(tfs)
   let p = Overlay(tfsInit)
   ftpDisk = TFSInit(sysZone, 1, tfsUnit)
   if ftpDisk eq 0 then CallSwat("TFSInit failed")
   savedSwatContextProc = @lvSwatContextProc
   @lvSwatContextProc = TFSSwatContextProc
   Free(sysZone, p)
   ]

initCode = Overlay(init)
InitFtpUtil()
InitFtpPList()

Closes(overlayStream)

initDone = true
// returning from a context does an implicit Block()
]