.TITLE DISASM ; ; L H GERHARDSTEIN ; 12/11/73 ; ; MODIFIED BY J.E. POLLACK, U.OF WASH, OCT 1975 ; ; MODIFIED BY A.J. CAPPELLO, RCA CHERRY HILL N.J. (RSX-11M SUPPORT) ; ; Modified by U.Schmeling CSA Da-Weiterstadt (RSX-11M/PLUS V4.1) ; ; Modified by U.Schmeling Nov 1989 increase segment size to 256. ; .SBTTL SYSTEM PARAMETERS ; ER.OA=1 ER.SF=2 ; MAXSEG=256. ; MAXIMUM SEGMENTS IN OVERLAY TABLE ; .SBTTL MACRO DEFINITIONS .library /lb:[1,1]exemc/ .MCALL DIR$,EXIT$S,SVTK$,GTIM$,LBLDF$,HDRDF$ ; ; DEFINE TASK IMAGE DATA STRUCTURES ; LBLDF$ ; DEFINE LABLE BLOCK OFFSETS HDRDF$ ; DEFINE HEADER BLOCK OFFSETS ; .SBTTL MISCELLANEOUS STORAGE ; .EVEN MaxAdr::.word 0 ; ***USC001 highest virtual address of task InPC:: .word 0 ; initial PC LOW:: .WORD 0 ; LOW ADDR HIGH:: .WORD 177777 ; HIGH ADDR CNT3:: .WORD 0 CNT4:: .WORD 0 FLAG:: .WORD 0 ; DATA ON LINE SWITCH ADRER:: .WORD 0 ; POINTER ERROR SWITCH LINES:: .WORD 0 ; LINES ON PAGE COUNT LINCT:: .WORD 0 ; LINES SINCE EXTRA LF COUNT PAGE:: .WORD 0 ; PAGE COUNTER ADR:: .WORD 0 ; POINTER B0.2:: .WORD 0 ; INST BITS 0-2 B0.5:: .WORD 0 ; INST BITS 0-5 B6.8:: .WORD 0 ; INST BITS 6-8 B6.11:: .WORD 0 ; INST BITS 6-11 INST:: .WORD 0 ; INSTRUCTIONS R0WD:: .WORD 0 ; WORD BUFFER POINTER .SWITCH::.WORD 0 ; ACTION SWITCH PRSWIT::.WORD 0 ; PREV SWITCH VALUE ASCSW:: .WORD 0 ; .ASCII SWITCH HDRSW:: .WORD 0 ; HDR COMMAND SWITCH KNLSW:: .WORD 1 ; KERNEL SWITCH TASK:: .BLKW 2 ; TASK NAME BUFFER (RAD50) STD:: .WORD 0 ; STD POINTER FPUSW:: .WORD 45. ; FLOATING POINT UNIT SWITCH ; .GETAD::$MGET ; ADDRESS OF ROUTINE TO FETCH NEXT VIRTUAL WORD ; .DBLOK::0,0 ; CURRENT VIRTUAL DISK BLOCK FOR DISK TASK IMAGES ; ; ; THE SEGMENT TABLE IS EXTRACTED FROM THE VIRTUAL TASK IMAGE ; AND DESCRIBES THE ADDRESSING CONSTANTS FOR THE TASKS SEGMENTS ; ; THE 'SEG=NAME' COMMAND PROVIDES ACCESS TO VARIOUS SEGMENTS OF THE TASK. ; ; SEGMENT TABLE OFFSETS: ; SGT.SZ==0 ; LOAD BYTE COUNT OF SEGMENT SGT.BL==2 ; DISK BLOCK ADDRESS (RELATIVE OF SEGMENT) SGT.BH==4 ; HIGH ORDER SGT.SN==6 ;,10 ; RAD50 NAME OF SEGMENT SGT.BA==12 ; LOAD ADDRESS OF SEGMENT SGT.BB==14 ; BYTE IN BLOCK SGT.SIZ==16 ; SIZE OF OUR FRAMES (BYTES) ; ; OFFSETS FOR TKB BUILT SEGMENT DESCRIPTOR TABLES ; ST.STA=0 ; STATUS/REL DISK ADDRESS ST.LA=2 ; LOAD ADDRESS ST.BC=4 ; LOAD BYTE COUNT ST.LUP=6 ; LINK UP ST.LDN=10 ; LINK DOWN ST.NXT=12 ; LINK NEXT ST.SN=14 ;,16 ; NAME 1/2 ST.SWDA=20 ; WINDOW DESCRIPTOR ADDRESS ST.SIZ=22 ; MAX SIZE OF ENTRY ; ; ; .Dummy:: 177777 ; SIZE OF FILE 1,0 ; START ADDRESS .RAD50 /.DUMMY/ 0 ; LOAD ADDRESS 0 ; BYTE IN BLOCK OF START OF FILE .CRSEG::.SEGRO ; POINTER TO CURRENT SEGMENT TABLE ENTRY ; .SEGLB:: 0 ; SIZE OF LABEL 1,0 ; START BLOCK ADDRESS OF LABEL .RAD50 /.LABL./ 0 ; LOAD ADDRESS 0 ; BYTE IN BLOCK OF START OF LABEL ; .SEGHD:: 0 ; SIZE OF HEADER 0,0 ; START BLOCK .RAD50 /.HEDR./ 0 ; LOAD ADDRESS 0 ; BYTE IN BLOCK OF START OF HEADER ; .SEGRO:: 177777 ; SIZE OF FILE 1,0 ; START ADDRESS .RAD50 /.FILE./ 0 ; LOAD ADDRESS 0 ; BYTE IN BLOCK OF START OF FILE ; .SEGTB:: .BLKW *MAXSEG ; TASK SEGMENTS . = .+SGT.SN+0 ; POSITION TO NEXT SEGMENT NAME LOCATION .WORD 0 ; STOPPER = 0 ; ; .COMMAND::0 ; ADDRESS OF COMMAND SUBROUTINE .STPTR::0 ; STRING FILL POINTER .LSPTR::0 ; LIST POINTER .SPSAV::0 ; TEMP STACK SAVE .TEMP:: 0 ; TEMPTEMP .TEMP0::0 ; ANOTHER .SRCSW::0 ; TASK LOCATION (0=KNL,-1=TASK,1=FILE) ; ; .CLRBEG: ; CLEAR BEFORE EACH COMMAND .STBUF::.BLKB 100. ; STRING BUFFER .LSBUF::.BLKW 16. ; 16-WORD BUFFER .NABUF::0,0 ; NAME STRING DESCRIPTOR .DESCM: 0 ; ADDRESS OF INPUT COMMAND DESCRIPTOR .PREFX::0 ; ADDRESS OF LINE PREFIX STRING .CLREND: ; ; ROOT: .RAD50 /.ROOT./ ; NAME FOR FILE ROOT SEGMENT SEGN: .RAD50 /SEG/ ; .SBTTL DIRECTIVE PARAMETER BLOCKS (DPB) ; SVTK: SVTK$ SSTTB,SSTTBL SSTTB: .WORD OASST .WORD SFSST SSTTBL=<.-SSTTB>/2 ; GTIM: GTIM$ TIME TIME: .BLKW 8. TIMEAD==TIME+G.TIYR ; ADDRESS OF BUFFER ; .SBTTL ASCII BUFFERS ; INPUT/OUTPUT BUFFER BUF:: BF.AD:: .BLKB 9. ; ADDRESS BUFFER BF.W1:: .BLKB 7. ; WORD 1 BUFFER BF.W2:: .BLKB 7. ; WORD 2 BUFFER BF.W3:: .BLKB 17. ; WORD 3 BUFFER BF.IN:: .BLKB 8. ; INSTRUCTION BUFFER BF.OP:: .BLKB 23. ; OPERANDS BUFFER .=BUF+132. ;132. TOTAL BUFSZ==.-BUF ; TITLE BUFFER TTLBF:: .BYTE 0 .BLKB 100. TTLBFE:: FILBUF:: .BLKB 40. .EVEN ; ; MESSAGE BUFFERS ; MSG ERRTNF,< TASK NAME NOT FOUND> MSG ERRTNR,< TASK NOT FIXED IN CORE> MSG ERRSYN,< COMMAND SYNTAX ERROR> MSG ERRNOT,< TASK NAME NOT SPECIFIED> MSG ERRNOS,< STD FOR TASK NOT FOUNT> MSG ERRIAD,< ILLEGAL ADDRESS REFERENCE> MSG ERRFPU,< ILLEGAL FPU VALUE (40. OR 45.)> MSG ERRUNI,< UNIMPLEMENTED COMMAND> MSG ERRFIL,< UNABLE TO ACCESS TASK FILE> MSG ERRFSU,< TASK FILE FETCH ERROR> MSG ERRKNH,< THE KERNAL HAS NO HEADER> MSG ERRSNF,< NO SUCH SEGMENT NAME IN SEGMENT TABLE> MSG ERRSGT,< SEGMENT TABLE OVERFLOW> MSG SYSIMG,< FILE CONTAINS SYSTEM IMAGE> ; ; TEXT BUFFERS ; PGE:: .ASCIZ / PAGE / BLKWTX::.ASCIZ /.BLKW / BCCTX:: .ASCIZ /BCC=BHIS / BCSTX:: .ASCIZ /BCS=BLO / ASCTX:: .ASCIZ /.ASCII / HDRTG:: .ASCIZ /H$+/ LABTG: .ASCIZ /L$+/ SEG:: .ASCIZ/ SEGMENT= / Instr:: .ASCIZ/ Initial PC: / .EVEN ; .SBTTL PDR/PAR BUFFER ; .PSECT $IMPURE,RW,D,GBL,CON ; ; ; PDR:: ; PAGE DESCRIPTOR REGISTERS PDR0: .WORD 0 PDR1: .WORD 0 PDR2: .WORD 0 PDR3: .WORD 0 PDR4: .WORD 0 PDR5: .WORD 0 PDR6: .WORD 0 PDR7: .WORD 0 PAR:: ; PAGE ADDRESS REGISTERS PAR0: .WORD 0 PAR1: .WORD 0 PAR2: .WORD 0 PAR3: .WORD 0 PAR4: .WORD 0 PAR5: .WORD 0 PAR6: .WORD 0 PAR7: .WORD 0 ; .SBTTL GET COMMAND LINE(S) .PSECT ; BGN: CALL $INITL ;INITALIZE COMMAND FDB'S AND FILE SYSTEM ; DIR$ #SVTK ; SETUP SST TV TABLE CALL .CMKNL ; ASSUME A KNL COMMMAND ; ;RESET FOR NEXT DISASSEMBLY ; BGN2: DIR$ #GTIM ; GET DATE/TIME BGN21: CLR PAGE ; PAGE = 0 BGN22: MOV #1000.,LINES ; LINES = LARGE CLR LINCT ; EXTRA LF COUNT CLR PRSWIT ; PREV .SWITCH = 0 = OCT ; GCOM:: MOV #.CLRBEG,R0 MOV #<.CLREND-.CLRBEG>/2,R1 5$: CLR (R0)+ SOB R1,5$ ;ZERO SOME SPACE ; MOV #.STBUF,.STPTR MOV #.LSBUF,.LSPTR ; CALL $GTCMD ;GET NEXT COMMAND, RETURN WITH ;R0=ADDRESS OF LINE DESCRIPTOR BCS .CMEXI ; EXIT IF EOF MOV R0,.DESCM ;SAVE DESCRIPTOR ADDRESS ; ; Uppercase conversion of input string ; MOV (R0),R1 ;***USC001 GET LENGTH OF COMMAND MOV 2(R0),R2 ;***USC001 GET ADDRESS OF COMMAND CLR r4 DECB r1 ;count from 0..length-1 16$: CMP R4,R1 ;loop for length BGT 66$ MOV R4,R3 ADD R2,R3 CMPB (R3),#141 BCS 62$ CMPB (R3),#172 BHI 62$ CLR R5 BISB (R3),R5 SUB #40,R5 MOVB R5,(R3) 62$: INC R4 BVC 16$ 66$: MOV #CMDTAB,R1 ;POINT TO COMMAND PARSET TABLE DESC. CALL $CMDPRS ;PARSE COMMAND BCS 10$ ;BR IF SYNTAX ERROR MOV .COMMAND,R2 ;GET ADDRESS OF COMMAND HANDLER BEQ GCOM ;NONE, GO FOR NEXT CALL (R2) ;CALL HANDLER BR GCOM ; 10$: CALL CMILL BR GCOM .SBTTL 'EXIT' COMMAND ; ; EX(IT) .CMEXI::JMP $EXIT ; CLOSE FILES AND LEAVE .SBTTL COMMAND HANDLERS ; ; ; ILLEGAL COMMAND ; CMILL: TYPMSG #ERRSYN SHOCMD: MOV .DESCM,R0 TYPMSG R0 RETURN ; .SBTTL 'ASC','DAT','SYM',AND 'OCT' COMMAND ; ; ASC(II) LOW HIGH ; DAT(A) LOW HIGH ; SYM(BOLIC) LOW HIGH ; OCT(AL) LOW HIGH .CMDIS:: MOV .LSBUF+0,LOW ; GET LOW LIMIT MOV .LSBUF+2,HIGH ;GET HIGH LIMIT CMP LOW,HIGH ; LOW MUST BE .LE. HIGH BLOS 20$ ;BR IF RANGE IS IN CORRECT ORDER ; TYPMSG #ERRIAD ;ILLEGAL ADDRESS RANGE RETURN ; 20$: CLR HDRSW ; CLEAR HDR .SWITCH ; PRNT: MOV #BUF,R0 ; INIT ASCII STRING POINTER TST .SWITCH ; CURRENT .SWITCH BEQ 5$ ; 0 = OCT TST PRSWIT ; PREV .SWITCH BNE 11$ ; 0 = OCT 5$: TST LINCT ; CHECK IF EXTRA LF'S BEQ 10$ ; NO CMP LINCT,#5 BEQ 10$ ; NO CALL $PUTBUF ; EXTRA LF INC LINES ; LINES = LINES +1 INC LINCT ; LINCT = LINCT +1 BR 5$ 10$: CLR LINCT 11$: MOV .SWITCH,R5 MOV R5,PRSWIT ; PREV .SWITCH ASL R5 ; 2*.SWITCH MOV LOW,ADR ; ADR = LOW ; ; JMP @20$(R5) ; DISPATCH TO PRINT ROUTINE 20$: .WORD OCT ; OCT .WORD SYM ; SYM .WORD SYM ; DAT .WORD SYM0 ; ASC .SBTTL 'PAR', AND 'PDR' COMMAND ; PAR= N0 N1 N2 ... ; PDR= N0 N1 N2 ... .ENABL LSB .CMPAR:: MOV #PAR,R1 ; FILL POINTER FOR PARS BR 10$ .CMPDR:: MOV #PDR,R1 ; FILL POINTER FOR PDRS 10$: MOV #.LSBUF,R2 ; SOURCE POINTER MOV #8.,R3 ; MAX COUNT 15$: DEC R3 ; COUNT ONE BLE 20$ ; DONE CMP R2,.LSPTR ; LAST MOVED? BHIS 17$ ; YES MOV (R2)+,(R1)+ ; SET NEXT BR 15$ 17$: CLR (R1)+ BR 15$ 20$: RETURN .DSABL LSB .SBTTL 'KNL' COMMAND ; KNL .CMKNL:: CALL CLRFIL MOV #KIPDR,R0 ; SET PAR/PDR TO KERNEL MOV #KIPAR,R1 CLR TASK ; CLEAR TASK NAME .SWITCH MOV #1,KNLSW ; SET KERNEL .SWITCH RETURN ; BR SETMAP .SBTTL 'PAG' COMMAND ; ; PAG(E) .CMPAG:: CLR LINCT ;RESET LINE COUNT CLR PRSWIT ;RESET PREVIOUS SWITCH MOV #1000., LINES ;RESET ? RETURN .SBTTL 'TTL' COMMAND ; ; TTL= ... TEXT ... .CMTIT:: MOV #TTLBF,R1 ;DES POINTER MOV #.STBUF,R0 ;SRC POINTER 10$: MOVB (R0)+,(R1)+ ;SHUFFLE ONE BNE 10$ ;UNTIL TERMINATOR ; RETURN ;THEN EXIT .SBTTL 'TES' COMMAND ; ; TES(T) .CMTES:: ;**** TYPMSG #ERRUNI RETURN ;*** ; CALL CLRFIL ; MOV #-1,.SRCSW ; SET TASK MAPPED SWITCH ; MOV #UIPDR,R0 ; SET PAR/PDR TO CURRENT USER ; MOV #UIPAR,R1 ; CLR TASK ; CLEAR TASK NAME .SWITCH ; CLR KNLSW ; CLEAR KERNEL .SWITCH ; BR SETMAP ; GO SETUP TO MAP OURSELVES .SBTTL 'FPU' COMMAND ; ; FPU=NN .CMFPU:: MOV .LSBUF,R5 ; GET VALUE CMP R5,#40. BEQ 1$ ; LEGAL CMP R5,#45. BNE 10$ ; ILLEGAL 1$: MOV R5,FPUSW ; LEGAL RETURN 10$: TYPMSG #ERRFPU RETURN ; ; SETMAP: MOV #$MGET,.GETAD ;SET MAPPED GET MOV #PDR,R2 MOV #PAR,R3 MOV #8.,R4 1$: MOV (R0)+,(R2)+ MOV (R1)+,(R3)+ SOB R4,1$ RETURN ; .SBTTL 'TSK' COMMAND ; TSK=TASNAM .CMTSK:: ;**** TYPMSG #ERRUNI RETURN ;*** ; CALL CLRFIL ; DEACCESS THE TASK IMAGE IF ANY ; MOV #1,.SRCSW ; SET SOURCE SWITCH ; MOV .NABUF+2,R0 ; POINT TO STRING ; MOV PC,R1 ; SET R1.NE.0 ; CALL $CAT5 ; CONVERT ; MOV R1,TASK+0 ; CMP .NABUF,#3 ; MORE? ; BLE 5$ ; NO ; CALL $CAT5 ; AGAIN ; MOV R1,TASK+2 ; SECOND HALF ;5$: ; MOV #TASK,R5 ; TASK NAME BUFFER ; CALL SSTD ; SEARCH STD ENTRIES ; BCC TSKNF ; TASK NAME NOT FOUND ; BIT SF.FX!SF.TA,S.FW(R4) ; TEST STD FLAGS WORD ; BEQ TSKNR ; NEITHER BIT SET ; MOV R4,STD ; TASK'S STD ENTRY ADDRESS ; MOV #77406,-(SP) ; FULL PAGE PDR ; MOV S.BA(R4),-(SP) ; TASK HEADER BASE ADDRESS ; MOV #60000+H.PD0,R0 ; TASK'S PDR BLOCK ; MOV #60000+H.PA0,R1 ; TASK'S PAR BLOCK ; CLR KNLSW ; CLEAR KERNEL .SWITCH ; CALL @#..SPD3 ; .SWITCH PAGE 3 DESCRIPTOR ; CALL SETMAP ; CALL @#..SPD3 ; RESTORE MAPPING ; CMP (SP)+,(SP)+ ; CLEAN STACK ; RETURN ;; ; .ENABL LSB ;TSKNF: ; TYPMSG #ERRTNF ; BR 10$ ;; ;TSKNR: ; TYPMSG #ERRTNR ;10$: ; CLR TASK ; RETURN ; .DSABL LSB ; .SBTTL 'HDR' COMMAND ; ; HDR .CMHDR:: ;**** TYPMSG #ERRUNI RETURN ;*** ; TST .SRCSW ; WHERE IS TASK IMAGE? ; BGT 20$ ; BR IF IT IS A DISK FILE ; BEQ 30$ ; BR IF KNL ; ; TST TASK ; TEST IF TASK NAME SPECIFIED ; BEQ 10$ ; NO - ILLEGAL ; MOV PAR0,-(SP) ; SAVE TASK'S PAR0 ; MOV PDR0,-(SP) ; SAVE TASK'S PDR0 ; CALL 5$ ; CONTINUE DUMP ; MOV (SP)+,PDR0 ; MOV (SP)+,PAR0 ; RETURN ; ;5$: ; MOV STD,R5 ; TASK'S STD ENTRY ADDR ; BEQ 15$ ; NO STD SPECIFIED ; ; ; MOV S.BA(R5),PAR0 ; TASK'S BASE ADDR ; MOV #77406,PDR0 ; FULL PAGE ; MOV #H.HSZ,R5 ; ADDR OF HDR SIZE ; GETWRD ; GET (1/64)*SIZE ; ASH #6,R5 ; HIGH +1 ; SUB #1,R5 ; CLR LOW ; LOW = 000000 ; MOV R5,HIGH ; HIGH = 64*N-1 ; CLR .SWITCH ; PRINT AS OCT COMMAND ; MOV #1,HDRSW ; SET HDR .SWITCH ; JMP PRNT ; ; ;10$: TYPMSG #ERRNOT ; NO TASK NAME ; RETURN ;15$: TYPMSG #ERRNOS ; NO STD SPECIFIED ; RETURN ; ;20$: ; MOV .CRSEG,-(SP) ; SAVE CURRENT SEGMENT POINTER ; MOV #.SEGHD,.CRSEG ; USE HEADER DESCRIPTOR ; MOV .SEGHD+SGT.BA,LOW ; SET DUMP RANGE (LOW) ; MOV .SEGHD+SGT.SZ,HIGH ; GET LENGH OF HEADER ; ADD LOW,HIGH ; SET DUMP RANGE (HIGH) ; MOV #1,HDRSW ; SET HEADER SWITCH ; CLR .SWITCH ; PRINT AS OCTAL DUMP ; MOV #HDRTG,.PREFX ; SET LINE PREFIX ; CALL PRNT ; CLR .PREFX ; RESET LINE PREFIX ; MOV (SP)+,.CRSEG ; RESET SWITCHES AND OFFSETS ; CLR HDRSW ; RETURN ; ;30$: ; TYPMSG #ERRKNH ; RETURN .SBTTL 'FILE=FNAME' COMMAND ; ; ; COMMAND SYNTAX: 'FILE= FILEDESCRIPTOR' ; .CMFIL:: CALL CLRFIL CALL $ACCTSK ; ACCESS TASK IMAGE. OPEN FILE FOR READ BCC 5$ ; TYPMSG #ERRFIL ; UNABLE TO ACCESS TASK IMAGE JMP 80$ ; EXIT COMMAND ; 5$: MOV #1,.SRCSW ; SAY TASK IS IN A DISK FILE MOV #-1,.DBLOK+0 ; RESET 'CURRENT BLOCK' MOV #-1,.DBLOK+2 MOV #$VGET,.GETAD ; SET ADDRESS OF ROUTINE TO PERFORM GETS MOV #.SEGRO,.CRSEG ; SET '32K' SEGMENT AS CURRENT GETWRD #L$BBLK ; OBTAINTHE LABEL SIZE IN BLOCKS BCC 100$ ; ; 100$: TST R5 ; ***USC001 IF LABEL SIZE ZERO --> MPLUS Task BNE 10$ ; with options .LIST MEB GETWRD #L$BBLK+$LBXL ; .NLIST MEB BCS 7$ 10$: ; ASH #9.,R5 ; COMPUTE LABLE SIZE IN BYTES (SIZE*512.) MOV R5,.SEGLB+SGT.SZ; SET BYTE COUNT OF THE LABEL ; MOV #.SEGLB,.CRSEG ; SET 'LABEL' SEGMENT AS CURRENT GETWRD #L$BFLG ; get task flag word BCS 7$ bit r5,#TS$NHD ; test if system image beq 12$ MOV #.SEGHD,.CRSEG ; SET 'HEADER' SEGMENT AS CURRENT MOV #177777,.SEGHD+SGT.SZ ; SET TEMPORARY HEADER SIZE mov #2,.seghd+sgt.bl ; system image starts at bl #3 mov #1000,.seghd+sgt.bb ; this fits better TYPMSG #SYSIMG ; this is an system image file return 7$: JMP 75$ ; TASK FILE FETCH ERROR RELAY JUMP 12$: GETWRD #L$BHRB ; OBTAIN THE RELATIVE BLOCK NUMBER OF HEADER BCS 7$ TST R5 BNE 101$ GETWRD #L$BHRB+$LBXL ; ***USC001 MPLUS task with options ; 101$: INC R5 ; CONVERT RELATIVE BLOCK NUMBER MOV R5,.SEGHD+SGT.BL; SET BASE BLOCK OF THE HEADER ; GETWRD #L$BMXV ; GET highest virtual ADDRESS OF TASK BCS 7$ MOV R5,MaxAdr ; ***USC001 everybody should know about it ; GETWRD #L$BSA ; GET BASE ADDRESS OF TASK BCS 7$ ; MOV R5,.SEGHD+SGT.BA ; SET LOAD ADDRESS OF SEGMENT ; MOV #.SEGHD,.CRSEG ; SET 'HEADER' SEGMENT AS CURRENT MOV #177777,.SEGHD+SGT.SZ ; SET TEMPORARY HEADER SIZE ; MOV #H.IPC,R5 ; POINT TO HEADER LENGTH ADD .SEGHD+SGT.BA,R5 ;ADD BASE ADDRESS OF HEADER GETWRD ; GET HEADER SIZE VALUE IN HEADER BCS 7$ MOV R5,InPC ; get initial PC value MOV #H.HDLN,R5 ; POINT TO HEADER LENGTH ADD .SEGHD+SGT.BA,R5 ;ADD BASE ADDRESS OF HEADER GETWRD ; GET HEADER SIZE VALUE IN HEADER BCS 7$ MOV R5,.SEGHD+SGT.SZ ; SET HEADER SIZE FOR HDR COMMANDS ; MOV #.SEGLB,.CRSEG ; SET 'LABEL' SEGMENT AS CURRENT GETWRD #L$BSEG ; GET SIZE OF SEGMENT DESCRIPTORS BCS 7$ MOV R5,R4 ; SAVE SIZE OF SEGMENT DESCRIPTORS ; MOV #.SEGTB,R0 ; GET ADDRESS OF SEGMENT TABLE MOV #MAXSEG*,R1 ; SET NUMBER OF WORDS IN TABLE 112$: CLR (R0)+ ; CLEAR A WORD SOB R1,112$ ; LOOP TILL DONE ; MOV .SEGHD+SGT.BL,.SEGTB+SGT.BL ; SET BASE BLOCK OF ROOT SEGMENT MOV .SEGHD+SGT.BA,.SEGTB+SGT.BA ; SET LOAD ADDRESS OF SEGMENT ; MOV ROOT+0,.SEGTB+SGT.SN+0 ; SET SEGMENT NAME TO 'ROOT' NAME MOV ROOT+2,.SEGTB+SGT.SN+2 ; MOV #.SEGHD,.CRSEG ; SET 'HEADER' SEGMENT AS CURRENT MOV #H.OVLY,R5 ; POINT TO ADDRESS OF OVERLY IMPURE AREA ADD .SEGHD+SGT.BA,R5 ;ADD BASE ADDRESS OF HEADER GETWRD ; GET ADDRESS OF OVERLAY IMPURE STORAGE BCS 7$ ; TST R5 ; OVERLAYED TASK ? BNE 11$ ; BR IF YES ; 42$: MOV #.SEGLB,.CRSEG ; SET 'LABEL' SEGMENT AS CURRENT ; GETWRD #L$BHGV ; GET HIGHEST WINDOW 0 VIRTUAL ADDRESS BCS 7$ ; SUB .SEGTB+SGT.BA,R5 ; COMPUTE LENGTH OF ROOT INC R5 ; ADJUST FOR SIZE MOV R5,.SEGTB+SGT.SZ ; SET SEGMENT SIZE MOV .SEGHD+SGT.BL,.SEGTB+SGT.BL ; MOV .SEGHD+SGT.BH,.SEGTB+SGT.BH ; ; DEC R1 ; show we've been here BR 35$ 11$: ; MOV #.Dummy,.CRSEG ; SET 'Dummy' SEGMENT AS CURRENT MOV .SEGHD+SGT.BL,.Dummy+SGT.BL ; MOV .SEGHD+SGT.BH,.Dummy+SGT.BH ; MOV .SEGHD+SGT.BA,.Dummy+SGT.BA ; MOV #177777,.SEGTB+SGT.SZ ; SET TEMPORARY SIZE FOR ROOT ADD #N.STBL,R5 ; POINT TO ADDRESS OF SEGMENT DESCRIPTORS GETWRD ; GET ADDRESS OF SEGMENT DESCRIPTORS BCS 75$ ; MOV R5,R3 ; SAVE ADDRESS OF SEGMENT DESCRIPTORS ; MOV (PC)+,@(PC)+ ; SET FIRST DUMMY NAME .RAD50 /00A/ .TEMP ; CLR R1 ; INITIALIZE SEGMENT COUNT MOV #.SEGTB,R2 ; GET ADDRESS OF SEGMENT TABLE ; ; ; Loop for all segment descriptors ; if resident common -- skip that ; 20$: MOV R3,R5 ; GET ADDRESS OF SEGMENT DESCRIPTOR ADD #ST.STA,R5 ; POINT TO STATUS/RELATIVE DISK ADDRESS GETWRD ; GET STATUS/RELATIVE DISK ADDRESS BCS 75$ ; TST R5 ; LAST SEGMENT DESCRIPTOR ? BEQ 35$ ; EQ IF YES, END OF SEGMENT DESCRIPTORS ; INC R1 ; ADJUST COUNT OF SEGMENTS PRESENT CMP R1,#MAXSEG ; SEGMENTS PRESENT EXCEED MAX ? BHI 79$ ; HI IF YES, SEGMENT TABLE OVERFLOW ; BIC #^C1777,R5 ; CLEAR STATUS BITS CLR SGT.BH(R2) ; CLEAR HIGH DISK BLOCK FOR THIS SYSTEM ADD .SEGHD+SGT.BL,R5 ; ADD BASE DISK BLOCK OF HEADER MOV R5,SGT.BL(R2) ; STORE LOW DISK BLOCK ADDRESS ADC SGT.BH(R2) ; ADD POSSIBLE CARRY FROM LOW ; MOV R3,R5 ; GET ADDRESS OF SEGMENT DESCRIPTOR ADD #ST.LA,R5 ; POINT TO LOAD ADDRESS GETWRD ; GET LOAD ADDRESS BCS 75$ ; CMP MaxAdr,R5 ; is it in task image? bhi 44$ ; hi -- yes go on with it ; ; ; dec r1 ; uncount this descriptor ADD R4,R3 ; POINT TO NEXT SEGMENT DESCRIPTOR Br 20$ ; AND SKIP THIS SEG 44$: MOV R5,SGT.BA(R2) ; SET LOAD ADDRESS ; MOV R3,R5 ; GET ADDRESS OF SEGMENT DESCRIPTOR ADD #ST.BC,R5 ; POINT TO BYTE COUNT GETWRD ; GET BYTE COUNT BCS 75$ ; MOV R5,SGT.SZ(R2) ; SET SIZE OF SEGMENT ; CMP #ST.SN,R4 ; SEGNEMT DESCRIPTORS CONTAIN NAMES ? BEQ 25$ ; EQ IF NO ; MOV R3,R5 ; GET ADDRESS OF SEGMENT DESCRIPTOR ADD #ST.SN+0,R5 ; POINT TO NAME GETWRD ; GET FIRST 1/2 OF NAME BCS 75$ ; MOV R5,SGT.SN+0(R2) ; SET FIRST 1/2 OF NAME MOV R3,R5 ; GET ADDRESS OF SEGMENT DESCRIPTOR ADD #ST.SN+2,R5 ; POINT TO NAME GETWRD ; GET SECOND 1/2 OF NAME BCS 75$ ; MOV R5,SGT.SN+2(R2) ; SET SECOND 1/2 OF NAME BR 30$ ; ; CONSTRUCT A NAME FOR THIS SEGMENT ; 25$: CMP #1,R1 ; FIRST SEGMENT SEEN BEQ 30$ ; EQ IF YES, SEGMENT NAME 'ROOT' IN PLACE ; MOV SEGN,SGT.SN+0(R2) ; SET DUMMY FIRST 1/2 OF NAME MOV .TEMP,SGT.SN+2(R2) ; SET DUMMY SECOND 1/2 OF NAME INC .TEMP ; CHANGE SECOND 1/2 OF NAME FOR NEXT SEGMENT ; 30$: ADD R4,R3 ; POINT TO NEXT SEGMENT DESCRIPTOR ADD #SGT.SIZ,R2 ; POINT TO NEXT SEGMENT TABLE ENTRY BR 20$ ; PROCESS NEXT SEGMENT ; 35$: TST R1 BNE 1035$ JMP 42$ ; if nothing found, do root segment 1035$: MOV #FILBUF,R0 ; COPY THE COMMAND TO THE FILENAME MOV .DESCM,R1 ; BUFFER FOR USE IN THE TITLE MOV (R1)+,R2 ; GET SIZE MOV (R1),R1 ; GET SOURCE POINTER 36$: MOVB (R1)+,(R0)+ ; MOVE COMMAND SOB R2,36$ ; LOOP TILL DONE CLRB (R0) ; SET STOPPER ; MOV #.SEGTB,.CRSEG ; SET CURRENT SEGMENT POINTER RETURN ; 75$: TYPMSG #ERRFSU ; TASK IMAGE FETCH ERROR BR 80$ 79$: TYPMSG #ERRSGT ; SEGMENT TABLE OVERFLOW ; 80$: CALL CLRFIL JMP SHOCMD ; ; CLEAR OUT ARTIFACTS OF A FILE ; CLRFIL: CLRB FILBUF ; CLEAR 'FILE=' COMMAND CALL $DEATSK ; CLOSE TASK IMAGE FILE CLR .SRCSW ; RESET SOURCE SWITCH ; MOV #.SEGRO,.CRSEG ; SET '32K' SEGMENT AS CURRENT CLR .SEGTB+SGT.SN+0 ; SET STOPPER ; RETURN ; RETURN FROM CALL .SBTTL 'SEG=NAME' COMMAND ; ; .CMSEG:: MOV .NABUF+2,R0 ; POINT TO USER SPECIFIED NAME MOV PC,R1 ; SET R1.NE.0 CALL $CAT5 ; CONVERT TO RAD50 MOV R1,R4 ;SAVE FOR COMPARE CLR R5 ;ASSUME NO MORE CMP #3,.NABUF+0 ; MORE CHARACTERS? BGE 5$ ; NO, GO START SEARCH CALL $CAT5 ; CONVERT SECOND 3 MOV R1,R5 ; 5$: MOV #.SEGLB,R0 ; SET TOP OF TABLE FOR SEARCH ; 10$: TST SGT.SN(R0) ; END OF TABLE YET? BEQ 30$ ; SORRY CMP R4,SGT.SN+0(R0) ;NAME 1 BNE 20$ CMP R5,SGT.SN+2(R0) ;NAME 2 BEQ 25$ 20$: ADD #SGT.SIZ,R0 BR 10$ 25$: MOV R0,.CRSEG ; SET NEW CURRENT SEGMENT CALL .CMPAG ; KICK A PAGE BR 35$ ; AND RETURN 30$: TYPMSG #ERRSNF ; NO SUCH SEGMENT CALLR SHOCMD ; ECHO COMMAND AND RETURN 35$: RETURN ; ; .SBTTL 'PSGT','TSGT' COMMANDS ; ; PRINT/TYPE SEGMENT TABLE ENTRIES ; .CMPSG:: MOV #$PUTLIN,.TEMP ;GET ADDRESS OF PRINT RTOUTINq CALLR PRTSGT ;CALL ROUTINE TO POUTPUT SEGTABLE ; MSG CMTSG,< Initial PC: > .CMTSG:: MOV #$TYPMSG,.TEMP ;SET ADDRESS OF TYPE ROUTINE ; CALLR PRTSGT ; ; ; ; OUTPUT CONTENTS OF SEGMENT DESCRIPTOR TABLE ; ; FOR EACH ENTRY IN THE TABLE AT .SEGTB FORMAT A LINE AND OUTPUT ; IT VIA THE ROUTINE WHOSE ADDRESS IS IN .TEMP. ; PRTSGT: MOV #BUF,R0 ;BLANK OUT BUFFER MOV #72,R1 6$: MOVB #40,(R0)+ SOB R1,6$ MOV #BUF,R0 MOV #INstr,R1 4$: movb (r1)+,(r0)+ ;null-terminated string bne 4$ mov InPc,r5 call poct ;convert addr mov #buf,r1 mov r0,r2 sub r1,r2 ;string length call @.temp MOV #.SEGLB,-(SP) ;GET ADDRESS OF NEXT FRAME TO PRInT ; 10$: MOV (SP),R4 ;PICK UP FRAME ADDRESS ADD #SGT.SIZ,(SP) ;AND ADVANCE SAVED POINTER ; TST SGT.SN+0(R4) ;IF NAME1=0, NO MORE FRAMES BEQ 15$ ;BYE ; MOV #BUF,R0 ;BLANK OUT BUFFER MOV #72,R1 12$: MOVB #40,(R0)+ SOB R1,12$ ; ; SEGMENT NAME MOV #BF.AD,R0 ;OUTPPUT POINTER MOV SGT.SN+0(R4),R5 ;NAME1 CALL PR50 MOV SGT.SN+2(R4),R5 CALL PR50 ;NAME2 ; ; BASE ADDRESS MOV #BF.W1,R0 MOV SGT.BA(R4),R5 CALL POCT ;PUT 6 OCTAL ADDRESS ; ; SIZE MOV #BF.W2,R0 MOV SGT.SZ(R4),R5 CALL POCT ; ; DISK ADDRESS MOV #BF.W3,R0 MOV SGT.BH(R4),R5 CALL POCT MOVB #',,(R0)+ MOV SGT.BL(R4),R5 CALL POCT ; ; BYTE IN BLOCK MOVB #'+,(R0)+ ;SEPARATOR MOV SGT.BB(R4),R5 ;GET VAALUE CALL POCT3 ;PUT 3 OCTAL CHARACTERS ; MOV #BUF,R1 MOV R0,R2 SUB R1,R2 ;SET R1=ADDRESS,R2=COUNT ; CALL @.TEMP BR 10$ ;GO FOR NEXT ENTRY ; 15$: TST (SP)+ RETURN ; .SBTTL TASK SUBROUTINES ; ; SEARCH STD LIST FOR TASK NAME ; (IN) R5 = TASK NAME POINTER ; (OUT)R4 = STD ENTRY POINTER ; (OUT)C = 0(NFD)/1(FND) SSTD: MOV R1,-(SP) ; SAVE REGS MOV R2,-(SP) MOV R3,-(SP) MOV @#.STDTA,R1 ; BOTTOM OF LIST PTR MOV R1,R2 ADD @#.STDTZ,R2 ; TOP OF LIST PTR 1$: CMP R1,R2 ; TEST IF SEARCH EXHAUSTED BHI 20$ ; YES - NOT FOUND MOV R1,R3 ; SPLIT LIMITS ADD R2,R3 ; (BOTTOM+TOP) ROR R3 ; (BOTTOM +TOP)/2 BIC #1,R3 ; LIST CENTER MOV (R3),R4 ; STD ENTRY ADDRESS CMP S.TN(R4),(R5) ; COMPARE TASK NAME WORD 1 BHI 10$ BLO 11$ CMP S.TN+2(R4),2(R5) ; COMPARE TASK NAME WORD 2 BHI 10$ BLO 11$ 5$: MOV (SP)+,R3 ; RESTORE REGS MOV (SP)+,R2 MOV (SP)+,R1 TST R4 ; FOUND ? - C = 0 BEQ 6$ ; NO - C = 0 SEC ; YES - C = 1 6$: RETURN 10$: MOV R3,R2 ; NEW TOP LIMIT TST -(R2) ; ADJ DOWN BR 1$ 11$: MOV R3,R1 ; NEW BOTTOM LIMIT TST (R1)+ ; ADJ UP BR 1$ 20$: CLR R4 ; NOT FOUND BR 5$ ; .SBTTL SYNC SYSTEM TRAPS ; ; ODD ADDRESS SST OASST: BIS #ER.OA,ADRER ; ODD ADDR ERROR BIT BR RTT0 ; ; SEGMENTATION FAILURE SST SFSST: BIS #ER.SF,ADRER ; SET ERROR FLAG RTT3: CMP (SP)+,(SP)+ ; CLEAN UP STACK RTT1: TST (SP)+ RTT0: RTT .END BGN