Hi! 6-Feb-98 17:21 John Payson wrote about "Re: Accessing text strings.": >> > Yes, strings are a pain on the PIC. :( >> BTW, another useful trick when writing code that should be equivalent to >> printf("Answer=%3d Result=%05D", answer, result); >> is to code it like this [more or less]; note that if there weren't very >> many printfs, it might be better to put more of the work in the "format" >> section and less in the library section. Note that "Format" is designed >> to be used as a string in a string-print procedure. >> >> Format: >> db "Answer=" >> movlw answer >> call IntPConvert >> goto BGetHund >> goto BGetTens >> goto GetOnes >> db " Result=" ..... >> IntPConvert: >> bsf blankflag >> movwf FSR >> movf IND,w >> movwf TempL >> incf IND >> movf IND,w >> movwf TempH >> goto Convert ; My wonderful bin->dec convert routine ..... Unfortunatly, one should note that this code can't be used exactly as a string. The string planned to be read is: 0123456789 (index in "CALL ReadFormat") "Answer=ddd".. (string to be read; ddd is the decimal value of the two bytes pointed by answer) Actually, we shell read "Answer=", but then some strange effects will be produced. (I suppouse that "Convert" makes convertion only). If index==7 then instructions "movlw answer" and "call IntPConvert" will be done. So, the value returned by conversion rotine "Convert" will be obtained by caller instead of the first digit of ansver (hundreds). If index==8 then only "call IntPConvert" will be done, and W will cotain value of 8 (if "addwf PCL,f" is used). So, TempL and TempH will be replaced with the values of SFR's 0x08 and 0x09 "Convert" routine will be called again. The value returned by "Convert" will be included into the string too. The string will be like this: 0123456789012 (index in CALL ReadFormat) "Answer=??ddd".. (string; '?' is unpredictable chars returned by "Convert") To avoid this one should perform additional increment by 2 the value of "index" in routine "Convert" or in code labeled with "IntPConvert" (it is better, because routine "Convert" remain unchanged and can be called with no connection with any strings). But generally, nobody can know what variable was used as index in "CALL ReadFormat". Thus we have to use the same variable ("format_index") for every format string. Another method is to make some improvements. Every char of the desired string should be represented by the only command. It may be something like this: Format: db "Answer=" ; movlw answer ; call IntPConvert ; goto BGetHund goto GetAnswer_And_Hund ;; !!! goto BGetTens goto GetOnes db " Result=" ..... GetAnswer_And_Hund: movlw answer call IntPConvert goto BGetHund IntPConvert: bsf blankflag movwf FSR movf IND,w movwf TempL incf IND movf IND,w movwf TempH goto Convert ; My wonderful bin->dec convert routine ..... Now if index==7 then "goto GetAnswer_And_Hund" will be executed. The desired value vill be transfered into TempL,TempH; "Convert" will be called and executed but returned value ignored; then "goto BGetHund" will be executed and the digit of hundreds of the desired number will be returned as a next char of the string. The next call (index==8) will cause the "goto BGetTens" executed and so on. I use method like described above for an interfacing to formatted output library. But I don't build a "string-like" code. Instead of this I build an "output list". Here is a siplified example (FMT... are entry points of library routines; index of current processing element is mantained in the library): Example: goto FMT_BLANK goto proc_answer_string goto proc_asnwer_value goto FMT_BLANK ; there are special entries for often used chars goto FMT_COMMA ; like " .,;:+-*" goto FMT_ENDLIST ; No comments :) proc_answer_value: movlw answer goto FMT_03D_I ; Use "%03d" coversion, "FMT..._I" means ; indirect addressing proc_answer_string: movlw high(answer_string) movwf hi_addr movlw low(answer_string) goto FMT_S_ROM answer_string: db "Answer=",0 This example was mentioned as simplified because this library has many other entry points. For example it is not efficient to use FMT_03D_I in this case. There is another entry (let us refer it as FMT_03D_I_ALT). It produce the same effect as FMT_03D_I but index of current processing element will be incremented by 2. So, we can eliminate one GoTo command and one label. (It's not joke, total number of labels will be too high and the risk of undetected mistypes will be very high too.) The example became as follows: printf(" Answer=%03d, ", *answer); Example: goto FMT_BLANK goto proc_answer_string movlw answer goto FMT_03D_I_ALT goto proc_asnwer_value goto FMT_COMMA ; there are special entries for often used chars goto FMT_BLANK ; like " .,;:+-*". It was not necessary to use ; this possibility here. It's illustration only goto FMT_ENDLIST ; No comments :) proc_answer_string: movlw high(answer_string) movwf hi_addr movlw low(answer_string) goto FMT_S_ROM answer_string: db "Answer=",0 Entry point FMT_S_ROM (and other string rotines) maintain its own internal index (rather than index of the list elements) for access to procesing string. This library can be used to implement more complicated printfs. For example: printf("Status is \'%s\'", ok==0?"Failed":"OK!"); Actually will be implemented some other printf: printf("%s%s%c", "Status is \'", ok==0?"Failed":"OK!",'\''); Example2: goto proc_status_string goto proc_status_report movlw "'" goto FMT_C_ALT