// PupTestInit.bcpl
// Copyright Xerox Corporation 1979, 1982
// Last modified February 15, 1982  5:18 PM by Boggs

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

external
[
// outgoing procedures
InitPupTest

// incoming procedures
CreateDisplayStream; ShowDisplayStream
CharWidth; InvertLine; GetLinePos; SetBitPos
MyFrame; Usc; LoadRam; InitBcplRuntime; StartIO; Zero
PupChecksum; UPupChecksum; BlockEq; UBlockEq
InitializeZone; AddToZone; Allocate; Idle
InitPupLevel1; Enqueue; InitializeContext; Block
DefaultOtherPupProc; OtherSpigot; InitStatServ
BSPReceive; EFTPReceive; EchoServer; PupTestParams
Command; RemoteControl; OtherSpigotProcess
PutTemplate; Ws; Wss; Confirm

// outgoing statics
sendPort; tp; checkBuffer
savedFinish; spigotQ; ctxQ; bootFlag
spyBuffer; sysZone; dsp

// incoming statics
PupTestFinish; maxPupDataBytes
lvUserFinishProc; sysFont; PupTestEIAMc; PupTestCPMc
eiaMcLoaded; etherMcLoaded; cpMcLoaded
]

manifest
[
stkLim = #335
black = -1
white = 0
]

static
[
lastShownStream; savedSwatCP
spyBuffer; sysZone; dsp
sendPort; tp; checkBuffer
savedFinish; spigotQ; ctxQ; bootFlag
]

structure Byte↑0,0 byte

//----------------------------------------------------------------------------
let InitPupTest() be
//----------------------------------------------------------------------------
[
bootFlag = PupTestParams eq 0  //hack...should be done in a cleaner way
let versionText = "PupTest of February 15, 1982"

let freeBegin = @stkLim
@stkLim = MyFrame() -1000
let length = @stkLim - freeBegin
let lenInit = length ls 0? #77777, length
sysZone = InitializeZone(freeBegin, lenInit)
freeBegin = freeBegin + lenInit
length = length - lenInit
if length gr 10 then AddToZone(sysZone, freeBegin, length)

//This ugly patch of code discovers whether an EIA or ComProc
// (or both) is present, and therefore what microcode to load.
//If both are present, the user must choose one.
//The boot version loads the EIA version to get the Extra Ether code.
let eiaPresent, cpPresent = true, false
unless bootFlag do
   [
   @177700b = 140000b  //@eiaControl = swi
   eiaPresent = @177704b ne 0  //read status
   for line = 0 to 15 do
      [
      @(177300b + 4*line) = 1
      if @(177300b + 4*line) eq 1 then [ cpPresent = true; break ]
      ]
   if cpPresent & eiaPresent then
      [
      Ws("This machine has both an EIA and a ComProc.")
      Ws("*NI can use one or the other but not both.")
      test Confirm("*NShall I use the ComProc?")
         ifso eiaPresent = false
         ifnot cpPresent = false
      ]
   ]

//Flip the Memory Refresh Task into the ram only if
// this is an Alto II XM.
//The boot locus vector is in ramImage!0.
let ramImage = eiaPresent? PupTestEIAMc, PupTestCPMc
structure Vers: [ eng bit 4; blank bit 12 ]
if (table [ #61014; #1401 ])()<<Vers.eng ne 3 then
   ramImage!0 = ramImage!0 % 400b

//Now load the microcode
if LoadRam(ramImage, true) eq 0 then
   [
   InitBcplRuntime()
   PupChecksum = UPupChecksum
   BlockEq = UBlockEq
   etherMcLoaded = 3  //two extra ethers, tasks 1 and 2
   eiaMcLoaded = eiaPresent
   cpMcLoaded = cpPresent
   ]

//Set up the display
lastShownStream = MakeBar(white, 24)
ShowDisplayStream(lastShownStream, DSalone)
ShowDisplayStream(MakeBar(white, 1), DSbelow, lastShownStream)
let lenDS = lDCB + 38*((sysFont!-2 +1) & -2) +1
let title = CreateDisplayStream(1,Allocate(sysZone,lenDS),lenDS,sysFont)
Wss(title, versionText)
SetBitPos(title, 450)
PutTemplate(title, "Alto $UO#", StartIO(0) & #377)
InvertLine(title, GetLinePos(title))
GCShowDisplayStream(MakeBar(black, 2))
GCShowDisplayStream(title)
GCShowDisplayStream(MakeBar(black, 1))
dsp = CreateDisplayStream(20, Allocate(sysZone, 7000), 7000, sysFont)
GCShowDisplayStream(dsp)
GCShowDisplayStream(MakeBar(black, 1))

//more initialization!
savedFinish = @lvUserFinishProc
@lvUserFinishProc = PupTestFinish
spyBuffer = Allocate(sysZone, 1000)
sendPort = Allocate(sysZone, lenPort)
ctxQ = Allocate(sysZone, 2); ctxQ!0 = 0
Idle = Block
spigotQ = Allocate(sysZone, 2); spigotQ!0 = 0
DefaultOtherPupProc = OtherSpigot
InitPupLevel1(sysZone, ctxQ, 0)
InitStatServ(sysZone, ctxQ)
unless bootFlag do PupTestParams()
tp = Allocate(sysZone, lenTP)
checkBuffer = Allocate(sysZone, (maxPupDataBytes+1)/2)
for i = 0 to maxPupDataBytes-1 do checkBuffer>>Byte↑i = i

Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 400, 300)),
 (alto? 400, 300), Command))
Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 200, 150)),
 (alto? 200, 150), RemoteControl))
Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 200, 150)),
 (alto? 200, 150), EchoServer))
Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 200, 100)),
 (alto? 200, 100), OtherSpigotProcess))
Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 400, 300)),
 (alto? 400, 300), BSPReceive))
Enqueue(ctxQ,InitializeContext(Allocate(sysZone, (alto? 400, 300)),
 (alto? 400, 300), EFTPReceive))
]

//---------------------------------------------------------------------------
and GCShowDisplayStream(st) be
//---------------------------------------------------------------------------
[
ShowDisplayStream(st, DSbelow, lastShownStream)
lastShownStream = st
]

//---------------------------------------------------------------------------
and MakeBar(background, nLines) = valof
//---------------------------------------------------------------------------
[
structure Bar: [ fdcb word; ldcb word; @DCB ]
manifest lenBar = size Bar/16
let bar = Allocate(sysZone, lenBar, false, true)
Zero(bar, lenBar)
bar>>Bar.fdcb = lv bar>>Bar.next
bar>>Bar.ldcb = lv bar>>Bar.next
bar>>Bar.background = background
bar>>Bar.width = 0
bar>>Bar.height = nLines
resultis bar
]