Thanks for all the answers, and thanks to Johnny for providing a pointer
to the DX driver code. FWIW, the DX driver performs the logical to physical
translation using a "logical sector number", where each logical block
contains four consecutive logical sectors. The routine that converts an
LSN to a track and sector, and handles interleave and skew at the same time,
is below. I'm not even going to pretend I know how this works - it's a bit
obscure - but it's straight forward enough to translate it literally into C.
Bob
;+
; *** - TRKSEC - CONVERT LOGICAL OR PHYSICAL BLOCK NUMBER TO
; TRACK-SECTOR PAIR
; FROM ALGORITHM BY J GILBERT MODIFIED BY H. JACOBS
;
; INPUT:
; R3 - I/O PACKET ADDRESS
; I.PRM+10(R3) - LOGICAL OR PHYSICAL SECTOR
;
; OUTPUT:
; I.PRM+14(R3) - SECTOR (1-26.)
; I.PRM+15(R3) - TRACK (0-77.)
; R3 - UNCHANGED
; C CLEAR - VALID BLOCK
; C SET - BAD BLOCK NUMBER (PHYSICAL OR LOGICAL)
;
;-
TRKSEC: MOV I.PRM+10(R3),R1 ; GET LOGICAL OR
PHYSICAL BLOCK
MOV #8.,R0 ; SET LOOP COUNT
MOV #6400,R2 ; SET DIVISOR
1$: CMP R2,R1 ; DOES 26 GO INTO DIVIDEND?
BHI 2$ ; BRANCH IF NOT, C
CLEAR
SUB R2,R1 ; SUBTRACT 26 FROM
DIVIDEND
SEC ; SET CARRY
2$: ROL R1 ; SHIFT DIVIDEND AND
QUOTIENT
DEC R0 ; DONE?
BGT 1$ ; NO, LOOP
MOVB R1,R0 ; GET TRACK NUMBER
CLRB R1 ; CLEAR TRACK NUMBER
SWAB R1 ; SHIFT DONE SECTOR NUMBER
BITB #IO.RPB&377,I.FCN(R3) ; PHYSICAL BLOCK WANTED?
BNE 10$ ; YES
CMP #12.,R1 ; NO, C=1 IF 13<=R1<=25
ROL R1 ; DOUBLE FOR INTERLEAVE
FACTOR
ASL R0 ; ADD TRACK -TRACK
SKEW
ADD R0,R1 ; SKEW BY 2*TRACK
ADD R0,R1 ; SKEW BY 4*TRACK
ADD R0,R1 ; SKEW BY 6*TRACK
ASR R0 ; RESTORE TRACK NUMBER
MOV #26.,R2 ; SET MODULUS
5$: SUB R2,R1 ; MODULO SECTOR INTO RANGE
-26. TO -1.
BGE 5$ ; LOOP TILL REMAINDER
GOES NEG
ADD R2,R1 ; CONVERT TO RANGE 0-25.
INC R0 ; LBN0 STARTS ON TRACK
1
10$: INC R1 ; CONVERT TO RANGE 1-26.
MOV R1,I.PRM+14(R3) ; SAVE SECTOR NUMBER
MOVB R0,I.PRM+15(R3) ; SAVE TRACK NUMBER
CMP #77.*256.,I.PRM+14(R3) ; IS IT A VALID
TRACK/SECTOR?
RETURN