// RaidProcs.bcpl. Supplementary procedures for RAID // Last modified September 19, 1981 2:01 PM by Bill van Melle // Last modified August 4, 1981 12:47 PM by Beau Sheil // Last modified March 16, 1981 12:56 PM by Beau Sheil // Last modified July 27, 1980 6:56 PM by Beau Sheil // Last modified May 27, 1980 4:36 PM by Beau Sheil get "AltoDefs.d" get "Raid.decl" get "Pup0.decl" get "Pup1.decl" get "Stats.decl" get "Streams.d" external [ // defined here AtomNum; ShowRealCore; TeleRaid; uPCTracing; @uPCTraceAddr DisplayVMinBitMap; DisplayVMbit; VMDisplay ] external [ // procedures used Zero; VirtualPage; CallSwat; CRLF; Ws; Wo; Bytes2 StealFromBcplDisplay; AddToBcplDisplay; DumpBlockToStats RaidReset; UPCTrace; ShowDisplayStream @BGetBase; @BGetBasePtr; @XPutBase; @XSetBR; @RRead; @RWrite Dequeue; MoveWords; CompletePup; ExchangePorts; ReleasePBI SetTimer; TimerHasExpired; EmAddr; Block // statics used EmulatorSpace; LastRealPageNo; @lvVPtr dsp; @DisplayAddrHi ] static [ VMDisplay = 0 @uPCTraceAddr = 0 ] manifest [ LastSegment = 63 // 22-bit address space IMSize = #20000; DummyHeight = 32 VMbitMapOffset = 2+2*lDCB // bitmap within VMDisplay VMDisplayWidth = 16; VMDisplayHeight = LastSegment+1 VMDisplayScanLines = DummyHeight + VMDisplayHeight VMDisplaySize = VMbitMapOffset + VMDisplayWidth*VMDisplayHeight TRRead = #201 // teleRaid constants TRHereIsPage = #301 TRStore = #200 TRStoreDone = #300 TRGo = #202 TRGoAck = #302 TRGoReply = #203 TRShow = #210 TRShown = #310 TRError = #304 ] let AtomNum(S) = valof // Finds atom number for BCPL string. pn char format is that of bcpl strings [ let LEN = S>>String.length let NW = LEN rshift 1 // Compute the hash code for the name. Mimic the behavior of LISP let SS = 0 for i = 1 to LEN do [ let h1 = ((SS & #7777) lshift 2) + SS SS = (h1 lshift 8) + h1 + S>>String.char^i ] [ let H = ((SS𒿑) rem (AHTSIZE lshift 8)) + AHTbase // H is the virtual address in the AtomHashTable let P = BGetBase(AHTspace, H) // P is address of hash table entry if P eq 0 then RaidReset("No such atom") // since P was non zero, it is the virtual address of an atom+1 P = P-1 // fetch atom and check its pname. Check its characters (word-by-word) // with those in pname. Count is first byte, and pad byte (if any) is 0. XSetBR(BGetBasePtr(PNPspace, PNPbase+(P lshift 1))) for i = 0 to NW do if RRead(i) ne S!i goto reprobe resultis P // pnames are the same; return virtual address reprobe: SS = SS+HashInc ] repeat // comparison failed so reprobe ] and ShowRealCore() be // Displays a segment page usage map [ let base = vec LastSegment+2; Zero(base, LastSegment+3) for i = 0 to LastRealPageNo-1-PagesPerSegment do [ let bucket = VirtualPage(i)<>PupSoc.iQ) unless pb do resultis 0 let pup = lv pb>>PBI.pup // let lastid = 0 // cache low order bits of id // test lastid eq pup>>Pup.id^2 // ifso [ ReleasePBI(pb); resultis 0 ] // duplicate suppression // ifnot [ lastid = pup>>Pup.id^2 ] switchon pup>>Pup.type into [ case TRRead: [ TellUser("Read") // ID is virtual addr of desired page MoveWords(lv pup>>Pup.id^1, EmAddr(lv pup>>Pup.words^1), WordsPerPage) ExchangePorts(pb) CompletePup(pb, TRHereIsPage, WordsPerPage lshift 1 + pupOvBytes) endcase ] case TRStore: [ TellUser("Store") // First two words are VA, third word is value to store XPutBase(lv pup>>Pup.words^1, pup>>Pup.words^3) ExchangePorts(pb) CompletePup(pb, TRStoreDone, pupOvBytes) endcase ] case TRGo: [ TellUser("Go") ExchangePorts(pb) CompletePup(pb, TRGoAck, pupOvBytes) let Timer = nil SetTimer(lv Timer, 1000) // 10 sec timeout [ pb = Dequeue(lv s>>PupSoc.iQ) if pb % TimerHasExpired(lv Timer) then break Block() ] repeat test pb & (pb>>PBI.pup.type eq TRGoReply) ifso [ // ^N = go! ReleasePBI(pb) resultis #16 ] ifnot [ TellUser("Go abort") if pb then [ ExchangePorts(pb) CompletePup(pb, TRError, pupOvBytes) ] ] endcase ] case TRShow: [ // Body is a bcpl string to print Ws(lv pup>>Pup.bytes^1) ExchangePorts(pb) CompletePup(pb, TRShown, pupOvBytes) endcase ] default: [ TellUser("Error") ExchangePorts(pb) CompletePup(pb, TRError, 0) ] ] resultis 0 ] and TellUser(s) be [ Ws("["); Ws(s); Ws("]") ] and uPCTracing(flg) be [ test uPCTraceAddr eq 0 ifso [ // turn tracing on uPCTraceAddr = StealFromBcplDisplay(IMSize, 0) UPCTrace(uPCTraceAddr) ] ifnot [ // turn tracing off and dump to lisp.stats UPCTrace(0) DumpBlockToStats(uPCevent, uPCTraceAddr, IMSize/128, 128) if flg then AddToBcplDisplay(uPCTraceAddr, IMSize, 0) uPCTraceAddr = 0 ] ] and DisplayVMinBitMap() be [ if VMDisplay then [ VMDisplay = 0 AddToBcplDisplay(VMDisplay, VMDisplaySize, VMDisplayScanLines) return ] VMDisplay = StealFromBcplDisplay(VMDisplaySize, VMDisplayScanLines) let VMDisplayDCB = VMDisplay + 2 // insert a null dcb DummyHeight/2 scan lines high first VMDisplay>>DS.fdcb = VMDisplayDCB VMDisplayDCB>>DCB.next = VMDisplayDCB + lDCB VMDisplayDCB>>DCB.width = 0 VMDisplayDCB>>DCB.bitmap = 0 VMDisplayDCB>>DCB.height = DummyHeight/2 VMDisplayDCB = VMDisplayDCB + lDCB VMDisplay>>DS.ldcb = VMDisplayDCB VMDisplayDCB>>DCB.next = 0 VMDisplayDCB>>DCB.height = VMDisplayHeight/2 VMDisplayDCB>>DCB.indentation = 1 VMDisplayDCB>>DCB.width = VMDisplayWidth VMDisplayDCB>>DCB.bitmap = VMDisplay + VMbitMapOffset // Turn on bits for pages already in core. Emulator done specially. for i=0 to PagesPerSegment-1 do DisplayVMbit(Bytes2(EmulatorSpace,i), true) for i=0 to LastRealPageNo-1-PagesPerSegment do [ let vp = VirtualPage(i) unless vp<