; PROGRAM DISOBJ.MAC ; PROGRAM TO DISASSEMBLE A MACRO OBJECT FILE ; PRODUCED FOR TASK BUILDER UNDER RSX-11M ; IT IS OPERATED AS AN MCR FUNCTION WITH STANDARD COMMAND LINE FORMAT ; WITH TWO LEVELS OF INDIRECT COMMAND FILES. ; CALL: ; MCR>DOB [OUTSPEC=]FILESPEC/SWS ; WHERE FILESPEC IS THE FILES-11 SPEC (OR INDIRECT COMMAND FILE). ; DEFAULTS: SY:DISOBJ.OBJ ; OUTSPEC IS OPTIONAL. IF NOT SPECIFIED THE OUTPUT FILE HAS THE ; FOLLOWING DEFAULTS: TI:DISOBJ.DOB ; THE LUN FOR FILESPEC IS 1 AND FOR OUTSPEC IT IS 3. ; THE DEVICES CAN BE CHANGED IN THE BUILD FILE OR WITH THE MCR REASSIGN FCN. ; THERE IS ONE SWITCH SUPPORTED: ; /LB:MODNAM ; or ; /EX:MODNAM ; THIS SWITCH SPECIFIES A MODULE NAME WITHIN A LIBRARY SPECIFIED IN FILESPEC. ; ; Modified by:- ; ; Phil Stephensen-Payne, ; c/o Systime Ltd., ; Concourse Computer Centre, ; 432 Dewsbury Road, ; LEEDS LS11 7DF, ; England. ; .TITLE DISOBJ ; DEFINE MACROS USED IN THIS PROGRAM .MACRO FERR,X,P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14 .IIF NB , MOV P1,ARGBLK ;Arguments for insertion .IIF NB , MOV P2,ARGBLK+2 .IIF NB , MOV P3,ARGBLK+4 .IIF NB , MOV P4,ARGBLK+6 .IIF NB , MOV P5,ARGBLK+8. .IIF NB , MOV P6,ARGBLK+10. .IIF NB , MOV P7,ARGBLK+12. .IIF NB , MOV P8,ARGBLK+14. .IIF NB , MOV P9,ARGBLK+16. .IIF NB , MOV P10,ARGBLK+18. .IIF NB , MOV P11,ARGBLK+20. .IIF NB , MOV P12,ARGBLK+22. .IIF NB , MOV P13,ARGBLK+24. .IIF NB , MOV P14,ARGBLK+26. MOV #I.'X,R1 ;Address of Error String JMP FERR .ENDM .MACRO DIAG,X,P1,P2,P3,P4 .IIF NB , MOV P1,ARGBLK .IIF NB , MOV P2,ARGBLK+2 .IIF NB , MOV P3,ARGBLK+4 .IIF NB , MOV P4,ARGBLK+6 MOV #I.'X,R1 CALL DIAG .ENDM .MACRO QIOEXE ADD,LEN PUT$ #OUTFDB,ADD,LEN CALL TOFC .ENDM QIOEXE .MACRO BLNKLN ADD,LEN MOV ADD,R0 MOV LEN,R1 JSR PC,BLNKIT .ENDM BLNKLN .MACRO R5ASCL ADR,RAD50 MOV ADR,R0 MOV RAD50,R1 JSR PC,$C5TA .ENDM R5ASCL .MACRO CBASCL ADR,NUM,FLAG,ROUTIN MOV ADR,R0 MOV NUM,R1 MOV FLAG,R2 JSR PC,ROUTIN .ENDM CBASCL .CSECT .MCALL FDBDF$ FDBK$A FDOP$A FDBF$A NMBLK$ .MCALL GCMLB$ CSI$ GCML$ CSI$1 CSI$2 .MCALL OPEN$R READ$ CLOSE$ EXIT$S WAIT$ .MCALL FINIT$ DIR$ QIOW$ FSRSZ$ GET$ .MCALL FDRC$A FDOF$L FCSBT$ FILIO$ PUT$ .MCALL FDAT$A OPEN$W GTIM$S SPWN$ WTSE$S .MCALL CSI$SW CSI$ND CSI$SV SVTK$S ; ; GLOBALS DEFINED HERE .GLOBL BLNKIT RECINP EOMPRC FILFDB RECBF2 .GLOBL PSCBUF ENDPRC STKSAV HBUF1 HBUF1E .GLOBL PSCCNT OUTFDB RECSET STRPSC HBUFL .GLOBL ATTACH DETACH MOFDB MOB SWORD ; ; GLOBALS DEFINED ELSEWHERE .GLOBL RECFIL TXTSET OUTBUF $CBDSG DS.END .GLOBL FLWORD DS.GSD DS.NRL $C5TA $CBOMG .GLOBL TXTRAN GSDDEC PSECAD XFRADD .GLOBL $CAT5 .POINT ; DEFINE VARIOUS SYMBOLS LOCALLY FDOF$L ;FDB OFFSETS FCSBT$ ;FDB BIT VALUES FILIO$ ;QIO FCN CODES FILFDB: FDBDF$ ;DEFINE FDB FOR DISK FILE FDRC$A ,RECBF2,1000 FDOP$A 1,CSIBLK+C.DSDS,FIDFNB,FO.RD .EVEN OUTFDB: FDBDF$ ;DEFINE FDB FOR OUTPUT FDAT$A R.VAR,FD.CR FDOP$A 3,,OUTFNB,FO.WRT RECBF2: .BLKB 1000 MOFDB: FDBDF$ FDAT$A R.VAR,FD.CR FDRC$A ,MOB FDOP$A 4,,TRMFNB,FO.WRT MOB: .BLKW 40. FIDFNB: NMBLK$ DISOBJ,OBJ,,SY OUTFNB: NMBLK$ DISOBJ,DOB,,SY TRMFNB: NMBLK$ DISOBJ,DOB,,TI ULBFNB: NMBLK$ USLIB,OLB,,SY SLBFNB: NMBLK$ SYSLIB,OLB,,LB DIRDSC: .WORD DIREND-DIRST .WORD DIRST DIRST: .ASCII /[1,1]/ DIREND: .EVEN CMLBLK: GCMLB$ 2,DOB,FIDSPT,2 FIDSPT: .BLKW 41. CSI$ .EVEN CSIBLK: .BLKB C.SIZE HBUFL: .WORD 0 ;PLACE FOR LEN OF HEADER HBUF1: .ASCII <11><11><11><11>/; / .BLKB 40. HBUF1E: .EVEN LABWRD: .ASCII /.WORD / .EVEN .BLKB 20 ; Buffer STKSAV: .WORD 0 ;PLACE TO SAVE ORIGINAL STACK POINTER HLSPWN: SPWN$ MCR...,,,,,1,,,HELCMD,HELCML HELCMD: .ASCII /HELP DOB/ HELCML=.-HELCMD .EVEN SWORD: .WORD 0 ;WORD FOR SWITCH FLAGS SWTABL: CSI$SW LB,1,SWORD,SET,,SVTABL CSI$SW EX,1,SWORD,SET,,SVTABL CSI$SW HE,2,SWORD,SET CSI$SW MA,4,SWORD,SET CSI$ND SVTABL: CSI$SV ASCII,MODNAM,6 CSI$ND MODNAM: .BLKW 3 ;SPACE FOR ASCII MODULE NAME R50MOD: .BLKW 2 ;SPACE FOR RAD50 MODULE NAME LIBBUF=RECBF2 ;USE SAME BUFFER FOR RECORD AND BLOCK I/O MNBLST: .WORD 0 ;STARTING BLOCK FOR MODULE MNENCT: .WORD 0 ;# OF MODULE ENTRIES MNENSZ: .WORD 0 ;SIZE OF EACH ENTRY (BYTES) MNENUS: .WORD 0 ;# USED SSTTAB: .WORD SSTOD ; Odd Address Trap .WORD SSTMP ; Memory Protect .WORD SSTBE ; BPT .WORD SSTIO ; IOT .WORD SSTIL ; Reserved Instruction .WORD SSTEM ; Non-RSX EMT .WORD SSTTE ; TRAP .WORD SSTFP ; Floating Point SSTNUM: .WORD 0 ; Store for SST Number EXIT1: JMP EXIT ;BRANCH HELP RWP2: .BLKW 1 ;POINTER FOR "REWIND" RWP3: .BLKW 1 ; LIKEWISE ATTDET: QIOW$ IO.ATT,3,1,,STATUS STATUS: .BLKW 2 ATTACH: MOV #IO.ATT,ATTDET+Q.IOFN BR COMATD DETACH: MOV #IO.DET,ATTDET+Q.IOFN COMATD: DIR$ #ATTDET RTS PC START1: FINIT$ SVTK$S #SSTTAB,#8. ; Specify SST Table OPEN$W #MOFDB MOV SP,STKSAV ;SAVE SP IN CASE RE-START FROM ERROR ROUTINE MOV #FILFDB,R0 ;SET UP FOR MOV #SLBFNB,R1 ;CALL TO GET DEFAULT DIRECTORY MOV #DIRDSC,R2 ;INFO IN SYSTEM LIBRARY JSR PC,.GTDIR ;DFNB START: CLR FLWORD ;CLEAR FLAG WORD IN CASE 2ND FILE CLR LINEC ;RESET PAGE COUNT JSR PC,DETACH ;IN CASE WE HAVE ATTACHED TERMINAL MOV STKSAV,SP ;RESTORE STACK POINTER CLR PSCCNT ;CLEAR THE PSECT COUNT MOV #MODNAM,R5 ;CLEAR OUT MODULE NAME CLR (R5)+ CLR (R5)+ CLR (R5)+ CLR OUTFDB+F.DSPT ;CLEAR THE DATASET POINTER CLR SWORD ;CLEAR THE SWITCH WORD GCML$ #CMLBLK BCC 2$ CMPB #GE.EOF,G.ERR(R0) ; Was it an end-of-file? BEQ EXIT1 ; If EQ yes - terminate program CMPB #GE.OPR,G.ERR(R0) ; Invalid command file? BNE 5000$ ; If NE no - carry on FERR GIN ; yes - log the message ; 5000$: MOVB G.ERR(R0),R0 ; Sign-extend the error FERR GCM,R0 ; Else log error 2$: GTIM$S #MOB ; Get the current date and time MOV #MOB,R1 ; Get address of date MOV #HBUF1+6,R0 ;ADDRESS FOR DATE MOVB #40,HBUF1+8.+6 ; Put in last space just in case CALL $DAT ; Convert the date MOVB #40,HBUF1+9.+6 ;PUT IN MOVB #40,HBUF1+10.+6 ;SPACES MOV #HBUF1+6+2+9.,R0 ;ADDRESS FOR TIME MOV #2,R2 ; just hours & minutes CALL $TIM ; Convert the time MOVB #40,(R0)+ ;PUT IN SPACE MOVB #76,(R0)+ ;AND ">" MOV R0,R5 ; Save address MOV CMLBLK+G.CMLD+2,R0 ;PUT COMMAND STRING AS HEADER MOV CMLBLK+G.CMLD,R1 ;ON OUTPUT FILE BEQ START ; If no text - just go again JSR PC,TXTRAN SUB #HBUF1,R5 ;LEN IN R5 MOV R5,HBUFL ;STORE FOR FUTURE CSI$1 #CSIBLK,CMLBLK+G.CMLD+2,CMLBLK+G.CMLD BCC 3$ MOV CSIBLK+C.FILD+2,R0 ; Get Address of Error SUB CMLBLK+G.CMLD+2,R0 ; And hence offset INC R0 ; Starting at 1 FERR CS1,R0 ; Log the error 3$: MOVB #CS.OUT,CSIBLK+C.TYPR ;SPEC OUT MOV #OUTFDB,R0 MOV #TRMFNB,F.DFNB(R0) ;PUT IN TERMINAL DFNB BITB #CS.EQU,CSIBLK+C.STAT ;BOTH SPECS? BEQ 1$ ;IF NOT, DO DEFAULT OPEN MOV #OUTFNB,F.DFNB(R0) ;USE SY AS DEFAULT DEVICE CSI$2 #CSIBLK BCC 4$ FERR CSO ; Output error message 4$: BITB #CS.MOR,C.STAT(R0) ; See if more output files BEQ 3000$ ; If EQ OK - carry on FERR MRO ; Else log error 3000$: MOV #CSIBLK+C.DSDS,OUTFDB+F.DSPT ;USE DATA SET POINTER MOVB #CS.INP,CSIBLK+C.TYPR ;SPEC INPUT FOR INPUT CSI 1$: OPEN$W #OUTFDB BCC 4000$ ; If Open OK carry on MOVB OUTFDB+F.ERR,R0 ; Sign-extend the error FERR OPO,R0 ; Else error ; 4000$: CSI$2 #CSIBLK,,#SWTABL BCC 5$ ; If CC OK - carry on FERR CSI ; No - Log Error 5$: BITB #CS.MOR,C.STAT(R0) ; See if more input files BEQ 7000$ ; If EQ OK - carry on FERR MRI ; Else log error 7000$: MOV #FILFDB,R0 ;CHECK FOR PROPER DFNB TO USE BIT #1,SWORD ; Library switch? BNE 19$ ; If NE yes - handle it BIT #2,SWORD ; Help requested? BEQ 20$ ; If EQ no - carry on DIR$ #HLSPWN ; No - ask for help WTSE$S #1 ; Wait for it to finish CLOSE$ #OUTFDB JMP START ; and start again ; 19$: BITB #CS.NMF!CS.DIF!CS.DVF,CSIBLK+C.STAT BNE 21$ ;IF NOTHING SPEC'D, USE SYSLIB MOV #SLBFNB,F.DFNB(R0) ;PUT IN DFNB SPEC BR 22$ 21$: MOV #ULBFNB,F.DFNB(R0) ;PUT IN USER LIBRARY SPEC BR 22$ 20$: MOV #FIDFNB,F.DFNB(R0) ;PUT IN OBJ FILE SPEC 22$: BITB #FD.TTY,F.RCTL+OUTFDB ;AT TERMINAL? BEQ 8$ ;IF NOT, DON'T ATTACH JSR PC,ATTACH 8$: OPEN$R #FILFDB BCC 6$ MOVB FILFDB+F.ERR,R0 ; Sign-extend the error FERR OPI,R0 ; Else error 6$: MOV #1,RWP2 CLR RWP3 ;INITIALIZE "REWIND" POINTERS BIT #1,SWORD ;LIBRARY? BNE 17$ ;IF SO, DO LIB THING JMP 7$ ;ELSE SKIP ALL THIS 17$: BISB #FD.RAN,F.RACC(R0) ;SET FOR RANDOM ACCESS CLR F.RCNM(R0) ;SET FOR FIRST RECORD (BLOCK) MOV #1,F.RCNM+2(R0) GET$ ,,#1000 MOV #LIBBUF,R1 ;BUFFER ADDRESS IN R1 MOVB 32(R1),MNENSZ ;STORE SIZE MNT ENTRIES MOV 34(R1),MNBLST ;STORE STARTING BLOCK # MOV 36(R1),MNENUS ;AND # ALLOC SUB 40(R1),MNENUS ;USED MOV #MODNAM,R0 MOV #1,R1 CLR R50MOD+2 JSR PC,$CAT5 ;CONVERT FROM ASCII TO RAD50 MOV R1,R50MOD ;PUT RESULT AWAY BCS 11$ ;IF C, NON RAD50 TERM. JSR PC,$CAT5 ;CONVERT SECOND HALF MOV R1,R50MOD+2 ;PUT IT AWAY 11$: MOV #FILFDB,R0 MOV MNBLST,F.RCNM+2(R0) ;SET UP FOR SEARCH MOV MNENUS,R1 MOV MNENSZ,R2 MOV #R50MOD,R4 BR 16$ 14$: CMP R3,#1000 BLT 15$ 16$: CLR R3 ;R3=OFFSET INTO BLOCK GET$ ;READ IN NEXT BLOCK 15$: CMP LIBBUF(R3),(R4) ;COMPARE 1ST HALF OF RAD50 NAME BNE 12$ CMP LIBBUF+2(R3),2(R4) ;THEN SECOND BEQ 13$ ;IF MATCH, GO FINISH 12$: ADD R2,R3 ;INC OFFSET SOB R1,14$ ;KEEP GOING TILL DONE FERR LSF ;LIBRARY SEARCH FAILURE 13$: CLR R1 ;SET BLOCK NUM MOV LIBBUF+4(R3),R2 ;(TWO PARTS) MOV R2,RWP2 MOV LIBBUF+6(R3),R3 ;AND BYTE MOV R3,RWP3 MOVB #R.VAR,F.RTYP(R0) ;SET VARIABLE RECORD TYPE BICB #FD.RAN,F.RACC(R0) ;MAKE SEQUENTIAL JSR PC,.POINT ;POINT TO MODULE HEADER GET$ ;READ IT IN 7$: JMP RECSET EXIT: CLOSE$ #MOFDB EXIT$S ENDPRC: CLOSE$ #FILFDB CLOSE$ #OUTFDB JMP START BLNKIT: TST R1 ;CHECK NO OF BYTES BEQ 2$ ;IF ZERO, THEN DONE 1$: MOVB #40,(R0)+ ;MOVE IN A BLANK SOB R1,1$ ;AND DO IT TILL DONE 2$: RTS PC RECINP: GET$ #FILFDB,#RECBF2,#200 BCC 1$ MOVB FILFDB+F.ERR,R0 ; Sign-extend the error FERR INP,R0 ; Else error 1$: RTS PC RECSET: JSR PC,RECINP ;GET A RECORD MOV #RECBF2,R4 ;USE R4 TO KEEP LINE POSITION MOV (R4)+,R1 ;RECORD TYPE IN R1 TST R1 ;CHECK FOR ZERO BPL 2$ ;POSITIVE OK FERR RTP,R1 2$: CMP R1,#6 ;SEE IF > 6 BLE 1$ FERR RTP,R1 1$: DEC R1 ;SET UP R1 ASL R1 ;TO BE JMP @JMPTBL(R1) ;A JUMP INDEX AND DO IT JMPTBL: .WORD GSDDEC ;GLOBAL SYMBOL DECODE .WORD ENDGSD ;END OF GLOBAL SYMBOL DIRECTORY .WORD RECSET .WORD RECSET .WORD RECSET .WORD EOMPRC ;IN CASE STOPPED SHORT ; ; ROUTINE FOR END OF GLOBAL SYMBOL DIRECTORY ; ENDGSD: MOV #FILFDB,R0 ;"REWIND" FILE CLR R1 MOV RWP2,R2 MOV RWP3,R3 JSR PC,.POINT BIT #1,SWORD ;LIBRARY? BEQ 2$ ;IF EQ, NO GET$ ;SKIP HEADER 2$: BIC #DS.GSD,FLWORD ;TURN OFF GLOBAL SYMBOL FLAG SUB #PSCBUF,R5 ;NO. OF BYTES USED IN R5 ASR R5 ;DIVIDE BY 4 ASR R5 DEC R5 ;PSECT NO. 0 IS FIRST PSECT MOV R5,PSCCNT ;AND STORE IT BLNKLN #OUTBUF,#80. ;BLANK OUT A LINE MOV #OUTBUF,R5 ;START FILLING MOV #<11*400+11>,(R5)+ ;LINE WITH TABS MOV #<11*400+11>,(R5)+ MOV #"; ,(R5)+ ;AND FINISH WITH ; SUB #OUTBUF,R5 ;LEN -> R5 QIOEXE #OUTBUF,R5 ;OUTPUT IT CLR PCCURR ; Initialize PC 3$: JSR PC,RECINP MOV RECBF2,R1 CMP R1,#4 ;IS RECORD AN RLD RECORD BEQ 1$ ;IF SO, GOOD CMP R1,#6 ;IS IT FAST STOP BEQ EOMPRC ;IF SO, GO END BR 3$ ;IGNORE RECORD 1$: BIS #DS.NRL,FLWORD ;INDICATE TYPE JMP TXTSET ;AND GO PROCESS ; ; ROUTINE TO PROCESS END OF MODULE ; EOMMSG: .ASCII <11><11><11><11><11>/.END/ EOMMS1: .BLKB 20. .EVEN EOMPRC: MOV #EOMMS1,R5 ;START AT END OF FIXED PART BIT #1,XFRADD ;SUBROUTINE BNE 1$ ;IF SO, BRANCH MOVB #11,(R5)+ ;PUT IN TAB MOV #PSCNAM,R0 ; Cover over PSECT whatsit MOV #6,R1 ; 5$: MOVB (R0)+,(R5)+ SOB R1,5$ MOVB #'+,(R5)+ ; and a + CBASCL R5,XFRADD,#1,$CBOMG MOV R0,R5 ;UPDATE R5 1$: MOV #EOMMSG,R1 ; Assume normal .END BIT #4,SWORD ; /MA specified? BEQ 10$ ; If EQ no - carry on ADD #4,R1 ; Yes - add 4 to omit 4 tabs ; 10$: SUB R1,R5 ;LEN IN R5 QIOEXE R1,R5 ;PRINT IT JMP ENDPRC STRPSC: MOV R0,-(SP) ;SAVE R0 MOV PSECAD,R0 ;CURRENT NEXT OPEN ADDRESS IN R0 ADD #4,R0 ;SEE IF ROOM FOR ONE MORE CMP R0,#PSCCNT ;AT END? BLE 1$ ;IF NOT, OK FERR PSC ;ELSE ERROR 1$: SUB #4,R0 ;BACK TO WHERE WE WERE MOV -4(R4),(R0)+ ;MOVE IN RAD50 MOV -2(R4),(R0)+ ;PSECT NAME INC PSCCNT ;COUNT IT MOV R0,PSECAD ;STORE NEW ADDRESS MOV (SP)+,R0 ;RESTORE OLD R0 RTS PC .PAGE .SBTTL SST SST Handling Routines ; ; This routine handles any SSTs by logging an error, closing the file ; and exiting. This should make it easy to track down the error. ; SSTFP: INC SSTNUM ; Floating Point SSTTE: INC SSTNUM ; TRAP SSTEM: INC SSTNUM ; Non-RSX EMT SSTIL: INC SSTNUM ; Reserved Instruction SSTIO: INC SSTNUM ; IOT SSTBE: INC SSTNUM ; BPT SSTMP: INC SSTNUM ; Memory Protect SSTOD: ; Odd Address Trap TST SSTNUM ; Have we been here before? BGE 20$ ; If GE no - carry on CMP SSTNUM,#-1000. ; Yes - twice? BLE 10$ ; If LE yes - don't even try to close the file MOV #-2000.,SSTNUM ; Stop second level of recursion CLOSE$ OUTFDB ; No - close the file ; 10$: EXIT$S ; Exit ; 20$: CMP SSTNUM,#1 ; Memory Protect? BNE 30$ ; If NE no - carry on ADD #6,SP ; Yes - chuck three words off the stack ; 30$: CMP SSTNUM,#5 ; TRAP or EMT? (ignore FP as impossible) BLT 40$ ; If LT no - carry on TST (SP)+ ; Yes - chuck a word off the stack ; 40$: MOV (SP)+,ARGBLK+28. ; Save the old PC TST (SP)+ ; Ignore the PS MOV SSTNUM,ARGBLK+26. ; Save the SST number MOV #-100.,SSTNUM ; And stop recursion FERR SST,ARGBLK+26.,ARGBLK+28.,R0,R1,R2,R3,R4,R5,SP,(SP) ; ; .PSECT PSCSEC N.PSCT=60 ;DEFINE NO. OF PSECTS TO ALLOW PSCBUF: .BLKW 2*N.PSCT ;TWO WORDS FOR EACH PSECT .PSECT PSCSED ;PSECT TO FOLLOW PSCSEC PSCCNT: .WORD 0 ;COUNT OF NO. OF PSECTS USED FSRSZ$ 4 .END START1