// D0load.bcpl -- machine-dependent subroutines called by MLOAD.BCPL // Last edited: 21 October 1981 get "mdecl.d" get "mcommon.d" get "d0.d" manifest [ get "d0regmem.d" ] external [ // OS Zero // MIDAS MidasSwat; Initialized // MASM VUsc; StrSize // MDATA MCTimeOut // MSYM MapSymBlocks; @BHsize // MMPRGN UpdateMPDValues // MCMD DisplayError; ErrorAbort // MGO @CantContinue // D0TABLES @MEMLEN; @MEMWID // D0MEM readrr // D0GO AddBp // D0VM SetVirtP; LookUpAA; RetrieveBlock; VAtab; AAtab; IMstab; RMstab // Defined here PrepareLoad; RestoreAfterLoad; PutMDSymOnly; AddToVM; LoadCleanUp ] static [ oldMDATAwid; TypeOfLoad ] //Verify that the hardware is in good shape for the Ld, LdData, LdSyms, //Cmpr, or Dump and do other setup. Call DisplayError if probably not //ok to do the operation; if DisplayError returns (indicating user wants //to go ahead with the operation), then do ResetsCSS(). let PrepareLoad(LoadType) be [ if Initialized & (LoadType ne 0) do [ CantContinue = CantContinue % didLoad //DisplayError("Power is off", "Continue-loading") //ResetsCSS() Zero(MCTimeOut,6) //Zero error counters ] TypeOfLoad = LoadType oldMDATAwid = MEMWID!MDATAx MEMWID!MDATAx = MDATAwid ] and RestoreAfterLoad() = valof [ MEMWID!MDATAx = oldMDATAwid //2nd arg to SetVirtP causes UpdateMPDValues. //Have to update the display even on LdSyms because virtual addresses //may be displayed (e.g., CIA or TPC 20). //***FormCmdMenu may be called redundantly here, once by SetVirtP and //***once by InitLoad. if LookUpAA(0) ge 0 then SetVirtP(true,nil) if VUsc(MCTimeOut,table [ 0; 0; 0; 0; 0; 0 ] ,6) ne 0 then ErrorAbort("****Communication errors occurred****") ] //Special kludge subroutine used by MLOAD on "LdSyms" because the //virtual to absolute correspondence table has to be loaded even though //we are only loading symbols and we have to record the BP's in the BP //table for the load (???) and PutMDSymOnly(MemX,DVec,AVec) = valof [ if MemX eq IMx do [ if VUsc(AVec,MEMLEN+MemX+MemX,2) ge 0 then resultis false let AA = AddToVM(AVec!1,DVec) if AA < 0 then resultis false //AA exceeds phsyical microstore ] resultis true ] //Called only during Ld, LdSyms, or LdData by PutMemData or PutMDSymOnly. //VA must be valid. and AddToVM(VA,DVec) = valof [ let DV3 = DVec!3 if DV3<<IMV.Undef ne 0 then resultis -1 let AA = DV3<<IMV.Addr //Don't insert BP's on LdSyms if TypeOfLoad eq 0 then DV3 = DV3 & #37777 //Load the VM except on LdData if TypeOfLoad ne 1 do [ let Block = RetrieveBlock(VAtab+(VA rshift BlockShift),VAKind, 2,0,#17777) Block!(VA & BlockMask) = DV3 Block = RetrieveBlock(AAtab+(AA rshift BlockShift),AAKind, 2,0,#17777) Block!(AA & BlockMask) = VA+(DV3 & not AA) ] //Insert BP, if any, unless LdSyms if (DV3 & #140000) ne 0 do [ switchon AddBp(DV3<<IMV.Addr) into [ case -1: //Inserted BP ok case 1: endcase //Already in BP table case 0: MidasSwat(BPTableOvf) ] ] resultis AA ] //Build IMstab indexed by IM address, contains BlockAddr for the symbol //block which contains the nearest IM symbol le each IM address. //Similarly, build RMstab indexed by RM address. and LoadCleanUp() be [ if not Initialized then return MapSymBlocks(BuildAddrInvert,1) let BestBlockAddr = 0 //Fill gaps in IMstab table for I = 0 to (MEMLEN!(IMx+IMx+1) rshift (BlockShift+1))-1 do [ let Block = RetrieveBlock(IMstab+I,IMKind,1) if Block ne 0 then BestBlockAddr = ExtendSyms(BestBlockAddr,Block,BlockSize*2) ] ExtendSyms(0,RMstab,MEMLEN!(RMx+RMx+1)) ] and ExtendSyms(BestBlockAddr,Table,Length) = valof [ for I = 0 to Length-1 do [ let W = Table>>Bytes.Byte↑I test W eq 0 ifso Table>>Bytes.Byte↑I = BestBlockAddr ifnot BestBlockAddr = W ] resultis BestBlockAddr ] //Called from MapSymBlocks. Fills an IMstab entry for each IM address symbol //with BlockAddr for the block containing the symbol; fill RMstab entry for //each RM symbol with BlockAddr for the block containng the symbol. and BuildAddrInvert(B,nil,nil,nil,nil) be [ let Block,BlockAddr = B>>BT.Core,B>>BT.BlockAddr let Blk = nil for I = BHsize to Block>>BH.LastPntr do [ let Sym = Block+Block!I let Body = Sym+StrSize(Sym) let Addr = Body>>Symb.A.A2 switchon Body!0 into [ case (AddrSymb*#400)+IMx: Blk = RetrieveBlock(IMstab+(Addr rshift (BlockShift+1)), IMKind,1,Block,0) Addr = Addr & (BlockMask+BlockMask+1); endcase case (AddrSymb*#400)+RMx: Blk = RMstab; endcase default: loop ] Blk>>Bytes.Byte↑Addr = BlockAddr ] ]