; ; VMEM.MU -- microcode for VMEM package ; last modified October 13, 1977 5:55 PM ; ; R registers required ; ;$mapbase $Rxx; base of hash map, must be even ;$mapsptr $Rxx; map statistics pointer (up to mapbase), or 0 ;$mapmask1 $Rxx; hash table size -2 (e.g. 376, 776) $mmx $R5; =SAD, temp for mask bits $key $R7; =XREG, temp for hash key (virtual page #) $mrx $R10; =XH, miscellaneous temp ; ; Other requirements ; ;$M $R40; the new L register ;!1,20,START; ROM entry to Nova emulator ; ; Constants ; $readref $4; $writeref $6; $notrefbit $4; $reprobinc $30; use with reprobinc+1 +1 $mamask $177400; address part of map entry ; Predefinitions for labels ; !1,2,nempty,empty; for dispatch on empty entry !1,1,empty1; !1,2,nomatch,match; for dispatch on match with key !1,2,nmaskok,maskok; for dispatch on ref/dirty bits !1,2,nclean,clean; for dispatch on write ref. to clean page !1,2,noskip,coreaddr; testing for core address !1,2,dostat,nostat; testing mapsptr=0 !1,2,nfull,full; testing mapsptr=mapbase ; read/write mapping - v.a. is in AC0, AC1 rref: L←readref, TASK, :domap; mask for reading wref: L←writeref, TASK, :domap; mask for writing domap: mmx ← L; ; ; form hash key from AC0 (8-15) and AC1 (0-7) ; T←177400; T←AC1.T; L←T←AC0 OR T; key←L LCY 8; stash key ; form initial probe T←key+T+1; +1 is noise probe: L← mapmask1.T, TASK; mrx ← L; save initial probe for TASK T ← mrx; L ← MAR ← mapbase+T; AC3 ← L; T←key; L←MD+T+1, BUS=0; catch memory data,test for empty SH=0, T←MD, :nempty; catch second word of data ;dispatch on empty,test for match ; test for match hanging nempty: L ← mmx AND T, :nomatch; dispatch on match, test for r/w empty: T ← 377 - 1, :empty1; override match dispatch empty1: L ← AC0 XOR T; SH=0, L ← AC1; :noskip; test for core addr coreaddr: AC3 ← L, :mstats; ; testing for masked bits match: mrx ← L RSH 1, L ← T, SH=0; save masked bits T ← mamask.T, :nmaskok; dispatch on bits set or not nomatch: T← reprobinc + 1; add in the first 1 T← mrx+T+1, :probe; add in the other 1 nmaskok: T← mrx, BUSODD, TASK; L has 2nd word from hash map mrx ← L, :nclean; test for write to clean page maskok: L← AC1+T, TASK; AC3← L, :mstats; nclean: MAR← AC3+1; going to set ref bit to zero T ← mrx; L ← notrefbit XOR T; MD ← M; rewrite second word T ← mamask.T, :maskok; ; write ref to clean page clean: L ← PC, SWMODE, :nskip1; noskip return with AC3=hashmap ptr ; page not in core noskip: L ← PC, SWMODE, :nskip1; ditto ; Skip return to Nova emulator nskip: L ← PC+1, SWMODE; nskip1: PC ← L, :START; ; Log map reference mstats: L ← T ← mapsptr; L ← mapbase-T, SH=0; test for no logging MAR ← T, SH=0, :dostat; test for buffer full nostat: L ← PC+1; SINK ← MD, SWMODE, :nskip1; discard memory data, do skip return dostat: L ← 2+T, :nfull; full: L ← mapsptr-1, TASK; signal buffer overflow with funny AC3 AC3 ← L, :noskip; nfull: MD ← AC0; MAR ← L ← mapsptr+1; L ← M+1; mapsptr ← L, TASK; MD ← AC1, :nskip;