;*************************************
;
;  THESE ROUTINES WILL MARK A GIVEN SECTOR
;  EITHER FREE OR ALLOCATED
;  THE SECTOR IS INDICATED BY "TRACK" & "SECTOR"
;
;*************************************
;
;  LOCATE THE BIT REPRESENTING A GIVEN SECTOR
;
FINDTS
 LDA #2 ;REQUEST TYPE
 BNE FRETSC ;GO COMMON
;
;
; THIS ROUTINE WILL MARK A GIVEN SECTOR AS USED
;
USEDTS
 LDA #0 ;SET SWITCH
 BEQ FRETSC ;GO COMMON
;
;  THIS ROUTINE WILL MARK A GIVEN SECTOR FREE
;
FRETS
 LDA #1 ;SET THE FREE SWITCH
FRETSC
 STA HDTMP5 ;*
;
;
;  THIS IS THE COMMON LOGIC TO LOCATE
;  AND CHANGE A BIT IN THE BAM CORRESPONDING
;  TO A GIVEN TRACK AND SECTOR
;
 ;CALCULATE BAM INDEX AS:
 ;(((CD-LC)*(SF*NS))+(HD*NS)+SR)/8
 ;WHERE:
 ; CD=CYLINDER (TRACK) DESIRED
 ; LC=LOW CYLINDER IN BAM
 ; SF=#SURFACES ON MEDIA
 ; NS=NUMBER OF SECTORS / SURFACE
 ;
 LDA #<HDZLOC ;PT TO HARD DISK ZONE LOCTR
 LDX #>HDZLOC ;*
 LDY DRVNUM ;CHK DRIVE
 BEQ HDCBI2 ;JMP IF HARD DISK
 LDA #<HDFZLC ;PT TO FLOPPY ZONE LOCTR
 LDX #>HDFZLC ;*
HDCBI2
 STA HDTMP ;PT IND WORD TO LIST
 STX HDTMP+1 ;*
 LDY #0 ;BEGINNING OFFSET
 LDA DRVNUM ;DRIVE 0 (RR)
 BEQ HDCBI3 ;BRIF IT IS (RR)
 LDA SECTOR ;CHK FOR VALID SECTOR
 CMP #128 ;REASONABLE MAX
 BCS FBAD ;BR IF TOO BIG
 LDA TRACK ;DESIRED TRACK IN A
 LDX DRVNUM ;CHK TRACK FOR REASONABILITY
 CMP HDNTK,X ;*
 BCC HDCBI3 ;BR IF OK
 BEQ HDCBI3 ; "  "  "
FBAD
 LDA #BADTS ;GIVE BAD T/S ERROR
 JMP CMDERR ;*
HDCBI3
 LDA TRACK
 CMP (HDTMP),Y ;COMP TO DESIRED TRACK
 BEQ HDCBI4 ;BR IF IN ZONE
 BCC HDCBI4 ;*
 INY ;BUMP TO NEXT LOCATOR BYTE
 BNE HDCBI3 ;JMP
HDCBI4 ;FOUND THE ZONE
 STY HDCZN ;SAVE THE ZONE NUMBER
 TYA ;PUT THE ZONE IN X
 TAX ;*
 JSR HDCIND ;CONVERT ZONE # TO INDEX
 JSR HDISU ;SET UP THE IND WORD
 JSR HDLBM ;LOAD THE DESIRED BAM
;
; DESIRED BAM IS NOW RESIDENT
; CALCULATE THE INDEX INTO IT
;
 LDY #HDCYL ;PT TO BEGINNING CYLINDER
