; ; GETSLB - mapping between disks ; Getslb is the single mapping function used to decide, given a ; lbn, which storage it goes on, and where in that storage it goes. ; All such processing happens here to avoid differences between two ; computations. It also simplifies changing the logic, should such be ; desired. One potential such change would be to reserve space only ; in the first container for saveset info., since it is only ; stored/used there. This is not done here to keep all geometries ; alike. ;getslb ; input: r5=ucb, r3=irp, r0=lbn to start ; output: r0=container number (0,1...ucb$ncont), r1=start lbn, ; r2 = number bytes that can be transferred in this chunk. getslb: cmpl ucb$ncont(r5),#1 ;1 container case? bneq 2$ brw 2000$ 2$: pushr #^m clrl r1 tstl ucb$ssegsz(r5) ;be sure segsize nonzero beql 1112$ ediv ucb$ssegsz(r5),r0,r8,r9 ;r8 = lbn/segsiz, r9=rem pushl r9 clrl r9 ;divd is 64 bits tstl ucb$ncont(r5) beql 1112$ ;no div-by-0 ediv ucb$ncont(r5),r8,r7,r6 ;r7 = seg on disk, r6=dsk index popl r9 mull3 r7,ucb$ssegsz(r5),r1 ;r1 = start lbn except offset addl2 ucb$sorig(r5),r1 ;r1 = start lbn ; bytes allowed = 512*(segsz-rem) movl ucb$ssegsz(r5),r2 ;form max bytes subl2 r9,r2 ;subtract offset bgtr 1111$ ;must be positive movl #1,r2 ;clamp legal if not legal at first! 1111$: ashl #9,r2,r2 ;shift to multiply by 512 ; mainline uses word - long size. Don't exceed it here. movzwl r2,r2 ;remove anything over a word ;now get container no. movl r6,r0 ;container offset addl2 r9,r1 ;update start LBN to correct one. popr #^m rsb 1112$: clrl r0 movl ucb$sorig(r5),r1 movl #200,r2 ;on error use 1st lbn popr #^m rsb ; special case if 1 container only. 2000$: movl r0,r1 ;lbn unchanged movzwl irp$w_bcnt(r5),r2 ;# bytes addl2 ucb$sorig(r5),r1 ;add seg origin to lbn clrl r0 ;use container 1 always if only one rsb