
 *|   Version 0.03
 *|   This should be distributed with dooperfplib.s
 *|   fpconvrt is required for dooperfplib to work.
 *|   It converts double precision floating point numbers to ones
 *|     with a 32-bit mantissa that will neatly fit an ARM register.
 *|   This is not really expected to work with anything other
 *|     than ARM GCC versions 2.95.2 and 2.95.4
 *|   I accept no responsibility for it being useless.  :-)
 *|         <mech@toth.org.uk> 2001, 2002

 ONERROR PRINTREPORT$+" at "+STR$ERL:END

 SYS "OS_GetEnv" TO env$
 pos%=INSTR(env$,"fpconvrt")+9
 name$=RIGHT$(env$,LENenv$-pos%)
 fh%=OPENIN name$
 sz%=EXT#fh%
 CLOSE#fh%
 DIM in% sz%
 SYS "OS_File", 255, name$, in%
 out%=OPENOUT name$
 ONERROR CLOSE#out%:PRINTREPORT$+" at "+STR$ERL:END

 pos%=0
 REPEATline$="":REPEATchr$=CHR$(in%?pos%):line$+=chr$:pos%+=1:UNTIL chr$=CHR$10 OR pos%=sz%
 IF MID$(line$,2,3)="DCD" AND INSTR(line$,"double") AND INSTR(line$,",") THEN
    split% = INSTR(line$,CHR$9+";")
    lh$ = LEFT$(line$,split%)
    rh$ = RIGHT$(line$,LENline$-split%+1)
    hex1% = INSTR(line$,"&")
    hex2% = INSTR(line$,"&",hex1%+1)
    hiwordin% = EVAL(MID$(line$,hex1%,hex2%-hex1%))
    lowordin% = EVAL(MID$(line$,hex2%,split%-hex2%))
    PROCfpconv(hiwordin%,lowordin%,hiwordout%,lowordout%)
    hex1$ = STR$~(hiwordout%)
    hex2$ = STR$~(lowordout%)
    hex1$ = LEFT$("00000000", 8-LEN(hex1$)) + hex1$
    hex2$ = LEFT$("00000000", 8-LEN(hex2$)) + hex2$
    BPUT#out%,CHR$9+"dcd &"+hex1$+", &"+hex2$+LEFT$(rh$)
 ELSE
    BPUT#out%,LEFT$(line$)
 ENDIF
 UNTILpos%=sz%

 CLOSE#out%
 END


DEFPROCfpconv(in1%, in2%, RETURN out1%, RETURN out2%)
 sign%=in1%AND(1<<31)
 IF ((in1%ANDNOT(1<<31))=0)AND((in2%>>>1)<(1<<19)) out1%=sign%:out2%=0:ENDPROC
 out1% = sign% OR (&3C00 + ((in1%ANDNOTsign%)>>>20))
 out2% = (in1%<<11) OR (in2%>>>21) OR 1<<31
 IF (out2% <> -1) THEN
   IF ((in2%<<11)>>>11)>=(1<<20) out2%+=1
 ELSE
   out2%=1<<31:out1%-=1
 ENDIF
 ENDPROC