;
;  CALCULATE (CYL # DESIRED - LOW CYL IN BAM)
;
 SEC ;PREP FOR SUBTRACT
 LDA TRACK ;DESIRED CYLINDER
 SBC (HDBMP),Y ;SUBTRACT LOW CYL
 STA HDTMP ;SAVE RESULT (CYL INDEX)
;
;  NOW CALCULATE # OF BITS PER CYLINDER
;  AS (# OF SURFACES * # OF SECTORS PER SURF.)
 LDX DRVNUM ;GET THE DRIVE NUMBER
 LDA HDNSUR,X ;GET # OF SURFACES ON THAT DRIVE
 AND #HDSURF
 TAX ;INTO REG X
 LDY #HDNSEC ;PT TO # SECTORS PER SURF
 LDA #0 ;ZERO THE RESULT
 CLC ;CLEAR THE CARRY BIT
HDCBI5
 ADC (HDBMP),Y ;DO MULT BY REP ADDS
 DEX ;DECR # SURFACES
 BNE HDCBI5 ;LOOP TILL DONE
 STA HDTMPC ;SAVE RESULT
;
;  NOW CALCULATE NUMBER OF BITS TO INDEX
;  INTO BAM AS (HDTMP)*(HDTMPC)
;  IE. CYL TIMES # BITS PER CYL
;
 LDA #0 ;RESET THE RESULT WORD
 STA HDTMPD ;*
 STA HDTMPE ;*
 LDA #8 ;NUMBER OF BITS COUNTER
 STA HDTMPF ;*
HDCBI6
 ASL HDTMP ;SHIFT MULTIPLIER LEFT
 BCC HDCBI7 ;BR IF HIGH BIT NOT SET
 CLC ;PREP FOR ADC
 LDA HDTMPD ;ADD MULTIPLICAND TO RESULT
 ADC HDTMPC ;*
 STA HDTMPD ;*
 BCC HDCBI7 ;JMP IF NO CARRY
 INC HDTMPE ;CARRY INTO HIGH BYTE
HDCBI7
 DEC HDTMPF ;DECREMENT SHIFT COUNTER
 BEQ HDCBI8 ;JMP IF DONE
 ASL HDTMPD ;SHIFT RESULT WORD
 ROL HDTMPE ;*
 JMP HDCBI6 ;LOOP TILL DONE
;
;  NOW USE "SECTOR" TO CALC # SECTORS
;  OR BITS INTO THE CYLINDER
;
HDCBI8
 LDA SECTOR ;GET THE HEAD # FROM SECTOR
 ROL A ;HEAD IS IN HIGH TWO BITS
 ROL A ;SO SHIFT IT TO LOW TWO BITS
 ROL A ;*
 AND #03 ;LEAVE ONLY TWO BITS
 TAX ;MOVE HEAD TO REG X
 LDY #HDNSEC ;#SECTORS PER SURFACEE
 LDA #0 ;CLEAR RESULT
 CPX #0 ;CHK TRACK = 0
 BEQ HDCBIJ ;BR IF SO
 CLC ;PREP FOR ADC
HDCBI9
 ADC (HDBMP),Y ;MULTIPLY HEAD * # SECTORS PER EA.
 DEX ;*
 BNE HDCBI9 ;LOOP TILL DONE
HDCBIJ
 CLC
 STA HDTMP ;SAVE RESULT
;
 LDA SECTOR ;NOW ADD THE NUMBER OF SECTORS
 AND #$3F ;*
 ADC HDTMP ;*
 ADC HDTMPD ;ADDED TO PREV PRODUCT ALSO
 STA HDTMPD ;*
 BCC HDCBIA ;16 BIT ADD
 INC HDTMPE ;HIGH BYTE
HDCBIA
;
;  NOW DIVIDE TOTAL NUMBER BY 8
;  GIVING NUMBER OF BYTES AND A
;  REMAINDER INDICATING NUMBER OF
;  BITS TO INDEX INTO BAM
 LDA HDTMPD ;SAVE THE REMAINDER NOW
 AND #7 ;LOW THREE BITS
 STA HDTMPF ;*
 LDX #3 ;SHIFT COUNT
HDCBIB
 LSR HDTMPE ;SHIFT THE HIGH BYTE
 ROR HDTMPD ;SHIFT THE LOW ALSO
 DEX ;DO IT THREE TIMES
 BNE HDCBIB ;LOOP TILL DONE
;
;  NOW INDEX INTO THE BAM
;
 CLC ;PREP FOR THE ADD
 LDA #HDBIT1 ;DISP TO FIRST BYTE
 ADC HDTMPD ;ADD BYTE INDEX
 TAY ;RESULT IN Y
 LDA #$80 ;SET 2^7
HDCBIC
 DEC HDTMPF ;DECR BIT NUMBER COUNTER
 BMI HDCBIE ;JMP WHEN DONE
 LSR A ;SHIFT BIT RIGHT 1 POSITION
 BNE HDCBIC ;LOOP TILL DONE
HDCBIE
;
;  NOW EITHER SET THE BIT OR CLEAR IT
;
 LDX HDTMP5 ;CHECK REQUEST TYPE
 BEQ HDCBIF ;JMP IF ALLOCATION
 DEX ;CHK IF FIND
 BNE HDDBCX ;BR IF FIND
 ; IT WAS A FREE REQUEST
 PHA ;DEBUG CHK
 AND (HDBMP),Y
 BNE HDCBII ;BAD REQUEST
 LDX HDCZN ;GET CURRENT ZONE
 JSR HDCIND ;CALC INDEX
 LDA #0 ;RESET ZONE FULL SWITCH
 STA HDZFUL,X ;*
 PLA
 ORA (HDBMP),Y ;SET THE BIT
 LDX DRVNUM ;BUMP # SECTORS AVAIL
 INC HDNFRL,X ;BUMP LOW
 BNE HDCBIG ;BR IF NO OVFL
 INC HDNFRH,X ;BUMP HIGH
 JMP HDCBIG ;JMP TO COMMON
 ; IT WAS AN ALLOCATION REQUEST
HDCBIF
 PHA ;DEBUG CHK
 AND (HDBMP),Y
 BNE HDCBIH ;OK
HDCBII
 JMP HDCLB3 ;DIRECTORY ERROR
HDCBIH
 PLA
HDCBIK
 EOR #255 ;INVERT THE MASK
 AND (HDBMP),Y ;TURN OFF THE BIT
 JSR HDDBC ;DECR COUNT OF AVAIL
HDCBIG ;THIS IS COMMON
 STA (HDBMP),Y ;STORE IT BACK
 JMP HDCLRC ;CALC NEW LRC
;
;
;  DECREMENT # SECTORS AVAIL
;
HDDBC
 LDX DRVNUM ;GET DR #
 PHA ;SAVE A
 LDA HDNFRH,X ;CHK IF ALREADY ZERO
 BNE HDDBC2 ;BR IF NOT ZERO
 LDA HDNFRL,X ;CHK LOW BYTE TOO
 BEQ HDCBII ;BR IF CT ALREADY ZERO
 CMP #3 ;CHK IF LESS THAN 3 LEFT
 BCS HDDBC2 ;BR IF 3 OR MORE
 TYA ;SAVE Y
 PHA ;*
 LDA #DSKFUL ;GIVE EARLY WARNING
 JSR ERRMSG ;*
 PLA ;RESTORE Y
 TAY ;*
HDDBC2
 LDX DRVNUM ;RESTORE X
 DEC HDNFRL,X ;DECR LOW BYTE
 LDA HDNFRL,X ;CHK FOR UNDERFLOW
 CMP #$FF ;*
 BNE HDDBC1 ;BR IF NO OVRFL
 DEC HDNFRH,X ;DECR HIGH BYTE
HDDBC1
 PLA ;RESTORE A
HDDBCX
 RTS ;EXIT TO CALLER
 .END
