// D1LOAD.BCPL -- machine-dependent subroutines called by MLOAD.BCPL // Last edited: 2 May 1980 get "mdecl.d" //**Cannot get d1.d here because of duplicate lh, rh defs. get "mcommon.d" manifest [ get "d1regmem.d" ] external [ // OS Zero // MIDAS Initialized // MASM VUsc; StrSize // MDATA MIRPE // MSYM MapSymBlocks; @BHsize // MMPRGN UpdateMPDValues // MCMD DisplayError; ErrorAbort // MGO @CantContinue // D1TABLES @MEMLEN; @MEMWID // D1ASM ReadDMux // D1VM LookUpAA; SetVirtP; RetrieveBlock; VAtab; AAtab IMstab; RMstab; BRstab; DEVICEstab; TASKNstab // Defined here PrepareLoad; RestoreAfterLoad; PutMDSymOnly; AddToVM; LoadCleanUp ] static [ oldMDATAwid ] //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(SymOnly) be [ if Initialized & not SymOnly do [ CantContinue = CantContinue % didLoad //DisplayError("Power is off", "Continue-loading") //ResetsCSS() ] oldMDATAwid = MEMWID!MDATAx MEMWID!MDATAx = MDATAwid Zero(MIRPE,2) //Zero error counters ] and RestoreAfterLoad() be [ MEMWID!MDATAx = oldMDATAwid //Avoid disturbing hardware on LdSyms or during initialization. if (CantContinue & didLoad) ne 0 do ReadDMux() test LookUpAA(0) ge 0 ifso SetVirtP(true,nil,nil) ifnot if (CantContinue & didLoad) ne 0 then UpdateMPDValues() if (MIRPE!0 ne 0) % (MIRPE!1 ne 0) do ErrorAbort("MIR PE's 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 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 [ //**Format will change after MicroD is revised to output 14-bit AA's. let AA = DVec!3 & #7777 if AA ge MEMLEN!(IMXx+IMXx+1) then ErrorAbort("Abs. addr in IM word too big for IMX") let Other = (DVec!3 lshift 2) & #140000 let Block = RetrieveBlock(VAtab+(VA rshift BlockShift),VAKind, 2,0,#137777) Block!(VA & BlockMask) = AA+Other if Other ge 0 do [ Block = RetrieveBlock(AAtab+(AA rshift BlockShift),AAKind, 2,0,#137777) Block!(AA & BlockMask) = VA+Other ] 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,RMlen) ExtendSyms(0,BRstab,BRlen) ExtendSyms(0,TASKNstab,NTasks) ExtendSyms(0,DEVICEstab,DEVICElen) ] 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 case (AddrSymb*#400)+BRx: Blk = BRstab; endcase case (AddrSymb*#400)+TASKNx: Blk = TASKNstab; endcase case (AddrSymb*#400)+DEVICEx: Blk = DEVICEstab; endcase default: loop ] Blk>>Bytes.Byte↑Addr = BlockAddr ] ]