;****************************************************************** ; S e c t o r T r a n s l a t i o n R o u t i n e ; ; 1.0 - 3 Jul 92 - First General Release. HFB ; 0.0 - 12 Jun 91 - Initial Test Release HFB ;****************************************************************** CSEG ; Translate the sector given by BC using the translate table given by DE ; SECSHF and SECMSK must be set by SELDSK prior to calling this routine. ; CALCSK equate in DEF-xx.LIB controls use of this code. If FALSE, the ; bulk of this module will NOT be used, and a physical skew table will be ; associated with each DPB. SECTRN: IF BANKED CALL BIOSTK CALL GOSYSB JP JBSTRN COMMON /BANK2/ ENDIF BSTRN: LD (CPMSEC),BC ; Save logical record from Dos for deblocker LD A,D OR E ; Check if translation required LD H,B LD L,C ; Sector number to hl RET Z ; Return if no translation LD A,C ; Logical record number CALL PHYSEC ; Convert to logical host sector ; Returns with b=0 IF CALCSK ; Calculate the skew factor. Skew table contains physical sectors ; per track (byte) and skew factor (byte) LD B,A ; Logical record number LD A,(DE) ; De points to skew table AND A ; Test skew factor for <0 JP P,SEC00 ; Go if positive LD A,1 ; Else no skew on read/write SEC00: LD H,A ; Skew factor INC DE ; Skip starting sector INC DE LD A,(DE) LD C,A ; Physical sectors/track INC B ; Lrn+1 XOR A ; Clear a LD E,A SUB H ; Initialize a SEC0: ADD A,H ; Add SKF CP C JR C,SEC1 ; Check for wrap SUB C ; If wrap JR NZ,SEC1 ; Check for repeat INC E ; If so, advance by one sector SEC1: DJNZ SEC0 ; Dec lrn and continue building the sec # ADD A,E ; Add in the number of repeats LD L,A ; Save it for now ELSE ; Look up the sector to get. NOTE: Skew Table is constructed of physical ; sectors - not 128 byte logical records! EX DE,HL ; Point to skew table CALL ADDAHL ; Index to sector needed LD L,(HL) ; And get it ENDIF ; Calcsk LD H,B ; B=0 from above LD A,(SECSHF) ; Get sector shift count (0=128 byte sectors) OR A RET Z ; ..return If 128 byte sectors, we are finished. LD B,A ; Save shift factor as a counter. LD A,L ; Get physical (skewed) sector. SEC2: RLA ; Shift it into position DJNZ SEC2 ; ..Until B = 0 LD L,A ; In L LD A,(SECMSK) ; Sector mask LD C,A ; To C LD A,(CPMSEC) ; Logical record AND C ; Mask for offset within physical sector OR L ; Or them with skewed and shifted physical sec. LD L,A ; To L for DOS (H=0 from above) RET ; ..back to ZSDOS ; Enter with logical record in A, Exit with logical host sector in A PHYSEC: LD C,A ; Save logical record LD A,(SECSHF) ; Get sector shift LD B,A ; Make loop count INC B ; Comp for djnz LD A,C ; Restore logical record JR PHYLP1 ; Do xlate PHYLOP: SRL A ; Divide by 2 PHYLP1: DJNZ PHYLOP ; Loop as required RET ; Exit w/ logical host sector in A ;========================== End of SECTRAN ================================