TITLE SAVE AND RESTORE STATE OF A MUDDLE RELOCATABLE .INSRT DSK:MUDDLE > SYSQ IFE ITS,[ IF1,[ .INSRT STENEX > EXPUNGE SAVE ] ] .GLOBAL MOPEN,MIOT,MCLOSE,MUDSTR,SWAP,STRTO6,GCPDL,RGPRS .GLOBAL CHNL0,CHNL1,REOPN,AGC,SWAPIN,MASK1,MASK2,IPCBLS .GLOBAL P.CORE,P.TOP,SGSNAM,%RUNAM,%RJNAM,INTINT,CLOSAL,TTYOPE .GLOBAL NOTTY,PURCLN,6TOCHS,DISXTR,IDVAL1,N.CHNS MFUNCTION FSAVE,SUBR ENTRY PUSH P,. ; SAY WE ARE FAST SAVER JRST SAVE1 MFUNCTION SAVE,SUBR ENTRY PUSH P,[0] ; SAY WE ARE OLD SLOW SAVE SAVE1: SKIPG MUDSTR+2 ; DON'T SAVE FROM EXPERIMENTAL MUDDLE JRST EXPVRS PUSH P,[0] ; GC OR NOT? IFE ITS,[ MOVE B,[400600,,] MOVE C,[440000,,100000] ] PUSHJ P,GTFNM ; GET THE FILE NAME ONTO P JRST .+2 JRST SAVEON JUMPGE AB,TMA ; TOO MUCH STRING GETYP 0,(AB) ; WHAT IS ARG CAMGE AB,[-3,,0] ; NOT TOO MANY JRST TMA CAIN 0,TFALSE IFN ITS, SETOM -4(P) ; GC FLAG IFE ITS, SETOM (P) SAVEON: IFN ITS,[ MOVSI A,7 ; IMAGE BLOCK OUT HRR A,-2(P) ; DEVICE PUSH P,A PUSH P,[SIXBIT /_MUDS_/] PUSH P,[SIXBIT />/] MOVEI A,-2(P) ; POINT TO BLOCK PUSHJ P,MOPEN ; ATTEMPT TO OPEN JRST CANTOP SUB P,[3,,3] ; FLUSH OPEN BLOCK PUSH P,-4(P) ; GC FLAG TO TOP OF STACK ] EXCH A,(P) ; CHAN TO STACK GC TO A JUMPL A,.+2 MCALL 0,GC ; NOW GET VERSION OF MUDDLE FOR COMPARISON MOVE A,MUDSTR+2 ; GET # MOVEI B,177 ; CHANGE ALL RUBOUT CHARACTERS MOVEI C,40 ; ----- TO SPACES PUSHJ P,HACKV PUSHJ P,WRDOUT MOVEI A,0 ; WRITE ZERO IF FAST IFN ITS, SKIPE -6(P) IFE ITS, SKIPE -1(P) PUSHJ P,WRDOUT MOVE A,VECTOP ; CORE REQUIREMENTS FOR THIS SAVED MUDDLE PUSHJ P,WRDOUT IFN ITS,[ SETZB A,B ; FIRST, ALL INTS OFF .SETM2 A, SKIPE DISXTR ; IF HAVE DISPLAY, CLOSE IT .DSTOP ; STOP THE E&S IF RUNNING ; IF FAST SAVE JUMP OFF HERE SKIPE -6(P) JRST FSAVE1 ; NOW DUMP OUT GC SPACE MOVEI A,E+1 ; ADDRESS OF FIRST NON-SCRATCH WORD POP P,0 ; CHAN TO 0 LSH 0,23. ; POSITION IOR 0,[.IOT A] ] IFE ITS,[ MOVEI A,400000 ; FOR THIS PROCESS DIR ; TURN OFF INT SYSTEM ; IF FAST, LEAVE HERE SKIPE -1(P) JRST FSAVE1 ; NOW DUMP OUT GC SPACE POP P,0 ; RESTORE JFN MOVE A,[-,,E] ; NUMBER OF ACS TO GO PUSH P,(A) AOBJN A,.-1 MOVE A,0 MOVE B,P BOUT MOVEI A,20 ; START AT LOCN 20 ] DMPLP1: MOVEI B,(A) ; POINT TO START OF STUFF SUB B,VECTOP ; GET BLOCK LENGTH MOVSI B,(B) HRRI B,(A) ; HAVE IOT POINTER SKIPL B ; SKIP IF OK AOBJN POINTER HRLI B,400000 ; OTHER WISE AS MUCH AS POSSIBLE ; MAIN NON-ZERO DUMPING LOOP DMPLP: SKIPN C,(B) ; FIND FIRST NON-ZERO AOBJN B,.-1 JUMPGE B,DMPDON ; NO MORE TO SCAN DMP4: MOVEI E,(B) ; FOUND ONE, SAVE POINTER TO IT DMP3: MOVSI D,-5 ; DUPLICATE COUNTER SETUP DMP1: CAMN C,(B) ; IS NEXT SAME AS THIS? JRST CNTDUP ; COUNT DUPS MOVSI D,-5 ; RESET COUNTER SKIPE C,(B) ; SEARCH FOR ZERO DMP5: AOBJN B,DMP1 ; COUNT AND GO JUMPGE B,DMP2 ; JUMP IF BLOCK FINISHED AOBJP B,DMP2 ; CHECK FOR LONE ZERO SKIPE C,(B) JRST DMP1 ; LONE ZERO, DONT END BLOCK DMP2: MOVEI D,(E) ; START COMPUTING OUTPUT IOT SUBI D,(B) ; D=> -LNTH OF BLOCK HRLI E,(D) ; E=> AOBJN PNTR TO OUTPUT IFN ITS,[ HRROI A,E ; MAKE AN IOT POINTER TO IT XCT 0 ; WRITE IT MOVE A,E ; NOW FOR THE BLOCK XCT 0 ; ZAP!, OUT IT GOES ] IFE ITS,[ EXCH E,B ; AOBJN TO B MOVE A,0 ; JFN TO A BOUT ; WRITE IT MOVE D,B ; SAVE POINTER HRLI B,444400 ; BYTPE POINTER HLRE C,D ; # OF BYTES SOUT ] ; NOW COMPUTE A CKS IFN ITS,[ MOVE D,E ; FIRST WORD OF CKS ROT E,1 ADD E,(D) AOBJN D,.-2 ; COMP CKS HRROI A,E XCT 0 ; WRITE OUT THE CKS ] IFE ITS,[ MOVE B,D ROT B,1 ADD B,(D) AOBJN D,.-2 BOUT MOVE B,E ; MAIN POINTER BACK ] DMP7: JUMPL B,DMPLP ; MORE TO DO? DMPDON: SUB B,VECTOP ; DONE? JUMPGE B,DMPDN1 ; YES, LEAVE IFN ITS, MOVEI A,400000+PVP ; POINT TO NEXT WORD TO GO IFE ITS, MOVEI A,400020 JRST DMPLP1 IFN ITS,[ DMPDN1: HRROI A,[-1] XCT 0 ; EOF DMPDN2: SETZB A,B ; SET UP RENAME WHILE OPEN ETC. MOVE E,(P) MOVE D,-1(P) LDB C,[270400,,0] ; GET CHANNEL .FDELE A ; RENAME IT FATAL SAVE RENAME FAILED XOR 0,[<.IOT A>#<.CLOSE>] ; CHANGE TO A CLOSE XCT 0 MOVE A,MASK1 ; TURN INTS BACK ON MOVE B,MASK2 .SETM2 A, SKIPE DISXTR ; SKIP IF NO E&S .DCONTINUE ; RESTART THE E&S IF WE HAVE IT ] IFE ITS,[ DMPDN1: MOVNI B,1 MOVE A,0 ; WRITE EOF BOUT DMPDN2: MOVE A,0 CLOSF FATAL CANT CLOSE SAVE FILE CIS ; CLEAR IT SYSTEM MOVEI A,400000 EIR ; AND RE-ENABLE ] SDONE: MOVE A,$TCHSTR MOVE B,CHQUOTE SAVED JRST FINIS ; SCAN FOR MANY OCCURENCES OF THE SAME THING CNTDUP: AOBJN D,DMP5 ; 4 IN A ROW YET CAIN E,-4(B) ; ANY PARTIAL BLOCK? JRST DMP6 ; NO, DUMP THESE SUB B,[4,,4] ; BACK UP POINTER JRST DMP2 DMP6: CAMN C,(B) ; FIND ALL CONTIG AOBJN B,.-1 MOVEI D,(B) ; COMPUTE COUNT SUBI D,(E) MOVSI D,(D) HRRI D,(E) ; HEADER IFN ITS,[ HRROI A,D XCT 0 HRROI A,C ; WRITE THE WORD XCT 0 ] IFE ITS,[ MOVE A,0 EXCH D,B BOUT MOVE B,C BOUT MOVE B,D ] JRST DMP7 ; HERE TO WRITE OUT FAST SAVE FILE FSAVE1: MOVE A,PARTOP ; DONT WRITE OUT "HOLE" ADDI A,1777 ANDCMI A,1777 MOVEI E,(A) PUSHJ P,WRDOUT MOVE A,VECBOT ANDCMI A,1777 HRLI E,(A) PUSHJ P,WRDOUT POP P,0 ; CHANNEL TO 0 IFN ITS,[ ASH 0,23. ; TO AC FIELS IOR 0,[.IOT A] MOVEI A,5 ; START AT WORD 5 ] IFE ITS,[ MOVE A,[-,,E] PUSH P,(A) AOBJN A,.-1 MOVE A,0 MOVE B,P ; WRITE OUT P FOR WIINAGE BOUT MOVE B,[444400,,20] MOVNI C,20-6 SOUT ; MAKE PAGE BOUNDARIES WIN MOVEI A,20 ; START AT 20 ] MOVEI B,(E) ; PARTOP TO B PUSHJ P,FOUT ; WRITE OUT UP TO PAIR TOP HLRZ A,E ; VECBOT TO A MOVE B,VECTOP ; AND THE REST PUSHJ P,FOUT JRST DMPDN2 IFN ITS,[ FOUT: MOVEI D,(A) ; SAVE START SUB A,B ; COMPUTE LH OF IOT PNTR MOVSI A,(A) SKIPL A ; IF + MEANS GROSS CORE SIZE MOVSI A,400000 ; USE BIGGEST HRRI A,(D) XCT 0 ; ZAP, OUT IT GOES CAMGE A,B ; SKIP IF ALL WENT JRST FOUT ; DO THE REST POPJ P, ; GO CLOSE FILE ] IFE ITS,[ FOUT: MOVEI C,(A) SUBI C,(B) ; # OF BYTES TP C MOVEI B,(A) ; START TO B HRLI B,444400 MOVE A,0 SOUT ; WRITE IT OUT POPJ P, ] ; HERE TO ATTEMPT TO RESTORE A SAVED STATE MFUNCTION RESTORE,SUBR ENTRY SKIPG MUDSTR+2 ; DON'T RESTORE FROM EXPERIMENTAL MUDDLE JRST EXPVRS IFE ITS,[ MOVE B,[100600,,] MOVE C,[440000,,240000] ] PUSHJ P,GTFNM JRST TMA IFN ITS,[ MOVEI A,6 ; READ/IMAGE/BLOCK HRLM A,-2(P) MOVEI A,-2(P) PUSHJ P,MOPEN ; OPEN THE LOSER JRST FNF SUB P,[4,,4] ; REMOVE OPEN BLOCK PUSH P,A ; SAVE CHANNEL PUSHJ P,SGSNAM ; SAVE SNAME IN SYSTEM ] IFE ITS, PUSH P,A ; SAVE JFN PUSHJ P,WRDIN ; READ MUDDLE VERSION MOVEI B,40 ; CHANGE ALL SPACES MOVEI C,177 ; ----- TO RUBOUT CHARACTERS PUSHJ P,HACKV CAME A,MUDSTR+2 ; AGREE ? JRST BADVRS IFN ITS, MCALL 0,IPCOFF ; CLOSE ALL IPC CHANS PUSHJ P,CLOSAL ; CLOSE CHANNELS IFN ITS,[ SETZB A,B ; KILL ALL POSSIBLE INTERRUPTION .SETM2 A, ] IFE ITS,[ MOVEI A,400000 ; DISABLE INTS DIR ; INTS OFF ] PUSHJ P,PURCLN ; DONT KEEP PURE SHAREDNESS POP P,A ; RETRIEVE CHANNEL MOVE P,GCPDL PUSH P,A ; AND SAVE IT ON A GOOD PDL PUSHJ P,WRDIN ; READ A WORD (VECTOP) OR 0==>FAST I.E. MAP RESTORE JUMPE A,FASTR MOVEM A,VECTOP ; SAVE FOR LATER ASH A,-10. ; TO BLOCKS MOVE C,A ; SAVE A COPY ADDI A,1 ; ROOM FOR GC PDL PUSHJ P,P.CORE PUSHJ P,NOCORE ; LOSE,LOSE, LOSE ; NOW READY TO READ IN GC SPACE POP P,0 ; GET CHAN MOVEI E+1,0 MOVE B,[E+1,,E+2] ; BLT SETUP TO ZERO CORE MOVE E,NOTTY MOVE A,VECTOP BLT B,-1+2000(A) ; THE WHOLE THING? IFN ITS,[ LSH 0,23. IOR 0,[.IOT A] ; BUILD IOT ] IFE ITS,[ MOVE A,0 BIN ; READ IN NEW "P" MOVE P,B ] LDLP: IFN ITS,[ HRROI A,B ; READ A HDR XCT 0 JUMPL A,LD1 ; DONE ] IFE ITS,[ MOVE A,0 BIN ; HDR TO B ] CAMN B,[-1] JRST LD1 JUMPGE B,LDDUPS ; JUMP IF LOADING DUPS IFN ITS,[ MOVE A,B ; TO IOTER XCT 0 MOVE C,B ; COMP CKS ROT C,1 ADD C,(B) AOBJN B,.-2 ; COMP AWAY HRROI A,D ; GET FILES CKS XCT 0 CAME D,C ; CHECK FATAL RESTORE CHECKSUM ERROR JRST LDLP ; LOAD MORE ] IFE ITS,[ MOVE D,B ; SAVE HLRE C,B HRLI B,444400 MOVE A,0 SIN ; READ IN A BUNCH MOVE B,D ROT D,1 ADD D,(B) AOBJN B,.-2 BIN ; READ STORED CKS CAME D,B FATAL RESTORE CHECKSUM ERROR JRST LDLP ] LDDUPS: IFN ITS,[ HRROI A,(B) ; READ 1ST IN PLACE XCT 0 ] IFE ITS,[ MOVE D,B ; SAVE HDR BIN ; READ WORD OF INTEREST MOVEM B,(D) MOVE B,D ] HLRZ A,B ; # TO A HRLI B,(B) ; BUILD A BLT PONTER ADDI B,1 ADDI A,-2(B) BLT B,(A) JRST LDLP LD1: IFN ITS,[ XOR 0,[<.IOT A>#<.CLOSE>] ; CHANGE TO CLOSE XCT 0 ; AND DO IT ] IFE ITS,[ MOVE A,0 CLOSF JFCL FASTR1: MOVEI A,P-1 MOVEI B,P-1-E POP P,(A) SUBI A,1 SOJG B,.-2 ] IFN ITS,[ FASTR1: ] MOVE A,VECTOP ; REAL CORE TOP ADDI A,2000 ; ROOM FOR GC PDL MOVEM A,P.TOP MOVEM E,NOTTY ; SAVE TTY FLAG PUSHJ P,PURCLN ; IN CASE RESTORED THING HAD PURE STUFF PUSHJ P,INTINT ; USE NEW INTRRRUPTS ; NOW CYCLE THROUGH CHANNELS MOVE C,TVP ADD C,[CHNL1+2,,CHNL1+2] ; POINT TO REAL CHANNELS SLOTS PUSH TP,$TVEC PUSH TP,C PUSH P,[N.CHNS] CHNLP: SKIPN B,-1(C) ; GET CHANNEL JRST NXTCHN PUSHJ P,REOPN PUSHJ P,CHNLOS MOVE C,(TP) ; GET POINTER NXTCHN: ADD C,[2,,2] ; AND BUMP MOVEM C,(TP) SOSE (P) JRST CHNLP SKIPN C,CHNL0(TVP)+1 ; ANY PSUEDO CHANNELS JRST RDONE ; NO, JUST GO AWAY MOVSI A,TLIST ; YES, REOPEN THEM MOVEM A,(TP)-1 CHNLP1: MOVEM C,(TP) ; SAVE POINTER SKIPE B,(C)+1 ; GET CHANNEL PUSHJ P,REOPN PUSHJ P,CHNLO1 MOVE C,(TP) ; GOBBLE POINTER HRRZ C,(C) ; REST LIST OF PSUEDO CHANNELS JUMPN C,CHNLP1 RDONE: SUB TP,[2,,2] SUB P,[1,,1] PUSHJ P,TTYOPE IFN ITS,[ PUSHJ P,IPCBLS ;BLESS ALL THE IPC CHANNELS PUSHJ P,SGSNAM ; GET SNAME SKIPN A .SUSET [.RSNAM,,A] PUSHJ P,6TOCHS ; TO STRING PUSH TP,A PUSH TP,B MCALL 1,SNAME ] PUSHJ P,%RUNAM PUSHJ P,%RJNAM MOVE A,$TCHSTR MOVE B,CHQUOTE RESTORED JRST FINIS FASTR: IFN ITS,[ PUSHJ P,WRDIN ; GET CORE TOP ASH A,-10. ; TO PAGES MOVEI B,(A) ; SAVE ADDI A,1 ; ROOM FOR GC PDL PUSHJ P,P.CORE ; GET ALL CORE PUSHJ P,NOCORE ; LOSE RETURN PUSHJ P,WRDIN ; GET PARTOP ASH A,-10. ; TO PAGES MOVEI E,(A) PUSHJ P,WRDIN ; NOW GET VECBOT ASH A,-10. ; TO PAGES EXCH A,E ; AND SAVE IN E MOVNS A MOVSI A,(A) ; TO PAGE AOBJN MOVE C,A ; COPY OF POINTER MOVE 0,NOTTY ; SAVE NOTTY FLAG AROUND MOVE D,(P) ; CHANNEL DOTCAL CORBLK,[[1000,,104000],[1000,,-1],A,D,C] FATAL CORBLK ON RESTORE LOSSAGE SUBM E,B ; AOBJN LH TO E HRLI E,(B) ; AOBJN TO CORE HRLI C,(B) ; AND TO DISK DOTCAL CORBLK,[[1000,,104000],[1000,,-1],E,D,C] FATAL CORBLK ON RESTORE LOSSAGE MOVSI A,(D) ; CHANNEL BACK ASH A,5 MOVEI B,E ; WHERE TO STRAT IN FILE IOR A,[.ACCESS B] XCT A ; ACCESS TO RIGHT ACS XOR A,[<.IOT B>#<.ACCESS B>] MOVE B,[D-P-1,,E] XCT A ; GET ACS MOVE E,0 ; NO TTY FLAG BACK XOR A,[<.IOT B>#<.CLOSE>] XCT A ] IFE ITS,[ FASTR: POP P,A ; JFN TO A BIN ; CORE TOP TO B MOVE E,B ; SAVE BIN ; PARTOP MOVE D,B BIN ; VECBOT MOVE C,B BIN ; SAVED P MOVE P,B MOVE 0,NOTTY ; SAVE NOTTY FLAG AROUND HRL E,C ; SAVE VECTOP MOVSI A,(A) ; JFN TO LH MOVSI B,400000 ; FOR ME MOVSI C,120400 ; FLAGS ASH D,-9. ; PAGES TO D PMAP ADDI A,1 ADDI B,1 SOJG D,.-3 ASH E,-9. ; E==> CORTOP PAGE,,VECBOT PAGE HLR B,E ; B NOW READY MOVEI D,(E) SUBI D,(B) PMAP ADDI A,1 ADDI B,1 SOJG D,.-3 HLRZS A CLOSF FATAL CANT CLOSE RESTORE FILE MOVE E,0 ; NOTTY TO E ] MOVE A,PARTOP ; ZERO OUT NEW FREE HRLI A,(A) MOVE B,VECBOT SETZM (A) ADDI A,1 BLT A,-1(B) ; ZAP...YOU'RE ZERO JRST FASTR1 ; HERE TO GROCK FILE NAME FROM ARGS GTFNM: IFN ITS,[ PUSH TP,$TPDL PUSH TP,P IRP A,,[DSK,MUDDLE,SAVE] PUSH P,[SIXBIT /A/] TERMIN PUSHJ P,SGSNAM ; GET SNAME PUSH P,A ; SAVE SNAME JUMPGE AB,GTFNM1 PUSHJ P,RGPRS ; PARSE THESE ARGS JRST .+2 GTFNM1: AOS -4(P) ; SKIP RETURN POP P,A ; GET SNAME .SUSET [.SSNAM,,A] MOVE A,-3(P) ; GET RET ADDR HLRZS -2(P) ; FIXUP DEVICE SPEC SUB TP,[2,,2] JRST (A) ; HERE TOO OUT 1 WORD WRDOUT: PUSH P,B PUSH P,A HRROI B,(P) ; POINT AT C(A) MOVE A,-3(P) ; CHANNEL PUSHJ P,MIOT ;WRITE IT POPJB: POP P,A POP P,B POPJ P, ; HERE TO READ 1 WORD WRDIN==WRDOUT ] IFE ITS,[ PUSH P,C PUSH P,B MOVE B,IMQUOTE SNM PUSHJ P,IDVAL1 GETYP 0,A CAIN 0,TUNBOU MOVEI B,0 MOVEI A,(P) PUSH P,[377777,,377777] PUSH P,[-1,,[ASCIZ /DSK/]] PUSH P,B PUSH P,[-1,,[ASCIZ /MUDDLE/]] PUSH P,[-1,,[ASCIZ /SAVE/]] PUSH P,[0] PUSH P,[0] PUSH P,[77] ; USE AN OBSCURE JFN IF POSSIBLE MOVE B,1(AB) GTJFN JRST FNF SUB P,[9.,,9.] POP P,B OPENF JRST FNF ADD AB,[2,,2] SKIPL AB AOS (P) POPJ P, WRDIN: PUSH P,B MOVE A,-2(P) ; JFN TO A BIN MOVE A,B POP P,B POPJ P, WRDOUT: PUSH P,B MOVE B,-2(P) EXCH A,B BOUT EXCH A,B POP P,B POPJ P, ] ;REPLACE ALL OCCURANCES OF CHARACTER (B) TO CHARACTER (C) IN A HACKV: PUSH P,D PUSH P,E MOVE D,[440700,,A] MOVEI E,5 HACKV1: ILDB 0,D CAIN 0,(B) ; MATCH ? DPB C,D ; YES, CLOBBER SOJG E,HACKV1 POP P,E POP P,D POPJ P, CANTOP: PUSH TP,$TATOM PUSH TP,EQUOTE CANT-OPEN-OUTPUT-FILE JRST CALER1 FNF: PUSH TP,$TATOM PUSH TP,EQUOTE FILE-NOT-FOUND JRST CALER1 BADVRS: PUSH TP,$TATOM PUSH TP,EQUOTE MUDDLE-VERSIONS-DIFFER JRST CALER1 EXPVRS: PUSH TP,$TATOM PUSH TP,EQUOTE EXPERIMENTAL-MUDDLE-VERSION JRST CALER1 CHNLO1: MOVE C,(TP) SETZM 1(C) JRST CHNLO2 CHNLOS: MOVE C,(TP) SETZM (C)-1 CHNLO2: MOVEI B,[ASCIZ / CHANNEL-NOT-RESTORED /] JRST MSGTYP" NOCORE: PUSH P,A PUSH P,B MOVEI B,[ASCIZ / WAIT, CORE NOT YET HERE /] PUSHJ P,MSGTYP" MOVE A,(P) ; RESTORE BLOCKS NEEDED MOVEI B,1 .SLEEP B, PUSHJ P,P.CORE JRST .-4 MOVEI B,[ASCIZ / CORE ARRIVED /] PUSHJ P,MSGTYP POP P,B POP P,A POPJ P, END