.TITLE CONVERT .IDENT "V1.2" ; ; Author: D. Mischler 03-JUL-87 ; ; This module contains the routine for converting ; a value to ASCII depending on the mode. ; .PSECT RODATA,D,RO ; ; Control character mnemonic table. ; CTLTBL: .RAD50 "NULSOHSTXETXEOTENQACKBEL" .RAD50 "BS HT LF VT FF CR SO SI " .RAD50 "DLEDC1DC2DC3DC4NAKSYNETB" .RAD50 "CANEM SUBESCFS GS RS US " .PAGE .PSECT CODE,I,RO ; ; Subroutine to convert the value in R1 to ASCII (R0)+. ; The mode and radix determine the type of conversion. ; C$VALU:: MOV R2,-(SP) ; Save volatile registers. MOV R1,-(SP) CALL @CNMODE ; Convert value according to mode. MOV (SP)+,R1 ; Recover saved volatile registers. MOV (SP)+,R2 RETURN ; ; Convert the value to ASCII. ; C$ASCI:: MOV R1,-(SP) ; Save value. CALL C$ASCB ; Convert low byte to ASCII. MOV (SP)+,R1 ; Recover value. SWAB R1 ; Position high byte. C$ASCB::BIC #177600,R1 ; Mask to low 7 bits. CMPB #-1,R1 ; Delete character? BEQ 20$ ; Yes, print mnemonic. CMPB #' ,R1 ; Is character printable? BHI 30$ ; No, print control character mnemonic. MOVB R1,(R0)+ ; Buffer character. RETURN ; Buffer delete mnemonic. 20$: MOV #^RDEL,R1 ; Get RAD50 representation of mnemonic. BR 40$ ; Dump it. ; Buffer control character mnemonic. 30$: ASL R1 ; Produce word offset. MOV CTLTBL(R1),R1 ; Get mnemonic in RAD50. 40$: MOVB #'<,(R0)+ ; Buffer opening mnemonic indicator. CALL C$R50 ; Convert mnemonic to ASCII. CALL U$RMTB ; Remove trailing blanks. MOVB #'>,(R0)+ ; Buffer closing mnemonic indicator. RETURN .PAGE ; ; Convert the value to a numeric byte. ; C$NUMB:: JSR R5,.SAVR1 ; Save everything but the output pointer. MOVB R1,R1 ; Sign extend byte to a word. MOV NCFLGS,R2 ; Get numeric conversion flags. BIT #NC.SGN,R2 ; Is conversion signed? BNE 10$ ; Yes, everything is OK. BIC #177400,R1 ; Make sure high byte is clear. 10$: MOV R2,R3 ; Copy conversion flags. ROR R3 ; Divide in half. BIC #100000!,R3 ; Get half of normal field width. SUB R3,R2 ; Cut field width to half of normal. BR C.NUM ; Perform conversion and exit. ; ; Convert the value to a numeric. ; C$NUM:: MOV NCFLGS,R2 ; Get numeric conversion flags. C.NUM: CALL $CBTA ; Convert to ASCII numeric representation. RETURN ; ; Convert RAD50 word to ASCII. ; C$R50:: MOV R2,-(SP) ; Save volatile registers for later. MOV R1,-(SP) CALL $C5TA ; Convert RAD50 word to ASCII. MOV (SP)+,R1 ; Recover saved registers. MOV (SP)+,R2 RETURN .PAGE ; ; Convert the value symbolically. ; C$SYMB:: MOV R0,-(SP) ; Save output pointer. ; If value represents a saved register then use the register name. MOV #REGSYM,R0 ; Point to register symbol table head. CALL S$LVAL ; Look up symbol by value, OK? BCS 10$ ; No, use normal symbolic name. CMP R1,S.VALU(R0) ; Is value exact? BEQ 20$ ; Yes, convert register name to ASCII. ; Check value against global symbol table. 10$: CMP R1,SYMLOW ; Is value too low to be symbolic? BLO 40$ ; Yes, convert it numerically. CMP R1,SYMHI ; Is value too high to be symbolic? BHI 40$ ; Yes, convert it numerically. MOV #SYMTBL,R0 ; Point to global symbol table head. CALL S$LVAL ; Is value in table? BCS 40$ ; No, convert it numerically. 20$: MOV R1,-(SP) ; Copy value onto stack. SUB S.VALU(R0),R1 ; Produce offset from symbol value. CMP R1,SYMOFF ; Is the offset too high to be useful? BLOS 30$ ; No, go ahead and use it. MOV (SP)+,R1 ; Pop incoming value. BR 40$ ; Just convert it numerically. ; Offset is not too high. 30$: MOV R1,(SP) ; Save offset on top of stack. MOV S.NAME(R0),R1 ; Get first word of RAD50 name. MOV S.NAME+2(R0),-(SP) ; Push second word of name on stack. MOV 4(SP),R0 ; Recover output pointer. CALL $C5TA ; Convert first word of name to ASCII. MOV (SP)+,R1 ; Pop second RAD50 name word. CALL $C5TA ; Convert it too. CALL U$RMTB ; Remove trailing blanks. MOV (SP)+,R1 ; Is symbol offset non-zero? BEQ 50$ ; Yes, conversion is complete. MOVB #'+,(R0)+ ; Indicate symbol offset. MOV R0,(SP) ; Save updated output pointer. 40$: MOV (SP),R0 ; Get output pointer. CALL C$NUM ; Convert numeric value. 50$: TST (SP)+ ; Remove old output pointer from stack. RETURN .END