// D1Config.bcpl 12 October 1984
//Contains FindConfiguration, called from D1I2 to establish board
//configuration and memory system parameters and the Config action
//that overrules automatically-determined parameters with those supplied
//by the user. FindConfiguration is also called from MStopped, if the
//machine was running when Midas connected to it.
get "d1.d"
manifest [ get "d1dmux.d" ]
manifest [ get "d1regmem.d" ]
external [
// OS
SetBlock; Zero
// MINIT0
@ACTS
// MASM
Wss; PutsCSS; @WssCSS; WssCS1; ResetsCSS; ResetsCS1; @MBlock
// MMENU
@WsMarkA; CreateAction; ItemStream; MarkMenus
// MMPRGN
UpdateMPDValues
// MCMD
WnsCSS; WnsCSSD; WnsCS1D; FormCmdMenu; QuitCmdOverlay
// D1I0
DChecked; @DMuxTab; @SaveMIR; HWStatus
// D1I2
ConfigUnknown
// D1TABLES
@MEMLEN; @MEMFORMS
// D1ASM
LoadMIR; @XctR16; @DoStrobe; LoadDMD; ReadDMux
// D1MEM
MGetMemData
// Defined here
FindConfiguration; D1Config
HaveControl; HaveProcH; HaveProcL; HaveMemC; HaveMemD; HaveMemX
HaveIFU; HaveDskEth; HaveDisplay
log2pgsize; log2rows; IMXmask
AColumnShift; DColumnShift; CacheAMask0; CacheAMask1
//Defined here for D1I2 only
FixForConfiguration; ShowConnection
MapICcode; MainICcode; ModuleMask; NoCacheAParity
]
static
[ //Basic parameters
HaveControl; HaveProcH; HaveProcL; HaveMemC; HaveMemD; HaveMemX
HaveIFU; HaveDskEth; HaveDisplay
log2pgsize = 8 //8 for 256-word pages, 10 for 1024-word,
//12 for 4096-word
MapICcode = 0 //0 (no map), 1 (illegal bit comb.)
//2 (16k), 3 (64k), 4 (256k)
MainICcode = 0 //0 (no storage), 1 (illegal bit comb.),
//2 (4k), 3 (16k), 4 (64k), 5 (256k)
//4k and 16k no longer supported
ModuleMask = 0 //4-bits: M0, M1, M2, M3
log2rows = 6 //6 for 64 rows, 7 for 128, 8 for 256
NoCacheAParity = 0 //0 if CacheA parity, 1 if 16 address bits
IMXmask = 7777B //Length of IMX less 1
//Derived
AColumnShift = 5 //5 for 4k cache, 4 for 8k, 3 for 16k
DColumnShift = 1 //1 for 4k, 0 for 8k, -1 for 16k
CacheAMask0; CacheAMask1 //Mask for CacheA read-write:
//17xxxx 17yyyy, where the unspecified
//bits vary with no. rows and whether the
//16th bit is an address bit or parity
]
manifest
[ get "d1instrs.d"
//Indices to ACTS
hControl = 1; hProcL = 4; hProcH = 7
hIFU = 10; hMemC = 13; hMemD = 16; hMemX = 19
hDskEth = 22; hDsp = 25
r64 = 28; r256 = 31
p256 = 34; p1K = 37; p4K = 40
m16 = 43; m64 = 46; m256 = 49
m0 = 52; m1 = 55; m2 = 58; m3 = 61; m4 = 64
s4 = 67; s16 = 70; s64 = 73; s256 = 76
]
//Determine which boards are plugged in and fill in configuration
//parameters. Note that with power on, mufflers should read 0 for a
//non-existent board. With no Dorado connected, all mufflers read 1,
//reasonable for debugging Midas.
//*Called from D1I2 and D1GO
let FindConfiguration() be
[
//Do ReadDMux() first, providing enough information to estimate the
//configuration; cannot do ReadAllRegs() until after FixForConfiguration()
//because FixForConfiguration() modifies DCHK, which might be displayed.
ReadDMux(); HWStatus!0 = DMuxTab!dCLKRUN
HaveControl = OrMufflers(dCJNK0,dREADY) ne 0
let T = OrMufflers(dALUB,dPJUNK)
HaveProcL,HaveProcH = T<<rh ne 0,T<<lh ne 0
HaveMemC = OrMufflers(dPVAH,dPIPEAD) ne 0
HaveMemD = OrMufflers(dMEMD0,dDADE) ne 0
HaveMemX = OrMufflers(dP34INEC,dINMAP) ne 0
HaveIFU = OrMufflers(dMEMRQ,dFFK) ne 0
HaveDskEth = OrMufflers(dKSTATE,dERX1) ne 0
HaveDisplay = OrMufflers(140B,147B) ne 0
ConfigUnknown = false
//Index is 3 bits: MapIs16K, MapIs64K, MapIs256K
MapICcode = table [ 0; 4; 3; 1; 2; 1; 1; 1 ] !
((DMuxTab!dAPESRN rshift 5) & 7B)
//Index is 2 bits: ChipsAre16K/256k (interpreted as 256k), ChipsAre64K
MainICcode = table [ 0; 4; 5; 1 ] !
((DMuxTab!dSTOUT rshift 1) & 3B)
//*Note that ReadAllRegs() has not been executed when FindConfiguration
//is called from D1I2, so ALUFM is not setup, but ok for this instruction.
//Wind up with M0, M1, M2, and M3 in right-most 4 bits of ModuleMask
ModuleMask = (XctR16(RCONFG,lv ModuleMask) rshift 4) & 17B
LoadMIR(SaveMIR)
//CacheConfig eq 0 and PageConfig eq 0 are undefined values
let CacheConfig = (DMuxTab!dPIPEAD rshift 10) & 3
let PageConfig = (DMuxTab!dPIPEAD rshift 8) & 3
log2rows = table [ 6; 8; 8; 6 ] !CacheConfig
NoCacheAParity = CacheConfig eq 1 ? 1,0
log2pgsize = table [ 8; 12; 10; 8 ] !PageConfig
//**Need to compute IMXmask here
FixForConfiguration()
]
and OrMufflers(first,last) = valof
[ let T = 0
for I = first to last do
[ T = T % DMuxTab!I
]
resultis T
]
//**NOTE: when put in command files, this action will only work, in
//**general, if the Have actions are executed in the correct order.
and D1Config(nil,nil) = valof
[ ACTS!0 = CreateAction("Done",lv ConDone,0)
//Haves
DefTF("Control","Control'",hControl,lv HaveControl)
DefTF("ProcL","ProcL'",hProcL,lv HaveProcL)
DefTF("ProcH","ProcH'",hProcH,lv HaveProcH)
DefTF("IFU","IFU'",hIFU,lv HaveIFU)
DefTF("MemC","MemC'",hMemC,lv HaveMemC)
DefTF("MemD","MemD'",hMemD,lv HaveMemD)
DefTF("MemX","MemX'",hMemX,lv HaveMemX)
DefTF("DskEth","DskEth'",hDskEth,lv HaveDskEth)
DefTF("Dsp","Dsp'",hDsp,lv HaveDisplay)
//Cache rows
DefCon(lv log2rows,"64-rows",r64,6)
DefCon(lv log2rows,"256-rows",r256,8)
//Page size
DefCon(lv log2pgsize,"256",p256,8)
DefCon(lv log2pgsize,"1K",p1K,10)
DefCon(lv log2pgsize,"4K",p4K,12)
//Map chips
DefCon(lv MapICcode,"16K-wds",m16,2)
DefCon(lv MapICcode,"64K-wds",m64,3)
DefCon(lv MapICcode,"256K-wds",m256,4)
//Modules
DefCon(lv ModuleMask,"0",m0,0)
DefCon(lv ModuleMask,"1",m1,10B)
DefCon(lv ModuleMask,"2",m2,14B)
DefCon(lv ModuleMask,"3",m3,16B)
DefCon(lv ModuleMask,"4",m4,17B)
//Storage chips
DefCon(lv MainICcode,"4K-ics",s4,2)
DefCon(lv MainICcode,"16K-ics",s16,3)
DefCon(lv MainICcode,"64K-ics",s64,4)
DefCon(lv MainICcode,"256K-ics",s256,5)
resultis D1ConMenu
]
and DefTF(Strue,Sfalse,X,lvStat) be
[ ACTS!X = CreateAction(Strue,lv DoConTrue,X)
ACTS!(X+1) = CreateAction(Sfalse,lv DoConFalse,X)
ACTS!(X+2) = lvStat
]
and DefCon(lvStat,Str,X,Val) be
[ ACTS!X = CreateAction(Str,lv DoConSel,X)
ACTS!(X+1) = lvStat
ACTS!(X+2) = Val
]
and D1ConMenu(S,nil) be
[ FixForConfiguration()
WsMarkA(ACTS!0)
Wss(ItemStream," Have: "); MarkMenus(0)
ShowOnOffAct(hControl)
if HaveControl then
[ ShowOnOffAct(hProcL)
if HaveProcL do
[ ShowOnOffAct(hProcH)
if HaveProcH do
[ ShowOnOffAct(hIFU); ShowOnOffAct(hMemC)
if HaveMemC do
[ ShowOnOffAct(hMemD); ShowOnOffAct(hMemX)
]
ShowOnOffAct(hDskEth); ShowOnOffAct(hDsp)
]
]
]
if HaveMemC do
[ Wss(ItemStream," Rows: "); MarkMenus(0)
WsMarkA(ACTS!r64); WsMarkA(ACTS!r256)
if HaveMemX do
[ Wss(ItemStream," Pgsize: "); MarkMenus(0)
WsMarkA(ACTS!p256); WsMarkA(ACTS!p1K); WsMarkA(ACTS!p4K)
Wss(ItemStream," Map size: "); MarkMenus(0)
WsMarkA(ACTS!m16); WsMarkA(ACTS!m64); WsMarkA(ACTS!m256)
if HaveMemD do
[ Wss(ItemStream," Modules: "); MarkMenus(0)
WsMarkA(ACTS!m0); WsMarkA(ACTS!m1)
WsMarkA(ACTS!m2); WsMarkA(ACTS!m3); WsMarkA(ACTS!m4)
Wss(ItemStream," Storage has: "); MarkMenus(0)
WsMarkA(ACTS!s4); WsMarkA(ACTS!s16); WsMarkA(ACTS!s64)
WsMarkA(ACTS!s256)
]
]
]
]
and ShowOnOffAct(X) be
[ WsMarkA((rv ACTS!(X+2) ? ACTS!(X+1),ACTS!X))
]
and ConDone(nil,nil,nil) be
[ UpdateMPDValues()
QuitCmdOverlay()
]
and DoConTrue(X,MBunion,nil) be
[ rv ACTS!(X+2) = true
FormCmdMenu()
]
and DoConFalse(X,MBunion,nil) be
[ rv ACTS!(X+2) = false
FormCmdMenu()
]
and DoConSel(X,MBunion,nil) be
[ rv ACTS!(X+1) = ACTS!(X+2)
FormCmdMenu()
]
//Establish consequences for the selected configuration: set DCHK
//appropriately; compute AColumnShift and DColumnShift from log2rows for
//ConvertAV; fill in lengths for configuration-dependent memories;
//copy the basic configuration parameters into HWStatus to preserve them
//for future Run-Prog.
and FixForConfiguration() be
[ HWStatus>>HWStatus.HaveControl = HaveControl
HWStatus>>HWStatus.HaveProcL = HaveProcL
HWStatus>>HWStatus.HaveProcH = HaveProcH
HWStatus>>HWStatus.HaveMemC = HaveMemC
HWStatus>>HWStatus.HaveMemD = HaveMemD
HWStatus>>HWStatus.HaveMemX = HaveMemX
HWStatus>>HWStatus.HaveIFU = HaveIFU
HWStatus>>HWStatus.HaveDskEth = HaveDskEth
HWStatus>>HWStatus.HaveDisplay = HaveDisplay
HWStatus>>HWStatus.ConfigUnknown = ConfigUnknown
HWStatus>>HWStatus.MapICcode = MapICcode
HWStatus>>HWStatus.MainICcode = MainICcode
HWStatus>>HWStatus.ModuleMask = ModuleMask
HWStatus>>HWStatus.log2rows = log2rows
HWStatus>>HWStatus.NoCacheAParity = NoCacheAParity
HWStatus>>HWStatus.log2pgsize = log2pgsize
HWStatus>>HWStatus.IMXmask = IMXmask
LoadDMD(IMControl)
DoStrobe(Clock)
let ProcMask = HaveProcH ? -1,377B
let MapLen,VMLen,MainLen = vec 1,0,0
Zero(MapLen,2)
SetBlock(DChecked+dCLKRUN,-1,10B) //Baseboard
SetBlock(DChecked,HaveControl,20B) //Control section
SetBlock(DChecked+dSaveMIR,HaveControl,10B) //MIR & IMOUT
DChecked!dESTAT = HaveControl
test HaveControl & HaveProcL
ifso
[ SetBlock(DChecked+20B,ProcMask,20B)
//Testing above the processor requires both processor boards alive
SetBlock(DChecked+40B,HaveProcH,dBMUX-40B)
DChecked!dBMUX = ProcMask
unless HaveProcH do
[ DChecked!dCIA = 177776B //No B.C.'s
DChecked!dSTKRB = 137B //Not RBaseBypass', RBaseWriteEn'
DChecked!dRTSB = 177B //Not StkPSaveEn'
DChecked!dALUCON = 277B //Not Pdata.08
]
//Use of MemD and MemX requires MemC
test HaveProcH & HaveMemC
ifso
[
//VMLen is set to the limit imposed by CacheA; limit imposed by Map
//is ignored (???)
VMLen = 1 lshift (3+log2rows+NoCacheAParity)
test HaveMemX
ifso
[ MBlock(MapLen,
table [ 0; 0; //nothing
0; 40000B; //illegal--use 16K
0; 40000B; //16K
1; 0; //64K
4; 0 //256K
] + MapICcode+MapICcode,2)
//Use the largest module number to determine the the size of storage
//in case there are holes in the address space.
let LargestModule =
table [ 0; 4; 3; 4; 2; 4; 3; 4;
1; 4; 3; 4; 2; 4; 3; 4 ] ! ModuleMask
//Set multiplier for 64k ic's when ic size readings are inconsistent.
let ICSizeMul =
table [ 0; 20B; 1B; 4B; 20B; 100B ] ! MainICcode
MainLen = LargestModule*ICSizeMul
]
ifnot
[ Zero(DChecked+dMAPBUF,20B)
DChecked!dHIT = 177377B //Not XWantsPipeDly
//Not WantCHdly', MDhold', Dbusy, AtookST, AwantsMapFS'
DChecked!dHOLD = 165656B
//Not IoStoreInA, Map←InPair', FlushInA, IoRefInA',VicInPair'
//bEcHasA, ←PrVArow
DChecked!dPAIR = 106725B
DChecked!dPIPEAD = 7777B //Not PipeAd
DChecked!dFD = 176677B //Not MakeMDM←D', DadH←'
DChecked!dEC = 171777B //Not StartEcGen, StartEcChk
DChecked!dDADE = 7777B //Not DCE'c
DChecked!dMCR = 163770B //Not MemX MCR bits, Victim
]
//Since RunRefresh is false during SimGo, can't enable MemoryPE stops,
//but MD should always have good parity, so ok to enable.
unless HaveMemD do
[ Zero(DChecked+dMEMD0,10B)
DChecked!dHIT = DChecked!dHIT & 177477B //Not ColVic
MainLen = 0
]
]
ifnot //MemC, MemD, MemX unusable
[ HaveMemD,HaveMemX = 0,0
Zero(DChecked+dPVAH,40B)
Zero(DChecked+dAAD,2) //AAD, MEMB
]
unless HaveIFU do
[ Zero(DChecked+dMEMRQ,20B)
//Not IfuRefInA, KillIfuRef, ←PrVArow, PairFull
DChecked!dPAIR = DChecked!dPAIR & 175770B
DChecked!dSTA = DChecked!dSTA & 177776B //Not UseAsrn
DChecked!dPIPEAD = DChecked!dPIPEAD & 7777B //Not PipeAd
DChecked!dHIT = DChecked!dHIT & 177377B //Not MiscPCHP'
]
unless HaveDskEth do Zero(DChecked+dKSTATE,10B)
unless HaveDisplay do Zero(DChecked+140B,10B)
]
ifnot //No simulation above control
[ Zero(DChecked+20B,160B)
DChecked!dCIA = DChecked!dCIA & 177776B //No B.C.'s
HaveProcL,HaveProcH = 0,0
HaveMemC,HaveIFU = 0,0
HaveMemD,HaveMemX = 0,0
HaveDskEth,HaveDisplay = 0,0
]
//Turn off signals affected by simulator bugs not fixed yet.
let T = table [
dPCJ; 377B //PCJ/I
dIDLY; 173777B //GLdDlyx
//Also, saw BNT.2 wrong when old CTASK=NEXT=17b & old BNT=PEnc=15b, RepeatCur
//is true; predicted BNT=15b, got BNT=17b. Old RWIMorTPC was true.
// dMX; 177477B //DSel[0:1] (maybe fixed)
// dSTA; 177775B //MapFree/X
// dPIPEAD; 77777B //PipeAd.0/C
// dP34INEC; 170377B //Pipe34Ad[0:3]/X (maybe fixed)
// dAPESRN; 173777B //ProcSrn.0/X
// dPEEC; 77777B //PEsrn.0/X
//Next 4 are believed to be a slow path problem:
// dINMAP; 127777B //RefUsesD10InMap'/X (maybe fixed)
// //WriteInMap'/X (maybe fixed)
// dMAPCTRL; 177747B //MapFnc'[0:1] (maybe fixed)
]
for I = 0 to 0 by 2 do DChecked!(T!I) = DChecked!(T!I) & (T!(I+1))
MBlock(MEMLEN+MAPx+MAPx,MapLen,2)
MEMLEN!(IMXx+IMXx+1) = IMXmask+1
MEMLEN!(IMx+IMx+1) = IMXmask+1
MEMLEN!(VMx+VMx) = VMLen
MEMLEN!(ROWx+ROWx+1) = 1 lshift log2rows
MEMLEN!(CACHEAx+CACHEAx+1) = 4B lshift log2rows
MEMLEN!(CACHEDx+CACHEDx+1) = 100B lshift log2rows
AColumnShift = 11-log2rows
DColumnShift = 7-log2rows
//Flags put in DVec!0[0:3], VA[4:15] in DVec!0[4:15]; value has a
//total of 15 address bits, or 16 if parity bit is converted to address
//bit
CacheAMask0 = 170000B+(-1 rshift (13-log2rows-NoCacheAParity))
//VA[16:31] munch and row address bits not part of value
CacheAMask1 = -1 lshift (log2rows+4)
let FormCACHEA = MEMFORMS!CACHEAx
FormCACHEA!3 = #15-log2rows-NoCacheAParity
FormCACHEA!4 = #17+NoCacheAParity
//Show board configuration
ShowConnection()
test HaveControl
ifso
[ WssCSS(", ContA")
WnsCS1D(MEMLEN!(IMXx+IMXx+1)); WssCS1("-word IMX")
//Require ContA/B and ProcL/H to indicate any others
test HaveProcL
ifso test HaveProcH
ifso
[ unless HaveIFU do WssCSS("-ProcH")
test HaveMemC
ifso
[ test HaveIFU
ifso unless HaveMemX do WssCSS("-MemC")
ifnot WssCSS(", MemC")
WssCS1(", "); WnsCS1D(1 lshift log2rows)
WssCS1(" rows")
test HaveMemX
ifso test HaveMemD
ifso
[ WssCSS("-MemD")
WssCS1(", ")
test MapICcode ne 1
ifso
[ WnsCS1D(table [ 0; 0; 16; 64; 256 ] ! MapICcode)
WssCS1("K ")
WnsCS1D(1 lshift log2pgsize)
WssCS1("-word pages")
]
ifnot WssCS1("??Map ic size??")
test (ModuleMask eq 0) % (MainICcode eq 0)
ifso WssCS1(", no storage")
ifnot
[ test MainICcode ge 2
ifso
[ WssCS1(", ")
WnsCS1D(MainLen lshift 6)
WssCS1("K storage")
let ModOK =
table [ -1; 0; 0; 0; 0; 0; 0; 0
-1; 0; 0; 0; -1; 0; -1; -1 ] !
ModuleMask
unless ModOK do WssCS1(" with holes")
]
ifnot WssCS1(", ??storage IC size??")
]
]
ifnot WssCSS("-MemX")
ifnot if HaveMemD then WssCSS(", MemD")
]
ifnot if HaveIFU then WssCSS("-IFU")
if HaveDskEth then WssCSS(", DskEth")
if HaveDisplay then WssCSS(", Dsp")
]
ifnot WssCSS("-ProcL")
ifnot WssCSS("-ContB")
]
ifnot WssCSS(", no control section")
WssCSS(", Clk = ");
let T = 20000/((DMuxTab+dCLKRUN)>>lh)
WnsCSSD(T/10); PutsCSS($.); WnsCSSD(T rem 10); WssCSS(" ns")
]
and ShowConnection() be
[ ResetsCSS(); ResetsCS1()
let ConnectedMachine = HWStatus>>HWStatus.ConnectedMachine
test ConnectedMachine eq -1
ifso WssCSS("Disconnected")
ifnot
[ WssCSS("Serial #"); WnsCSS(ConnectedMachine)
let Version = vec 1
MGetMemData(ABSOLx,Version,table [ 0; 0 ] )
WssCSS(", ZVer="); WnsCSS(Version>>lh)
]
]