Annotation of researchv10no/libc/stdio/ostdio/doprnt.s, revision 1.1

1.1     ! root        1: # 1 "doprnt.nS"
        !             2: 
        !             3:        # C library -- conversions
        !             4: 
        !             5: .globl __doprnt
        !             6: .globl __flsbuf
        !             7: 
        !             8: 
        !             9: 
        !            10: 
        !            11: 
        !            12: 
        !            13: 
        !            14: 
        !            15: 
        !            16: 
        !            17: 
        !            18: 
        !            19: 
        !            20: 
        !            21: 
        !            22: 
        !            23: 
        !            24: 
        !            25: 
        !            26: 
        !            27: 
        !            28: 
        !            29:        .set ch.zer,'0                  # cpp doesn't like single appostrophes
        !            30:        .set ch.per,'%                  # I'm convinced BE
        !            31: 
        !            32:        .align 2
        !            33: 
        !            34: 
        !            35: 
        !            36: 
        !            37: 
        !            38: 
        !            39: 
        !            40: 
        !            41: 
        !            42: 
        !            43: 
        !            44: 
        !            45: 
        !            46: 
        !            47: 
        !            48: 
        !            49: 
        !            50: 
        !            51: strfoo:
        !            52:        clrl r4                                 # fix interrupt race
        !            53:        jbr strok                               # and try again
        !            54: strmore:
        !            55:        movzbl (r1)+,r2                 # one char
        !            56: 
        !            57:        jeql stresc2                    # BE
        !            58:        cmpl r2,$ch.per                 # BE
        !            59:        jeql stresc2                    # bad guy in disguise (outbuf is full)
        !            60: strout2:               # enter here to force out r2; r0,r1 must be set
        !            61: 
        !            62:        movq r0,-(sp)   # BE
        !            63:        pushl -4(fp)                            # FILE
        !            64:        pushl r2                                # the char
        !            65:        calls $2,__flsbuf               # please empty the buffer and handle 1 char
        !            66:        tstl r0                                 # successful?
        !            67:        jgeq strm1                              # yes
        !            68:        jbcs $31,-16(fp),strm1  # turn on -17(fp) bit of -16(fp) to signify error
        !            69: strm1:
        !            70:        incl -16(fp)                            # count the char
        !            71: 
        !            72:        movq r0,(sp)+           # BE
        !            73: strout:                        # enter via bsb with (r0,r1)=input descriptor
        !            74: 
        !            75:        movq *-4(fp),r4                 # output descriptor
        !            76:        jbs $31,r4,strfoo               # negative count is a no no
        !            77: strok:
        !            78:        addl2 r0,-16(fp)                        # we intend to move this many chars
        !            79: 
        !            80:        clrl r2
        !            81:        tstl    r0
        !            82:        bleq    movdon
        !            83: movlp:
        !            84:        tstl    r4
        !            85:        bleq    movdon
        !            86:        movzbl  (r1)+,r3
        !            87: 
        !            88:        beql    2f              # BE
        !            89:        cmpl    r3,$ch.per      # BE
        !            90:        bneq    1f
        !            91: 2:                             # BE
        !            92:        mnegl   $1,r2
        !            93:        decl    r1
        !            94:        brb     movdon
        !            95: 1:
        !            96:        movb    r3,(r5)+
        !            97:        decl    r4
        !            98:        sobgtr  r0,movlp
        !            99:   
        !           100: 
        !           101: 
        !           102:   
        !           103: movdon: movq r4,*-4(fp)                  
        !           104:        subl2 r0,-16(fp)                        # some chars not moved
        !           105:        jbs $1,r2,stresc                # terminated by escape?
        !           106:        sobgeq r0,strmore               # no; but out buffer might be full
        !           107: stresc:
        !           108:        rsb
        !           109: stresc2:
        !           110:        incl r0                                 # fix the length
        !           111:        decl r1                                 # and the addr
        !           112:        movl $1<1,r2                    # fake condition codes
        !           113:        rsb
        !           114: 
        !           115: errdone:
        !           116:        jbcs $31,-16(fp),prdone # set error bit
        !           117: prdone:
        !           118:        movl -16(fp),r0
        !           119:        ret
        !           120: 
        !           121:        .align  1
        !           122: __doprnt:
        !           123:        .word   0xfc0                   # uses r11-r6
        !           124:        movab -256(sp),sp               # work space
        !           125:        movl 4(ap),r11                  # addr of format string
        !           126:        movl 12(ap),-4(fp)              # output FILE ptr
        !           127:        movl 8(ap),ap                   # addr of first arg
        !           128:        clrl -16(fp)                            # number of chars transferred
        !           129: loop:
        !           130:        movzwl $65535,r0                # pseudo length
        !           131:        movl r11,r1                             # fmt addr
        !           132:                # comet sucks.
        !           133:        movq *-4(fp),r4
        !           134:        subl3 r1,r5,r2
        !           135:        jlss lp1
        !           136:        cmpl r0,r2
        !           137:        jleq lp1
        !           138:        movl r2,r0
        !           139: lp1:
        !           140:                #
        !           141:        bsbw strout                             # copy to output, stop at null or percent
        !           142:        movl r1,r11                             # new fmt
        !           143:        jbc $1,r2,loop          # if no escape, then very long fmt
        !           144:        tstb (r11)+                             # escape; null or percent?
        !           145:        jeql prdone                             # null means end of fmt
        !           146: 
        !           147:        movl sp,r5                      # reset output buffer pointer
        !           148:        clrq r9                         # r9; r10
        !           149:        clrq r6                         # r6,r7
        !           150: longorunsg:                            # we can ignore both of these distinctions
        !           151: short:
        !           152: L4a:
        !           153:        movzbl (r11)+,r0                # so capital letters can tail merge
        !           154: L4:    caseb r0,$' ,$'x-'              # format char
        !           155: L5:
        !           156:        .word space-L5                  # space
        !           157:        .word fmtbad-L5                 # !
        !           158:        .word fmtbad-L5                 # "
        !           159:        .word sharp-L5                  # #
        !           160:        .word fmtbad-L5                 # $
        !           161:        .word fmtbad-L5                 # %
        !           162:        .word fmtbad-L5                 # &
        !           163:        .word fmtbad-L5                 # '
        !           164:        .word fmtbad-L5                 # (
        !           165:        .word fmtbad-L5                 # )
        !           166:        .word indir-L5                  # *
        !           167:        .word plus-L5                   # +
        !           168:        .word fmtbad-L5                 # ,
        !           169:        .word minus-L5                  # -
        !           170:        .word dot-L5                    # .
        !           171:        .word fmtbad-L5                 # /
        !           172:        .word gnum0-L5                  # 0
        !           173:        .word gnum-L5                   # 1
        !           174:        .word gnum-L5                   # 2
        !           175:        .word gnum-L5                   # 3
        !           176:        .word gnum-L5                   # 4
        !           177:        .word gnum-L5                   # 5
        !           178:        .word gnum-L5                   # 6
        !           179:        .word gnum-L5                   # 7
        !           180:        .word gnum-L5                   # 8
        !           181:        .word gnum-L5                   # 9
        !           182:        .word fmtbad-L5                 # :
        !           183:        .word fmtbad-L5                 # ;
        !           184:        .word fmtbad-L5                 # <
        !           185:        .word fmtbad-L5                 # =
        !           186:        .word fmtbad-L5                 # >
        !           187:        .word fmtbad-L5                 # ?
        !           188:        .word fmtbad-L5                 # @
        !           189:        .word fmtbad-L5                 # A
        !           190:        .word fmtbad-L5                 # B
        !           191:        .word fmtbad-L5                 # C
        !           192:        .word decimal-L5                # D
        !           193:        .word capital-L5                # E
        !           194:        .word fmtbad-L5                 # F
        !           195:        .word capital-L5                # G
        !           196:        .word fmtbad-L5                 # H
        !           197:        .word fmtbad-L5                 # I
        !           198:        .word fmtbad-L5                 # J
        !           199:        .word fmtbad-L5                 # K
        !           200:        .word fmtbad-L5                 # L
        !           201:        .word fmtbad-L5                 # M
        !           202:        .word fmtbad-L5                 # N
        !           203:        .word octal-L5                  # O
        !           204:        .word fmtbad-L5                 # P
        !           205:        .word fmtbad-L5                 # Q
        !           206:        .word fmtbad-L5                 # R
        !           207:        .word fmtbad-L5                 # S
        !           208:        .word fmtbad-L5                 # T
        !           209:        .word unsigned-L5               # U
        !           210:        .word fmtbad-L5                 # V
        !           211:        .word fmtbad-L5                 # W
        !           212:        .word capital-L5                # X
        !           213:        .word fmtbad-L5                 # Y
        !           214:        .word fmtbad-L5                 # Z
        !           215:        .word fmtbad-L5                 # [
        !           216:        .word fmtbad-L5                 # \
        !           217:        .word fmtbad-L5                 # ]
        !           218:        .word fmtbad-L5                 # ^
        !           219:        .word fmtbad-L5                 # _
        !           220:        .word fmtbad-L5                 # `
        !           221:        .word fmtbad-L5                 # a
        !           222:        .word fmtbad-L5                 # b
        !           223:        .word charac-L5                 # c
        !           224:        .word decimal-L5                # d
        !           225:        .word scien-L5                  # e
        !           226:        .word float-L5                  # f
        !           227:        .word general-L5                # g
        !           228:        .word short-L5                  # h
        !           229:        .word fmtbad-L5                 # i
        !           230:        .word fmtbad-L5                 # j
        !           231:        .word fmtbad-L5                 # k
        !           232:        .word longorunsg-L5             # l
        !           233:        .word fmtbad-L5                 # m
        !           234:        .word fmtbad-L5                 # n
        !           235:        .word octal-L5                  # o
        !           236:        .word fmtbad-L5                 # p
        !           237:        .word fmtbad-L5                 # q
        !           238:        .word fmtbad-L5                 # r
        !           239:        .word string-L5                 # s
        !           240:        .word fmtbad-L5                 # t
        !           241:        .word unsigned-L5               # u
        !           242:        .word fmtbad-L5                 # v
        !           243:        .word fmtbad-L5                 # w
        !           244:        .word hex-L5                    # x
        !           245: fmtbad:
        !           246:        movb r0,(r5)+                   # print the unfound character
        !           247:        jeql errdone                    # dumb users who end the format with a %
        !           248:        jbr prbuf
        !           249: capital:
        !           250:        bisl2 $1<6,r10          # note that it was capitalized
        !           251:        xorb2 $'a^'A,r0                 # make it small
        !           252:        jbr L4                                  # and try again
        !           253: 
        !           254: string:
        !           255:        movl r8,r0
        !           256:        jbs $1,r10,L20          # max length was specified
        !           257:        mnegl $1,r0                     # default max length
        !           258: L20:   movl (ap)+,r2                   # addr first byte
        !           259:        locc $0,r0,(r2)                 # find the zero at the end
        !           260:        movl r1,r5                      # addr last byte +1
        !           261:        movl r2,r1                      # addr first byte
        !           262:        jbr prstr
        !           263: 
        !           264: htab:  .byte   '0,'1,'2,'3,'4,'5,'6,'7,'8,'9,'a,'b,'c,'d,'e,'f
        !           265: Htab:  .byte   '0,'1,'2,'3,'4,'5,'6,'7,'8,'9,'A,'B,'C,'D,'E,'F
        !           266: 
        !           267: octal:
        !           268:        movl $30,r2                     # init position
        !           269:        movl $3,r3                      # field r9
        !           270:        movab htab,r7   # translate table
        !           271:        jbr L10
        !           272: 
        !           273: hex:
        !           274:        movl $28,r2                     # init position
        !           275:        movl $4,r3                      # field r9
        !           276:        movab htab,r7   # translate table
        !           277:        jbc $6,r10,L10
        !           278:        movab Htab,r7
        !           279: L10:   mnegl r3,r6                     # increment
        !           280:        clrl r1
        !           281:        addl2 $4,r5                     # room for left affix (2) and slop [forced -17(fp)?]
        !           282:        movl (ap)+,r0                   # fetch arg
        !           283: L11:   extzv r2,r3,r0,r1               # pull out a digit
        !           284:        movb (r7)[r1],(r5)+             # convert to character
        !           285: L12:   acbl $0,r6,r2,L11               # continue until done
        !           286:        clrq r6                         # r6, r7
        !           287:        clrb (r5)                       # flag end
        !           288:        skpc $'0,$11,4(sp)              # skip over leading zeroes
        !           289:        jbc $5,r10,prn3 # easy if no left affix
        !           290:        tstl -4(ap)                             # original value
        !           291:        jeql prn3                       # no affix on 0, for some reason
        !           292:        cmpl r3,$4                      # were we doing hex or octal?
        !           293:        jneq L12a                       # octal
        !           294:        movb $'x,r0
        !           295:        jbc $6,r10,L12b
        !           296:        movb $'X,r0
        !           297: L12b:  movb r0,-(r1)
        !           298:        movl $2,r7              # leading 0x for hex is an affix
        !           299: L12a:  movb $'0,-(r1)  # leading zero for octal is a digit, not an affix
        !           300:        jbr prn3                        # omit -17(fp) (plus, 7) massaging
        !           301: 
        !           302: unsigned:
        !           303: lunsigned:
        !           304:        bicl2 $1<4|1<7,r10      # omit -17(fp) (plus, 7) massaging
        !           305:        extzv $1,$31,(ap),r0            # right shift logical 1 bit
        !           306:        cvtlp r0,$10,(sp)               # convert [n/2] to packed
        !           307:        movp $10,(sp),8(sp)             # copy packed
        !           308:        addp4 $10,8(sp),$10,(sp)        # 2*[n/2] in packed, at (sp)
        !           309:        blbc (ap)+,L14                  # n was even
        !           310:        addp4 $1,pone,$10,(sp)          # n was odd
        !           311:        jbr L14
        !           312: 
        !           313: patdec:                                        # editpc pattern for decimal printing
        !           314:        .byte 0xAA                      # eo$float 10
        !           315:        .byte 0x01                      # eo$end_float
        !           316:        .byte 0                         # eo$end
        !           317: 
        !           318: decimal:
        !           319:        cvtlp (ap)+,$10,(sp)            # 10 digits max
        !           320:        jgeq L14
        !           321:        incl r7                 # minus -17(fp) is a left affix
        !           322: L14:   editpc $10,(sp),patdec,8(sp)    # ascii at 8(sp); r5=end+1
        !           323:        skpc $' ,$11,8(sp)              # skip leading blanks; r1=first
        !           324: 
        !           325: prnum:                 # r1=addr first byte, r5=addr last byte +1, r7=size of signs
        !           326:                                # -1(r1) vacant, for forced -17(fp)
        !           327:        tstl r7
        !           328:        jneq prn3                       # already some left affix, dont fuss
        !           329:        jbc $4,r10,prn2
        !           330:        movb $'+,-(r1)          # needs a plus sign
        !           331:        jbr prn4
        !           332: prn2:  jbc $7,r10,prn3
        !           333:        movb $' ,-(r1)          # needs a blank sign
        !           334: prn4:  incl r7
        !           335: prn3:  jbs $1,r10,prn1
        !           336:        movl $1,r8              # default precision is 1
        !           337: prn1:  subl3 r1,r5,r6  # raw r9
        !           338:        subl2 r7,r6     # number of digits
        !           339:        subl2 r6,r8     # number of leading zeroes needed
        !           340:        jleq prstr                      # none
        !           341:        addl2 r7,r1             # where current digits start
        !           342:        pushl r1                        # movcx gobbles registers
        !           343:                # check bounds on users who say %.300d
        !           344:        movab 32(r5)[r8],r2
        !           345:        subl2 fp,r2
        !           346:        jlss prn5
        !           347:        subl2 r2,r8
        !           348: prn5:
        !           349:                #
        !           350:        movc3 r6,(r1),(r1)[r8]  # make room in middle
        !           351:        movc5 $0,(r1),$ch.zer,r8,*(sp)  # '0 fill
        !           352:        subl3 r7,(sp)+,r1       # first byte addr
        !           353:        addl3 r6,r3,r5  # last byte addr +1
        !           354: 
        !           355: prstr:                 # r1=addr first byte; r5=addr last byte +1
        !           356:                                # r9=minimum r9; r7=len. left affix
        !           357:                                # r8=<avail>
        !           358:        subl3 r1,r5,r8          # raw r9
        !           359:        subl3 r8,r9,r0  # pad length
        !           360:        jleq padlno                             # in particular, no left padding
        !           361:        jbs $3,r10,padlno
        !           362:                        # extension for %0 flag causing left zero padding to field r9
        !           363:        jbs $2,r10,padlz
        !           364:                        # this bsbb needed even if %0 flag extension is removed
        !           365:        bsbb padb                               # 7 pad on left
        !           366:        jbr padnlz
        !           367: padlz:
        !           368:        movl r7,r0
        !           369:        jleq padnlx                             # left zero pad requires left affix first
        !           370:        subl2 r0,r8                     # part of total length will be transferred
        !           371:        subl2 r0,r9                     # and will account for part of minimum r9
        !           372:        bsbw strout                             # left affix
        !           373: padnlx:
        !           374:        subl3 r8,r9,r0  # pad length
        !           375:        bsbb padz                               # zero pad on left
        !           376: padnlz:
        !           377:                        # end of extension for left zero padding
        !           378: padlno:                        # remaining: root, possible right padding
        !           379:        subl2 r8,r9             # root reduces minimum r9
        !           380:        movl r8,r0                      # root length
        !           381: p1:    bsbw strout                             # transfer to output buffer
        !           382: p3:    jbc $1,r2,padnpct       # percent -17(fp) (or null byte via %c) ?
        !           383:        decl r0                                 # yes; adjust count
        !           384:        movzbl (r1)+,r2                 # fetch byte
        !           385:        movq *-4(fp),r4                 # output buffer descriptor
        !           386:        sobgeq r4,p2                    # room at the out [inn] ?
        !           387:        bsbw strout2                    # no; force it, then try rest
        !           388:        jbr p3                                  # here we go 'round the mullberry bush, ...
        !           389: p2:    movb r2,(r5)+                   # hand-deposit the percent or null
        !           390:        incl -16(fp)                            # count it
        !           391:        movq r4,*-4(fp)                 # store output descriptor
        !           392:        jbr p1                                  # what an expensive hiccup!
        !           393: padnpct:
        !           394:        movl r9,r0      # size of pad
        !           395:        jleq loop
        !           396:        bsbb padb
        !           397:        jbr loop
        !           398: 
        !           399: padz:
        !           400:        movb $'0,r2
        !           401:        jbr pad
        !           402: padb:
        !           403:        movb $' ,r2
        !           404: pad:
        !           405:        subl2 r0,r9                     # pad r9 decreases minimum r9
        !           406:        pushl r1                                # save non-pad addr
        !           407:        movl r0,r7                      # remember r9 of pad
        !           408:        subl2 r0,sp                             # allocate
        !           409:        movc5 $0,(r0),r2,r7,(sp)        # create pad string
        !           410:        movl r7,r0                      # length
        !           411:        movl sp,r1                              # addr
        !           412:        bsbw strout
        !           413:        addl2 r7,sp                     # deallocate
        !           414:        movl (sp)+,r1                   # recover non-pad addr
        !           415:        rsb
        !           416: 
        !           417: pone:  .byte   0x1C                    # packed 1
        !           418:        
        !           419: charac:
        !           420:        movl (ap)+,r0           # word containing the char
        !           421:        movb r0,(r5)+           # one byte, that's all
        !           422: 
        !           423: prbuf:
        !           424:        movl sp,r1                      # addr first byte
        !           425:        jbr prstr
        !           426: 
        !           427: space: bisl2 $1<7,r10          # constant r9 e fmt, no plus -17(fp)
        !           428:        jbr L4a
        !           429: sharp: bisl2 $1<5,r10          # 'self identifying', please
        !           430:        jbr L4a
        !           431: plus:  bisl2 $1<4,r10          # always print -17(fp) for floats
        !           432:        jbr L4a
        !           433: minus: bisl2 $1<3,r10          # left justification, please
        !           434:        jbr L4a
        !           435: gnum0: jbs $0,r10,gnum
        !           436:        jbs $1,r10,gnump                # ignore when reading precision
        !           437:        bisl2 $1<2,r10          # leading zero fill, please
        !           438: gnum:  jbs $1,r10,gnump
        !           439:        moval (r9)[r9],r9       # r9 *= 5;
        !           440:        movaw -ch.zer(r0)[r9],r9        # r9 = 2*witdh + r0 - '0';
        !           441:        jbr gnumd
        !           442: gnump: moval (r8)[r8],r8       # r8 *= 5;
        !           443:        movaw -ch.zer(r0)[r8],r8 # r8 = 2*r8 + r0 - '0';
        !           444: gnumd: bisl2 $1<0,r10          # digit seen
        !           445:        jbr L4a
        !           446: dot:   clrl r8                 # start on the precision
        !           447:        bisl2 $1<1,r10
        !           448:        bicl2 $1<0,r10
        !           449:        jbr L4a
        !           450: indir:
        !           451:        jbs $1,r10,in1
        !           452:        movl (ap)+,r9           # r9 specified by parameter
        !           453:        jgeq gnumd
        !           454:        xorl2 $1<3,r10          # parameterized left adjustment
        !           455:        mnegl r9,r9
        !           456:        jbr gnumd
        !           457: in1:
        !           458:        movl (ap)+,r8           # precision specified by paratmeter
        !           459:        jgeq gnumd
        !           460:        mnegl r8,r8
        !           461:        jbr gnumd
        !           462: 
        !           463: float:
        !           464:        jbs $1,r10,float1
        !           465:        movl $6,r8                      # default # digits to right of decpt.
        !           466: float1:        bsbw fltcvt
        !           467:        addl3 -8(fp),r8,r7
        !           468:        movl r7,r6                      # for later "underflow" checking
        !           469:        bgeq fxplrd
        !           470:        clrl r7                         # poor programmer planning
        !           471: fxplrd:        cmpl r7,$31                     # expressible in packed decimal?
        !           472:        bleq fnarro                     # yes
        !           473:        movl $31,r7
        !           474: fnarro:        subl3 $17,r7,r0                 # where to round
        !           475:        ashp r0,$17,(sp),$5,r7,16(sp)   # do it
        !           476:        bvc fnovfl
        !           477:                # band-aid for microcode error (spurious overflow)
        !           478:        #       clrl r0                         # assume even length result
        !           479:        #       jlbc r7,fleven                  # right
        !           480:        #       movl $4,r0                      # odd length result
        !           481:        #fleven:        cmpv r0,$4,16(sp),$0            # top digit zero iff true overflow
        !           482:        #       bneq fnovfl
        !           483:                # end band-aid
        !           484:        aobleq $0,r6,fnovfl             # if "underflow" then jump
        !           485:        movl r7,r0
        !           486:        incl -8(fp)
        !           487:        incl r7
        !           488:        ashp r0,$1,pone,$0,r7,16(sp)
        !           489:        ashl $-1,r7,r0                  # displ to last byte
        !           490:        bisb2 -17(fp),16(sp)[r0]                # insert -17(fp)
        !           491: fnovfl:
        !           492:        movab 16(sp),r1         # packed source
        !           493:        movl r7,r6              # packed length
        !           494:        pushab prnum    # goto prnum after fall-through call to fedit
        !           495: 
        !           496: 
        !           497:        # enter via bsb
        !           498:        #       r1=addr of packed source
        !           499:        #          16(r1) used to unpack source
        !           500:        #          48(r1) used to construct pattern to unpack source
        !           501:        #          48(r1) used to hold result
        !           502:        #       r6=length of packed source (destroyed)
        !           503:        #       -8(fp)=# digits to left of decimal point (destroyed)
        !           504:        #       r8=# digits to right of decimal point (destroyed)
        !           505:        #       -17(fp)=1 if negative, 0 otherwise
        !           506:        # stack will be used for work space for pattern and unpacked source 
        !           507:        # exits with
        !           508:        #       r1=addr of punctuated result
        !           509:        #       r5=addr of last byte +1
        !           510:        #       r7=1 if minus -17(fp) inserted, 0 otherwise
        !           511: fedit:
        !           512:        pushab 48(r1)                   # save result addr
        !           513:        movab 48(r1),r3                 # pattern addr
        !           514:        movb $0x03,(r3)+                # eo$set_signif
        !           515:        movc5 $0,(r1),$0x91,r6,(r3)     # eo$move 1
        !           516:        clrb (r3)                               # eo$end
        !           517:        editpc r6,(r1),48(r1),16(r1)    # unpack 'em all
        !           518:        subl3 r6,r5,r1                  # addr unpacked source
        !           519:        movl (sp),r3                    # punctuated output placed here
        !           520:        clrl r7
        !           521:        jlbc -17(fp),f1
        !           522:        movb $'-,(r3)+          # negative
        !           523:        incl r7
        !           524: f1:    movl -8(fp),r0
        !           525:        jgtr f2
        !           526:        movb $'0,(r3)+          # must have digit before decimal point
        !           527:        jbr f3
        !           528: f2:    cmpl r0,r6                      # limit on packed length
        !           529:        jleq f4
        !           530:        movl r6,r0
        !           531: f4:    subl2 r0,r6                     # eat some digits
        !           532:        subl2 r0,-8(fp)         # from the exponent
        !           533:        movc3 r0,(r1),(r3)      # (most of the) digits to left of decimal point
        !           534:        movl -8(fp),r0                  # need any more?
        !           535:        jleq f3
        !           536:        movc5 $0,(r1),$'0,r0,(r3)       # '0 fill
        !           537: f3:    movl r8,r0              # # digits to right of decimal point
        !           538:        jgtr f5
        !           539:        jbs $5,r10,f5   # no decimal point unless forced
        !           540:        jbcs $9,r10,f6  # no decimal point
        !           541: f5:    movb $'.,(r3)+          # the decimal point
        !           542: f6:    mnegl -8(fp),r0         # "leading" zeroes to right of decimal point
        !           543:        jleq f9
        !           544:        cmpl r0,r8              # cant exceed this many
        !           545:        jleq fa
        !           546:        movl r8,r0
        !           547: fa:    subl2 r0,r8
        !           548:        movc5 $0,(r1),$'0,r0,(r3)
        !           549: f9:    movl r8,r0
        !           550:        cmpl r0,r6                      # limit on packed length
        !           551:        jleq f7
        !           552:        movl r6,r0
        !           553: f7:    subl2 r0,r8             # eat some digits from the fraction
        !           554:        movc3 r0,(r1),(r3)      # (most of the) digits to right of decimal point
        !           555:        movl r8,r0                      # need any more?
        !           556:        jleq f8
        !           557:                # check bounds on users who say %.300f
        !           558:        movab 32(r3)[r0],r2
        !           559:        subl2 fp,r2
        !           560:        jlss fb
        !           561:        subl2 r2,r0                     # truncate, willy-nilly
        !           562:        movl r0,r8              # and no more digits later, either
        !           563: fb:
        !           564:                #
        !           565:        subl2 r0,r8             # eat some digits from the fraction
        !           566:        movc5 $0,(r1),$'0,r0,(r3)       # '0 fill
        !           567: f8:    movl r3,r5                      # addr last byte +1
        !           568:        popr $1<1                       # [movl (sp)+,r1] addr first byte
        !           569:        rsb
        !           570: 
        !           571: patexp:        .byte   0x03                    # eo$set_signif
        !           572:        .byte   0x44,'e                 # eo$insert 'e
        !           573:        .byte   0x42,'+                 # eo$load_plus '+
        !           574:        .byte   0x04                    # eo$store_sign
        !           575:        .byte   0x92                    # eo$move 2
        !           576:        .byte   0                       # eo$end
        !           577: 
        !           578: scien:
        !           579:        incl r8
        !           580:        jbs $1,r10,L23
        !           581:        movl $7,r8
        !           582: L23:   bsbw fltcvt                     # get packed digits
        !           583:        movl r8,r7
        !           584:        cmpl r7,$31                             # expressible in packed decimal?
        !           585:        jleq snarro                             # yes
        !           586:        movl $31,r7
        !           587: snarro:        subl3 $17,r7,r0         # rounding position
        !           588:        ashp r0,$17,(sp),$5,r7,16(sp) # shift and round
        !           589:        bvc snovfl
        !           590:                # band-aid for microcode error (spurious overflow)
        !           591:        #       clrl r0                         # assume even length result
        !           592:        #       jlbc r8,sceven          # right
        !           593:        #       movl $4,r0                      # odd length result
        !           594:        #sceven:        cmpv r0,$4,16(sp),$0            # top digit zero iff true overflow
        !           595:        #       bneq snovfl
        !           596:                # end band-aid
        !           597:        incl -8(fp)                     # rounding overflowed to 100...
        !           598:        subl3 $1,r7,r0
        !           599:        ashp r0,$1,pone,$0,r7,16(sp)
        !           600:        ashl $-1,r7,r0          # displ to last byte
        !           601:        bisb2 -17(fp),16(sp)[r0]                # insert -17(fp)
        !           602: snovfl:
        !           603:        jbs $8,r10,gfmt         # %g format
        !           604:        movab 16(sp),r1
        !           605:        bsbb eedit
        !           606: eexp:
        !           607:        movl r1,r6              # save fwa from destruction by cvtlp
        !           608:        subl3 $1,-12(fp),r0     # 1P exponent
        !           609:        cvtlp r0,$2,(sp)        # packed
        !           610:        editpc $2,(sp),patexp,(r5)
        !           611:        movl r6,r1              # fwa
        !           612:        jbc $6,r10,prnum
        !           613:        xorb2 $'e^'E,-4(r5)
        !           614:        jbr prnum
        !           615: 
        !           616: eedit:
        !           617:        movl r7,r6              # packed length
        !           618:        decl r8         # 1 digit before decimal point
        !           619:        movl -8(fp),-12(fp)     # save from destruction
        !           620:        movl $1,-8(fp)          # and pretend
        !           621:        jbr fedit
        !           622: 
        !           623: gfmt:
        !           624:        addl3 $3,-8(fp),r0              # -8(fp) is 1 more than e
        !           625:        jlss gfmte              # (e+1)+3<0, e+4<=-1, e<=-5
        !           626:        subl2 $3,r0             # -8(fp) [==(e+1)]
        !           627:        cmpl r0,r8
        !           628:        jgtr gfmte              # e+1>n, e>=n
        !           629: gfmtf:
        !           630:        movl r7,r6
        !           631:        subl2 r0,r8             # n-e-1
        !           632:        movab 16(sp),r1
        !           633:        bsbw fedit
        !           634: g1:    jbs $5,r10,g2
        !           635:        jbs $9,r10,g2   # dont strip if no decimal point
        !           636: g3:    cmpb -(r5),$'0          # strip trailing zeroes
        !           637:        jeql g3
        !           638:        cmpb (r5),$'.           # and trailing decimal point
        !           639:        jeql g2
        !           640:        incl r5
        !           641: g2:    jbc $8,r10,eexp
        !           642:        jbr prnum
        !           643: gfmte:
        !           644:        movab 16(sp),r1         # packed source
        !           645:        bsbw eedit
        !           646:        jbsc $8,r10,g1  # 8 now means "use %f" [hence no exponent]
        !           647: 
        !           648: general:
        !           649:        jbs $1,r10,gn1
        !           650:        movl $6,r8              # default precision is 6 significant digits
        !           651: gn1:   tstl r8         # cannot allow precision of 0
        !           652:        jgtr gn2
        !           653:        movl $1,r8              # change 0 to 1, willy-nilly
        !           654: gn2:   jbcs $8,r10,L23
        !           655:        jbr L23                 # safety net
        !           656: 
        !           657:        # convert double-floating at (ap) to 17-digit packed at (sp),
        !           658:        # set 'sign' and 'exp', advance ap.
        !           659: fltcvt:
        !           660:        clrb -17(fp)
        !           661:        movd (ap)+,r5
        !           662:        jeql fzero
        !           663:        bgtr fpos
        !           664:        mnegd r5,r5
        !           665:        incb -17(fp)
        !           666: fpos:
        !           667:        extzv $7,$8,r5,r2               # exponent of 2
        !           668:        movab -0200(r2),r2              # unbias
        !           669:        mull2 $59,r2                    # 59/196: 3rd convergent continued frac of log10(2)
        !           670:        jlss eneg
        !           671:        movab 196(r2),r2
        !           672: eneg:
        !           673:        movab -98(r2),r2
        !           674:        divl2 $196,r2
        !           675:        bsbw expten
        !           676:        cmpd r0,r5
        !           677:        bgtr ceil
        !           678:        incl r2
        !           679: ceil:  movl r2,-8(fp)
        !           680:        mnegl r2,r2
        !           681:        cmpl r2,$29                     # 10^(29+9) is all we can handle
        !           682:        bleq getman
        !           683:        muld2 ten16,r5
        !           684:        subl2 $16,r2
        !           685: getman:        addl2 $9,r2                     # -ceil(log10(x)) + 9
        !           686:        jsb expten
        !           687:        emodd r0,r4,r5,r0,r5            # (r0+r4)*r5; r0=int, r5=frac
        !           688: fz1:   cvtlp r0,$9,16(sp)              # leading 9 digits
        !           689:        ashp $8,$9,16(sp),$0,$17,4(sp)  # as top 9 of 17
        !           690:        emodd ten8,$0,r5,r0,r5
        !           691:        cvtlp r0,$8,16(sp)              # trailing 8 digits
        !           692:                # if precision >= 17, must round here
        !           693:        movl r8,r7                      # so figure out what precision is
        !           694:        pushab scien
        !           695:        cmpl (sp)+,(sp)
        !           696:        jleq gm1                        # who called us?
        !           697:        addl2 -8(fp),r7                 # float; adjust for exponent
        !           698: gm1:   cmpl r7,$17
        !           699:        jlss gm2
        !           700:        cmpd r5,$0d0.5                  # must round here; check fraction
        !           701:        jlss gm2
        !           702:        bisb2 $0x10,8+4(sp)             # increment l.s. digit
        !           703: gm2:           # end of "round here" code
        !           704:        addp4 $8,16(sp),$17,4(sp)       # combine leading and trailing
        !           705:        bisb2 -17(fp),12(sp)            # and insert -17(fp)
        !           706:        rsb
        !           707: fzero: clrl r0
        !           708:        movl $1,-8(fp)          # 0.000e+00 and 0.000 rather than 0.000e-01 and .000
        !           709:        jbr fz1
        !           710: 
        !           711:        .align 2
        !           712: lsb: .long 0x00010000          # lsb in the crazy floating-point format
        !           713: 
        !           714:        # return 10^r2 as a double float in r0||r1 and 8 extra bits of precision in r4
        !           715:        # preserve r2, r5||r6
        !           716: expten:
        !           717:        movd $0d1.0,r0                  # begin computing 10^exp10
        !           718:        clrl r4                         # bit counter
        !           719:        movad ten1,r3                   # table address
        !           720:        tstl r2
        !           721:        bgeq e10lp
        !           722:        mnegl r2,r2                     # get absolute value
        !           723:        jbss $6,r2,e10lp                # flag as negative
        !           724: e10lp: jbc r4,r2,el1                   # want this power?
        !           725:        muld2 (r3),r0                   # yes
        !           726: el1:   addl2 $8,r3                     # advance to next power
        !           727:        aobleq $5,r4,e10lp              # through 10^32
        !           728:        jbcc $6,r2,el2                  # correct for negative exponent
        !           729:        divd3 r0,$0d1.0,r0              # by taking reciprocal
        !           730:        cmpl $28,r2
        !           731:        jneq enm28
        !           732:        addl2 lsb,r1                    # 10**-28 needs lsb incremented
        !           733: enm28: mnegl r2,r2                     # original exponent of 10
        !           734: el2:   addl3 $5*8,r2,r3                # negative bit positions are illegal?
        !           735:        jbc r3,xlsbh-5,eoklsb
        !           736:        subl2 lsb,r1                    # lsb was too high
        !           737: eoklsb:
        !           738:        movzbl xprec[r2],r4             # 8 extra bits
        !           739:        rsb
        !           740: 
        !           741:        # powers of ten
        !           742:        .align  2
        !           743: ten1:  .word   0x4220,0,0,0
        !           744: ten2:  .word   0x43c8,0,0,0
        !           745: ten4:  .word   0x471c,0x4000,0,0
        !           746: ten8:  .word   0x4dbe,0xbc20,0,0
        !           747: ten16: .word   0x5b0e,0x1bc9,0xbf04,0
        !           748: ten32: .word   0x759d,0xc5ad,0xa82b,0x70b6
        !           749: 
        !           750:        # whether lsb is too high or not
        !           751:        .byte 1:0,1:0,1:0,1:0,1:1,1:0,1:1,1:0   # -40 thru -33
        !           752:        .byte 1:0,1:1,1:0,1:0,1:0,1:0,1:1,1:0   # -32 thru -25
        !           753:        .byte 1:0,1:0,1:1,1:1,1:1,1:1,1:0,1:0   # -24 thru -17
        !           754:        .byte 1:0,1:1,1:0,1:0,1:1,1:1,1:1,1:1   # -16 thru -9
        !           755:        .byte 1:1,1:1,1:1,1:0,1:0,1:0,1:0,1:1   # -8  thru -1
        !           756: xlsbh:
        !           757:        .byte 1:0,1:0,1:0,1:0,1:0,1:0,1:0,1:0   # 0 thru 7
        !           758:        .byte 1:0,1:0,1:0,1:0,1:0,1:0,1:0,1:0   # 8 thru 15
        !           759:        .byte 1:0,1:0,1:0,1:0,1:0,1:0,1:0,1:0   # 16 thru 23
        !           760:        .byte 1:0,1:1,1:1,1:0,1:1,1:1,1:1,1:1   # 24 thru 31
        !           761:        .byte 1:1,1:1,1:1,1:1,1:1,1:1,1:1       # 32 thru 38
        !           762: 
        !           763:        # bytes of extra precision
        !           764:        .byte           0x56,0x76,0xd3,0x88,0xb5,0x62   # -38 thru -33
        !           765:        .byte 0xba,0xf5,0x32,0x3e,0x0e,0x48,0xdb,0x51   # -32 thru -25
        !           766:        .byte 0x53,0x27,0xb1,0xef,0xeb,0xa5,0x07,0x49   # -24 thru -17
        !           767:        .byte 0x5b,0xd9,0x0f,0x13,0xcd,0xff,0xbf,0x97   # -16 thru -9
        !           768:        .byte 0xfd,0xbc,0xb6,0x23,0x2c,0x3b,0x0a,0xcd   # -8  thru -1
        !           769: xprec:
        !           770:        .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00   # 0  thru 7
        !           771:        .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00   # 8  thru 15
        !           772:        .byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00   # 16 thru 23
        !           773:        .byte 0x00,0xa0,0xc8,0x3a,0x84,0xe4,0xdc,0x92   # 24 thru 31
        !           774:        .byte 0x9b,0x00,0xc0,0x58,0xae,0x18,0xef        # 32 thru 38

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.