;TITLE MACDMP - MAC DECTAPE UTILITY - R CLEMENTS 8 OCT 67 - V001 MODE==0 IFE MODE,TITLE MACDMP TD10 TAPE CONTROL VERSION IFN MODE,TITLE MACDMP 551/136 TAPE CONTROL VERSION NOSYMS RIM10 MEMSIZ==40000 ;16K DTC=320 DTS=324 F=0 ;MUST BE 0. USED BY JRA'S A=2 ;MISC TEMP. HOLDS 136 CONO INDEX IN UWAIT B=1 ;TEMP. HOLDS BLOCK # COMPUTATION IN SEARCH C=3 ;HOLDS BITS FOR DECTAPE CONO DURING I/O D=4 ;HOLDS POINTERS FOR AOBJN'S THROUGH CORE E=5 ;HOLDS COUNT OF WORDS IN CURRENT DT BLOCK P=6 ;PC FOR JSP'S CKS=7 ;USUALLY CHECKSUM FILN=10 ;NUMBER OF FILE IN DIRECTORY, 1 TO 27 OCTAL BLKNO=11 ;BLOCK NUMBER SEARCHED FOR ON TAPE WRITE=12 ;MULTI-STATE FLAG FOR DEFINING I/O OPERATION ;1=D 0=K -5=I -1=ELSE PNTR=13 ;POINTER TO BYTE TABLE IN DIRECTORY CH=14 ;HOLDS 6BIT CHARACTER OF COMMAND, OR -1 Q=15 ;ANOTHER JSP AC G=16 ;RARELY USED VERY TEMP DDT=MEMSIZ-4000 ;LOCATION OF HIGH DDT, MAC VERSION. COMPTR=MEMSIZ-1 ;COMMAND POINTER, IF SUPPLIED DEFINE INFORM A,B IF2,[PRINTX \A!B \] TERMIN LOC MEMSIZ-602 LOZAD=.-1 ;WHEN CORE IS CLEARED, IT ;IS FROM 40 THRU LOZAD LOW=20 ;FIRST LOCATION CONSIDERED FOR DUMPING HIGH=.-1 ;LAST LOCATION CONSIDERED FOR DUMPING FOOF: BLOCK 1 ;NEEDED FOR ZERO CORE SEARCH, ZEROED AT BEG1 TAB: BLOCK 200 ;FILE DIRECTORY TAPENO: BLOCK 1 ;TAPE UNIT SHIFTED LEFT FOR CONO ;INITIAL ENTRY IS AT BEGR, UNLESS A COMMAND POINTER IS ;SUPPLIED IN COMPTR. IN THAT CASE, ENTRY IS AT BEGR+1 BEGR: SETZM COMPTR ;CLEAR ANY JUNK IN COMMAND POINTER CONO 635550 ;I/O RESET, ETC. BEG: JSP P,CRR ;TYPE A CR-LF MOVEI D,SPNT-1 ;PREPARE TO REMOVE AOBJN POINTERS BEG1: SETZB A,FOOF ;CLEAR A TO PUT IN CORE, CLEAR ;FOOF FOR THE NEXT ZERO CORE SEARCH EXCH A,1(D) ;REMOVE HEADER LIST AOBJN A,. ;COUNT THROUGH TO NEXT HEADER TLNE A,-2 JRST .-2 MOVEI D,-1(A) ;ACCOUNT FOR OVERSHOOT IN AOBJN JUMPN D,BEG1 ;IF WE DIDNT AOBJN A 0, GO FOR NEXT HDR MOVE PNTR,[XWD 500,TAB+55] ;5 BIT BYTES IN DIRECTORY SETZB CH,F CRCH: SETOI WRITE,215 ;USED FOR CARRET TYPEOUT TYI: MOVSI B,400000 ;INIT FILE NAME TO @ @ SPACE: EXCH C,B ;COPY FIRST WORD OF NAME TO C MOVSI B,400000 ;PREPARE FOR SECOND WORD MOVSI E,20600 ;FAKE OUT END-TEST OF BYTE POINTER ;STOP TAPE DRIVE IFN MODE,CONO UTC,0 IFE MODE,CONO DTC,400000 NEXT: ILDB A,@BEGR ;GIVES A 0 UNLESS COMMAND POINTER SUPPLIED ;RH OF NEXT IS USED AS A CONSTANT JUMPN A,RCH ;JUMP IF COMMEND READ FROM CORE MOVNI FILN,1 ;INITIALIZATION FOR SEARCH MOVEI BLKNO,0 ; " CONSO TTY,40 ;TYPEIN FLAG? JRST .-1 ;NO,WAIT DATAI TTY,A ;GET TYPED IN CHARACTER JSP P,TYO ;ECHO IT (WITH PARITY) RCH: ANDI A,177 ;STRIP OFF PARITY CAIN A,177 ;RUBOUT? JRST BEGR ;YES. RESTART MACDMP CAIE A,33 ;NEW ALTMODE? CAIL A,175 ;OR 175 OR 176 ALTMODES? JRST ALTTST ;YES, SOME ALTMODE. CAIL A,140 ;LOWER CASE CHARACTER? TRZ A,40 ;YES. CHANGE TO UPPER CASE SUBI A,40 ;CONVERT TO SIXBIT JUMPL A,CARRET ;ANY CONTROL CHARACTER JUMPE A,SPACE ;CHAR WAS 40 NEXT1: TLNE E,770000 ;NO MORE THAN SIX CHARS IDPB A,E ;GOES INTO AC1 = B JRST NEXT ;GET ANOTHER CHARACTER ;HERE ON JUMP BLOCK DURING LOADS, OR NUMBER>7 ALT JBLK: CAILE CH,"M-40 ;SKIP IF SYMS NOT NEEDED JRA CH,LOAD ;F=0 C(CH)LT=0 C(F)=-1 ;STOP TAPE DRIVE IFN MODE,CONO UTC,0 IFE MODE,CONO DTC,400000 JUMPL CH,DDTG ;IF SYMS JUST READ HRRM D,SADR ;SAVE STARTING ADDRESS ;THE FOLLOWING CONDITIONAL ASSEMBLY ASSURES THAT THE ;TRZA INSTRUCTION AT THRU+2 WILL CLEAR BIT 35. IFE .&1,[ JUMPN CH,BEG ;IF NOT LOADGO COMMAND SADR: JRST BEG ;CURRENT S.A. ] IFN .&1,[SADR: JUMPE CH,BEG JRST BEG ] DDTG: HRROS DDT-1 ;TELL DDT ITS SYMBOL TABLE WAS BUGGERED JRST DDT ;AND GO TO DDT LOADS: ;HERE TO LOAD TAPE TO CORE, OR VERIFY MOVEI D,LOZAD+1 ;FIRST LOC NOT TO ZERO SETZM 40 ;A "FEATURE" MOVE C,[XWD 40,41] ;PREPARE TO CLEAR CORE. CAIN CH,"T-40 ;IF "T", DONT CLOBBER DDT SYMS OR DDT MOVE D,@DDT-1 ;GET FIRST LOC OF DDT SYMS TRNN CH,3 ;SKIP ON M,N,I NOT ON L,T,@ BLT C,-1(D) ;ZERO CORE LOAD: JSP Q,LODUMP ;START READING FILE. LODUMP PROCESSES ;ONE HEADER AND ITS DATA JSP P,UWAIT ;GET THE CHECKSUM OF THAT HEADER BLOCK CAMN CKS,D ;CHECK CHECKSUM JRST LOAD ;IF OK, GET NEXT BLOCK.(IF NONE, ;LODUMP RETURNS TO JBLK.) DELE: JUMPE C,BEG ;IF C IS ZERO, NO I/O WAS DONE. ;I.E., A "K" COMMAND SKIPN E,WRITE ;SKIP IF NOT IN THE K PHASE OF A D COMMAND. ;ALSO, SET E =0, SO SEARCH HAPPENS IN RBLK AOJA WRITE,CLSTP ; 0 TO 1. GO DUMP OUT DIRECTORY. ERR: SKIPA P,NEXT ;SET TO RETURN TO BEGR CRR: SKIPA A,CRCH ;LIKE HRROI A,215 AND SKIPA SKIPA A,FD3 ;GET A BELL CHARACTER TYO: SKIPN COMPTR ;DONT TYO IF NO TYI, UNLESS ERR DATAO TTY,A ;TYPE OUT CONSZ TTY,20 ;WAIT FOR TTY TO FINISH JRST .-1 ;NOT YET CAIE A,215 ;IF CR TYPED IN, JUMPGE A,(P) ;OR SIGN BIT OF CHAR ON,(SEE CRR) MOVEI A,12 ;APPEND A LINEFEED JRST TYO ;GO TYPE LF ALTTST: TLNN B,4040 ;IF ALPHA CHARACTERS, DONT GET CH LDB CH,E ;LAST CH BEFORE ALT, -40 JUMPN CH,ALTMD ;IF CH NOT NULL, GOT PROCESS ALTMODE CARRET: AOJE A,NEXT1 ;IGNORE A ^_ MOVSI FILN,-30 ;FILE NAME SPECIFIED. FIRST THING TO ;DO IS LOOK IT UP IN DIRECTORY LUP: AOJ FILN,DMP3A ;RH COUNTS BY 2,LH BY 1. NOTE AOBJN SKIPN TAB-1(FILN) ;SEARCH FOR FREE FILE SKIPE BLKNO,TAB(FILN) ;CHECK BOTH WORDS TDZA BLKNO,BLKNO ;ENSURE CLEAR BLOCK NMBER HRRM FILN,FREE ;SAVE NUMBER OF A FREE FILE CAMN C,TAB-1(FILN) ;SEARCH FOR TYPED-IN FILE CAME B,TAB(FILN) ;BOTH WORDS AOBJN FILN,LUP ;NOT THIS ONE. KEEP LOOKING JUMPL FILN,BEG69 ;IF FILE FOUND, JUMP JUMPLE WRITE,ERR ;IF NOT FOUND, BETTER BE DUMP FREE: MOVEI FILN,. ;DUMP & NOT FOUND, MAKE ENTRY WHERE FREE ;(ADDRESS MODIFIED ABOVE) SKIPE TAB(FILN) ;MAKE SURE HOLE AVAILABLE JRST ERR ;NO FREE SLOTS BEG69: SKIPN WRITE ;DELETE? (K COMMAND) SETZB B,C ;YES, KILL FILE MOVEM C,TAB-1(FILN) ;CLEAR IF DELE, ENTER IF NEW DUMP MOVEM B,TAB(FILN) ;BOTH WORDS MOVEI FILN,1(FILN) ;FILN IS (2*FILE #-1)+1, NOW +1 MORE LSH FILN,-1 ;FORM DIR NO 1 TO 27 JUMPLE WRITE,BEG69A ;JUMP IF NOT DUMP COMMAND ANDCAM WRITE,TAB+55(FILN) ;CLEAR MODE BIT,(WRITE)=1 IORM WRITE,TAB+104(FILN) ;SET MODE BIT BEG69A: TRNE WRITE,4 ;SKIP IF MODIFY DIRECTORY (D,K,I) SOJA F,LOADS ;ALL LOAD INSTRUCTIONS. F:=-1 ;DUMP WRITES OUT CORE ONTO TAPE ;DUMP THRU DUMP2-1 SETS UP POINTERS TO NON-ZERO CORE AREAS. THESE ;AOBJN POINTERS ARE CALLED "HEADERS", AND PRECEDE THE DATA WHEN ;THE TAPE IS WRITTEN. THE DATA BLOCKS ARE EACH FOLLOWED BY A CHECKSUM. ;THE FIRST HEADER IS KEPT IN SPNT. SUCCESIVE HEADERS GO INTO THE FIRST ;ZERO WORD FOLLOWING THE BLOCK CORRESPONDING TO THE PREVIOUS HEADER. ;AFTER THE LAST NON-ZERO BLOCK IS (BY DEFINITION) A ZERO, WHICH ;TERMINATES THE HEADER LIST. THIS WORD MAY BE LOCATION FOOF (37176) IF ;CORE WAS FILLED UP TO THE BASE OF MACDMP. DUMP: ;HERE ON D,K,I. (BLKN)=0, FILN SET UP MOVE A,[XWD LOW-HIGH,LOW] ;COUNTER TO EXAMINE ;CORE FOR BLOCKS OF 0 MOVEI CKS,SPNT ;FIRST HEADER GOES INTO SPNT DMP1: SKIPE (A) ;FIND SOME NON-ZERO CORE JRST DMP1C AOBJN A,DMP1 ;ZERO. KEEP LOOKING. TLNE A,-2 JRST DMP1 DMP1C: MOVEM A,D ;SAVE ADR DMP1B: SKIPN (A) ;FIND SOME ZERO CORE SKIPE 1(A) ;DON'T MAKE NEW BLOCK FOR 1 ZERO CAIA JRST DMP1A AOBJN A,DMP1B ;NON-ZERO. KEEP LOOKING TLNE A,-2 JRST DMP1B DMP1A: SUB D,A ;GET -COUNT IN BOTH HALVES OF D ADDI D,(A) ;GET F.A. IN RH OF D MOVEM D,(CKS) ;SAVE HEADER MOVE CKS,A ;F.A.+W.C.IS ADR OF NEXT HEADER ;I.E., FIRST 0 AFTER THE DATA TLNE A,-1 JRST DMP1 ;GET NEXT BLOCK IF MORE NON-ZERO CORE DMP2: MOVE CKS,[JRST 1] ;OUTPUT A MAGIC WORD, SIMULATING ;THE END OF THE DDT LOADER MOVEI D,SPNT ;SET UP TO FOLLOW THE HEADERS. DMP3A: JSP P,UWAIT ;START WRITING . THE POINTER IS IN ;WORD FOLLOWING THE JSP. JFCL CKS ;FIRST WORD TO LOOK LIKE END OF LOADER ;ON SUCCESSIVE LOOPS, THIS OUTPUTS THE CKSM DMP3: MOVE D,(D) ;GET HEADER JUMPGE D,THRU ;IF NULL HEADER FOUND SKIPA Q,LUP ;Q:= DMP3A AS A RETURN AFTER AOBJN LODUMP: CAMN D,[JRST 1] ;LOAD COMMANDS ENTER HERE, TOO TLO BLKNO,400000 ;JRST 1 DUMPED OR READ JSP P,UWAIT MOVE CKS,D ;IN/OUTPUT HEADER, ADD IT TO CKS JUMPGE BLKNO,LODUMP ;WAIT FOR JRST 1 ON READS. JUMPGE D,JBLK ;IF JRST BLOCK READ. CANT HAPPEN ON WRITE JUMPGE CH,DMP5 ;IF NOT LOADING SYMS HLRO P,D ADD P,D ADDB P,@DDT-1 ;COMPUTE LOAD ADR FOR SYMS AND UPDATE POINTER HRR D,P DMP5: ROT CKS,1 ;TRANSFER A DATA BLOCK JSP P,UWAIT ADD CKS,(D) ;IN/OUTPUT DATA WORD, AND CKSM IT AOBJN D,DMP5 ;COUNT DOWN THE HEADER TLNE D,-2 JRST DMP5 JRST (Q) ;END OF HEADER. TO DMP3A OR LOAD+1 ;WRITE: 1=D 0=K -5=I -1=ELSE THRU: JUMPL WRITE,BEG JSP P,UWAIT TRZA WRITE,SADR ;OUTPUT JRST BLOCK, WRITE := 0 (WAS 1), THEN ;CLEAR ANY FURTHER BLOCKS WITH THE ;CURRENT FILE NUMBER (IF REUSING AN OLD NAME) UWAIT: AOJL E,UWAIT1 ;RETURN ADDR = (P) DATA ADDR = @(P) ;E IS -WD COUNT IN BLOCK OR POSITIVE ;BYTE POINTER FIRST TIME THRU MNLUP: AOSA BLKNO ;NEXT BLOCK IN THE DIRECTORY MNLUP1: DPB B,PNTR ;FOR DELETE, 0 FILE NAME AND NUMBER ILDB A,PNTR ;SEARCH FILE DIR CAIN A,37 JRST DELE ;END OF TAB MARKER, DELE GOES TO ;CLSTP ON A "D" TO DUMP DIRECTORY TLO A,-1(WRITE) ;0 ON D, -1 ON K OR K PHASE OF D CAIE FILN,(A) ;IS THIS BLOCK ASSIGNED TO CURRENT FILE? JUMPN A,MNLUP ;OR MAYBE FREE? JUMP IF IN USE BY ;ANOTHER FILE. DPB FILN,PNTR ;SMASH AWAY WRITE BLOCK ON D OR K. BUT ;SEE MNLUP1 ON K. JUMPE WRITE,MNLUP1 ;K COMMAND ;RBLK SEARCHES FOR THE BLOCK IN BLKNO, ENTERS IT GOING FORWARD, ;AND THEN READS INTO CORE, DUMPS CORE, OR COMPARES CORE AS ;DETERMINED BY CONTENTS OF WRITE. RBLK: HRRO C,TAPENO ;CURRENT TAPE NO. ;SET LH TO PREPARE FOR JUMPN IN DELE IFE MODE,[ TRO B,-1 ;ENSURE GOING FORWARD WHEN FIRST SEARCH CONSO DTC,300000 ;IS A DIRECTION ASSERTED? TRO C,200000 ;NO. GO FORWARD RB1: TRNN B,400001 ;DECIDE WHETHER TO TURN AROUND TRO C,300000 ;TURN AROUND RBG: CONO DTC,20200(C) ;ISSUE THE COMMAND TO TD10. ;200=SEARCH, 300=READ, 700=WRITE. UWAIT1: CONSZ DTS,672700 ;ANY ERRORS? JRST ERR ;YES. GO DING AND THEN TYI CONSO DTS,1 ;DATA READY? JRST .-3 ;NO. GO WAIT SOME MORE JUMPL E,INOUT(WRITE) ;IF IN MIDST OF A DT BLOCK, DISPATCH DATAI DTC,B ;NO. SEARCHING. GET BLOCK NO. TRZ C,300000 ;CLOBBER DIRECTION BITS IN CONO SUBI B,(BLKNO) ;COMPARE WITH DESIRED BLOCK CONSZ DTC,100000 ;COMPLEMENT DECISION IF GOING REVERSE TRC B,-2 ;BIT 35 IS FOR TURNAROUND SPACE. ] IFN MODE,[ SETOB A,B ;GO FORWARD, SET DC FOR SEARCH CONSZ UTS,40 ;IS CHECKSUM BEING WRITTEN? JRST .-1 ;WAIT RB1: TRNN B,400001 ;DECIDE WHETHER TO TURN AROUND TRCA C,10000 ;CHANGE DIRECTION AND DELAY CONSO UTC,200000 ;UNIT SELECTED? TRO C,2000 ;INVOKE STARTUP DELAY RBG: CONO UTC,220200(C) ;COMMAND TO THE 551. ;200=SEARCH, 300=READ, 700=WRITE. CONO DC,4011(A) ;COMMAND TO THE 136. UWAIT1: CONSZ UTS,6 ;ANY ERRORS? JRST ERR ;YES. GO DING AND THEN TYI CONSO DC,1000 ;DATA READY? JRST .-3 ;NO. WAIT SOME MORE JUMPL E,INOUT(WRITE) ;IF IN MIDST OF A DT BLOCK, DISPATCH DATAI DC,B ;NO. SEARCHING. GET BLOCK NUMBER TRZ C,2000 ;DONT DELAY ANY MORE SUBI B,(BLKNO) ;COMPARE WITH DESIRED BLOCK TRNE C,10000 ;COMPLEMENT IF GOING REVERSE TRC B,-2 ;BIT 35 IS FOR TURNAROUND SPACE. ] JUMPN B,RB1 ;JUMP IF NOT GOING FORWARD INTO (BLKNO) MOVNI E,200 ;WORDS PER BLOCK TRO C,100 ;READ COMMAND, MAYBE JUMPLE WRITE,RBG ;JUMP IF READ TRO C,400 ;CHANGE TO WRITE COMMAND IFN MODE,MOVNI A,401 ;SET 136 TO OUTPUT JRST RBG ;AND GO PROCESS BLOCK. IFE MODE,[ DATAI DTC,G ;THIS SEQUENCE FOR VERIFY ("I") CAME G,@(P) ;CHECK WITH CORE JRST ERR ;BAD COMPARE JRST UWAIT2 ;OK DATAI DTC,@(P) ;READ COMMANDS. GET WORD TO CORE INOUT: JRST UWAIT2 ;INOUT-5 TO INOUT +1 ARE DISPATCHED TO. DATAO DTC,@(P) ;OUTPUT TO TAPE UWAIT2: AOJN E,UWAIT3 ;WAS THAT THE LAST WORD IN THE DT BLOCK? CONO DTS,1 ;YES. GIVE FUNCTION STOP TO TD10 CONSO DTS,100000 ;AND WAIT FOR CHECKSUM TO BE DONE JRST .-1 ;NOT YET. WAIT UWAIT3: SOJA E,0(P) ;DONE. COMPENSATE FOR THE AOJN ABOVE, AND ;RETURN TO CALLER OF UWAIT OR RBLK ] IFN MODE,[ DATAI DC,G ;THIS SEQUENCE FOR VERIFY ("I") CAME G,@(P) ;CHECK WITH CORE JRST ERR ;BAD COMPARE JRST UWAIT2 ;OK DATAI DC,@(P) ;READ COMMANDS. GET WORD TO CORE INOUT: JRST UWAIT2 ;INOUT-5 THRU INOUT+1 ARE DISPATCHED TO. DATAO DC,@(P) ;OUTPUT TO TAPE UWAIT2: JRST 0(P) ;RETURN TO CALLER OF UWAIT OR RBLK. ] ALTMD: MOVEI A,"$ JSP P,TYO ;ALTMODE IS PRINTED AS "$" CAIE CH,"K-40 ;FOR K, WRITE := 0 CAIN CH,"D-40 ;FOR D, WRITE :=1 AOJLE WRITE,.-1 ;COUNT (WRITE) CAIN CH,"G-40 ;GO TO PROGRAM? JRST @SADR ;YES. JUMP OUT CAIN CH,"F-40 ;FILE DIR PRINT? JRST FDIR ;YES. PRINT FILE DIR OF THIS TAPE CAIN CH,"I-40 ;CORE VS TAPE INTERROGATOR? MOVNI WRITE,5 ;WRITE :=-5 FOR "I" CAILE CH,27 ;SKIP IF OCTAL NUMBER JRST TYI ;NO. GO PROCESS FILE NAME LSH B,3 ;CONVERT SIXBIT TO OCTAL LSHC F,3 ;F+1=B JUMPN B,.-2 ;MAY BE MORE THAN 1 DIGIT (START ADR) CAILE F,7 ;SKIP IF ONE DIGIT JRA D,JBLK ;D:=SADR. DISPATCH TO JBLK WHICH SAVES SADR. OPNTP: ;SHIFT UNIT NUMBER LEFT FOR CONO IFE MODE, LSH F,11 IFN MODE,LSH F,3 MOVEM F,TAPENO ;SAVE IN CORE IFE MODE, CONO DTC,10000 ;DESELECT OLD DRIVE CLSTP: MOVEI BLKNO,100 ;BLK NO OF FILE DIR JSP P,RBLK ;MOVE TO BLOCK 100 JFCL TAB+200(E) ;READ OR WRITE DIR TAB AS DETERMINED BY WRITE AOJL E,UWAIT1 ;COUNT THE 200 WORDS JRST BEG ;GO ASK FOR NEXT COMMAND FDIR: MOVNI FILN,56 ;2*27(OCTAL) FILES. FD2: JSP P,CRR ;CR-LF FD3: AOJ FILN,207 ;USED FOR BELL TYPEOUT SKIPN C,TAB+55(FILN) ;FIRST WORD OF NAME. IS IT BLANK? AOJA C,FD1 ;YES. SET C=1 AND LOOP JSP G,SIXBP ;PRINT FIRST WORD OF FILE NAME MOVE C,TAB+56(FILN) ;SECOND WORD OF FILE NAME JSP G,SIXBP ;PRINT AND CEAR C FD1: AOJL FILN,FD2(C) ;CAN JUMP TO FD2 OR FD3. COUNT FILES. JRST BEG ;ALL FILES PRINTED OR BLANK. RETURN. SIXBP: MOVNI B,7 ;SIXBP PRINTS C(C) IN 6BIT ;AND APPENDS A SPACE ;LEAVES (C)=0 SIXBP1: MOVEI A,0 LSHC A,6 ADDI A,40 ;SIXBIT TO ASCII JSP P,TYO ;TYPE OUT CHARACTER AOJL B,SIXBP1 ;LOOP IF MORE CHARACTERS JRST 0(G) ;RETURN SPNT: 0 ;POINTER TO HEADERS IN CORE. CONSTANTS SLOP=COMPTR-17-. ;THIS MANY WORDS BEFORE RESERVED AREA ;FOR COMMAND STRINGS. INFORM ROOM AT TOP=,\ END BEGR