.TITLE DISUTL UTILITY ROUTINES FOR DISASSEMBLER .IDENT /DISU01/ ; ; ; ; L H GERHARDSTEIN ; 11/20/73 ; MODIFIED BY J.E POLLACK ; U.OF WASH ; OCTOBER L975 ; ; .SBTTL CHARACTER TESTS ; .SBTTL DIGIT TEST ; R0 = ASCII CHARACTER STRING POINTER ; R5 = DIGIT VALUE ; C = 0(NON-DIGIT)/1(DIGIT) ; DIGTST:: MOVB (R0),R5 ; GET CHARACTER CMPB #060,R5 ; ASCII(0) BGT 10$ ; NON-DIGIT CMPB #071,R5 ; ASCII(9) BLT 10$ ; NON-DIGIT BIC #177760,R5 ; MASK 4 BITS SEC ; C=1 BR 20$ ; RETURN 10$: CLC ; C=0 20$: RETURN ; .SBTTL RAD50 LETTER TEST ; R0 = ASCII CHARACTER STRING POINTER ; R5 = LETTER(A-Z) (01-32) ; C = 0(NON-RAD50 CHAR)/1(RAD50 CHAR) ; OR $ (33) ; OR . (34) ; OR DIGITS(0-9) (36-47) ; L50TST:: CALL DIGTST BCS 3$ ; DIGIT 0-9 CALL LETTST BCS 10$ ; LETTER A-Z CMPB #044,R5 ; $ BEQ 1$ CMPB #056,R5 ; . BEQ 2$ CLR R5 ; R5 = 0 CLC ; C=0 BR 20$ ; RETURN 1$: MOV #55,R5 ; R50($) = 33 2$: SUB #60,R5 ; R50(.) = 34 3$: ADD #36,R5 ; R50(DIGITS) = 36-47 10$: SEC ; R50(LETTERS) = 01-32 ; C=1 20$: RETURN ; .SBTTL LETTER TEST ; R0 = ASCII CHARACTER STRING POINTER ; R5 = LETTER(A-Z) SIX-BIT-TRIM (01-32) ; C = 0(NON-LETTER)/1(LETTER) ; LETTST:: MOVB (R0),R5 ; GET CHARACTER CMPB #101,R5 ; ASCII(A) BGT 10$ ; NON-LETTER CMPB #132,R5 ; ASCII(Z) BLT 10$ ; NON-LETTER BIC #177700,R5 ; MASK 6 BITS SEC ; C=1 BR 20$ ; RETURN 10$: CLC ; C=0 20$: RETURN ; .SBTTL PROCESS CHARACTER STRINGS .SBTTL GET DECIMAL VALUE ; R0 = ASCII STRING POINTER ; R5 = VALUE OF DECIMAL STRING ; C = 0(INVALID STRING)/1(VALID STRING) ; GDEC:: CLR -(SP) ; ZERO ACCUM CALL DIGTST ; GET DIGIT N BCC 10$ ; NON-DIGIT 1$: ASL (SP) ; 2*A ADD (SP),R5 ; R5 = 2*A + N ASL (SP) ; 4*A ASL (SP) ; 8*A ADD R5,(SP) ; 10*A + N INC R0 ; BUMP POINTER CALL DIGTST ; GET DIGIT N BCS 1$ ; DIGIT MOV (SP)+,R5 ; R5 = ACCUM VALUE SEC ; C = 1 BR 20$ ; RETURN 10$: TST (SP)+ ; CLEAN UP STACK - C = 0 20$: RETURN ; .SBTTL GET OCTAL VALUE ; R0 = ASCII STRING POINTER ; R5 = VALUE OF OCTAL STRING ; C = 0(INVALID STRING)/1(VALID STRING) ; GOCT:: MOV R0,-(SP) ; SAVE POINTER CLR -(SP) ; ZERO ACCUM CALL DIGTST ; GET DIGIT N BCC 10$ ; NON-DIGIT 1$: CMP #8.,R5 BLE 10$ ; NON-OCTAL DIGIT ASL (SP) ; 2*A ASL (SP) ; 4*A ASL (SP) ; 8*A ADD R5,(SP) ; 8*A + N INC R0 ; BUMP POINTER CALL DIGTST ; GET DIGIT N BCS 1$ ; DIGIT MOV (SP)+,R5 ; R5 = ACCUM VALUE TST (SP)+ ; CLEAR STACK SEC ; C=1 BR 20$ ; RETURN 10$: TST (SP)+ ; CLEAR STACK MOV (SP)+,R0 ; RESTORE POINTER CLC ; C=0 20$: RETURN .SBTTL GET RAD50 ; R0 = ASCII STRING POINTER ; R5 = RAD50 WORD (3 CHARS) ; C = 0(INVALID STRING)/1(VALID STRING) ; GR50:: CALL L50TST ; GET C1 BCC 10$ ; INVALID TSTB (R0)+ ; BUMP POINTER MUL #3100,R5 ; (50**2)*C1 MOV R5,-(SP) ; ACUM CALL L50TST ; GET C2 BCC 1$ ; INVALID TSTB (R0)+ ; BUMP POINTER MUL #50,R5 ; (50**1)*C2 ADD R5,(SP) ; ACUM 1$: CALL L50TST ; GET C3 BCC 2$ ; INVALID TSTB (R0)+ ; BUMP POINTER 2$: ADD (SP)+,R5 ; R5 = 3100*C1 + 50*C2 + 1*C3 SEC ; C = 1 BR 20$ 10$: CLR R5 ; R5 = 0 - C = 0 20$: RETURN ; .SBTTL PACK ASCII ROUTINES ; .SBTTL PACK 2 OCTAL DIGITS .SBTTL PACK 3 OCTAL DIGITS .SBTTL PACK 6 OCTAL DIGITS ; R0 = ASCII STRING POINTER ; R5 = VALUE ; POCT2:: MOV #2,-(SP) ; COUNT = 2 DIGITS BR POCT6+4 POCT3:: MOV #3,-(SP) ; COUNT = 3 DIGITS BR POCT6+4 POCT6:: MOV #6,-(SP) ; COUNT = 6 DIGITS MOV (SP),-(SP) ; COUNT = +NO. DIGITS ADD (SP),R0 ; NEW R0 = R0 + COUNT MOV R0,2(SP) ; SAVE NEW R0 ON STACK BR 2$ 1$: MOVB R5,-(R0) ; OCTAL DIGIT + GARBAGE BICB #370,(R0) ; CLEAR GARBAGE BISB #060,(R0) ; ASCII(DIGIT) ASH #-3,R5 ; SHIFT VALUE RIGHT 3 BITS BIC #160000,R5 ; CLEAR POSSIBLE SIGN BITS 2$: DEC (SP) ; DECR COUNT & TEST DONE? BPL 1$ ; NO - PACK NEXT CHARACTER TST (SP)+ ; YES - CLEAR STACK MOV (SP)+,R0 ; RESTORE R0 = NEW R0 20$: RETURN ; .SBTTL PACK SIGNED OCTAL NUMBER .SBTTL PACK UNSIGNED OCTAL NUMBER ; R0 = ASCII STRING POINTER ; R5 = VALUE ; POCTS:: CALL PSGN ; PACK SIGN AND ABS(R5) POCT:: CLR -(SP) ; CLEAR SUP SWITCH TST R5 ; TEST BIT 15 BPL 1$ ; BIT = 0 MOVB #061,(R0)+ ; BIT = 1 BIC #100000,R5 ; CLEAR BIT 15 INC (SP) ; SET SUP SWITCH 1$: CALL PDIG0S .WORD 10000 ; 8**4 CALL PDIG0S .WORD 1000 ; 8**3 CALL PDIG0S .WORD 100 ; 8**2 CALL PDIG0S .WORD 10 ; 8**1 ADD #060,R5 ; LAST DIGIT MOVB R5,(R0)+ TST (SP)+ ; CLEAN UP STACK RETURN ; .SBTTL PACK RAD50 ; R0 = ASCII STRING POINTER ; R5 = RAD50 WORD ; PR50:: MOV R4,-(SP) ; SAVE R4 CLR R4 ; R4,R5 = RAD50(C1,C2,C3) DIV #3100,R4 ; R4 = C1 - R5 = REM CALL 5$ DIV #50,R4 ; R4 = C2 - R5 = C3 CALL 5$ MOV R5,R4 ; R4 = C3 CALL 5$ MOV (SP)+,R4 ; RESTORE R4 RETURN ; 5$: BEQ 10$ ; 00 - IGNORE CMP R4,#33 BLT 11$ ; 01-32 [A-Z] BEQ 12$ ; 33 [ $ ] CMP R4,#35 BEQ 10$ ; 35 - IGNORE 13$: ADD #11,R4 ; +22 12$: SUB #67,R4 ; +11 11$: ADD #100,R4 ; +100 MOVB R4,(R0)+ 10$: CLR R4 RETURN ; .SBTTL PACK TEXT ; R0 = ASCII STRING POINTER ; R5 = TEXT POINTER ; TEXT FORMAT: ; TXT: .ASCII / ... TEXT ... /<0> ; .EVEN ; MOVB (SP)+,(R0)+ ; MOVE CHAR TO ASCII STRING PTXT:: MOVB (R5)+,-(SP) ; CHAR FROM TEXT BUFFER BNE PTXT-2 ; DONE TEST ( <0> ) TST (SP)+ ; CLEAN UP STACK RETURN ; .SBTTL PACK DECIMAL NUMBER ROUTINES ; .SBTTL PACK 5 DECIMAL DIGITS .SBTTL PACK 4 DECIMAL DIGITS .SBTTL PACK 3 DECIMAL DIGITS .SBTTL PACK 2 DECIMAL DIGITS .SBTTL PACK 1 DECIMAL DIGIT ; R0 = ASCII STRING POINTER ; R5 = VALUE ; PDEC5:: CALL PDIG0N ; 5 DIGITS .WORD 10000. ; 10**4 PDEC4:: CALL PDIG0N ; 4 DIGITS .WORD 1000. ; 10**3 PDEC3:: CALL PDIG0N ; 3 DIGITS .WORD 100. ; 10**2 PDEC2:: CALL PDIG0N ; 2 DIGITS .WORD 10. ; 10**1 PDEC1:: CALL PDIG0N ; 1 DIGIT .WORD 1 ; 10**0 RETURN ; ; PACK DIGIT - NON-SUPRESSED PDIG0N:: MOV R4,-(SP) ; SAVE R4 CLR R4 ; R4,R5 = NUMBER DIV @2(SP),R4 ; DIV BY ARG=BASE**N ; R4 = DIGIT - R5 = REM ADD #060,R4 ; ASCII(DIGIT) MOVB R4,(R0)+ MOV (SP)+,R4 ; RESTORE R4 ADD #2,(SP) ; FIX RETURN ADDR RETURN ; .SBTTL PACK SIGNED DECIMAL NUMBER .SBTTL PACK UNSIGNED DECIMAL NUMBER ; R0 = ASCII STRING POINTER ; R5 = VALUE ; PDECS:: CALL PSGN ; PACK SIGN AND ABS(R5) PDEC:: CLR -(SP) ; CLEAR SUP SWITCH CALL PDIG0S ; GET AND PACK DIGITS .WORD 10000. ; 10**4 CALL PDIG0S .WORD 1000. ; 10**3 CALL PDIG0S .WORD 100. ; 10**2 CALL PDIG0S .WORD 10. ; 10**1 ADD #060,R5 ; LAST DIGIT MOVB R5,(R0)+ TST (SP)+ ; CLEAN UP STACK RETURN ; ; PACK DIGIT SUPRESSED PDIG0S:: MOV R4,-(SP) ; SAVE R4 CLR R4 ; R4,R5 = NUMBER DIV @2(SP),R4 ; R4 = DIGIT - R5 = REM BEQ 6$ ; DIGIT = 0 INC 4(SP) ; DIGIT = NON0 - SET SWITCH 6$: TST 4(SP) ; TEST IF PACK BEQ 7$ ; NO ADD #060,R4 ; YES - ASCII(DIGIT) MOVB R4,(R0)+ 7$: MOV (SP)+,R4 ; RESTORE R4 ADD #2,(SP) ; FIX RETURN ADDR RETURN ; .SBTTL PACK SIGN AND ABS VALUE ; R0 = ASCII STRING POINTER ; R5 = VALUE ; PSGN:: TST R5 ; TEST SIGN BGE 1$ ; POSITIVE MOVB #055,(R0)+ ; ASCII( - ) NEG R5 ; ABS(R5) 1$: RETURN ; .SBTTL PACK TIME ; R0 = ASCII STRING POINTER ; R5 = TIME BUFFER POINTER ; TIME BUFFER OBTAINED BY USING ; THE GTIM$ DPB. ; OUTPUT FORMAT = HH:MM:SS.F ; PTIME:: MOV R4,-(SP) ; SAVE R4 MOV R5,-(SP) ; TIME BUFFER POINTER CALL 5$ ; GET HR CALL PDEC2 ; PACK HR MOVB #072,(R0)+ ; ASCII( : ) CALL 5$ ; GET MIN CALL PDEC2 ; PACK MIN MOVB #072,(R0)+ ; ASCII( : ) CALL 5$ ; GET SEC CALL PDEC2 ; PACK SEC MOVB #056,(R0)+ ; ASCII( . ) CALL 5$ ; GET TICKS MOV R5,R4 ; R4 = TICKS SINCE HH:MM:SS.0 MUL #10.,R4 ; 10*NT DIV @(SP),R4 ; (10*NT)/NTS ADD #060,R4 ; ASCII(DIGIT) MOVB R4,(R0)+ TST (SP)+ ; CLEAN UP STACK MOV (SP)+,R4 ; RESTORE R4 RETURN ; 5$: MOV @2(SP),R5 ; GET NEXT ENTRY FROM LIST ADD #2,2(SP) ; ADVANCE POINTER RETURN ; .SBTTL PACK DATE ; R0 = ASCII STRING POINTER ; R5 = DATE BUFFER POINTER ; DATE BUFFER OBTAINED BY USING ; THE GTIM$ DPB. ; OUTPUT FORMAT = DD-MMM-YY ; PDATE:: MOV (R5)+,-(SP) ; YR-1900 MOV (R5)+,-(SP) ; MONTH [1-12] MOV (R5)+,-(SP) ; DAY [1-31] MOV R5,-(SP) ; SAVE NEW R5 MOV 2(SP),R5 ; DAY NUNBER CALL PDEC ; PACK DECIMAL SUP MOVB #055,(R0)+ ; ASCII( - ) MOV 4(SP),R5 ; MONTH NUMBER [1-12] MUL #3,R5 ; 3*MONTH ADD PC,R5 ADD #<12$-.-3>,R5 ; ADDR OF .ASCII/MONTH/<0> MOVB (R5)+,(R0)+ ; MOVE 3 CHAR MONTH ABREV MOVB (R5)+,(R0)+ MOVB (R5)+,(R0)+ MOVB #055,(R0)+ ; ASCII( - ) MOV 6(SP),R5 ; YEAR-1900 CALL PDEC2 ; PACK 2 DECIMAL DIGITS MOV (SP)+,R5 ; POINTS TO TIME BUFFER CMP (SP)+,(SP)+ ; CLEAN UP STACK TST (SP)+ RETURN ; ; MONTH TABLE 12$: .ASCII /JAN//FEB//MAR/ .ASCII /APR//MAY//JUN/ .ASCII /JUL//AUG//SEP/ .ASCII /OCT//NOV//DEC/ .EVEN ; .END