TITLE MUSRUN 6/10 RELOCATABLE ;LOADED WITH H10D WHICH IS ASSEMBLED WITH OFFSET IF1,.INSRT DSK:JSF;STNDRD MACROS REL0:: ;RELOCATABLE 0 ;AC DEFINITIONS FF=0 A=1 AA=2 B=3 C=4 D=5 E=6 G=10 T=14 TT=15 Q=16 P=17 ;IO CHANNELS TYIC==1 ;TYPEIN TYOC==2 ;TYPEOUT UTYIC==3 ;LOADER IN UTYOC==4 ;DUMPER OUT USRIC==6 ;PDP10 IN USROC==7 ;PDP10 OUT ;FLAG DEFINITIONS GETTY==RHF FF,1 ;ONE => GE TTY PDPO==RHF FF,2 ;ONE => PDP10 IS OPEN ARGF==RHF FF,4 ;ARGUMENT TYPED ARGCF==RHF FF,10 ;ARGUMENT COMPLETED UTYIO==RHF FF,20 ;CLOSE UTYIC ON ERROR FFFLG==RHF FF,40 ;USED BY GETFIL LAFLG==RHF FF,100 ;NO USED BUT LOOKED AT BY GETFIL MINUSF==RHF FF,200 ;MINUS SIGN TYPED RTYIF==RHF FF,400 ;AVAIL. FOR MISC. RUNF==RHF FF,1000 ;MUSRUN THINKS PDP10 IS RUNNING NUPRGF==RHF FF,2000 ;PROGRAM IN PDP10 IS NEW PROGRAM UTYOO==RHF FF,4000 ;DELETE UTYOC ON ERROR ;RANDOM LPDL==40 ;LENGTH OF PDL UTIBFL==200 ;LENGTH OF LOADER BUFFER LCMBUF==40 ;LENGTH OF TYPEIN BUFFER IODEV PI,PI ;SO TSDDT WILL TYPE IT OUT STIME==1 ;STANDARD WAIT TIME IN THIRTIETHS UTOBFL==UTIBFL&<-2> ;LENGTH OF DUMPER BUFFER (MUST BE EVEN) MOBY==0 ;FOR 16K ;MACROS DEFINE CMD CHAR,ROUT,BLURB DEF CHR,\-40,[ -REL0 ] IFSE [BLURB],CONCAT CHB,\-40,==0 IFSN [BLURB],[DEF CHB,\-40,[ [ASCIZ \BLURB\]-REL0 ]] TERMIN DEFINE TAG ADR DEF TAG,\TAGNR,[ ADR=],\.,[+OFST ] TAGNR==TAGNR+1 TERMIN TAGNR==0 IF1,[REPEAT 100,[CONCAT CHR,\.RPCNT,==0 CONCAT CHB,\.RPCNT,==0 ] ] ;TTY ROUTINES ;USE STANDARD ONES SO NOT TOO HARD TO KEEP UP WITH SYSTEMS DEFINE RTYIQM ;MACRO EXECUTED ON RUBOUT TO BEG OF BUFFER ERR HUH TERMIN .INSRT JSF;DSK:STNDRD TTY SIXTYO: JUMPE AA,CPOPJ ;TYPE OUT SIXBIT WORD IN AA MOVEI A,0 LSHC A,6 ADDI A,40 PUSHJ P,TYO JRST SIXTYO SPACE4: PUSHJ P,.+1 ;TYPE OUT FOUR SPACES SPACE2: PUSH P,CTYO ;TYPE OUT TWO SPACES SPACE: MOVEI A,40 ;TYPE OUT ONE SPACE CTYO: JRST TYO ;(CONTAINS TYO IN RIGHT HALF) CRFF: TESTF E,GETTY ;GETTY => CLEAR SCREEN OR OTHER => TYPE CRLF JRST FORMF JRST CRLF TMPLOC 41,JSR UUOH DEFINE UUOIRP A IRPS UUO,,[GET BGET PUT BPUT ACCESS CTYPE TYPE ERR] A TERMIN TERMIN UUOIRP MINUUO==77-.IRPCNT, ;GET OP CODE OF MINIMUM UUO UUOIRP UUO=_33, ;DEFINE UUO'S UUOH: 0 ;UUO PROCESSOR PUSH P,A ;SAVE A PUSH P,AA ;SAVE AA PUSH P,B ;SAVE B PUSH P,C ;SAVE C MOVEI C,-C(P) ;SET POINTER TO PUSH'ED AC'S FOR ACRLOC HRRZ B,40 ;GIVE UUO ROUTINE RH OF LOCATION 40 LDB AA,[270400,,40] ;GET AC FIELD FOR UUO PROCESSOR LDB A,[331100,,40] ;GET OP CODE CAIGE A,MINUUO ;IF TOO SMALL, ILUUO: .VALUE ;THEN COMPLAIN PUSHJ P,@UUODTB-MINUUO(A) ;CALL ROUTINE FOR INDIVIDUAL UUO JRST .+2 ;NON-SKIP RETURN POINT AOS UUOH ;ROUTINE SKIPPED, INCREMENT RETURN POINT POP P,C ;RESTORE C POP P,B ;RESTORE B POP P,AA ;RESTORE AA POP P,A ;RESTORE A JRST 2,@UUOH ;RETURN UUODTB: UUOIRP A!UUO ;DISPATCH TABLE ;MAYBE RELOCATE AA (DOESN'T WORK FOR 0) ACRLOC: CAIG AA,C ;IF .LE. MAXIMUM PUSHED AC, ADDI AA,(C) ;THEN RELOCATE TO POINT TO AC ON PDL POPJ P, ;GET THE CONTENTS OF THE AC POINTED TO BY AA INTO A GETAC: PUSHJ P,ACRLOC ;RELOCATE AA MOVE A,(AA) ;GET THE AC POPJ P, ;RELOCATE AA, HRRO IT INTO A, AND SKIP-RETURN GETACP: PUSHJ P,ACRLOC ;RELOCATE AA HRROI A,(AA) ;GET THE AOBJN POINTER TO IT JRST POPJ1 ;SKIP-RETURN ;GET AC,ADR ;GETS THE CONTENTS OF ADR (IN THE PDP10) INTO AC ;BGET AC,ADR ;GETS PDP10 CORE BLOCK STARTING AT ADR INTO BLOCK IN PDP6 SPECIFIED BY AOBJN POINTER IN AC AGET: PUSHJ P,GETACP ;GET AOBJN POINTER TO AC, SKIP OVER .+1 ABGET: PUSHJ P,GETAC ;GET AOBJN POINTER FROM AC .ACCESS USRIC,B ;SET UP POINTER TO PDP10 CORE .IOT USRIC,A ;DO THE TRANSFER POPJ P, ;PUT AC,ADR ;PUT CONTENTS OF AC INTO PDP10 LOCATION ADR ;BPUT AC,ADR ;PUT PDP6 BLOCK SPECIFIED BY AOBJN POINTER IN AC INTO PDP10 BLOCK STARTING AT ADR APUT: PUSHJ P,GETACP ;GET AOBJN POINTER TO AC, SKIP-RETURN ABPUT: PUSHJ P,GETAC ;GET THE AOBJN POINTER FROM AC .ACCESS USROC,B ;SET UP POINTER TO PDP10 CORE .IOT USROC,A ;DO THE TRANSFER POPJ P, ;ACCESS IOCH,ADR ;SAME AS OLD VERSION OF .ACCESS AACCES: DPB AA,[270400,,.+1] ;DEPOSIT IO CHANNEL .ACCESS 0,B ;DO THE ACCESS ("0," FOR MACRO FOR PHASING IN) POPJ P, ;CTYPE "CH ;TYPE OUT THE ASCII CHARACTER CH (PUSHJ TO TYO) ACTYPE: MOVE A,B ;GET CHARACTER IN A JRST TYO ;TYPE IT OUT AND RETURN ;TYPE [ASCIZ /STRING/] ;TYPE OUT "STRING" CALLING TO TYO ;ATYPE IS IN STNDRD TTY ROUTINES ;ERR [ASCIZ /STRING/] ;TYPE OUT STRING AND RETURN TO ERRET (ERROR) AERR: TMODF ZE,UTYIO ;IF UTYIC SHOULD BE CLOSED, .CLOSE UTYIC, ;THEN CLOSE IT TESTF E,UTYOO ;IF FILE OPEN ON UTYOC SHOULD BE DELETED, PUSHJ P,FLUSHO ;THEN DELETE IT PUSHJ P,ATYPE ;TYPE OUT THE TEXT STRING, LDB A,[270400,,40] ;GET AC FIELD, CAIL A,NERRS ;IF ILLEGAL AC FIELD, ILLERR: .VALUE ;THEN COMPLAIN MOVE P,[-LPDL,,PDL] ;RESTORE PDL, JRST @ERRDTB(A) ;GO TO RETURN POINT ERRDTB: ERRET ;0, NORMAL ERROR RETURN POINT NERRS==.-ERRDTB IFGE NERRS-20,[PRINTC /TOO MANY ERR DISPATCHES. /] GETFIL: HRLM A,DNAM ;MODE FOR OPEN PUSHJ P,SPACE ;TYPE OUT A SPACE SETF FFFLG ;USED TO KEEP TRACK OF FILENAME COUNT GFIL1: MOVEI C,0 ;INITIALIZE WORD MOVE B,[440600,,C] ;SET UP BP FOR INPUT GFIL2: PUSHJ P,RTYI ;GET CHARACTER IN A CAIN A,": ;IF COLON... JRST GCOL ;THEN PROCESS AS SUCH CAIN A,"; ;SIMILARLY FOR SEMICOLON JRST GSEMC CAIN A,15 ;IF CARRIAGE RETURN... MOVEI A,0 ;THEN CLEAR A CAIN A," ;IF CONTROL Q... JRST GFILCQ ;THEN GET NEXT CHARACTER AND TREAT AS NON-SYNTACTICAL CAILE A,40 ;LOGICAL SPACE? (INCLUDING CR AND, WHEN ENABLED, LA) JRST GFILC JUMPE C,GFIL5 ;IGNORE NULL FILENAMES EXCH C,FN2 ;NON-FIRST FILENAME, MOVE INTO SECOND, TMODF ZE,FFFLG MOVE C,[SIXBIT /MUSIC/] ;THIS FIRST NAME TYPED IN, CLOBBER FN1 TO "MUSIC" MOVEM C,FN1 ;MOVE SECOND TO FIRST GFIL5: JUMPN A,GFIL1 ;A=0 IF CHARACTER=CR OR ENABLED LA POPJ P, ;DONE GCOL: JUMPE C,GFIL1 ;IF HE WANTS THE NULL DEVICE HE GETS TO TYPE IT IN HLRM C,DNAM ;MOVE TO RH OF DEVICE LOCATION JRST GFIL1 ;LOOP GSEMC: JUMPE C,GFIL1 ;NO NULL SYSTEM NAMES PLEASE MOVEM C,SNAM ;MOVE TO SYSTEM NAME LOCATION JRST GFIL1 ;LOOP GFILCQ: PUSHJ P,RTYI ;CONTROL Q EATS UP THE NEXT CHARACTER GFILC: SUBI A,40 ;CONVERT CHARACTER TO SIXBIT TLNE B,770000 ;TOO MANY CHARACTERS? IDPB A,B ;NO JRST GFIL2 ;LOOP ;FFFLG USED TO SORT OUT FILENAMES DNAM: (SIXBIT /DSK/) ;ROUTINE OUTPUTS HERE FN1: SIXBIT /@/ FN2: SIXBIT /@/ SNAM: SIXBIT /PDP10/ ;SYSTEM NAME BEG: MOVEI FF,0 ;INITIALIZE FLAGS MOVE P,[-LPDL,,PDL] PUSHJ P,TYINIT ;INITIALIZE TTY PUSHJ P,CRFF ;TYPE CRLF OR CRFF TYPE [ASCIZ /MUSRUN./] MOVE AA,[.FNAM2] PUSHJ P,SIXTYO .SUSET [.SSNAM,,[SIXBIT /PDP10/]] PUSHJ P,10INIT ;MUST BE LAST IN INITIALIZATION DUE TO POSSIBILITY OF FAILURE GCMD1: PUSHJ P,CRRR ERRET: CLEARF ARGF\ARGCF\MINUSF\RTYIF SETZM OVAL SETZM DVAL SETZM VALUE SETZM RTYIP ;COMMAND POINTER FOR TYPEIN WITH RUBOUT GCMD: PUSHJ P,TYI CAIL A,40 CAILE A,140 JRST N6B ;NOT SIXBIT MOVEI T,-40(A) IDIVI T,3 LDB T,DTBP(TT) JUMPE T,ERRET ;IF NOT COMMAND THEN CLEAR STATUS OF ARG, BUT OTHERWISE IGNORE PUSHJ P,REL0(T) JRST GCMD1 ;ROUTINE DIDN'T SKIP, REINITIALIZE ARGUMENTS JRST GCMD ;ROUTINE SKIPPED, DON'T REINITIALIZE JRST ERRET ;ROUTINE SKIPPED TWICE, REINITIALIZE BUT DON'T TYPE CRRR N6B: CAIN A,177 ;IF RUBOUT, ERR HUH ;THEN RESET COMMAND STATUS ;INSERT NON-SIXBIT COMMANDS HERE JRST ERRET ;REINITIALIZE ARGUMENT STATUS, OTHERWISE IGNORE CMD "?,QUEST,LIST COMMANDS QUEST: MOVE B,[441400,,BTB] MOVEI T,40 PUSHJ P,CRFF QUESTL: ILDB AA,B CAIN AA,7777 ;DONE? POPJ P, ;YES JUMPE AA,QUSTL2 ;NO, BUT JUMP IF INACTIVE CHARACTER MOVE A,T ;GET CHARACTER IN A FOR TYPEOUT PUSHJ P,TYO ;TYPE OUT THE CHARACTER PUSHJ P,SPACE4 ;TYPE 4 SPACES TYPE REL0(AA) ;TYPE THE BLURB PUSHJ P,CRLF ;NEW LINE QUSTL2: AOJA T,QUESTL ;GET THE CURRENT VALUE INTO A AND SKIP, OR DON'T SKIP IF NO VALUE ARGET: TESTF N,MINUSF ;IF MINUS NOT TYPED, SKIPA A,VALUE ;THEN RETURN VALUE MOVN A,VALUE ;RETURN NEGATIVE OF VALUE TESTF E,ARGF POPJ1: AOS (P) ;ARGUMENT EXISTS CPOPJ: POPJ P, ;NUMBERS REPEAT 10.,CMD "0+.RPCNT,NUM NUM: TESTF E,ARGCF ERR HUH ;ERROR IF CURRENT VALUE COMPLETED SUBI A,"0 ;CONVERT CHARACTER TO DIGIT MOVEI AA,10 ;UPDATE OCTAL VALUE IMULM AA,OVAL ADDM A,OVAL MOVEI AA,10. ;UPDATE DECIMAL VALUE IMULM AA,DVAL ADDM A,DVAL MOVE AA,CRADIX ;UPDATE VALUE IN CURRENT RADIX IMULM AA,VALUE ADDM A,VALUE SETF ARGF JRST POPJ1 ;SKIP-RETURN SO NOT TO KILL CURRENT VALUE CMD ".,PT,FORCE CURRENT VALUE TO DECIMAL CMD "',SQUOT,FORCE CURRENT VALUE TO OCTAL PT: SKIPA A,DVAL SQUOT: MOVE A,OVAL TMODF ZE,ARGF ;BARF IF NO ARGUMENT VALRET: TMODF OE,ARGF ;ENTRY TO RETURN VALUE IN A, BARF IF ARGUMENT ERR HUH TMODF OE,ARGCF ;BARF IF CURRENT VALUE COMPLETE ERR HUH ;ERROR IF NO CURRENT VALUE OR CURRENT VALUE COMPLETED MOVEM A,VALUE JRST POPJ1 OVAL: 0 ;CURRENT VALUE, UPDATED IN OCTAL DVAL: 0 ;CURRENT VALUE, UPDATED IN DECIMAL VALUE: 0 ;CURRENT VALUE, UPDATED IN CURRENT RADIX, OR FINAL CRADIX: 8 ;CURRENT RADIX RCHAR: "' ;CHARACTER TO DOCUMENT RADIX ON TYPEOUT CMD "R,RDXSEL,SELECT DEFAULT RADIX RDXSEL: PUSHJ P,ARGET ;GET ARGUMENT IN A ERR HUH ;NO ARGUMENT SPECIFIED MOVEM A,CRADIX MOVEI B,40 CAIN A,8 MOVEI B,"' CAIN A,10. MOVEI B,". MOVEM B,RCHAR POPJ P, CMD "=,EQLS,PRINT OUT VALUE IN CURRENT RADIX EQLS: PUSHJ P,ARGET ERR HUH RTYO: PUSHJ P,RDXTYO MOVE A,RCHAR JRST TYO RDXTYO: IDIV A,CRADIX JUMPE A,RDXTY2 HRLM AA,(P) PUSHJ P,RDXTYO HLRZ AA,(P) RDXTY2: MOVEI A,60(AA) JRST TYO CMD "-,MINUS MINUS: TESTF E,ARGF ;IF ARGUMENT, ERR HUH ;THEN COMPLAIN SETF MINUSF ;SET FLAG, JRST POPJ1 ;RETURN DK: TESTF E,ARGCF ;"K" WITHOUT ARGUMENT, MULTIPLY THE WORLD BY 1000, ERR HUH ;UNLESS ARGUMENT COMPLETED MOVEI A,1000 IMULM A,OVAL MOVEI A,1000. IMULM A,DVAL MOVE A,CRADIX REPEAT 3,IMULM A,VALUE JRST POPJ1 CMD "Q,WIPOUT,VALRET AN ALTX. REQUIRES . WIPOUT: PUSHJ P,LOSSNP ;LOSE IF USER TYPES OTHER THAN A . .VALUE [ASCIZ /./] POPJ P, CMD "X,RETTY,RETURN TTY TO DDT RETTY: PUSHJ P,PDPCLS ;GIVE UP PDP10 WHENEVER GIVING UP TTY .VALUE [0] JRST 10INIT ;TRY TO OPEN THE PDP10 UP AGAIN LOSSNP: PUSHJ P,TYI ;LOSE IF NEXT CHARACTER IS NOT A PERIOD CAIE A,". ERR HUH POPJ P, CMD "O,10INIT,OPEN THE PDP10 FOR MUNGING 10INIT: TESTF E,ARGF ;IF ARGUMENT, JRST TYPSET ;THEN SET NUPRGF FROM BOTTOM BIT .SUSET [.RUNAM,,UNAME] MOVEI A,6 ;BLOCK IMAGE INPUT HRLM A,PDPNAM .OPEN USRIC,PDPNAM ;OPEN IT FOR INPUT ERR [ASCIZ / PDP10 NOT AVAILABLE. /] MOVEI A,7 HRLM A,PDPNAM .OPEN USROC,PDPNAM ERR [ASCIZ / PDP10 NOT AVAILABLE FOR OUTPUT. /] SETF PDPO POPJ P, CMD "C,PDPCLS,CLOSE THE PDP10 PDPCLS: .CLOSE USRIC, .CLOSE USROC, CLEARF PDPO POPJ P, CMD "E,STADR,HAS VALUE OF STARTING ADDRESS STADR: SKIPN GOINST ;IF NO STARTING ADDRESS, ERR [ASCIZ / NO CURRENT STARTING ADDRESS. /] HRRZ A,GOINST ;GET IT JRST VALRET TYPSET: PUSHJ P,ARGET ;ARG SPECIFIED TO O, GET IT .VALUE ;SHOULDN'T HAPPEN DPB A,[FLGBP NUPRGF,] ;DEPOSIT IN NUPRGF POPJ P, CMD "L,LOAD,LOAD FROM SPECIFIED FILE LOAD: PUSHJ P,LOSSNO ;LOSS IF PDP10 NOT OPEN PUSHJ P,ARGET ;GET ARGUMENT (INTERPRETED AS MASK), MOVNI A,1 ;OR USE -1 IF NONE MOVE E,A ;SAVE AS MASK FOR LOAD SETZM SNAM ;DEFAULT SYSTEM NAME IS CURRENT ONE MOVEI A,6 ;MODE FOR OPEN PUSHJ P,GETFIL ;READ FILE DESCRIPTION SKIPE SNAM ;IF SYSTEM NAME SPECIFIED, .SUSET [.SSNAM,,SNAM] ;THEN USE IT .OPEN UTYIC,DNAM ;OPEN THE FILE ERR [ASCIZ /FNF? /] ;NOT FOUND? SETF UTYIO ;TELL ERR TO CLOSE FILE IF OPEN MOVEI AA,41 ;FOR CAIX'S SETZM 10SV41 ;DEFAULT C(41) SETOM 41SW ;INDICATE MUSRUN HAS THE REAL 41 TRNE E,2 ;IF 1.2 BIT OF LOAD MASK SET, PUSHJ P,PDPRS ;THEN CLEAR CORE PUSHJ P,GWD ;GET A WORD CAME A,[JRST 1] ;IF NOT END OF LOADER, JRST .-2 ;THEN WAIT SOME MORE PUSHJ P,GWD ;GET HEADER HRRZ C,A ;GET RH (PRESUMABLE NOT NULL PROGRAM) MOVNI G,1 ;WILL NOT MATCH ANY CAIG CLEARF NUPRGF ;INITIALLY ASSUME OLD PROGRAM CAIN C,2000 ;IF IT WANTS TO LOAD INTO 2000 FIRST, PUSHJ P,LDNUP ;THEN NEW PROGRAM, USE THE ONE ALREADY IN CORE JRST LOAD3 ;LOAD DATA AND MAYBE PROGRAM LOAD1: PUSHJ P,GWD ;GET A WORD LOAD3: JUMPGE A,LDJBLK ;IF POSITIVE THEN JUMP BLOCK CAILE G,(A) ;IF NEW PROGRAM AND LOADING BELOW DATA, SETF RTYIF ;THEN SUPRESS FURTHER LOADING INTO CORE MOVE C,A MOVE D,A LOAD2: CAMGE A,[-UTIBFL,,0] ;IF BIGGER THAN BUFFER, HRLI A,-UTIBFL ;THEN USE BUFFER LENGTH HRRI A,UTIBUF ;MAKE IT POINT TO THE BUFFER PUSHJ P,LODRED ;READ IN A BLOCK TESTF E,RTYIF ;IF NOT LOADING, JRST LOAD4 ;THEN DON'T LOAD ADDI B,(D) ;C(B)+UTIBUF=1+LAST LOCATION IN BLOCK CAIL AA,(D) ;IF 41 LOWER THAN FIRST WORD IN BLOCK, CAIG B,UTIBUF+41 ;OR 1+LAST LOCATION IN BLOCK <= 41, JRST NOLD41 ;THEN DON'T LOAD 41 MOVEI TT,41 ;LOAD INTO 41 SUBI TT,(D) ;MAKE TT POINT TO RELEVANT WORD IN BLOCK MOVEI T,0 ;WORD TO BE SUBSTITUTED EXCH T,UTIBUF(TT) ;SUBSTITUTE AND SAVE ORIGINAL MOVEM T,10SV41 ;SAVE FOR STARTING IT UP ;DROPS THROUGH ;(CODING DROPS THROUGH FROM PREVIOUS PAGE) NOLD41: TESTF N,NUPRGF ;IF NOT LOADING DATA FOR NEW PROGRAM, ACCESS USROC,(D) ;THEN SET UP POINTER TO PDP10 CORE MOVE T,A ;GET BUFFER POINTER AGAIN .IOT USROC,T ;LOAD INTO PDP10 CORE LOAD4: HLRS A ; -NUMBER OF WORDS PROCESSED HRLI A,-1(A) ;C(A):=<-# PROCESSED-1,,-# PROCESSED> = -<# PROCESSED,,# PROCESSED> SUBB D,A ;D HAD ORIGINAL AOBJN POINTER, ANSWER=NEW AOBJN POINTER JUMPL A,LOAD2 ;JUMP IF MORE BUFFERINGS IN THIS BLOCK PUSHJ P,GWD ;GET FILE'S VERSION OF CHECKSUM CAME A,C ;IF NOT EQUAL TO CALCULATED ONE, ERR [ASCIZ /CHECKSUM ERROR. /] ;THEN COMPLAIN JRST LOAD1 ;GO GET ANOTHER BLOCK ;FILE HAS NEW PROGRAM, LOAD THE ONE ALREADY IN PDP6 CORE INSTEAD LDNUP: MOVEI G,2000 ;FOR CAIG TO SEE IF FILE HEADER WANTS TO LOAD PROGRAM RATHER THAN DATA SETF NUPRGF ;DOCUMENT NEW PROGRAM BEING LOADED MOVE T,[JRST RDI"] ;STARTING INSTRUCTION FOR PROGRAM MOVEM T,GOINST ;SAVE AS STARTING INSTRUCTION MOVEM T,10SV41 ;ALSO SAVE AS CONTENTS OF LOCATION 41 ACCESS USROC,MUST" ;SET UP POINTER TO PDP10 CORE FOR LOADING DATA POPJ P, ;RETURN ;JUMP BLOCK ENCOUNTERED DURING LOAD LDJBLK: TESTF E,NUPRGF ;IF NEW PROGRAM, JRST NUJBLK ;THEN STILL HAVE TO LOAD PROGRAM .CLOSE UTYIC, ;CLOSE INPUT FILE MOVEM A,GOINST ;SAVE AS STARTING INSTRUCTION MBST: TRNE E,1 ;BIT 1.1 OF MASK, JRST STNOAR ;TO START UP WHEN LOADED POPJ P, ;OTHERWISE JUST RETURN ;JUMP BLOCK OR EQUIVALENT ENCOUNTERED WHILE READING DATA FOR NEW PROGRAM NUJBLK: .CLOSE UTYIC, ;CLOSE INPUT FILE MOVE T,[LODBEG"-LODEND",,LODBEG] ;GET AOBJN POINTER TO PROGRAM IN CORE BPUT T,100 ;LOAD PROGRAM INTO PDP10 TLC A,(JFCL) TLNN A,-1 ;IF JUMP BLOCK JFCL, PUT A,TMPO ;THEN SET INITIAL TEMPO JRST MBST ;MAYBE START IT UP GWD: HRROI T,A ;GET A WORD IN A GBLK: .IOT UTYIC,T ;ENTRY TO INPUT A BLOCK JUMPGE T,CPOPJ ;IF ENTIRE BLOCK WAS TRANSFERED THEN RETURN ERR [ASCIZ /EOF? /] ;END OF FILE ENCOUNTERED LODRED: MOVE T,A ;READ IN A BLOCK IN SBLK FORMAT PUSHJ P,GBLK ;GET THE BLOCK MOVE B,A ;SO NOT TO MUNG A CCKS: ;ENTRY FROM DUMPER TO CALCULATE CHECKSUM LODRD1: ROT C,1 ;CHECKSUM IN C, UPDATE IT ADD C,(B) ;" " " AOBJN B,LODRD1 ;DO IT FOR THE ENTIRE BLOCK POPJ P, ;RETURN WITH CALCULATED CHECKSUM IN C CMD "Z,ZEROC,[CLEAR CORE, REQUIRES PERIOD] ZEROC: PUSHJ P,LOSSNO ;LOSS IF PDP10 NOT OPEN PUSHJ P,LOSSNP ;LOSE IF NEXT CHARACTER NOT PERIOD. PDPRS: .RESET USROC, ;WIPE IT OUT CLEARF RUNF\NUPRGF ;DOCUMENT FACT THAT IT'S NOT "RUNNING" POPJ P, ;ROUTINE TO GENERATE ERROR IF PDP10 NOT OPEN LOSSNO: TESTF N,PDPO ERR [ASCIZ / PDP10 NOT OPEN. /] POPJ P, CMD "G,START,START UP PDP10 START: PUSHJ P,LOSSNO ;LOSE IF PDP10 NOT OPEN PUSHJ P,ARGET ;GET ARGUMENT IF ANY JRST STNOAR ;NO ARGUMENT HRLI A,(JRST) ;TURN INTO JRST MOVE B,GOINST ;GET OLD STARTADR IF ANY MOVEM A,GOINST ;SET NEW ONE TEMPORARILY PUSHJ P,START1 ;START IT UP MOVEM B,GOINST ;RESTORE OLD STARTING ADDRESS POPJ P, ;RETURN STNOAR: SKIPN GOINST ;IF NO CURRENT STARTING ADDRESS, ERR [ASCIZ / NO STARTING ADDRESS. /] START1: AOSN 41SW ;IF FILE JUST LOADED (PDP10 LOC 41 TO BE IGNORED) JRST START2 ;THEN SKIP FOLLOWING CODING GET T,41 ;GET PDP10'S 41 MOVEM T,10SV41 ;SAVE IT START2: PUSHJ P,STARTR ;ACTUALLY START IT UP (IF IT'S RUNNING) MOVEI Q,STIME ;STANDARD SLEEP TIME .SLEEP Q, ;WAIT GET A,DUNSW AOJE A,STRFJ ;IF DUNSW WAS SET THEN RETURN CLEARF RUNF ;NOT RUNNING, INDICATE "FACT" MOVE T,10SV41 ;RETRIEVE SAVED C(41) PUT T,41 ;PUT IT WHERE IT BELONGS RNNG: TYPE [ASCIZ / RUNNING?/] POPJ P, STARTR: MOVE A,[GOBEG-GOEND,,GOBEG] BPUT A,10GO ;DEPOSIT STARTING ROUTINE MOVE A,[JRST 10GO] ;INSTRUCTION TO START UP START ROUTINE PUT A,41 ;PUT IT IN 41 POPJ P, CMD "S,PSTOP,STOP PLAYING PSTOP: PUSHJ P,LOSSNO ;LOSS IF NOT OPEN TESTF N,NUPRGF ;IF OLD PROGRAM, JRST OPSTOP ;THEN HAVE TO GIVE IT COMMAND MOVNI T,1 ;PREPARE TO STOP NEW PROGRAM PUT T,H10CMD ;MUSIC PROGRAM PUTS EXECUTION LOCATION IN H10CMD WHEN STOPPED FROM PLAYING, ;POSSIBILITY THAT IT WON'T BE PLAYING WHEN STOPPED MOVE T,[QUITB"-QUITE",,QUITC"] ;GET AOBJN POINTER TO QUIT AREA IN CORE BPUT T,QUITB ;CLOBBER PDP10 WITH QUIT ROUTINE MOVEI T,STIME .SLEEP T, GET A,CMDQ" CAME A,[JFCL] TYPE [ASCIZ / RUNNING?/] GET T,H10CMD ;GET "PC" WHERE PLAYING MOVEM T,MPC ;SAVE FOR REFERENCE WITH B AND K COMMANDS POPJ P, OPSTOP: JSP Q,XCTCMD ;OLD PROGRAM, STOP WITH COMMAND SETZ WAIT" ;RH PRESUMABLY NOT USED, BUT... SETZ WAIT ;HAVE THE MUSIC PROGRAM EXECUTE A COMMAND ;CALLED AS FOLLOWS: ; JSP Q,XCTCMD ; DATA SWITCHES,,DISPATCH ;IF NO ARGUMENT ; DATA SWITCHES,,DISPATCH ;IF ARGUMENT XCTCMD: PUSHJ P,LOSSNO ;ENTRY FROM OTHER ROUTINES TO MAKE 10 EXECUTE A COMMAND PUSHJ P,ARGET ;IF NO ARGUMENT, XCMD1: SOJ Q, ;THEN DECREMENT PLACE TO GET COMMAND FROM SKIPN TT,1(Q) ;GET COMMAND IN AA, IF ZERO THEN COMPLAIN. ERR [ASCIZ / ARGUMENT? /] TESTF E,NUPRGF ;IF NEW PROGRAM, JRST NUPRGC ;THEN DO IT RIGHT HLL A,1(Q) ;GET PSEUDO-DATA SWITCHES MOVEM A,10CMD ;SET UP COMMAND MOVE A,[XCTBEG-XCTEND,,XCTBEG] BPUT A,XCTLOC MOVEI A,STIME .SLEEP A, GET A,10SW JUMPGE A,STRFJ ;IF SWITCH AOS'ED THEN EVERYTHING OK TESTF N,RUNF ;IF RUN FLAG NOT SET, JRST RNNG ;THEN SAY "RUNNING?" TYPE [ASCIZ / OLDPRG?/] POPJ P, STRFJ: SETF RUNF POPJ P, ;HAVE THE NEW PROGRAM EXECUTE A COMMAND NUPRGW: MOVEI T,7 ;LOOP POINT, PROGRAM NOT READY, WAIT 1/4 SECOND AND CHECK AGAIN .SLEEP T, .LISTEN T, ;BUT IF CHARACTER TYPED AT CONSOLE, JUMPN T,[ERR] ;THEN RETURN ON NO-TYPEOUT ERROR CONDITION ;ENTRY POINT NUPRGC: GET T,H10CMD+1 ;GET CURRENT CONTENTS OF COMMAND LOCATION CAME T,[JFCL 1] ;IF NOT CLOBBERED TO JFCL 1, JRST NUPRGW ;THEN WAIT FOR SAME (READY FOR COMMAND) HRLI TT,(JRST) ;TURN DISPATCH INTO INSTRUCTION MOVE T,A ;GET ARGUMENT TO PDP10 IN T MOVE A,[-2,,T] BPUT A,H10CMD" ;PUT T AND TT INTO PDP10 COMMAND AREA POPJ P, CMD "K,KWIT,SAME AS SB= KWIT: TESTF E,ARGF ;IF ARGUMENT, JRST DK ;THEN A THOUSAND PUSHJ P,LOPGNO ;LOSS IF OLD PROGRAM OR OF PDP10 NOT OPEN PUSHJ P,PSTOP ;STOP PLAYING PUSHJ P,BMPC1 ;GET LOCATION (SEVERAL ERROR EXITS) PUSHJ P,SPACE2 ;TYPE TWO SPACES JRST RTYO ;TYPE OUT IN CURRENT RADIX AND RETURN CMD "B,BMPC,HAS VALUE OF PLACE LAST STOPPED BMPC: PUSHJ P,BMPC1 ;GET LOCATION JRST VALRET ;RETURN IT BMPC1: PUSHJ P,LOPGNO ;LOSS IF OLD PROGRAM OR PDP10 NOT OPEN SKIPGE A,MPC ;GET LOCATION, SKIP IF VALID ERR [ASCIZ / WASN'T PLAYING. /] LSH A,-1 ;MAKE IT NOT NECESSARILY EVEN POPJ P, ;RETURN IT ;ROUTINE TO CAUSE ERROR IF OLD PROGRAM OR PDP10 NOT OPEN LOPGNO: TESTF N,NUPRGF ERR [ASCIZ / OLD PROGRAM. /] JRST LOSSNO ;IT MET THE FIRST TEST, NOW TRY THE SECOND CMD "J,RESUME,PLAY FROM SPECIFIED PLACE OR CONTINUE RESUME: PUSHJ P,LOPGNO PUSHJ P,ARGET ;GET ARGUMENT JRST RESUM1 ;USE DEFAULT LSH A,1 ;SHIFT TO GUARANTEE EVEN-NESS ANDI A,37777 ;MAKE SURE IT'S IN CORE RESUM2: JSP Q,XCMD1 ;DO IT PLAYSL" ;PLAY FROM SELECTED LOCATION PLAYSL RESUM1: SKIPGE A,MPC ;NO ARG SPECIFIED, TRY TO PROCEDE ERR [ASCIZ / WHERE FROM? /] JRST RESUM2 CMD "T,STMPO,TEMPO (SET IT OR HAS VALUE OF) STMPO: PUSHJ P,LOPGNO ;LOSS IF OLD PROGRAM OR PDP10 NOT OPEN PUSHJ P,ARGET ;GET ARG JRST STMP1 ;NO ARGUMENT, RETURN VALUE ANDI A,377777 ;AND TO SAME AS MUSIC PROGRAM DOES CAIGE A,100 ;DO TEST DONE BY MUSIC PROGRAM ERR [ASCIZ / BAD TEMPO. /] PUT A,TMPO" POPJ P, STMP1: GET A,TMPO" ;ARG NOT SPECIFIED BY T COMMAND, RETURN VALUE OF TEMPO JRST VALRET CMD "P,GOPLAY,START PLAYING (TEMPO MAY BE SPECIFIED) GOPLAY: JSP Q,XCTCMD MOVE PLAYNT" 200001,,PLAYST" CMD "A,ADJUST,ADJUST TO MACHINE SPEED OR SET PITCH ADJUST: JSP Q,XCTCMD 10000,,ADJST" 100000,,TUNE" CMD "Y,YUMP,DUMP CORE ONTO SPECIFIED FILE YUMP: PUSHJ P,LOSSNO ;LOSS IF NOT OPEN MOVEI A,MUST ;WHERE TO START DUMPING FROM IF NEW PROGRAM MOVEM A,MSTLOC ;SAVE AS SUCH GET A,TMPO ;GET TEMPO ASSUMING NEW PROGRAM MOVEM A,TMPSAV ;SAVE IT FOR JFCL BLOCK DUMPED OUT AT END TESTF N,NUPRGF ;IF NOT NEW PROGRAM, PUSHJ P,MFIND ;THEN FIND THE REAL "MUST" AND TEMPO SETZM SNAM ;DEFAULT SYSTEM NAME IS CURRENT ONE MOVEI A,7 ;MODE FOR OPEN PUSHJ P,GETFIL ;GET FILE DESCRIPTION SKIPE SNAM ;IF SYSTEM NAME SPECIFIED .SUSET [.SSNAM,,SNAM] ;THEN SET IT .OPEN UTYOC,DNAM ;NOW TRY TO OPEN OUTPUT FILE ERR [ASCIZ /BAD DEVICE NAME? /] SETF UTYOO ;ERR ROUTINE TO DELETE FILE MOVE T,[-1,,[JRST 1]] .IOT UTYOC,T ;OUTPUT A JRST 1 MOVE D,MSTLOC ;GET LOCATION OF DATA AREA ;DATA AREA CONSISTS OF PAIRS OF WORDS TO BE DUMPED OUT IN SBLK FORMAT ;IF FIRST WORD OF A PAIR IS ZERO THEN END OF DATA ACCESS USRIC,(D) ;SET UP POINTER TO USER CORE MOVEI D,2000 ;PRETEND THE DATA STARTS AT 2000, KEY TO IT BEING "NEW PROGRAM" YUMP1: MOVE T,[-UTOBFL+2,,UTOBUF+1] .IOT USRIC,T ;READ INTO OTHER THAN FIRST AND LAST WORDS OF BUFFER MOVE B,[-UTOBFL+2,,UTOBUF+1] ;SET UP AOBJN POINTER FOR ZERO SEARCH YUMP2: SUB D,[2,,0] ;UPDATE LH OF WHAT WILL BE ALL AOBJN POINTERS ;NOTE THIS DUMPS OUT THE ZEROS FINALLY FOUND ;THIS FOR THE BENEFIT OF PRS PROGRAMS WHICH USE IT AS EOF INDICATION SKIPN (B) ;IF FIRST WORD OF PAIR IS ZERO, JRST YUMP3 ;THEN DONE, OUTPUT REMAINDER OF BUFFER THEN JFCL BLOCK AOBJN B,.+2 ;UPDATE POINTER ERR [ASCIZ /INTERNAL ERROR. /] AOBJN B,YUMP2 ;DO IT FOR THE ENTIRE BUFFER YUMP3: JUMPGE D,YJBLK ;IF D POSITIVE THEN ZERO WORD BLOCK MOVE C,D ;INITIALIZE CHECKSUM AS HEADER MOVE B,C ;LH OF AOBJN POINTER TO BUFFER, HRRI B,UTOBUF+1 ;RH OF " MOVEM D,UTOBUF ;SAVE HEADER FOR OUTPUT PUSHJ P,CCKS ;CALCULATE CHECKSUM (UPDATES B) MOVEM C,(B) ;STORE CHECKSUM AT NEXT LOCATION IN BUFFER HLLZ T,D ;GET - # DATA WORDS IN BLOCK ADD T,[-2,,UTOBUF] ;INCREMENT COUNT (DECREMENT) BY 2, RELOCATE RH TO POINT TO BUFFER .IOT UTYOC,T ;OUTPUT BUFFER CAIGE T,UTOBUF+UTOBFL ;IF LESS THAN THE ENTIRE BUFFER WAS OUTPUT, JRST YJBLK ;THEN DONE OUTPUTTING DATA MOVEI D,UTOBFL-2(D) ;INCREMENT TO NEXT BLOCK JRST YUMP1 ;DUMP NEXT BLOCK ;END OF DATA WHILE DUMPING YJBLK: MOVE A,TMPSAV ;GET SAVED TEMPO HRLI A,(JFCL) ;TURN INTO JFCL ;JFCL BLOCK => SET TEMPO FROM RH MOVE T,[-1,,A] .IOT UTYOC,T ;OUTPUT THE JFCL BLOCK .CLOSE UTYOC, ;FILE THE OUTPUT CLEARF UTYOO ;ERR NEED WORRY ABOUT OUTPUT NO LONGER POPJ P, ;DONE ;TRY TO GET THE FILE OPEN FOR WRITING DELETED FLUSHO: .GENSYM A, ;GET A UNIQUE SYMBOL MOVEM A,FLDBLK+3 ;SET FIRST FILENAME FOR RENAME ATTEMPT MOVEI A,UTYOC ;OUTPUT CHANNEL HRRZM A,FLDBLK+2 ;CHANNEL ON WHICH OPEN... SETZM FLDBLK+1 ;WHEN FN11 ZERO, FOR RENAME WHILE OPEN FOR WRITING .FDELE FLDBLK ;TRY TO RENAME IT JFCL ;DON'T CARE IF IT WORKS .CLOSE UTYOC, ;MAYBE RENAMED, NOW FILE IT MOVE A,DNAM ;GET DEVICE NAME ON WHICH OPENED MOVEM A,FLDBLK+2 ;SET DEVICE NAME FOR DELETE SETZM FLDBLK+5 ;INDICATE DELETE .FDELE FLDBLK+2 ;TRY TO DELETE IT JFCL ;DON'T OBJECT IF IT LOSES CLEARF UTYOO ;ERR ROUTINE NEED NO LONGER WORRY ABOUT IT POPJ P, ;DONE, RETURN FLDBLK=.-1 ;FIRST WORD OF "RENAME WHILE OPEN FOR WRITING" BLOCK IGNORED 0 ;ALWAYS 0, TELLS SYSTEM THIS RENAME WHILE OPEN FOR WRITING UTYOC ;CHANNEL ON WHICH OPEN (RENAME) OR DEVICE NAME FOR DELETE 0 ;GEN'D-SYM (FN1) SIXBIT /FOOBAZ/ ;FN2 0 ;FOR DELETE ;MUSIC PROGRAM IN CORE IS OF UNKNOWN TYPE, FIND DATA AREA AND TEMPO MFIND: MOVEI B,100 ;PLACE TO START LOOKING MOVEI D,MFIND2 ;PLACE TO GO IF CORE EXHAUSTED DURING SEARCH JSP Q,FIND ;STARTING FROM 100, LOOK... -1,, ;FOR A WORD, THE LEFT HALF OF WHICH... DATAI ;IS A DATAI DPB A,[270400,,MFNDA] ;SAVE THE DATAI DESTINATION AS THE AC FIELD FOR NEXT SEARCH JSP Q,FIND ;STARTING FROM WHERE IT LEFT OFF, LOOK FOR A WORD... -1#(66000) ;NOT LOOKING AT THE MODIFICATION AND CONDITION FIELDS OF THE TEST INSTRUCTION... MFNDA: TLNE 200000 ;WHICH LOOKS AT THE PROPER DATA SWITCH FOR PLAYING HRRZ B,UTOBUF+1(C) ;GET THE RIGHT HALF OF THE NEXT WORD (SHOULD BE A JUMP, SHOULD ALSO BE IN BUFFER) JSP Q,FIND ;STARTING FROM THERE, FIND THE TEMPO INSTRUCTION (IDIVI 15,) -1,, ;LOOK ONLY AT THE LEFT HALF IDIVI 15, ;ALL KNOWN MUSIC PROGRAMS USE AC 15 TLZ A,-1 ;TEMPO IN RH OF A MULI A,122700 ;UPDATE WITH APPROPRIATE FUDGING DIVI A,62213 ;THIS NUMBER DETERMINED AT EXECUTION TIME BY NEW PROGRAM, BUT THIS SHOULD DO FOR APPROXIMATION MOVEM A,TMPSAV ;SAVE AS TEMPO JSP Q,FIND ;NOW LOOK FOR A WORD, -1,, ;WHICH HAS IN THE LEFT HALF, MOVE 16, ;A MOVE INTO AC16 GET A,(A) ;GET WHAT IT IS MOVING FROM, TLC A,617 TLNN A,-1 ;IF SIXBIT BYTE POINTER INDEXED BY 17, JRST MFIND3 ;THEN FOUND TLC A,440000 ;ALSO TRY THE OTHER FLAVOR TLNE A,-1 MFIND2: ERR [ASCIZ / CAN'T FIND DATA AREA. /] SOJ A, MFIND3: MOVEM A,MSTLOC ;HURRAY, THE DATA HAS BEEN FOUND! POPJ P, MSTLOC: 0 ;LOCATION OF DATA AREA IN PDP10 CORE (USED BY DUMP) TMPSAV: 0 ;SAVES TEMPO DURING DUMP ;DO A MASKED WORD SEARCH STARTING FROM LOCATION POINTED TO BY B ;CALLED AS FOLLOWS: ;MOVEI B, ;JSP Q,FIND ; ; ;POINTER TO ERROR RETURN IN D ;DOESN'T SEARCH TOP 200 LOCATIONS IN MEMORY FIND: CAIL B,MOBY+40000-UTOBFL ;IF FOLLOWING .IOT WOULD CAUSE ILLUAD, JRST (D) ;THEN EXIT MOVE T,[-UTOBFL,,UTOBUF] ;SET UP POINTER TO BUFFER BGET T,(B) ;GET CRUFT MOVSI C,-UTOBFL ;SET UP AOBJN POINTER FOR SEARCH FIND1: MOVE A,UTOBUF(C) ;GET WORD TDC A,1(Q) ;COMPLEMENT COMPARISON BITS (MATCH => BIT WILL BE OFF) TDNN A,(Q) ;TEST MASKED BITS JRST FIND2 ;FOUND AOJ B, ;INCREMENT PDP10 LOCATION AOBJN C,FIND1 ;KEEP GOING, BUT IF BUFFER RUNS OUT, JRST FIND ;THEN RELOAD BUFFER AND KEEP GOING FIND2: TDC A,1(Q) ;WORD FOUND, RESTORE TO ORIGINAL STATE JRST 2(Q) ;RETURN ;PDP10 VARIABLES TAG 10GO GOBEG: CONO 635550 ;IO RESET, CLEAR NXMEM FLAG, ETC. CONO PI,11577 ;PI OFF, ETC. MOVE 1,BAR ;ROUTINE USED TO START UP THE TEN MOVEM 1,41 TAG DUNSW SETOM DUNSW ;SWITCH SO 6 KNOWS WHETHER 10 IS RUNNING PROPERLY GOINST: 0 ;STARTING INSTRUCTION LOADED FROM FILE OR SPECIFIED BY ARGUMENT TO "G" TAG BAR 10SV41: 0 ;C(41) FROM FILE LOADED OR PDP10 CORE GOEND: ;END OF ROUTINE TO START UP 10 XCTBEG: ;BEGINNING OF MUSIC PROGRAM VARIABLES TAG XCTLOC 10CMD: 0 ;COMMAND TO PDP10 TAG 10SW -1 ;SWITCH TO TELL 10 TO EXECUTE COMMAND XCTEND: OFST==37777-. REPEAT TAGNR,CONCAT TAG,\.RPCNT, TAGNR==0 PDPNAM: (SIXBIT /USR/) UNAME: 0 JNAME: SIXBIT /PDP10/ 41SW: 0 ;-1=> 10SV41 HAS C(41) VIA LOAD MPC: -1 ;-1 OR PLACE WHERE PLAYING WHEN LAST STOPPED HUH: ASCIZ /? / ;FREQUENT ERROR "MESSAGE" ;COMMAND DISPATCH TABLE DTBP: POINTS 12.,DTB(T) DTB: .BYTE 12. REPEAT 100,[CONCAT CHR,\.RPCNT ] .WALGN .BYTE ;BLURB TABLE BTB: .BYTE 12. REPEAT 100,[CONCAT CHB,\.RPCNT ] -1 ;FOR END OF TABLE DETECTION .WALGN .BYTE PAT": PATCH": BLOCK 40 ;PATCH AREA PATCHE"=.-1 CONST: CONSTANTS VARIABLES PDL: BLOCK LPDL+1 UTOBUF: ;DUMPER BUFFER UTIBUF: BLOCK UTIBFL ;LOADER BUFFER END BEG