.TITLE USRLIB user routines library .IDENT /01.02/ ; ; USRLIB is a collection of commonly used routines that are registered as ; system calls. ; ; routines provided: ; CNV8S converts a 8 bit byte to ASCII character string, arguments are ; radix code, byte and pointer to output buffer ; CNV16S converts a 16 bit word to ASCII character string, arguments are ; radix code, word and pointer to output buffer ; CNVS16 converts a ASCII character string to a 16 bit word, arguments ; are radix code and pointer to input string, conversion stops at ; the first character that is invalid in the selected radix, the ; output word is returned in R0 ; GETC reads a single character from an I/O channel and returns it in ; R0, argument is a pointer to an initialized I/O request packet ; PUTC writes a single character to an I/O channel, arguments are a ; pointer to an initialized I/O request packet and the character ; to be written ; GETS reads a block of characters from an I/O channel, arguments are ; a pointer to an initialized I/O request packet, a pointer to ; a buffer to hold the characters and the length of the buffer ; PUTS writes a block of characters to an I/O channel, arguments are ; a pointer to an initialized I/O request packet, a pointer to ; the buffer containing the characters and the size of the buffer ; ; 05-AUG-2005 H. Rosenfeld added CNV8S ; 28-MAY-2005 H. Rosenfeld added RAD50 decoding to CNV16S, added CNVS16 ; to convert strings to words ; 25-MAY-2005 H. Rosenfeld ; .LIST ME .NLIST CND .ENABL REG .LIBRARY /SYSCLL.SML/ .LIBRARY /JOBCTL.SML/ .LIBRARY /IOSYS.SML/ .LIBRARY /CALL.SML/ .MCALL $SYS,$REGSYS,$TERM .MCALL $IOREQ,$READ,$WRIT,.IOSYS,.IOFUNC .MCALL .IMAGE,.CALL,.ENTRY,.RETRN .MACRO .ULDEFS R$BIN=0 R$OCT=1 R$DEC=2 R$HEX=3 R$R50=4 R$MAX=4 .ENDM .IOSYS .IOFUNC .ULDEFS .IMAGE USRLIB .CSECT USRLIB::.ENTRY $REGSYS #^RCNV,#^R8S,#CNV8S,#0 $REGSYS #^RCNV,#^R16S,#CNV16S,#0 $REGSYS #^RCNV,#^RS16,#CNVS16,#0 $REGSYS #^RGET,#^RC,#IOGETC,#0 $REGSYS #^RPUT,#^RC,#IOPUTC,#0 $REGSYS #^RGET,#^RS,#IOGETS,#0 $REGSYS #^RPUT,#^RS,#IOPUTS,#0 $TERM .MACRO $CNV8S RAD,VAL,STR $SYS #^RCNV,#^R8S,RAD,VAL,STR .ENDM CNV8S:: .ENTRY MOV 6(R5),R4 ; first argument: radix code CMP R4,#R$MAX ; highest radix code is R$MAX BHI 1$ ; error: radix code too high CMP R4,#R$R50 ; Radix-50 requested? BEQ 1$ ; error: Radix-50 not supported ASL R4 ; shift to get index in tables MOV LEN8(R4),R3 ; get output length MOV 10(R5),R1 ; second argument: number to convert BIC #177400,R1 ; clear high byte MOV R3,R2 2$: CLR R0 ; prepare for division DIV RADTBL(R4),R0 ; R0 unconverted, R1 next digit ADD OFSTBL(R4),R1 ; add static table offset for radix MOVB NUMTBL(R1),-(SP) ; save decoded digit MOV R0,R1 ; continue with undecoded part SOB R2,2$ ; until all digits decoded MOV 12(R5),R2 ; third argument: output buffer 3$: MOVB (SP)+,(R2)+ ; store decoded digit SOB R3,3$ MOV R2,R0 ; return pointer to end of buffer CLC ; no error .RETRN 1$: SEC ; indicate error .RETRN .MACRO $CNV16S RAD,VAL,STR $SYS #^RCNV,#^R16S,RAD,VAL,STR .ENDM CNV16S::.ENTRY MOV 6(R5),R4 ; first argument: radix code CMP R4,#R$MAX ; highest radix code is R$MAX BHI 1$ ; error, radix too high ASL R4 ; shift to get index in tables MOV LEN16(R4),R3 ; get output length MOV 10(R5),R1 ; second argument: number to convert MOV R3,R2 2$: CLR R0 ; prepare for division DIV RADTBL(R4),R0 ; R0 unconverted, R1 next digit ADD OFSTBL(R4),R1 ; add static table offset for radix MOVB NUMTBL(R1),-(SP) ; save decoded digit MOV R0,R1 ; continue with undecoded part SOB R2,2$ ; until all digits decoded MOV 12(R5),R2 ; third argument: output buffer 3$: MOVB (SP)+,(R2)+ ; store decoded digit SOB R3,3$ MOV R2,R0 ; return pointer to end of buffer CLC ; no error .RETRN 1$: SEC ; indicate error .RETRN .MACRO $CNVS16 RAD,STR $SYS #^RCNV,#^RS16,RAD,STR .ENDM CNVS16::.ENTRY MOV 6(R5),R4 ; first argument: radix code CMP R4,#R$MAX ; highest radix code is R$MAX BHI 1$ ; error, radix too high ASL R4 ; shift to get index in table MOV 10(R5),R2 ; get output buffer CLR -(SP) ; prepare output word 2$: MOV RADTBL(R4),R3 ; get real radix MOVB (R2)+,R1 ; get character BEQ 5$ ; stop at zero byte MOV #NUMTBL,R0 ; compare to NUMTBL ADD OFSTBL(R4),R0 ; after an offset ADD R3,R0 ; start at end 3$: CMPB R1,-(R0) ; compare character BEQ 4$ ; stop if equal SOB R3,3$ BR 5$ ; unknown character, stop 4$: DEC R3 ; adjust R3 MOV (SP),R1 ; get output word MUL RADTBL(R4),R1 ; shift for adding character ADD R3,R1 ; add coded character MOV R1,(SP) ; save output word BR 2$ 5$: DEC R2 ; adjust buffer pointer MOV R2,R1 ; return buffer pointer in R1 MOV (SP)+,R0 ; return word in R0 CLC ; no error .RETRN 1$: SEC ; indicate error .RETRN .MACRO $GETC IORQP $SYS #^RGET,#^RC,IORQP .ENDM IOGETC::.ENTRY MOV 6(R5),R4 ; get I/O request packet $READ R4,#1,#0 ; read character .RETRN ; return values from $READ .MACRO $PUTC IORQP,CHAR $SYS #^RPUT,#^RC,IORQP,CHAR .ENDM IOPUTC::.ENTRY MOV 6(R5),R4 ; get I/O request packet MOV 10(R5),-(SP) ; store character on stack MOV SP,R3 ; get pointer to character $WRIT R4,#1,R3 ; write character .RETRN ; return values from $WRIT .MACRO $GETS IORQP,BUF,LEN $SYS #^RGET,#^RS,IORQP,BUF,LEN .ENDM IOGETS::.ENTRY MOV 6(R5),R4 ; get I/O request packet MOV 10(R5),R3 ; get buffer address MOV 12(R5),R2 ; get buffer length $READ R4,R2,R3 ; read string .RETRN ; return values from $READ .MACRO $PUTS IORQP,BUF,LEN $SYS #^RPUT,#^RS,IORQP,BUF,LEN .ENDM IOPUTS::.ENTRY MOV 6(R5),R4 ; get I/O request packet MOV 10(R5),R3 ; get buffer address MOV 12(R5),R2 ; get buffer size $WRIT R4,R2,R3 ; write string .RETRN ; return values from $WRIT .PSECT CONST NUMTBL: .ASCII /0123456789ABCDEF/ R50TBL: .ASCII / ABCDEFGHIJKLMNOPQRSTUVWXYZ$.?0123456789/ LEN16: .WORD 16.,6.,5.,4.,3. LEN8: .WORD 8.,3.,3.,2.,0. RADTBL: .WORD 1.,8.,10.,16.,50 OFSTBL: .WORD 0,0,0,0,R50TBL-NUMTBL .END USRLIB