.TITLE ROLLIN .LIST TOC,MEB .NLIST TTM .SBTTL ROLLIN - STAND-ALONE DISK/DECTAPE/MAGTAPE ROLLER .SBTTL .SBTTL COPYRIGHT 1973,1974 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS. .SBTTL EDIT: DATE: BY: .SBTTL 03 15-JAN-73 NAT/MHB/GWB/JDM .SBTTL 03MM 3-JAN-78 MNL .SBTTL .SBTTL LINKING INSTRUCTIONS: .SBTTL #ROLLIN,@#4 ;SET UP TM11 BOOT DEFAULT IF NO TJU MOV #7*40,@#6 ;KEPP AT PRIORITY 7 CLR @#MMCSR2 ;CHECK FOR EXISTANCE OF TJU AND ;INIT IT TO UNIT 0 MOV #MMDENS+MMFMT,@#MMTC ;SET DENSITY AND FORMAT FOR SLAVE 0 MOV #100.,R2 ;WAIT A MOMENT 22$: DEC R2 BNE 22$ BIT #MMDRY,@#MMDS ;DRIVE READY BEQ $TM11 MOV #MMDC,@#MMCSR1 ;DO DRIVE CLEAR ON UNIT 0 BIT #MMDRY,@#MMDS ;DONE BEQ .-6 ;WAIT UNTILL DONE MOV #BOOT,@#MMBA ;SET UP BUFFER MOV #-SIZWRD,@#MMWC ;GET IT ALL MOV #MMRD,@#MMCSR1 ;READ TSTB @#MMCSR1 ;WAIT BGE .-4 ;UNTIL DONE BIT #040000,@#MMCSR1 ;ERROR BNE MMBE1 ;YES-GO TO ERROR RETRY JMP @#START ;ELSE START MMBE1: MOV #-1,@#MMFC ;FRAME COUNT FOR SKIP 1 BLOCK MOV #MMSB,@#MMCSR1 ;BACKSPACE BIT #MMPIP,@#MMDS ;WAIT UNTIL DONE BNE .-6 BR MTBOOT ;AND TRY AGAIN $TM11: MOV #MTACMA,R0 MOV #BOOT,(R0) ;LOAD EVERYTHING MOV #0-SIZBYT,-(R0) ;THATS ABOUT ALL OF ROLLIN MOV #BPI+MTRD,-(R0) ;READ FROM UNIT 0 TSTB (R0) ;AND WAIT FOR DONE.. BPL .-2 TST (R0)+ ;CHECK FOR ERROR.. BMI MTB1 ;OUCH...ERROR JMP @#START ;START THE WORLD MTB1: MOV #-1,(R0) ;BACKSPACE RECORD AND TRY AGAIN... MOV #BPI+MTSR+1,-(R0) TSTB (R0) ;WAIT.... BPL .-2 BR MTBOOT .SBTTL DATA FOR CONTROLLING ROLLOUT/ROLLIN DTPAR: .BYTE 0 ;FUNCTION (+0) .BYTE 0 ;UNIT,DIRECTION (+1) .WORD 0 ;BLOCK # (+2) .WORD 0 ;CORE ADDRESS (+4) .WORD 0 ;BLOCK COUTN (+6) .WORD 0 ;ERROR COUNT (+10) .WORD -1 ;INSURE THAT FIRST DTABL ENTRY <> THIS DTABL: .BYTE 0 ;PHYSICAL DRIVE FOR FIRST UNIT .BYTE 0 ;SECOND UNIT, ETC. .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 .BYTE 0 FLAGS: .WORD 0 ;FLAGS FROM SCAN ILB: + 0,0 ;INPUT LOGICAL BLOCK # ILB0: + 0,0 ;FIRST LOGICAL BLOCK IN SET ILBEND: + 0,0 ;LAST LOGICAL BLOCK IN SET OLB: + 0,0 ;OUTPUT LOGICAL BLOCK # OLB0: + 0,0 ;FIRST LOGICAL BLOCK ON OUTPUT OLBEND: + 0,0 ;LAST LOGICAL BLOCK IN: + 0 ;ADDRESS OF INPUT ROUTINE OUT: + 0 ;ADDRESS OF OUTPUT ROUTINE DTIBC: + 0 ;# OF BLOCKS WRITTEN ON INOUT TAPE DFPAR: .WORD 0,0 ;SECTOR ADDRESS (+0,+2) .WORD 0 ;CORE ADDRESS (+4) .WORD 0 ;SECTROR COUNT (+6) .WORD 0 ;FUNCTION (+10) .WORD 0 ;ERROR COUNT (+12) .SBTTL SWITCH PARAMETERS--- DISKS: + 0 ;# DISKS TO DO NUM: + 0,0 ;# TRACKS TO DO TRACK: + 0,0 ;FIRST 1K TRACK TO DO LABEL: + 0 ;0 FOR NORMAL PROCESSING, -1 TO SKIP LABEL RBFLAG: + 0 ;RUBOUT FLAG FOR GETIN LPYFLG: + 0 ;LEAP YEAR FLAG (/DATE) TRACKS: + 0 ;NUMBER OF TRACKS ON ONE PLATTER BUFSIZ: + 0 ;NUMBER OF BLOCKS IN BUFFER (SHOULD BE POWER OF 2) DSKDAE: + 0 ;0 IF RC11 -- RFDAE POINTER IF RF11 -- +1 IF RK11 ; + 2 IF RP11 RKIN: + 0 ;INPUT RK UNIT # IN BITS 15-13 RKOUT: + 0 ;OUTPUT RK UNIT # IN BITS 15-13 MTRWD: + 0 ;MAGTAPE FLAG: ;+1 TO INDICATE REWIND IS TO BE PERFORMED ;0 TO INDICATE LABEL CHECKING (WRITING) ;-1 TO INDICATE NORMAL OPERATION MTSKIP: + 0 ;SET TO NUMBER OF FILES TO SKIP MTREEL: + 0 ;CURRENT REEL IN FILE (FOR LABELS) MTNAM0: + 0 ;FILE NAME FOR MAGTAPE MTNAM1: + 0 ;FILE NAME (2ND WORD) MTDATE: + 0 ;DATE WORD FOR MAGTAPE LABELS MTFIND: + 0 ;FIND FILE SWITCH... V4A: + 0 ;SPECIAL V4A SWITCH VERIFY: + 0 ;SPECIAL VERIFY PASS OPTION PFMT: + 0 ;SPECIAL PACK FORMATTING OPTION MTLIST: + 0 ;MAGTAPE LIST NAME DURING SEARCH MTSTAY: + 0 ;SUPRESS MAG TAPE REWIND MCOPYX: - 1 ;MAGTAPE COPY FLAG .SBTTL FLAG BIT ASSIGNMENTS---USED TO REPORT RESULTS OF COMMAND SCAN RHS =100000 ;RIGHT HAND SIDE WAS PRESENT WL =40000 ;WRITE LOCK SWITCH SET MM =40 ;DEVICE IS TJU-PROHIBIT MT AND DT DFL =20 ;DISK SEEN ON LEFT DFR =10 ;DISK SEEN ON RIGHT DTL =4 ;DECTAPE SEEN ON LEFT DTR =2 ;DECTAPE SEEN ON RIGHT MTAPE =1 ;MAGTAPE SEEN...PROHIBIT DECTAPE .SBTTL USEFUL PARAMETERS LB0= 25 LABLK= 24 SIZWRD =12400 ;SIZE OF ROLLIN IN WORDS SIZBYT =25000 ;SIZE OF ROLLIN IN BYTES SIZBLK =25 ;SIZE OF ROLLIN IN 256. WORD BLOCKS .SBTTL ONE TIME ONLY CODE TO START UP ROLLIN START: RESET ;CAN'T HURT NAT SAYS MOV #7*40,@#PS ;DITTO MOV #BOOT,SP ;INIT STACK JSR PC,INI ;OFF TO COMMON INITIALIZER JSR R5,MES ;TYPE ROLLIN VERSION + VERMES BR COMCO1 ;FALL INTO COMMAND DECODER .SBTTL NO-EXISTANT DEVICE ERROR (TRAP AT 4 OCCURED) NXD: JSR R5,MES ;TELL HIM + ERRNXD BR COMCON .SBTTL MAGTAPE FILE WAS SHORTER THAN REQUEST ON READ... MTXAB: JSR R5,MES ;LET HIM KNOW IT + ERRXAB BR COMCON .SBTTL COMMAND DECODER------------ ;USER TYPES COMMANDS OF THE FORM ; ; DEV: ] BR GTOK ;GO BACK FOR MORE TOKMT: BIT #MM,FLAGS ;HAS MM ALREADY BEEN SELECTED BNE GTERR ;BLEW IT AGAIN BIT #MTAPE,FLAGS ;IS MTCOPY POSSIBLE? BNE 10$ ;YEAH...AVOID CHECK BIT #DTR+DTL,FLAGS ;CAN'T HAVE BOTH MT AND DT BNE GTERR ;ERROR IF WE DO BIS #MTAPE,FLAGS ;SET MAGTAPE SEEN FLAG 10$: CMPB (R0),#': ;WAS A UNIT # GIVEN? BNE TOKDT0 ;IF SO GO ON MOVB #'0,-(R0) ;FORCE MT0: FOR MT: BR TOKDT0 ;REST IS COMMON WITH DECTAPE TOKMM: BIT #MM,FLAGS ;HAS MM ALREADY BEEN SELECTED BNE 10$ ;IF YES-NO NEED FOR OTHER TESTS BIT #MTAPE,FLAGS ;HAS TU10 BEEN SELECTED BNE GTERR ;DOWN THE TUBES AGAIN BIT #DTL+DTR,FLAGS ;HOWABOUT DECTAPE-IN EITHER DIRECTION BNE GTERR ;YOU MUST LIKE THE RIDE BIS #MM+MTAPE,FLAGS ;SET FLAGS 10$: CMPB (R0),#': ;WAS NXT CHR UNIT NO BNE TOKDT0 ;YES MOVB #'0,-(R0) ;ELSE FAKE UNIT 0 BR TOKDT0 TOKCOL = GTOK ;FOR COLON, JUST PASS IS BY TOKCOM = GTOK ;FOR COMMA, JUST PASS IT BY TOKLRO: BIS #RHS,FLAGS ;SHIFTING TO RIGHT HAND SIDE BR GTOK ;GO BACK FOR MORE TOKWL: BIS #WL,FLAGS ;SET WRITE LOCK BIT BR GTOK TOKVE: MOV #-1,VERIFY ;SET VERIFY FLAG BR TOKDF2 ;PASS OFF REST OF SWITCH TOKEOL: RTS PC ;END THE SCANN! TOKDIS: JSR PC,TOKA2I ;TOKEN WAS "/DISK" MOV R2,DISKS ;SAVE # OF DISKS BR GTOK ;GET SOME MORE TOKNUM: JSR PC,TOKA2I ;TOKEN WAS "/NUM" MOV R2,NUM ;GET NUMBER OF TRACKS TO SAVE/READ MOV R3,NUM+2 ; TOKN2: BR GTOK ;AND GO BACK TOKTRK: JSR PC,TOKA2I ;TOKEN WAS "/TRACK" MOV R2,TRACK ;SAVE STARTING DISK TRACK TO LOAD/SAVE MOV R3,TRACK+2 ; BR GTOK ;GO BACK TOKA2I: JSR R5,SKIPPER ;SKIP TO COLON IN STRING + COL INC R0 ;SKIP PAST THE COLON JSR PC,ATOI ;CONVERT TO INTEGER RTS PC TOKSK: JSR PC,TOKA2I ;SET TO SKIP N FILES MOV R2,MTSKIP ;ON MAGTAPE... BR TOKN2 ;AND RETURN TOKV4A: MOV #-1,V4A ;SET V4A FLAG BR TOKDF2 ;AND RETURN TOKDT: BIT #MTAPE,FLAGS ;CAN'T MIX DT AND MT BNE GTERR1 ;BAD, BAD TOKDT0: CMPB (R0),#'0 ;"DT" SEEN--UNIT SPECIFIED? BLO TOKDT2 ;NO--SET DT SEEN FLAG & GO BACK CMPB (R0),#'7 ;MAYBE-- BHI TOKDT2 ;NO MOVB (R0)+,R2 ;YES--ENTER IN DTABLE IN FIRST OPEN SLOT SUB #'0,R2 ;CONVER TO BINARY MOV #DTABL,R3 ;LOCATE TABLE TOKDT1: TSTB (R3)+ ;THIS ENTRY SET? BPL TOKDT1 ;YES--KEEP LOOKING MOVB R2,-(R3) ;NO--REPLACE -1 BYTE WITH UNIT # TOKDT2: CMPB (R0)+,#': ;NEXT CHAR MUST BE COLON BNE GTERR1 ;IF NOT ITS AN ERROR MOV #MTNAM0+4,R1 ;R1 POINTS TO NAME CLR -(R1) ;CLEAR NAME INITIALLY CLR -(R1) MOV #55533,R2 ;LOOP CONTROL FLAG TOKDT3: MOVB (R0)+,R3 ;GET NEXT CHAR CMPB R3,#'A ;CHAR MUST BE A-Z OR 0-9 BLT TOKDT4 CMPB R3,#'Z BLE TOKDT5 ;ITS A-Z TOKDT4: CMPB R3,#'0 ;0-9? BLT TOKDT7 ;IF NOT EXIT LOOP CMPB R3,#'9 BGT TOKDT7 ;EXIT LOOP IF NOT SUB #22-100,R3 ;0-9 CORRECTION TOKDT5: SUB #100,R3 ;A-Z CORRECTION TOKDT6: ASRB R2 BCC TOKDT8 ;BRANCH IF NO MULTIPLY NEEDED ASL R3 ;MULTIPLY R3 BY 40. ASL R3 ASL R3 MOV R3,R4 ASL R3 ASL R3 ADD R4,R3 ;ALL DONE BR TOKDT6 ;CHECK IF MORE SHIFTING NEEDED TOKDT8: CMP R1,#MTNAM0+4 ;ARE WE PAST THE SIXTH CHAR ? BEQ TOKDT3 ;YES ADD R3,(R1) ;STORE CHARACTER ASRB R2 BCS TOKDT3 ;TEST FOR THIRD CHAR TST (R1)+ ;GO TO NEXT NAME WORD SWAB R2 ;NEW FLAGS BR TOKDT3 ;CONTINUE TOKDT7: DEC R0 ;RESCAN LAST CHAR MOV #DTR,R2 ;NOW SET THE DT SEEN ON RIGHT SIDE BIT JMP TOKDF1 ;AND SEE IF REALLY ON RIGHT SIDE GTERR1: JMP GTERR TOKDAT: JSR PC,TOKA2I ;GET DAYS FOLLOWING COLON TST R2 ;CANT BE 0 BEQ GTERR1 CMP R2,#31. ;IS HE PLAYING GAMES? BGT GTERR1 ;IF SO ERROR MOV R2,-(SP) ;SAVE DAYS MOV #TOKETY,R1 ;SET R1 TO POINT TO MONTH TABLE MOV #-1,LPYFLG ;SET LEAP YEAR FLAG JMP GTOKX TOKDEC: ADD #30.,(SP) ;ADD IN DAYS PREECEDING IN YEAR TOKNOV: ADD #31.,(SP) TOKOCT: ADD #30.,(SP) TOKSEP: ADD #31.,(SP) TOKAUG: ADD #31.,(SP) TOKJUL: ADD #30.,(SP) TOKJUN: ADD #31.,(SP) TOKMAY: ADD #30.,(SP) TOKAPR: ADD #31.,(SP) TOKMAR: ADD #28.,(SP) MOV #3,LPYFLG ;RESET LEAP YEAR FLAG... TOKFEB: ADD #31.,(SP) TOKJAN: JSR PC,ATOI ;GET YEAR BIT LPYFLG,R2 ;CHECK FOR LEAP YEAR CORRECTION BNE .+4 INC (SP) ;CORRECT FOR FEB 29 CMP R2,#99. BGT GTERR1 ;BAD YEAR SUB #70.,R2 BLT GTERR1 ;BAD YEAR TOKDA1: BEQ TOKDA2 ADD #1000.,(SP) ;CORRECT FOR YEAR-1970 DEC R2 BR TOKDA1 TOKDA2: MOV (SP)+,MTDATE ;SAVE DATE JMP GTOK ;AND RETURN TOKETY: TOKN ^"-JAN-",TOKJAN TOKN ^"-FEB-",TOKFEB TOKN ^"-MAR-",TOKMAR TOKN ^"-APR-",TOKAPR TOKN ^"-MAY-",TOKMAY TOKN ^"-JUN-",TOKJUN TOKN ^"-JUL-",TOKJUL TOKN ^"-AUG-",TOKAUG TOKN ^"-SEP-",TOKSEP TOKN ^"-OCT-",TOKOCT TOKN ^"-NOV-",TOKNOV TOKN ^"-DEC-",TOKDEC .WORD 0,0 .SBTTL TOKEN IS BOOTSTRAP... TKBOOT: JSR R5,REGSAV JSR PC,INICR ;DO CR/LF 1$: TSTB @I.TPS ;WAIT FOR READY BPL 1$ JSR R5,REGRES JSR R5,SKIPPER ;SKIP TO COLON IN STRING... + COL MOV #TOKETX,R1 ;POINT INTO NEW TABL... JMP GTOKX ;AND CONTINUE TOKETX: TOKN ^":DF",RF11 ;BOOT FROM RF11 TOKN ^":DT",TC11 ;BOOT FROM DECTAPE TOKN ^":DK",RK11 ;BOOT FROM RK11 DISK TOKN ^":DC",RC11 ;BOOT FROM RC11 DISK TOKN ^":MT",TM11 ;BOOT FROM MAGTAPE TOKN ^":DP",RP11 ;BOOT FROM RP03 TOKN ^":MM",TJU ;BOOT FROM TJU .WORD 0,0 ;END THE LIST RF11: MOV PC,R2 ;FIXED HEAD DISK (256KW) BR OTHER 177462 5 RC11: MOV PC,R2 ;FIXED HEAD DISK (64KW) BR OTHER 177450 ;ADRS OF WORD COUNT (COMMAND+2) 5 ;COMMAND WORD TC11: MOV PC,R2 BR TAPES 177344 ;ADRS OF WORD COUNT 5 ;LAST COMMAND 4003 ;FIRST COMMAND 100000 ;DONE MASK 24000 ;ERROR MASK TJU: BIS #MM,FLAGS ;SET UP FOR TJU BOOT CLR R1 ;FROM UNIT 0 JSR R5,MSET ;SET UP REGISTERS JSR PC,REWIND ;REWIND MM MOV #-1,@#MMFC ;1 FRAME MOV #MMSF,@#MMCSR1 ;SPACE FORWARD 1 BLOCK BIT #MMDRY,@#MMDS ;WAIT UNTIL DONE BEQ .-6 MOV #-1000,@#MMWC ;GET BOOT-1000 WORDS CLR @#MMBA ;LOAD AT LOC 0 MOV #MMRD,@#MMCSR1 ;DO READ BIT #MMDRY,@#MMDS ;WAIT UNTIL DONE BEQ .-6 BIT #040000,@#MMCSR1 ;ANY ERRORS BNE TJU ;RETRY UNTILL NONE CLR PC ;DO BOOT TM11: MOV PC,R2 BR TM11X 172524 ;ADRS OF BYTE COUNT 60003 ;LAST COMMAND 60011 ;FIRST COMMAND 200 ;DONE MASK 100000 ;ERROR MASK RK11: MOV PC,R2 ;MOVING HEAD DISK (CARTRIDGE) BR OTHER 177406 ;COMMAND WORD (5) IS THE RESET TAPES: RESET MOV R2,R0 ;GET THE ADDRESS OF THE BRANCH TST (R0)+ ;R0 TO POINT AT LAST COMMAND MOV (R0)+,R1 ;GET THE WORD COUNT ADDRESS DEC (R1) ;IF ITS MAGTAPE SET TO SKIP JUST ONE RECORD TST (R0)+ ;MOVE R0 TO FIRST COMMAND MOV (R0)+,-(R1) ;COMMAND WORD TO COMMAND REG. BIT (R0),(R1) ;LOOK FOR DONE INDICATORS BEQ .-2 ;NONE SET, TRY AGAIN TST (R0)+ ;DONE FIRST COMMAND, CHECK FOR ERROR BIT (R0),-(R1) ;LOOK FOR SET ERROR BITS BEQ OTHER ;NO ERRORS - TRY THE READ AGAIN: JMP (R2) ;RERUN FOR ERRORS RP11: MOV PC,R2 ;MOVING HEAD DISK (PACK) BR OTHER 176716 ;COMMAND WORD (5) IS THE RESET OTHER: RESET MOV R2,R0 ;R0 TO POINT AT WORD COUNT ADRS TST (R0)+ ;POINT TO ADDRESS MOV (R0)+,R1 ;WORD COUNT ADRS TO R1 MOV #-1000,(R1) ;LOAD WORD COUNT MOV (R0),-(R1) ;COMMAND TO COMMAND REGISTER BIT #100200,(R1) ;CHECK FOR ERROR OR DONE BEQ .-4 ;IF NEITHER, KEEP LOOKING BMI AGAIN ;ERROR, TRY AGAIN CLR PC TM11X: RESET BIT #MTBOT,@#MTAS BNE TAPES MOV #MTREW,@#MTAC TM11Y: BIT #MTTUR,@#MTAS BEQ TM11Y BR TAPES TOKML: INC MTLIST ;SET LIST FILE NAME FLAG BR TOKN1 ;AND CONTINUE TOKST: INC MTSTAY ;INC NO REWIND FLAG BR TOKN1 TOKFI: INC MTFIND ;SET FLAG TO FORCE SEARCH FOR FILE ;ALSO FORCE REWIND FIRST... TOKRE: BIT #MTAPE,FLAGS BEQ 1$ ;ERROR IF NO DEV SPECIFIED INC MTRWD ;INDICATE REWIND IS TO BE PERFORMED BR TOKN1 ;AND GO BACK 1$: JMP GTERR TOKNOL: MOV #-1,LABEL ;SET LABEL SWITCH TO -1 TOKN1: JMP TOKDF2 ;AND SKIP TO NEXT TOKEN TOKHLP: JSR R5,MES ;GIVE HIM THE SPIEL + HELPER ;SO HE KNOWS WHAT TO DO JMP COMCON ;AND START ALL OVER AGAIN TOKDP: MOV #2,R2 ;FLAG IT AS AN RP11 DISK MOV #RPTRKS,TRACKS ;SET UP DISK SIZE BR TOKDK0 ;REST IS COMMON WITH RK TOKDK: MOV #1,R2 ;FLAG IT AS AN RK11 DISK MOV #RKSIZE/4,TRACKS;SET UP DISK SIZE TOKDK0: CMPB (R0),#': ;SEE IF DK: WAS SPECIFIED BNE 1$ ;NO SO GO ON MOVB #'0,-(R0) ;FORCE DK0: FOR DK: 1$: CMPB (R0),#'0 ;NEXT CHAR MUST BE UNIT NUMBER BLO GTOERR ;IF NOT COMPLAIN CMPB (R0),#'7 BHI GTOERR RORB (R0) ;PUT UNIT# IN HIGH 3 BITS RORB (R0) RORB (R0) RORB (R0) BICB #37,(R0) ;LEAVE ONLY UNIT BITS BIT #RHS,FLAGS ;INPUT OR OUTPUT UNIT? BEQ TOKDK1 ;RIGHT HAND SIDE MOVB (R0)+,RKIN+1 ;SAVE INPUT UNIT BIT #DFL,FLAGS ;DISK OUTPUT TOO ? BEQ TOKDK2 ;NO PROBLEM IF NOT CMP R2,DSKDAE ;SAME TYPE ? BNE GTOERR ;ERROR IF NOT CMPB RKIN+1,RKOUT+1 ;IN AND OUT UNITS SAME ? BEQ GTOERR ;YES, WE CAN'T DO THAT BR TOKDK2 TOKDK1: MOVB (R0)+,RKOUT+1 ;SAVE OUTPUT UNIT TOKDK2: MOV R2,DSKDAE ;SET DISK TYPE JMP TOKDF0 ;HANDLE OTHERWISE AS ORDINARY DISK TOKFO: BIT #RHS,FLAGS ;FORMAT SWITCH MUST BE ON LHS BEQ 2$ ;IT IS 1$: JMP COMERR ;ELSE ERROR 2$: BIT #DFL,FLAGS ;MUST HAVE DISK ON LEFT BEQ 1$ ;ELSE ERROR TST DSKDAE ;ALSO MUST BE RK OR RP BLE 1$ ;YOU GUESSED IT MOV #-1,PFMT ;SET FORMAT SWITCH ON JSR R5,SKIPPE ;FORGET REST OF SWITCH + 0 ; JMP GTOK ;GET < AND RHS .SBTTL ROUTINE TO SKIP OVER REST OF CURRENT TOKEN ;CALL JSR R5,SKIPPER ; + BITS ;STOP ON GIVEN CHARS ;IF EOL IS DETECTED, AND NOT A STOPPING CHAR, THEN COMPLAIN! ;BITS TESTED INCLUDE COL =100000 ;STOP ON COLON COM =200 ;STOP ON COMMA EOL =1 ;STOP ON END OF LINE SL =2 ;STOP ON SLASH SKIPPE: CMPB (R0),#15 ;IS THIS AN EOL? BEQ SKIP01 ;YES--SEE IF EXPECTED CMPB (R0),#': ;IS IT A : BEQ SKIP02 ;YES CMPB (R0),#', ;COMMA? BEQ SKIP03 ;YES CMPB (R0),#40 ;SKIP SPACES, ALPHAS, AND NUMERICS BEQ SKIP04 ;SPACES CMPB (R0),#'/ ;HOW ABOUT SLASH BEQ SKIP07 CMPB (R0),#'0 ;NUMBER? BLT SKIP05 ;NO--STOP ON WEIRDO CMPB (R0),#'9 ;IN NUMERIC RANGE? BLE SKIP04 ;YES--SKIP IT CMPB (R0),#'A ;ALPHA? BLT SKIP05 ;STOP ON WEIRDO CMPB (R0),#'Z ;IN ALPHA RANGE? BGT SKIP05 ;NO WEIRDO-- SKIP04: INC R0 ;SKIP CHAR & TRY NEXT BR SKIPPE ;UNTIL END COND. IS DETEC. SKIP01: BIT #EOL,(R5) ;END EXPECTED BNE SKIP05 ;YES-RETRUN TO CALLER GTOERR: JMP COMERR ;NO--COMPLAIN SKIP07: BIT #SL,(R5) BEQ SKIP04 BR SKIP05 SKIP02: TST (R5) ;":" SEEN--SHOULD WE STOP SKIP06: BEQ SKIP04 ;NO--KEEP GOING SKIP05: TST (R5)+ ;SKIP ARG IN CALL RTS R5 ;AND RETURN SKIP03: TSTB (R5) ;COMMA SEEN--SHOULD WE STOP? BR SKIP06 ;WILL TELL .SBTTL ROLL OUT DRIVERS DFIN: MOV ILB,DFPAR ;INPUT FROM DISK MOV ILB+2,DFPAR+2 ; MOV #RFUN,DFPAR+10 ;DISK FUNCTION IS READ MOV ILBEND,R0 ;END BLOCK FOR COMPUTATION MOV ILBEND+2,R1 ; MOV RKIN,-(SP) ;SAVE INPUT RKUNIT BR DF01 ;REST IS COMMON FOR READ/WRITE DFOUT: MOV OLB,DFPAR ;FIRST LOGICAL BLOCK TO OUTPUT MOV OLB+2,DFPAR+2 ; MOV #WFUN,DFPAR+10 ;FUNCTION IS WRITE MOV OLBEND,R0 ;SAVE END BLOCK HERE TOO MOV OLBEND+2,R1 ; MOV RKOUT,-(SP) ;SAVE OUTPUT RKUNIT TST VERIFY ;IS THIS THE VERIFY PASS? BLE DF01 ;NO...GO ON ;SPECIAL VERIFY PASS DISK CODE MOV #RFUN,DFPAR+10 ;DO A READ INSTEAD OF A WRITE MOV BUFSIZ,R2 ;COMPUTE BUF2 ADDRESS SWAB R2 ;AS BUF+(BUFSIZ*512.) ASL R2 ADD R2,DFPAR+4 ;ADD TO BUF ADDRESS MOV (SP),-(SP) ;DO SOME STACK DIDDLING MOV #DFCHK1,2(SP) ;TO FORCE RTS TO GO TO DFCHK1! BR DF02 ;AND CONTINUE DF01: MOV #BUF,DFPAR+4 ;CORE ADDRESS DF02: JSR R5,ROOM ;COMPUTE NUMBER OF SECTORS TO READ + DFPAR ;CURRENT SECTOR NUMBER + DFPAR+6 ;SECTOR COUNT FOR TRANSFER MOV #5,DFPAR+12 ;ERROR COUNT = 5 JSR PC,DFGO ;DO IT TST (SP)+ ;FLUSH UNIT NUMBER OFF STACK RTS PC ;AND RETURN ;WE GET HERE FROM THE RTS PC!! DFCHK1: MOV DFPAR+6,R4 ;GET NUMBER OR SECTORS READ SWAB R4 ;AND CONVERTS TO BYTES ASL R4 JMP CHECK ;DO VERIFY AND FALL OUT TO EXIT DFGO: MOV #DFPAR,R4 ;POINTER TO DFPAR DFGO1: MOV (R4)+,-(SP) ;SECTOR # (LOW ORDER BITS) MOV (R4)+,-(SP) ;AND THE HIGH ORDER BITS BNE DFGO7 ;IF NOT SECTOR 0,DON'T CHECK FLAG TST 2(SP) ;BOTH WORDS = 0 FOR SECTOR 0 BEQ DFGO6 ;IF SECTOR 0,CHECK FORMAT AND V4A FLAG DFGO7: MOV DSKDAE,R1 ;GET POINTER TO EXTENDED ADDRESS IN R1 BEQ DFISDC ;CHECK FOR AN RC11 DISK BGT DFISDK ;CHECK FOR RK11 DISK MOV #RFCLR,@#RFSTS ;CLEAR OUT THE RF11 TST (SP)+ ;POP EXTENDED SEGMENT NUMBER SWAB (SP) ;TIMES 256. CLR (R1) ;CLEAR EXTENDED ADDR MOVB (SP),(R1) ;AND SET IT CLRB (SP) ;CLEAR IT ON STACK DFGO5: MOV (SP)+,-(R1) ;SET LOW ORDER ADDRE DFGO4: MOV (R4)+,-(R1) ;AND CORE ADDRESS MOV (R4)+,-(R1) ;AND POSITIVE SECTOR COUNT SWAB (R1) ;NOW ITS A WORD COUNT NEG (R1) ;AND A NEGATIVE WORD COUNT MOV (R4)+,-(R1) ;LOAD FUNCTION DFGO2: BIT #100200,(R1) ;WAIT BEQ DFGO2 ;STILL WAITING BMI DFGO3 ;ERRRRORRRR RTS PC ;RETURN---ALL IS OK DFGO3: MOV #1,(R1) ;RESET ANY DISK CONTROL TSTB (R1) ;WAIT FOR READY BPL .-2 ;KEEP WAITING DEC DFPAR+12 ;OTHER ERRORS BEFORE? BNE DFGO ;KEEP TRYING BIT #DTR+DTL,FLAGS ;IS DECTAPE BEING USED? BEQ 2$ ;SKIP IF NOT BIT #MTAPE,FLAGS ;REALLY DECTAPE? BNE 2$ ;SKIP IF NOT MOVB #SST,@#DT.CMD ;STOP DECTAPES AT THIS POINT. 2$: RESET ;OOPS TST DSKDAE ;IS IT RK OR RP? BLE 3$ ;BRANCH IF NOT MOV 2(SP),R1 ;GET UNIT NUMBER ROL R1 ROL R1 ROL R1 ROL R1 ;PUT IT IN BITS 2-0 ADD #60,R1 ;CONVERT TO ASCII MOVB R1,DKOKU ;AND STORE IN MESSAGE JSR R5,MES ;TELL HIM ABOUT THE ERROR + DKOK BR 4$ 3$: JSR R5,MES ;REPORT FAILURE + DFOK ;AND QUIT 4$: CLR VERIFY ;AVOID FALLING INTO VERIFY JMP COM11 ;CLOSE OUT MAGTAPE OUTPUT (IF ANY) ;AND ABORT .SBTTL LOAD RK11 DISK ADDRESS DFISDK: ASR R1 ;IS IT RP OR RK? MOV 6(SP),R1 ;COMPUTE DISK ADDRESS (UNIT BITS) BCC DFISDP ;ITS AN RP11 DISK TST (SP)+ ;POP EXTENDED SEGMENT NUMBER BR DFDK1 DFDK2: ADD #20,R1 ;ADD INTO CYLINDER/SURFACE ADDR DFDK1: SUB #12.,(SP) ;COMPUTE CYLINDER NUMBER BGE DFDK2 ;BY DIVISION ADD #12.,(SP) ;REMAINDER IS TRACK # ADD R1,(SP) ;FULL ADDRESS NOW COMPUTED MOV #RKDA+2,R1 ;SET UP RKDA POINTER DFGO5.: BR DFGO5 ;THE REST IS COMMON .SBTTL LOAD RC11 DISK ADDRESS REGISTER DFISDC: TST (SP)+ ;DON'T NEED EXTENDED SEG # FOR RC11 ASL (SP) ;MULTIPLY SECTOR NUMBER BY 8. ASL (SP) ASL (SP) MOV (SP)+,@#RCDA ;LOAD DISK ADDRESS FOR RC11 MOV #RCCMA+2,R1 ;SET UP R1 BR DFGO4 DFGO6: TST PFMT ;FORMATTING SPECIFIED ? BEQ 1$ ;NO,FORGET IT JSR PC,FORMAT ;GO FORMAT A PACK CLR PFMT ;ONE TIME ONLY 1$: TST V4A ;CHECK FLAG BEQ DFGO7 ;NOT SET SO CONTINUE CLR V4A ;ONE TIME ONLY MOV DFPAR+6,-(SP) ;SAVE SECTOR COUNT MOV #1,DFPAR+6 ;SET SECTOR COUNT TO 1. MOV 10(SP),-(SP) ;GET UNIT NUMBER FOR RK JSR PC,DFGO ;READ/WRITE BOOTSTRAP TST (SP)+ ;FLUSH UNIT NUMBER MOV #DFPAR+6,R4 ;RESTORE R4.... DEC (SP) ;UPDATE SAVED SECTOR COUNT MOV (SP)+,(R4) ;AND RESTORE IT ADD #1000,-(R4) ;UPDATE BUFFER ADDRESS MOV #17.,2(SP) ;SKIP TO SECTOR 17 (LEAVES ROOM FOR MFD) MOV #ILB+2,-(SP) ; MOV #ILB,-(SP) ; CMP #RFUN,DFPAR+10 ;READ OR WRITE ? BEQ 2$ ;READ, SO BRANCH MOV #OLB+2,2(SP) ; MOV #OLB,(SP) ; 2$: ADD #16.,@(SP)+ ; UPDATE SECTOR NUMBER ADC @(SP)+ ; JMP DFGO7 ;AND FINISH REQUEST .SBTTL HANDLE RP11C/RP03 DISKS DFISDP: SWAB R1 ;UNIT NUMBER TO BITS 7-5 ASL R1 ;MOVE TO BITS 8-10 ASL R1 ASL R1 ADD R1,DFPAR+10 ;AND MAKE IT PART OF FUNCTION. ;CONVERT SECTOR NUMBER TO DISK ADDRESS MOV (SP)+,R1 ;GET HIGH ORDER SECTOR NUMBER MOV (SP),R3 ;RPDA IS BUILT IN R3 CLR (SP) ;STACK CONTAINS CYLINDER ADDR. BR DFDP1 DFDP2: INC (SP) ;COUNT CYLINDER DFDP1: SUB #200.,R3 ;THERE ARE 200 SECTORS PER CYLINDER SBC R1 ;CARRYON BHIS DFDP2 ;REMEMBER THAT SECTOR CAN BE GT 32K ADD #200.,R3 ;RESET VALUE BR DFDP3 DFDP4: ADD #400,R3 ;INCREMENT TRACK ADDR SUB #10.,R3 DFDP3: CMPB R3,#10. ;ARE WE THERE? BHIS DFDP4 ;NO CONTINUE COUNTING MOV #RPDA,R1 MOV R3,(R1) BR DFGO5. .SBTTL FORMAT DISKS FORMAT: JSR R5,REGSAV ;SAVE ALL REGISTERS FMT1: CMP DSKDAE,#1 ;IS IT AN RK ? BEQ 2$ ;YES, GO FORMAT CMP DSKDAE,#2 ;IS IT AN RP ? BNE FMTKIL ;NOPE,ERROR JSR R5,INPUT ;"SET FORMAT ENABLE SWITCHES" + FMTENB ;AND WAIT FOR CR REPLY CMPB (R0),#15 ;WAS IT REALLY A CR BNE FMTKIL ;ASSUME HE WANTS TO ABORT JMP FMTRP ;GO FORMAT RP 2$: JSR R5,MES ;TYPE + FMTBGN ;"STARTING RK FORMAT PASS" JMP FMTRK ;GO FORMAT RK FMTDNE: CMP DSKDAE,#2 ;WAS THAT AN RP FORMAT ? BNE 1$ ;NO,TWAS RK JSR R5,INPUT ;"DISABLE FORMAT SWITCHES" + FMTDSB ;WAIT FOR ANY REPLY BR 2$ ;RESTORE REGISTERS AND CARRY ON 1$: JSR R5,MES ;TYPE + FMTEND ;"END RK FORMAT PASS" 2$: JSR R5,REGRES ;RESTORE ALL REGISTERS RTS PC ;GET ON WITH IT FMTBAD: JSR R5,MES ;ERROR IN FORMATTING + FMTERR ;"FORMATTING FAILED - RESTART" JMP COMCON ;RESTART FMTRDY: JSR R5,INPUT ;"DRIVE NOT READY - TYPE CR WHEN READY" + FMTRDI ;WAIT FOR CR CMPB (R0),#15 ;DID HE TYPE CR ? BEQ FMT1 ;RETRY FORMATTING ON CR FMTKIL: JSR R5,MES ;TYPE MESSAGE + FMKILL ;"REQUEST KILLED" JMP COMCON ;START ALL OVER .SBTTL FORMAT AN RK DISK ; ; FMTRK: MOV RKOUT,R0 ;GET DIRIVE NUMBER BIC #17777,R0 ;ONLY TOP 3 BITS MOV R0,RKDA ;SET DISK ADDRESS MOV #1,RKCS ;RESET CONTROLLER MOV R0,RKDA BIT #100,RKDS BEQ 1$ TSTB RKDS BMI 2$ 1$: JMP FMTRDY ;DRIVE IS NOT READY 2$: CLR RKMA CLR RKWC MOV #15,RKCS ;ISSUE HOME SEEK FMTRK1: TSTB RKCS ;WAIT BPL FMTRK1 BIT #100,RKDS ;WAIT FOR DRIVE READY BEQ FMTRK1 TST RKCS BPL FMTRK2 ;BRANCH IF NO ERROR FMTRKX: JMP FMTBAD ;PRINT FMT FAIL MSG.RESTART FMTRK2: MOV R0,RKDA ;SET DRIVE NUM AGAIN FMTRK3: MOV #-1,RKWC ;SET WORD COUNT=1 CLR RKMA ;CLEAR CORE ADDR MOV #2003,RKCS ;ISSUE WRITE EMT FMTRK4: BIT #100200,RKCS ;WAIT BEQ FMTRK4 BPL FMTRK3 ;BRANCH IF NOT DONE ADD #14533,R0 ;CHECK OF PAST LAST CYL CMP R0,RKDA BHI FMTRKX ;IF NOT, ERROR MOV #1,RKCS ;ISSUE CONTROL RESET 1$: BIT #100200,RKCS ;WAIT FOR CONTROLLER READY BEQ 1$ ; BMI FMTRKX ;BRANCH ON ANY ERROR JMP FMTDNE .SBTTL FORMAT AN RP DISK ; FMTRP: INCB RPCS+1 CLR RPCS ;BYPASS HARDWARE CROCK CLR RPDA CLR RPCA CLR RPMA CLR RPWC MOVB RKOUT+1,R0 ;GET UNIT BITS ASL R0 ;GOTTA BE IN BITS 8-10 ASL R0 ; ASL R0 ; BIC #174377,R0 ;CLEAR OUT ALL JUNK MOV R0,RPCS ;SET DISK UNIT INC RPCS ;RESET CONTROLLER MOV R0,RPCS TST RPDS BMI .+6 JMP FMTRDY ;DISK NOT READY MOVB #15,RPCS ;ISSUE HOME SEEK FMTRP1: TSTB RPCS ;WAIT BPL FMTRP1 TST RPDS ;WAIT FOR DRIVE READY BPL FMTRP1 TST RPCS BPL FMTRP2 ;BRANCH IF NO ERROR FMTRPX: JMP FMTBAD ;PRINT FMT FAIL.RESTART FMTRP2: BIS #14000,RPCS ;SET HEADER AND PDP10 BIT MOV #-3,RPWC ;SET WORD COUNT CLR RPMA ;CLEAR MEMORY ADDR MOVB #3,RPCS ;ISSUE WRITE (FMT) FMTRP3: BIT #100200,RPCS ;WAIT BEQ FMTRP3 BMI FMTRPX ;BRANCH IF ERROR TST RPCA ;CYLINDER ADDRESS SHOULS BE ZERO BNE FMTRPX ;ERROR IF NOT BIC #4000,RPCS ;CLEAR HEADER ON BIT JMP FMTDNE .SBTTL DECTAPE ROUTINES------- .SBTTL INPUT FROM DECTAPE--- DTIN: MOVB #DTAR,DTPAR ;WE WANT RO READ DATA MOV ILB,R0 ;GET LOGICAL BLOCK WE WANT JSR PC,LBCHK ;SEE IF IT'S FIRST ON REEL BEQ DTIN2 ;IT IS--A LITTLE LABEL CHECKING THEN DTIN1: MOVB (R2),DTPAR+1 ;MAP PHYSICAL UNIT # MOV #BUF,DTPAR+4 ;CORE ADDRESS MOV R0,DTPAR+2 ;DECTAPE BLOCK # WANTED MOV ILBEND,R0 ;LAST BLOCK TO READ JSR R5,ROOM1 ;COMPUTE NUMBER OF BLOCKS TO READ + DTPAR+2 ;CURRENT BLOCK TO READ + DTPAR+6 ;NUMBER OF BLOCKS STORED HERE SUB DTPAR+6,DTIBC ;DO WE HAVE THEM ON THIS REEL? BPL DTIN10 ;YES ;HACK--WE DON'T SEEM TO HAVE THE RIGTH NUMBER OF BLOCKS ON THIS REEL ;HOWEVER, WE WANT TO FINISH WITH THE BLOCKS WE DO HAVE BEFORE WE QUIT. MOV BUFSIZ,-(SP) ;SAVE BUFSIZ ADD DTIBC,DTPAR+6 ;CHANGE TO SHOW HOW MANY BLOCKS WE HAVE BEQ DTIN6 ;HEY--THERE IS NOTHING THERE! JSR PC,DTG ;READ JUST A FEW BLOCKS MOV DTPAR+6,BUFSIZ ;SET UP BUFSIZ TO FOOL DFOUT JSR PC,@OUT ;DUMP THESE BLOCKS OUT DTIN6: SUB DTIBC,DTPAR+6 ;RESTORE TOTAL BLOCKS TO DUMP MOV (SP)+,BUFSIZ ;RESTORE BUFSIZ ;WE'RE OK NOW--WE'LL REPEAT TRANSFER IF HE CONTINUES. MOVB #SST,@#DT.CMD ;STOP THE TAPE THIS TIME JSR R5,INPUT ;NO--SEE IF HE WANTS TO CHANCE IT + DTEOF ;"LOGICAL END OF MEDIUM---K OR P" CMPB (R0),#'K ;WAHT'S HE WANT BEQ DTIN5 ;KILL REQUEST MOV #512.,DTIBC ;DON'T BOTHER ASKING AGAIN DTIN10: JSR PC,DTG ;READ DATA RTS PC ;AND RETURN DTIN2: MOV R2,-(SP) ;IT'S A NEW REEL MOV R1,-(SP) ;SAVE R2,R1,R0 FOR LATER USE MOV R0,-(SP) ; JSR PC,DTNEW ;SET UP NEW DRIVE DTIN3: JSR PC,DTG ;READ LABEL CMPB @#BUF1+1,2(SP) ;IS THIS THE RIGHT LOGICAL REEL? BEQ DTIN4 ;YES JSR R5,INPUT ;NO--SEE WHAT HE WANTS TO DO + DTWRRL ;WRONG LOGICAL REEL -- K, M, OR P CMPB (R0),#'K ;KILL REQUEST BEQ DTIN5 ;KILL REQUEST CMPB (R0),#'M ;MOUNT NEW REEL & TRY AGAIN? BEQ DTIN3 ;YES--CHECK IT'S LABEL THEN MOV #512.,@#BUF1+2 ;PROCEED HAZARDOUTSLY---ASSUME ALL THERE DTIN4: MOV @#BUF1+2,DTIBC ;NUMBER OF BLOCKS WRITEN ON TAPE MOV (SP)+,R0 ;RESTORE R0, R1, R2 FROM STACK MOV (SP)+,R1 ; MOV (SP)+,R2 ; BR DTIN1 ;READY TO READ DATA DTIN5: JMP COMCON ;START ALL OVER AGAIN .SBTTL DECTAPE OUTPUT ROUTINE DTOUT: MOVB #DTAW,DTPAR ;FUNCTION = WRITE MOV OLB,R0 ;BLOCK TO WRITE JSR PC,LBCHK ;SEE IF FIRST BLOCK ON UNIT BEQ DTOU2 ;IT IS--DO SOME HOUSEKEEPING FIRST DTOU1: MOVB (R2),DTPAR+1 ;SET UP PHYSICAL UNIT # MOV #BUF,DTPAR+4 ;CORE ADDRESS MOV R0,DTPAR+2 ;BLOCK # ON TAPE MOV OLBEND,R0 ;COMPUTE NUMBER OF BLOCKS TO READ JSR R5,ROOM1 + DTPAR+2 ;CURRENT BLOCK NUMBER + DTPAR+6 ;STORE NUMBER OF BLOCKS JSR PC,DTG ;DO IT RTS PC ;AND GO BACK DTOU2: MOV R2,-(SP) ;SAVE R2, R1, R0 MOV R1,-(SP) ;ON STACK MOV R0,-(SP) ;FOR LATERUSE JSR PC,DTNEW ;DO REEL SWITCHING AS NECESSARY CLR DTPAR+2 ;WRITE OUT ROLLIN PROGRAM ON BLOCKS 0-N MOV #BOOT,DTPAR+4 ;START OF CODE MOV #SIZBLK,DTPAR+6 ;ROLLIN SIZE IN BLOCKS JSR PC,DTG ;WRITE IT OUT JSR PC,DTNEW1 ;RESET PARAMTERS JUST MESSED UP MOV #BUF1,R3 ;CLEAR OUT LABEL BUFFER DTOU3: CLR (R3)+ ;ONE WORD CMP R3,#BUF1+512. ;AT A TIME BLT DTOU3 ;UNTIL END MOV ILB,@#BUF1+4 ;DISK BLOCK CORRESPONDING TO THIS ONE MOV ILB+2,@#BUF1+6 ; MOV OLBEND,R0 ;GET LAST BLOCK # WHICH WILL BE WRITTEN JSR PC,LBCHK ;GET # MOD 512. BEQ DTOU4 ;REMAINDER = 0---NO WASTE! SUB #LB0,R0 ;LBCHK CONVERTED TO ABSOLUTE #--NO GOOD HERE MOV R1,R3 ;SAVE RESULT INC R1 ;R1 IS # OF REELS CMPB R3,2(SP) ;IS THIS THE LAST IN SET BEQ DTOU5 ;YES--COULD BE PARTIALLY FILLED THEN DTOU4: MOV #512.,R0 ;NO--ALL 512. BLOCKS WILL BE FILLED THEN DTOU5: MOVB R1,@#BUF1 ;# REELS IN SET MOVB 2(SP),@#BUF1+1 ;WHICH REEL THIS IS IN SET MOV R0,@#BUF1+2 ;HOW MANY BLOCK WRITTEN ON REEL TST LABEL ;ARE WE SUPPOSED TO SKIP ALL THIS? BMI DTOU6 ;YES--THEN SKIP IT JSR PC,DTG ;WRITE THE LABEL DTOU6: MOV (SP)+,R0 ;RESTORE R0 MOV (SP)+,R1 ;AND OTHERS FROM STACK MOV (SP)+,R2 ;AND CONTINUE BR DTOU1 ;WITH LABLE WRITEEN .SBTTL DECTAPE CONTROLLER ASSIGNMENTS DT.CSR =177340 ;ERROR STATUS REGISTER DT.CMD =177342 ;COMMAND REGISTER DT.WC =177344 ;WORD COUNT REGISTER DT.CA =177346 ;CURRENT ADDRESS REGISTER DT.NUM =177350 ;DATA REGISTER - HOLDS BLOCK # ON SEARCH .SBTTL BITS AND PATTERNS DT.REV =4000 ;REVERSE BIT IN DT.CMD RNUM =03 ;READ BLOCK NUMBERS DTAR =05 ;READ DATA SST =011 ;STOP TRANSPORT DTAW =15 ;WRITE DATA DTG: MOV #10.,DTPAR+10 ;INITIALIZE ERROR/ROCK COUNT DTG0: MOV #DT.CMD,R0 ;POINT TO STATUS MOV #DT.REV,R3 ;REVERSE BIT IN STATUS MOV #DT.NUM,R4 ;POINT TO DATA REGISTER FOR SEARCH MOV DTPAR,-(SP) ;UNIT # + FUNCTION MOVB #RNUM,(SP) ;FIRST THE FUNCTION IS SEARCH BIS R3,(SP) ;START SEARCHING BACKWARDS USUALLY MOV (SP)+,(R0) ;LOAD FUNCTION DTG1: BIT #100200,(R0) ;WAIT BEQ DTG1 ;WAIT SOME MORE BPL DTG2 ;DONE WAITING--NO ERROR TST -2(R0) ;ERROR--IS IT END ZONE? BPL DTG7 ;NO--THEN RETRY IT BR DTG3 ;YES--TURN TAPE AROUND DTG2: BIT R3,(R0) ;WHICH WAY ARE WE SEARCHING? BEQ DTG5 ;FORWARD--ARE WE THERE YET? MOV DTPAR+2,R5 ;BACKWARD---FAR ENOUGH? SUB #2,R5 ;TWO BLOCKS IS ENOGUH ROOM CMP R5,(R4) ;SEE IF WE'RE THERE YET BLT DTG4 ;KEEP BACKING UP DTG3: DEC DTPAR+10 ;CHECK ROCK COUNT BEQ DTG7A ;TOO MANY ROCKS MOV R3,R5 ;XOR IN THE REVERSE BIT BIT R3,(R0) ;WHICH WAY NOW? BEQ .+4 ;FORWARD NEG R5 ;BACKWARD--SUBTRACK REVERSE BIT OUT ADD R5,(R0) DTG4: INC (R0) ;DO IT AGAIN BR DTG1 ;AND WAIT... DTG5: CMP (R4),DTPAR+2 ;ARE WE AT DESIRED BLOCK? BGT DTG3 ;TOO FARR--BACK UPP BLT DTG4 ;NO FAR ENOUGH---KEEP GOING MOV DTPAR+4,-(R4) ;JUST RIGHT--SET CORE ADDRESS MOV DTPAR+6,-(SP) ;AND GET BLOCK COUNT SWAB (SP) ;WORD COUNT NEG (SP) ;NEGATIVE WORD COUNT MOV (SP)+,-(R4) ;LOAD IT MOVB DTPAR,(R0) ;LOAD TRANSFER FUNCTION DTG6: BIT #100200,(R0) ;NOW WAIT FOR TRANSFER BEQ DTG6 ;STILL WAITING BMI DTG7 ;ERROR ON XFER--TRY AGAIN BIS R3,(R0) ;LEAVE TAPE GOING IN REVERSE MOVB #RNUM,(R0) ;FOR AUTOMATIC UNLOAD RTS PC ;AND RETURN DTG7: DEC DTPAR+10 ;ERROR COUNT =0 BNE DTG0 ;STILL ROOM TO RECOVER DTG7A: MOVB #SST,(R0)+ ;GENERATE A NICE MESSAGE MOVB (R0),R2 ;GET UNIT # BIC #-7-1,R2 ;JUST UNIT # ADD #60,R2 ;ASCII UNIT # MOVB R2,DTOKU ;PUT IN STRING JSR R5,INPUT ;TYPE IT OUT + DTOK CMPB (R0),#'K BNE DTG ;NOT KILL- THEN TRY AGAIN JMP COMCON ;QUIT .SBTTL REEL SWTICHER ;EVERY TIME WE GO FROM ONE LOGICAL UNIT TO ANOTHER, ;WE CHECK TO SEE IF IT IS ON SAME DRIVE. ;IF IT IS, THEN WE GIVE OPERATOR A CHANCE TO MOUNT NEW REEL ;R2 POINTS TO ENTRY IN DTABL ON ENTRY DTNEW: TSTB (R2) ;HAVE WE REACHED UNSPECIFIED DRIVE? BMI DTNEW2 ;YES--COMPLAIN MOVB (R2),DTPAR+1 ;SET UP NEW UNIT # IN PARAMETERS CMPB -1(R2),(R2) ;IS THIS SAME UNIT AS OTHER BNE DTNEW1 ;NO--ASSUME IT IS SET UP MOVB (R2),DTPAR+1 ;SET UNIT # IN PARAMETERS MOVB (R2),-(SP) ;SET UP OUTOUT MESSAGEE ADD #'0,(SP) ;CONVERT TO ASCII MOVB (SP)+,DTMTUN ;STORE IN OUTPUT STRING JSR R5,INPUT ;GIVE HIM THE NEWS + DTMONT ;MOUNT REEL ON DT'X'; TYPE ANY CHAR WHEN READY DTNEW1: MOV #LABLK,DTPAR+2 ;SET UP LABEL BLOCK # MOV #BUF1,DTPAR+4 ;CORE ADDRESS MOV #1,DTPAR+6 ;JUST ONE BLOCK RTS PC DTNEW2: JSR R5,MES ;REPORT PROBLEM + NOMORE ;EXHAUSETED DTA SPECIFICATIONS XCOMC: JMP COMCON ;NEW REQUEST .SBTTL LOGICAL BLOCK CHECKER ;CONVERTS A LOGICAL BLOCK IN DTA SET TO REEL # AND BLOCK IN REEL ;EACH REEL HAS 512. LOGICAL BLOCKS ;ON EXIT, R2 POINTS TO PHYSCIAL UNIT IN DTABL, R0 HAS BLOCK #, ;AND Z =1 IF FIRST LOGICAL BLOCK ON REEL LBCHK: CLR R1 ;REEL COUNTER =0 LBCH1: CMP R0,#512. ;REACHED RIGHT REEL? BLT LBCH2 ;YES SUB #512.,R0 ;NOT YET INC R1 ;NOTE BR LBCH1 ;CONITINUE LBCH2: MOV R0,-(SP) ;SAVE LOGCAL BLOCK MOD 512. ADD #LB0,R0 ;CONVERT TO ABSOLUTE BLOCK IN TAPE MOV R1,R2 ; ADD #DTABL,R2 ; LBCH3: TST (SP)+ ;SET CC'S ON LOGICAL BLOCK # RTS PC ;AND EXIT .SBTTL MAGTAPE ROUTINES.... ;INPUT FROM MAGTAPE MTIN: JSR PC,MTRWSK ;PERFORM REWIND AND SKIP IF NEEDED MOV #MTRD,DTPAR ;FUNCTION IS READ TST MTRWD ;CHECK FOR LABEL CHECKING TIME BEQ MTIN1 ;GO DO LABEL CHECKING MTIN3: MOV #BUF,DTPAR+4 ;SET UP TRANSFER ADDR MOV ILBEND,R0 ;LAST BLOCK TO READ MOV ILBEND+2,R1 ; JSR R5,ROOM ;COMPUTER NUMBER OF BLOCKS TO READ + ILB ;CURRENT INPUT BLOCK + DTPAR+6 ;NUMBER OF BLOCKS STORED HERE JSR PC,MTGO ;PERFORM READ RTS PC MTIN0: JSR PC,MTRW3 ;SKIP TO EOF MTIN1: MOV #BUF1,DTPAR+4 ;LABEL CHECKING MOV #-LBLSIZ,DTPAR+6;JUST READ LABEL BLOCK BIT #MM,FLAGS ;GUESS WHO AGAIN BEQ 1$ BIT #MMBOT,@#MMDS ;BOT ON TJU BEQ 2$ ;NO MOV #MTBOT,-(SP) ;YES BR 3$ 2$: CLR -(SP) ;NO BR 3$ 1$: MOV MTAS,-(SP) ;SAVE BOT FLAG 3$: JSR PC,MTGO ;READ LABEL MOV #BUF1,R0 CMP (R0)+,MTNAM0 ;VERIFY FILE NAME BNE MTIN9 CMP (R0)+,MTNAM1 BNE MTIN9 CMP (R0)+,(PC)+ ;CHECK EXTENSION .RAD50 /ROL/ ;REQUIRED EXTENSION BNE MTIN9 MTIN8: BIT #MTBOT,(SP)+ ;ARE WE AT BOT? BEQ MTIN7 ;NO... BIT #MM,FLAGS ;FOR WHO BEQ 1$ MOV #MMDC,@#MMCSR1 ;DRIVE CLEAR MOV #-2,@#MMFC ;SKIP 2 BLOCKS MOV #MMSF,@#MMCSR1 ;PAST BOOT AND ROLLIN IMAGE BIT #MMDRY,@#MMDS ;WAIT UNTIL DONE BEQ .-6 BIT #040000,@#MMCSR1 ;ERROR BNE MTFTL ;YES-GO DIE BR MTIN7 ;CORRECTLY DONE 1$: MOV #MTABRC,R0 ;NOW PERFORM SKIP MOV #-2,(R0) ;THATS TWO RECORDS TO SKIP TST -(R0) MOVB #MTSF+1,(R0) ;EXECUTE SKIP FUNCTION TSTB (R0) BPL .-2 TST (R0) ;CHECK FOR ERROR BMI MTFTL ;IF ERROR ITS FATAL MTIN7: CLR DTPAR+6 ;READ ROLLIN LABEL JSR PC,MTGO ;DO READ CMP MTREEL,BUF1 ;CHECK REEL NUMBER BNE MTIN2 MTIN4: INC MTREEL ;FOR NEXT REEL IF NEEDED MOV #-1,MTRWD ;SET FLAG BACK TO NORMAL CLR MTFIND ;CLEAR FIND FLAG BR MTIN3 MTIN9: TST (SP)+ ;FLUSH BOT FLAG OFF STACK TST MTLIST ;LIST FOUND FILE NAME BEQ 17$ ;NO-OK SKIP NEXT MOV #BUF1,R4 ;SET UP TO CONVERT RAD50 TO ASCII MOV #AFILNM,R5 ;DESTINATION JSR PC,18$ JSR PC,18$ ;2 WORDS OF FILE NAME MOVB #'.,(R5)+ ;SEPERATOR JSR PC,18$ ;EXT JSR R5,MES ;OUTPUT NAME + FND BR 17$ ;AND CONTINUE 18$: MOV #3,R1 MOV #20$,R3 MOV (R4)+,R2 15$: TST -(R3) MOV #-1,R0 CMP #174777,R2 BCS 4$ 5$: INC R0 SUB (R3),R2 BCC 5$ ADD (R3),R2 TST R0 BEQ 6$ CMP #33,R0 BCS 10$ BEQ 11$ 4$: ADD #40,R0 6$: ADD #16,R0 10$: ADD #11,R0 11$: ADD #11,R0 MOVB R0,(R5)+ DEC R1 BNE 15$ RTS PC .WORD 1,50,3100 20$: .WORD 0 17$: TST MTFIND ;ARE WE LICENSED TO FIND FILE? BEQ .+6 JMP MTIN0 JSR PC,BKSP ;RESET TAPE POSITION JSR R5,MES ;BAD FILE NAME.. + BFN MTINX: JMP XCOMC ;ABORT MTIN2: JSR R5,INPUT ;LABEL CHECK ERROR + DTWRRL CMPB (R0),#'P ;PROCEED ANYWAY? BEQ MTIN4 ;BR IF P MTIN6: CMPB (R0),#'M ;MOUNT A NEW REEL? BEQ MTIN5 ;BR IF M MABORT: JMP COMCON ;ELSE KILL REQUEST MTIN5: JSR R5,INPUT ;WAIT FOR TAPE TO BE MOUNTED + MTMONT INC MTRWD ;FORCE REWIND JMP MTIN ;AND TRY AGAIN MTFTL: JMP MTRWF ;FATAL ERROR BRANCH .SBTTL OUTPUT TO MAGTAPE MTOUT0: JSR R5,MES ;WRITE LOCK ERROR + ERRMWL JSR R5,INPUT + ERRMX ;TRY AGAIN? CMPB (R0),#'K ;DOES HE WANT TO ABORT BEQ MABORT ;YES MTOUT: BIT #MM,FLAGS ;LOOK FAMILAR BEQ 1$ BIT #MMWRL,@#MMDS ;WRITELOCKED BNE MTOUT0 BR 2$ 1$: BIT #MTWRL,MTAS ;CHECK FOR SELECT ERRORS BNE MTOUT0 ;BRANCH IF WRITE LOCK 2$: TST MTFIND ;CHECK FOR FORCE END-OF-TAPE BEQ MTOUTA ;NO.. CLR MTFIND ;ONCE ONLY PLEASE MOV #-1,MTSKIP ;SKIP ALL FILES ON TAPE MTOUTA: JSR PC,MTRWSK ;PERFORM REWIND AND SKIP IF NEEDED MOV #MTWT,DTPAR TST MTRWD ;CHECK FOR LABEL WRITING BEQ MTOUT1 ;GO TO LABEL WRITE ROUTINE MTOUT3: MOV #BUF,DTPAR+4 ;LOAD BUFFER ADDRESS MOV OLBEND,R0 ;LAST BLOCK TO WRITE MOV OLBEND+2,R1 ; JSR R5,ROOM ;COMPUTE NUMBER OF BLOCKS TO WRITE + OLB ;CURRENT OUTPUT BLOCK + DTPAR+6 ;NUMBER OF BLOCKS JSR PC,MTGO ;PERFORM WRITE RTS PC MTOUT1: MOV #BUF1,R0 MOV R0,DTPAR+4 ;BUFFER ADDRESS FOR WRITE BIT #MM,@#FLAGS BEQ 1$ BIT #MMBOT,@#MMDS ;BOT BEQ 2$ ;NO MOV #MTBOT,-(SP) ;YES BR 3$ 2$: CLR -(SP) ;NO BR 3$ 1$: MOV MTAS,-(SP) ;SAVE BOT FLAG 3$: MOV #MTNAM0,R1 MOV (R1)+,(R0)+ ;STORE FIRST WORD OF NAME BNE MTOUT6 ;NAME MUST BE SPECIFIED... JSR R5,MES ;NO NAME SPECIFIED + NFN BR MTINX ;ABORT MTOUT6: MOV (R1)+,(R0)+ MOV (PC)+,(R0)+ ;EXTENSION .ROL ALWAYS.. .RAD50 /ROL/ MOV #401,(R0)+ ;UIC = 1,1 MOV #233,(R0)+ ;PROTECTION = 233 MOV (R1)+,(R0)+ ;DATE WORD CLR (R0) ;UNUSED WORD MOV #-LBLSIZ,DTPAR+6;FLAG IT AS LABEL RECORD JSR PC,MTGO ;DO WRITE CLR DTPAR+6 ;NEXT TIME WRITE 256 WORDS.. BIT #MTBOT,(SP)+ ;TIME TO WRITE ROLLIN? BEQ MTOUT4 ;NO... MTOUT5: MOV #MTBOOT,DTPAR+4 ;WRITE BOOTSTRAP JSR PC,MTGO ;DO WRITE MOV #BOOT,DTPAR+4 ;WRITE ROLLIN ITSELF MOV #SIZBLK,DTPAR+6 ;ROLLIN SIZE IN BLOCKS JSR PC,MTGO ;DO WRITE MTOUT4: MOV #BUF1,R0 MOV R0,DTPAR+4 ;SET UP BUFFER ADDRESS CLR DTPAR+6 ;RECORD IS 256 WORDS MOV MTREEL,(R0)+ ;STORE REEL NUMBER INC MTREEL ;FOR NEXT LABEL IF ANY MOV #255.,R1 ;CLEAR THE REST OF THE BLOCK MTOUT2: CLR (R0)+ DEC R1 ;SOB R1,MTOUT2 BNE MTOUT2 JSR PC,MTGO ;WRITE ROLLIN LABEL MOV #-1,MTRWD ;SET FLAG TO NORMAL BR MTOUT3 .SBTTL MAGTAPE IO DRIVER MTGO: MOV #15.,R4 ;LOAD ERROR COUNT MTGO0: BIT #MM,FLAGS BEQ 1$ MOV DTPAR+4,@#MMBA ;LOAD BUFFER ADDRESS MOV DTPAR+6,R0 ;GET WORDCOUNT BLT 2$ ;ACT LENGHT IN BYTES BNE .+4 ;SIZE IN BOCKS INC R0 ;LABEL -MAKE 256 WORDS LONG SWAB R0 ;MUL BY 256 NEG R0 ;AND MAKE NEGATIVE BR 6$ 2$: ASR R0 ;CONVERT BYTE COUNT TO WC 6$: MOV R0,@#MMWC ASL R0 MOV R0,@#MMFC CMP #MTRD,DTPAR ;WAS IT A READ BEQ 3$ ;IF YES HANDLE ELSEWARE MOV #MMWR,@#MMCSR1 ;MUST BE A WRITE(NO XIRG WRITES FOR TJU) BR 4$ 3$: MOV #MMRD,@#MMCSR1 ;DO READ 4$: TSTB @#MMCSR1 ;WAIT UNTIL DONE BGE 4$ BIT #40000,@#MMCSR1 ;ERROR??? BNE MTGO1 ;HAH GOTYA TST @#MMWC ;RECORD LENGTH ERROR BNE 5$ ;NOT RIGHT BR MTGOX 5$: TST MCOPYX BGE MTGOX MOVB @#MMWC+1,R0 ;GET BLOCKS NOT READ ADD R0,BUFSIZ MOV #MTXAB,IN BR MTRW3 1$: MOV #MTACMA,R1 MOV DTPAR+4,(R1) ;LOAD BUFFER ADDRESS MOV DTPAR+6,-(R1) ;LOAD BLOCK COUNT BLT MTG16 ;IF NEGATIVE IT'S THE ACTUAL SIZE MTGO0A: BNE .+4 ;IS IT LABEL (0 LENGTH) INC (R1) ;YES...MAKE IT 256 WORDS LONG. ASL (R1) SWAB (R1) ;AND MULTIPLY BY 512 NEG (R1) MTG16: TST -(R1) ;R1 = MTAC MOVB DTPAR,(R1) ;LOAD FUNCTION TSTB (R1) ;WAIT TILL DONE BPL .-2 TST (R1) BMI MTGO1 ;BRANCH IF ERROR TST (R1)+ TST (R1)+ ;WAS A SHORT RECORD READ?? BNE MTGO2 ;BRANCH IF SO (OUCH) MTGOX: RTS PC ;NO ERRORS...WASN'T THAT EASY MTGO2: TST MCOPYX ;ARE WE COPYING MAGTAPE? BGE MTGOX ;YES....SO IGNORE THIS ERROR MOVB -(R1),R0 ;RECORD WAS LESS THAN I WANTED ASR R0 ;GET NUMBER OF BLOCKS NOT READ ADD R0,BUFSIZ ;AND ADJUST BUFSIZ FOR WRITE MOV #MTXAB,IN ;FUDGE NEXT CALL TO @IN TO ABORT MTRW3: CLR R2 ;DON'T ABORT AT EOF! MOV #1,MTSKIP ;SKIP TO EOF BR MTRW2 ;FALL OUT THRU SKIP MTGO1: DEC R4 ;CHECK ERROR COUNT BEQ MTRWF. ;BRANCH TO FATAL ERROR BIT #MM,FLAGS ;YAWN BEQ 1$ BIT #20400,@#MMCSR2 BNE MTGO1A BIT #2004,@#MMDS BNE MTGO1A BIT #100000,@#MMER BNE MTGO1A BR 2$ 1$: TST -(R1) BMI MTRWF. ;ILLEGAL COMMAND IS FATAL ERROR BIT #MTEOF+MTCRE+MTPAE+MTEOT,(R1) ;IS IT AN INTERESTING ERROR BNE MTGO1A ;CONTINUE IF NORMAL ERROR BIT #MTRLE,(R1) ;IS IT A PHONY ERROR BEQ MTGO0 ;RETRY ON OTHER ERRORS 2$: TST MCOPYX ;IS IT MAGTAPE COPY? BGE MTGOX ;IF NOT IGNORE RECORD LENGTH ERRORS JSR R5,MES ;ELSE RECORD IS TOO LONG FOR BUFFER + MTARTL ;TELL HIM ABOUT IT JMP MTRWA. ;AND ABORT MTGO1A: BIT #MM,FLAGS ;ZZZZZ BEQ 1$ BIT #MMTM,@#MMDS BEQ MTGO3 BR 2$ 1$: BIT #MTEOF,(R1) ;CHECK FOR END OF FILE BEQ MTGO3 ;BRANCH IF NOT 2$: TST MCOPYX ;IS IT MAGTAPE COPY? BLT 17$ ;IF NOT DO SPECIAL CHECK COM R4 ;MAKE R4 NEGATIVE TO INDICATE EOF RTS PC ;AND EXIT 17$: TST DTPAR+6 ;WERE WE TRYING TO READ LABEL BGE MTGO1B ;NO... JSR R5,MES ;CANT FIND FILE + CNF JMP MTRWA. ;FATAL ERROR ;WE HAVE READ EOF...OPEN ANOTHER REEL MTGO1B: JSR R5,MES ;TELL HIM ABOUT IT + MTEOF0 JSR R5,INPUT + MTEOF1 TST (SP)+ ;FLUSH MTGO RETURN OFF STACK JMP MTIN6 ;AND GET RESPONSE TO QUESTION MTGO3: BIT #MM,FLAGS BEQ 2$ BIT #MMCRC+MMLRC+MMVPE,@#MMER BEQ MTGO4 BR 3$ 2$: BIT #MTCRE+MTPAE,(R1) ;PARITY ERROR? BEQ MTGO4 ;IF NOT IT MUST BE EOT 3$: JSR PC,BKSP ;BACKUP OVER THE LAST RECORD CMP DTPAR,#MTWT ;WAS THE FUNCTION A WRITE BNE 1$ ;NO..THEN CONTINUE MOV #MTWTX,DTPAR ;NEXT TRY WRITE WITH EXTENDED IRG 1$: JMP MTGO0 MTGO4: TST MCOPYX ;IS IT MAGTAPE COPY? BGE MTGOX ;IF SO IGNORE EOT! JSR PC,BKSP ;BACKUP OVER LAST RECORD JSR PC,WTEOF ;WRITE THE NECESSARY END OF FILE JSR R5,INPUT ;TELL HIM ABOUT THE PROBLEM + ERREOT CMPB (R0),#'M ;DOES HE WANT TO CONTINUE BEQ 1$ JMP MTRWA ;NO...SO ABORT THE OPERATION 1$: JSR R5,INPUT ;WAIT FOR TAPE MOUNTED + MTMONT MOV #1,MTRWD ;FORCE REWIND AND LABEL CHECKING TST (SP)+ ;FLUSH MTGO RETURN OFF STACK JMP MTOUT ;AND CONTINUE MTRWF.: JMP MTRWF .SBTTL SUBROUTINE CHECKS "REWIND" FLAG AND MTSKIP ;IF MTRWD = -1 NORMAL EXIT ; = 0 CHECK MTSKIP (AND DO LABEL CHECK) ; = +1 REWIND UNIT, THEN CHECK MTSKIP ;WHEN MTSKIP IS NON-ZERO IT CONTAINS THE NUMBER OF FILES TO SKIP... MTRWSK: MOV MTRWD,R0 ;GET FLAG BLT MTRWX1 ;NORMAL EXIT... BEQ MTRW0 ;GO CHECK MTSKIP JSR PC,REWIND ;REWIND THE MAGTAPE MTRW0: MOV #1,R2 ;IF WE SEE AN IMMEDIATE EOF IT EOD ON TAPE MTRW2: BIT #MM,FLAGS BEQ 1$ MOV #MMSF-1,@#MMCSR1 BR 2$ 1$: MOV #MTAC,R1 ;SET UP R1 JUST IN CASE MOVB #MTSF,(R1) ;SET FOR SKIP FORWARD 2$: TST MTSKIP ;ARE THERE ANY SKIPS TO DO? BEQ MTRWX ;BRANCH IF NOT... .SBTTL ROUTINE SKIPS N FILES MTSK: BIT #MM,FLAGS BEQ 1$ MOV #MMCLR,@#MMCSR2 ;DRIVE CLEAR CLR @#MMFC INC @#MMCSR1 BIT #MMDRY,@#MMDS BEQ .-6 BIT #MMTM,@#MMDS BEQ 3$ MOV #MMCLR,@#MMCSR2 BR 2$ 3$: JMP MTRWF 1$: MOV #MTABRC,R1 ;LOAD R1 CLR (R1) INC -(R1) ;AND SET GO BIT TSTB (R1) ;WAIT FOR EOF ERROR BPL .-2 BIT #MTEOF,-(R1) BEQ 3$ ;ANYTHING OTHER THAN EOF IS FATAL 2$: DEC MTSKIP ;ARE WE DONE? BNE MTSK1 MTRWX: CLR MTRWD ;CLEAR MAGTAPE FLAG MTRWX1: RTS PC ;AND EXIT MTSK1: BIT #MM,FLAGS BEQ 1$ CMP #1,@#MMFC BNE MTSK3 BR 2$ 1$: CMP (R1)+,(R1)+ CMP #1,(R1) ;WAS IT AN IMMEDIATE EOF? BNE MTSK3 ;IF NOT CONTINUE 2$: DEC R2 ;WAS IT SECOND EOF IN A ROW? BNE MTSK JSR PC,BKSP CMP OUT,#MTOUT ;IS THIS OK?? BEQ MTRWX ;YEP.THATS WHERE WE WANT TO BE JSR R5,MES ;TELL HIM WE AT THE END OF TAPE + ERREOD MTRWA.: BR MTRWA ;AND QUIT MTSK3: MOV #1,R2 ;RESET R2 TO EOF STATE BR MTSK .SBTTL CLOSE OUTPUT FILE ON MAGTAPE WTEOF: MOV #3,R4 ;WRITE 3 EOF RECORDS WTEOF1: BIT #MM,FLAGS BEQ 1$ MOV #MMDC,@#MMCSR1 ;DRIVE CLEAR MOV #MMWEOF,@#MMCSR1 BIT #MMDRY,@#MMDS BEQ .-6 BR 2$ 1$: MOV #MTAC,R0 MOVB #MTWTE,(R0) ;EXECUTE WRITE EOF TSTB (R0) BPL .-2 ;WAIT FOR DONE 2$: DEC R4 BGT WTEOF1 ;PERFORM 3 TIMES MOV #2,MTSKIP ;NOW SKIP BACK OVER 2 EOF'S CLR R2 ;FUDGE COUNT FOR MTSK BIT #MM,FLAGS BEQ 3$ MOV #MMSB-1,@#MMCSR1 BR MTSK 3$: MOVB #MTSR,(R0) ;LOAD NEW FUNCTION BR MTSK ;AND FALL OUT THROUGH MTSK .SBTTL BACKSPACE OVER RECORD JUST READ/WRITTEN BKSP: BIT #MM,FLAGS BEQ 1$ MOV #MMDC,@#MMCSR1 ;DRIVE CLEAR MOV #-1,@#MMFC MOV #MMSB,@#MMCSR1 BIT #MMDRY,@#MMDS BEQ .-6 RTS PC 1$: MOV #MTABRC,R1 ;SET UP R1 MOV #-1,(R1) ;AND SKIP ONLY ONE RECORD TST -(R1) MOVB #MTSR+1,(R1) ;EXECUTE SKIP REVERSE TSTB (R1) BPL .-2 ;WAIT FOR DONE RTSX: RTS PC ;AND EXIT .SBTTL SUBROUTINE REWINDS THE SELECTED MAGTAPE REWIND: TST MTSTAY BNE RTSX BIT #MM,FLAGS BEQ 1$ BIT #MMBOT,@#MMDS BNE RTSX MOV #MMDC,@#MMCSR1 ;DO DRIVE CLEAR ON UNIT 0 BIT #MMDRY,@#MMDS ;DONE BEQ .-6 ;WAIT UNTILL DONE MOV #MMRW,@#MMCSR1 BIT #MMDRY,@#MMDS BEQ .-6 MOV #MMDC,@#MMCSR1 ;DO DRIVE CLEAR ON UNIT 0 BIT #MMDRY,@#MMDS ;DONE BEQ .-6 ;WAIT UNTILL DONE BR RTSX ; BIT #40000,@#MMCSR1 ; BEQ RTSX ; BR MTRWF 1$: MOV #MTAS,R1 BIT #MTBOT,(R1)+ ;ARE WE AT BOT? BNE RTSX ;IF SO FORGET ABOUT REWIND MOVB #MTREW,(R1) ;REWIND TAPE TST -(R1) ;LOOK AT STATUS REGISTER BIT #MTTUR,(R1) ;WAIT ON UNIT READY BEQ .-4 TST (R1) BPL RTSX ;IF OK THEN EXIT MTRWF: JSR R5,MES ;FATAL MAGTAPE ERROR + ERRMTF MTRWA: JMP COMCON ;ABORT .SBTTL SUBROUTINE COMPUTES THE NUMBER OF DECTAPE BLOCKS OR DISK .SBTTL SECTORS (256 WORDS IN BOTH CASES) TO TRANSFER. ; ONLY THE ;LAST TRANSFER CAN BE A PARTIAL TRANSFER. ROOM1: ADD #LB0,R0 ;TAKE UNUSED DECTAPE BLOCKS INTO ACCOUNT SUB @(R5)+,R0 ;SUBTRACT CURRENT BLOCK NUMBER SUB BUFSIZ,R0 ;SUBTRACT BUFFER SIZE AVAILABLE BR ROOMCK ; ROOM: MOV (R5)+,-(SP) ;STACK ADDRESS OF CRRENT BLOCK NUMBER MOV (SP),-(SP) ;TWICE ADD #2,2(SP) ;POINT TO MSB OF CURRENT BLOCK # SUB @(SP)+,R0 ;SUBTRACT CURRENT BLOCK NUMBER SBC R1 ;(DOUBLE PRECISION FOR DEM BIG DISKS) SUB @(SP)+,R1 ; SUB BUFSIZ,R0 ;SUBTRACT BUFFER SIZE AVAILABLE SBC R1 ; ROOMCK: BMI 1$ ;SKIP IF LAST TRANSFER(PARTIAL BLOCK) CLR R0 ;ELSE WILL JUST USE BUFFER SIZE 1$: ADD BUFSIZ,R0 ; MOV R0,@(R5)+ ;STORE RESULT IN PARAMETER BLOCK RTS R5 ;AND QUIT INPUT: MOV (R5)+,R0 ;COMBINATION OF PROMPTER, INPUTER MOV R5,-(SP) ;SAVE RETURN MOV #GETIN,R5 ;SET INTERMEDIATE RETURN BR MESS01 ;BUT FIRST, TYPE MESSAGE MES: MOV (R5)+,R0 ;STRING ADDRESS MESS01: MOVB (R0)+,R2 ;CHARACTER TO R2 BEQ MESS04 ;ITS END OF STRING TIME. JSR PC,INIOUT ;OUTPUT THE CHARACTER IN R2 .SBTTL CODE TO CHECK FOR ^O... MESS03: TSTB @I.TKS ;HAS HE BEEN TYPING BPL MESS02 ;...NO MOV @I.TKB,R2 BIC #-177-1,R2 ;LOW 7 BIT OF CHARACTER TYPED CMPB R2,#17 ;IS IT CTRL/O? BNE MESS02 ;...NO JSR PC,INICTL ;ECHO CHARACTER MESS04: RTS R5 ;GO HOME MESS02: TSTB @I.TPS ;READY FOR NEXT CHAR OUTPUT? BPL MESS03 ;...NO BR MESS01 ;AND CONTINUE INICR: MOV #15,R2 ;FIRST THE JSR PC,INIOUT ;TO THE TTY MOV #12,R2 ;AND NOW THE INIOUT: TSTB @I.TPS ;READY? BPL INIOUT ;NOT YET MOV R2,@I.TPB ;YES-OUTPUT IT JMP INFILL ;NO GO CHECK FOR FILL GETIN: CLR RBFLAG ;CLEAR FLAG MOV #KBUF,R0 ;USE FISTAK FOR BUFFER MOV R0,R1 ;MARK BEGINNING OF BUFFER GETI01: TSTB @I.TKS ;ANYTHING WAITING? BPL GETI01 ;JUST THIS LOOP... MOV @I.TKB,R2 ;GET CHARACTER FROM TTY BIC #-177-1,R2 ;USE LOW ORDER 7 BITS BEQ GETI01 ;IGNOR NULLS CMPB R2,#177 ;IS IT A RUBOUT? BEQ GETI02 ;YES TST RBFLAG ;RUBOUT FLAG - IS IT SET? BEQ GETI10 ;SKIP AROUND CRAP IF NOT CLR RBFLAG MOV R2,-(SP) ;SAVE R2 SO WE CAN PRINT \ MOV #'\,R2 JSR PC,INIOUT ;ECHO BACKSLASH MOV (SP)+,R2 ;RESTORE CHARACTER GETI10: CMPB R2,#25 ;IS IT A ^U? BEQ GETI08 ;YES--ECHO ^U, AND DELETTE LINE CMPB R2,#40 ;IS IT A SPACE? BEQ GETI05 ;YES CMPB R2,#15 ;IS IT A ? BEQ GETI07 ;YES CMPB R2,#3 ;DID HE TYPE A ^C BEQ GETI09 ;YES--BACK TO COMCON GETI06: MOVB R2,(R0)+ ;JUST A PLAIN, OLD CHARACTER, SO STORE IT GETI03: JSR PC,INIOUT ;AND ECHO IT BR GETI01 ;AND WAIT SOME MORE GETI02: CMP R0,R1 ;IT'S A RUBOUT, ANYTHING IN BUFFER? BEQ GETI04 ;NO, SO ECHO CRLF0 TST RBFLAG ;IS RUBOUT FLAG SET? BNE GETI11 ;NO NEED TO TYPE \ IF IT IS MOV #'\,R2 JSR PC,INIOUT ;ECHO BACKSLASH MOV R2,RBFLAG ;SET THE RUBOUT FLAG GETI11: MOVB -(R0),R2 ;GET THE CHARACTER PREVIOUSLY TYPED BR GETI03 ;AND ECHO IT GETI08: MOV R1,R0 ;FOR ^U, RESET TO START OF LINE JSR PC,INICTL ;EMPTY BUFFER- ECHO ^U BR GETI01 ;AND CONTINUE GETI04: JSR PC,INICR ;ECHO A CRLF BR GETI01 ;AND WAIT GETI09: JSR PC,INICTL ;ECHO HIS ^C JMP COMCON ;AND BACK TO COMCON GETI05: CMP R0,R1 ;IGNORE LEADING SPACES--IS THIS A LEADING SPACE? BEQ GETI03 ;YES-IGNORE IT BR GETI06 ;NO-PRESERVE IT GETI07: MOVB R2,(R0) ;STORE THE CHARACTER MOV R1,R0 ;R0 POINTS TO START OF STRING JSR PC,INICR ;OUTPUT A RTS R5 ;RETURN INICTL: ADD #100,R2 ;CONVERT CONTROL CHAR TO PRINTING CHAR MOV R2,-(SP) ;SAVE IT FOR NOW MOV #'^,R2 ;AND TYPE THE ^ JSR PC,INIOUT ;TYPER MOV (SP)+,R2 ;NOW THE CHARACTER JSR PC,INIOUT ;ECHO IT BR INICR ;TYPE THE AND EXIT .SBTTL ROUTINE TO INITIALIZE EVERYTHING INI: CLR R0 ;LOAD INITIAL VECTORS MOV #137,(R0)+ ;SET UP RESTART ADDR (0) MOV #START,(R0)+ MOV #ST2,(R0)+ ;SET UP TRAP VECTOR FOR ILL MEM REF MOV #7*40,(R0) MOV #100000,R0 ;TRY FOR A 16K BUFFER FIRST BR ST3 ;ENTER TEST LOOP ST2: CMP (SP)+,(SP)+ ;CLEAR TRAP GARBAGE OFF STACK CLC ;DON'T ROTATE BIT IN ROR R0 ;TRY A SMALLER BUFFER THIS TIME ST3: TST BUF-2(R0) ;FIND OUT IF THE LAST WORD IS THERE SWAB R0 ;IT IS NOW FOR SURE ,DIVIDE BY 256. ASR R0 ;DIVIDE BY 512 BYTES MOV R0,BUFSIZ ;STORE BUFFER SIZE IN BLOCKS MOV #-1,R2 ;DTABL INITIALIZED TO 16 BYTES ALL NEGATIVE MOV #DTABL,R0 ;THATS REALLY 8 WORDS MOV #8.,R1 INI0: MOV R2,(R0)+ DEC R1 BGT INI0 CLR NUM ;CLEAR SO /NUMBER OVERRIDES /DISK CLR NUM+2 ; MOV #1,DISKS ;# DISKS = 1 CLR LABEL ;LABEL = 0 FOR NORMAL PROCESSING, -1 OTHERWISE CLR TRACK ;FIRST TRACK TO READ/WRITE CLR TRACK+2 ; CLR FLAGS ;NOTHING SEEN IN SCAN (YET) CLR ILB0 ;INITIAL BLOCK TO READ CLR ILB0+2 ; CLR OLB0 ;INITIAL BLOCK TO WRITE CLR OLB0+2 ; CLR MTRWD ;CLEAR MAGTAPE FLAG CLR MTSKIP ;CLEAR MAGTAPE SKIP COUNT CLR MTDATE ;INITIALIZE DATE CLR MTFIND ;INITIALIZE FIND FLAG CLR V4A ;INITIALIZE V4A FLAG CLR PFMT ;CLEAR PACK FORMAT FLAG CLR VERIFY ;INITIALIZE VERIFY FLAG CLR MTLIST ;INIT LIST FILE NAME FLAG CLR MTSTAY ;CLEAR HOLD REWIND FLAG MOV #-1,MCOPYX ;TURN OFF MAGTAPE COPY FLAG MOV #1,MTREEL ;INITIALIZE MAGTAPE REEL NUMBER ;DETERMINE IF WE HAVE AN RF OR RC DISK INI3: MOV #INI2,@#4 ;STORE TRAP TO INI2 TST @#RFDAE ;TRAP IF NO RF MOV #RFDAE,DSKDAE ;SET UP POINTER TO EX. ADDR MOV #256.,TRACKS ;NUMBER OF TRACKS ON ONE DISK INI4: MOV #NXD,@#4 ;SET UP NON-EXISTANT DEVICE ERROR RTS PC ;ALL INTIALIZED ;INIT FOR RC11 ASSUMED INI2: CMP (SP)+,(SP)+ ;FLUSH TRAP GARBAGE OFF STACK MAKERC: CLR DSKDAE ;SET TO SHOW THAT ITS AN RC11 MOV #64.,TRACKS ;64K ON ONE PLATTER BR INI4 ATOI: CLR R2 ;CLEAR RESULT REGISTERS CLR R3 ;DOUBLE PRECISION FOR BIG DISKS ATOI1: MOVB (R0)+,R4 ;GET DIGIT SUB #'0,R4 ;CONVERT TO BINARY BMI ATOI2 ;NOT A DIGIT - FIX R0 AND EXIT CMP R4,#'9-'0 ;IN RANGE? BGT ATOI2 ;NOPE, SO QUIT ASL R2 ;MULTIPLY OLD VALUE BY 10 ROL R3 ;(DOUBLE PRECISION) MOV R3,-(SP) ; MOV R2,-(SP) ; ASL R2 ; ROL R3 ; ASL R2 ; ROL R3 ; ADD (SP)+,R2 ; ADC R3 ; ADD (SP)+,R3 ; ADD R4,R2 ;AND ADD NEW DIGIT TO THAT PRODUCT ADC R3 ; BR ATOI1 ;CONTINUE ATOI2: DEC R0 ;MAKE IT POINT TO BADDY RTS PC ;AND RETURN REGSAV: MOV R4,-(SP) ;SAVE REGISTERS R0 - R5 MOV R3,-(SP) ; MOV R2,-(SP) ; MOV R1,-(SP) ; MOV R0,-(SP) ; MOV 12(SP),-(SP) ; RTS R5 ; REGRES: TST (SP)+ ;REGISTER RESTORE MOV (SP)+,R0 ; MOV (SP)+,R1 ; MOV (SP)+,R2 ; MOV (SP)+,R3 ; MOV (SP)+,R4 ; RTS R5 ; INFILL: MOV R0,-(SP) ;SAVE R0 MOV #I.FILL,R0 ;AND GET FILL LIST 1$: TSTB (R0) ;ANY IN LIST? BEQ 2$ ;NOPE CMPB R2,(R0)+ ;YES, CHECK FOR MATCH BEQ 3$ ;FOUND MATCH INC R0 ;NOPE, SKIP COUNT BR 1$ ;AND TRY AGAIN 3$: MOVB (R0),R0 ;GET FILL COUNT MOV R2,-(SP) ;SAVE CHAR CLR R2 ;AND CHANGE TO NULL 4$: JSR PC,INIOUT ;SEND ONE DEC R0 ;MORE? BGT 4$ ;YEP MOV (SP)+,R2 ;NOPE, RESTORE CHAR 2$: MOV (SP)+,R0 ;RESTORE R0 RTS PC ;AND EXIT .CSECT I.FILL I.FILL: .BYTE 0,0 ;DUMMY FILL LIST .CSECT I.TKS I.TKS: .WORD 177560 I.TKB: .WORD 177562 I.TPS: .WORD 177564 I.TPB: .WORD 177566 .SBTTL MESSAGES .CSECT MESSAG .NLIST BEX HELPER: .ASCII %THE STANDARD COMMAND STRING FORMAT IS:% .BYTE 15,12,15,12 .ASCII % #DEV:[/FORMAT OPTION]