TITLE "MP5 by Douglas W. Jones" ; July 22, 2018 ; this is a minimally changed version of INTTOS from MP4 USE "hawk.h" USE "monitor.h" INT INTTOS ; this is the only change from MP4 ; special string constants needed by INTTOS ITOSQQ: ASCII "?",0 ; error return string, indicates bad base ITOSQD: ASCII "-",0 ; error return string, indicates number won't fit ITOSDA: ASCII "0123456789ABCDEFGHJKMNPQRSTVWXYZ" ; array of digits ALIGN 2 ; activation record structure ;RETAD = 0 R8SV = 4 ; save locations for R8 to R10 R9SV = 8 R10SV = 12 ARSIZE = 16 ; code INTTOS: ; expects R3 = buf -- address of buffer to use for conversion ; R4 = len -- length of buffer ; R5 = num -- unsigned number to convert to string ; R6 = base -- number base to use (from 2 to 32) ; returns R3 = str -- pointer to null terminated string holding result ; note that str points somewhere between buf and buf+len-1 ; except when there is an error. ; note register use changes after initial sanity checks ; restores R8-10 after use CMPI R6,2 BLT ITOSBNO CMPI R6,32 BLE ITOSBOK ; if ((base < 2)||(base > 32)) { -- illegal base ITOSBNO: LEA R3,ITOSQQ JUMPS R1 ; return "?" ITOSBOK: ; } CMPI R4,2 BGEU ITOSLOK ; if (len < 2) { -- no room for anything in buf LEA R3,ITOSQD JUMPS R1 ; return "-" ITOSLOK: ; } STORES R1,R2 STORE R8,R2,R8SV ; -- save registers STORE R9,R2,R9SV STORE R10,R2,R10SV ADDI R2,R2,ARSIZE ; uses R3 = num -- register use from here on ; R8 = buf ; R9 = str ; R10 = base MOVE R8,R3 ; -- move buf ADD R9,R4,R3 ; str = buf + len -- points off end of buffer MOVE R3,R5 ; -- move num MOVE R10,R6 ; -- move base ; -- we work from the end of the buffer forward ADDSI R9,-1 ; str = str - 1 LOADS R1,R9 STUFFB R1,R0,R9 STORES R1,R9 ; *str = NUL -- buffer terminator in place ITOSLP: ; loop { -- for each digit in number CMP R9,R8 BGTU ITOSSOK ; if (str <= buf) { -- another char won't fit LEA R3,ITOSQD BR ITOSSQT ; break to go return "-" ITOSSOK: ; } ; -- parameter num already in place MOVE R5,R10 ; -- parameter base (note this is in R5) LIL R1,DIVIDEU JSRS R1,R1 ; (quot, rem) = divideu( num, base ) ; num = quot LEA R1,ITOSDA ADD R4,R4,R1 LOADS R5,R4 EXTB R5,R5,R4 ; digit = itosda[rem] ADDSI R9,-1 ; str = str - 1 LOADS R1,R9 STUFFB R1,R5,R9 STORES R1,R9 ; *str = digit TESTR R3 BZR ITOSLP ; } until (num == 0) MOVE R3,R9 ; -- put str in place ITOSSQT: ; -- error break comes here with str in place ADDI R2,R2,-ARSIZE LOAD R8,R2,R8SV ; -- restore saved registers LOAD R9,R2,R9SV LOAD R10,R2,R10SV LOADS R1,R2 JUMPS R1 ; return str END