$PAGEWIDTH(96)
$NOLIST

   NAME   FORMATSETUP

;
;   FDCSETUP.ASM

CGROUP   GROUP   CODE
DGROUP   GROUP   DATA

  PUBLIC   SECTOR
  PUBLIC   SETUP


sectorZero            EQU   0H   
sectorOne             EQU   1H
sectorTwo             EQU   2H
zero                  EQU   0h
Four                  EQU   4H   
SizeOfSectorBuffer    EQU    9
ddFDCInterleaveFactor EQU    2
 
SECTORSIZE         EQU   0512/0256


;   Floppy Paramater Structures
;


ParameterStatus   STRUC
   pageSize          DW   ?
   logpageSize       DW   ?
   numPages          DW   ?
   driveReady        DB   ?
   bitMap            DW   ?
   dirFID            DW   ?
   minDirPages       DW   ?
   flush             DB   ?
   devName           DB   32 DUP(?)
   bytesPerSector    DW   ?
   sectorsPerTrack   DW   ?
   tracksPerCylinder DW   ?
   interleaveFactor  DB   ?
   secondSideCount   DB   ?
   numCylinders      DW   ?
ParameterStatus   ENDS


DATA   SEGMENT   PUBLIC   'DATA'
  EXTRN   CurrentSide:  BYTE 
  EXTRN   FStatus:	     ParameterStatus

  SECTOR    DB   sizeOfSectorBuffer DUP (?)
  FDCIntr   DB   1 DUP (?)
DATA   ENDS

$EJECT

CODE   SEGMENT   PUBLIC   'CODE'
  ASSUME   CS:CGROUP, DS:DGROUP
   

; SectorSetup: PROCEDURE;
;
; This routine will setup in the sector array the sector #'s
; in sequential order given the current interleave

SECTORSETUP   PROC   NEAR
   PUSH   AX
   PUSH   BX
   PUSH   CX
   PUSH   DS
   PUSH   ES
   PUSH   SI
   PUSH   DI

   MOV   CX, DS
   MOV   ES,CX
   MOV   SI, OFFSET SECTOR
   MOV   DI, SI

   MOV   CX, SizeofSectorBuffer       ; INITIAL SECTOR = 1
   CLD
   XOR   AX,AX
   REP   STOSB

   XOR   BX,BX                       ; CLEAR OFFSET

   MOV   AX, DS:FStatus.sectorsPerTrack
   MOV   DX,BX			     ; start sector # in DX
   CMP   BYTE PTR DS:CurrentSide, 0
   JE    SIDE0
   CMP   DS:FStatus.secondSideCount, 0
   JE    SIDE0
   MOV   DX,AX                      ; DOUBLE IF SIDE TWO and GRiD format  

 SIDE0:
   MOV   DS:[SI],AL                  ; TEMPORARY LOCATION FOR IDIV
   INC   DX
   INC   DX
   MOV   CX,SECTORTWO                ; START AT THE SECOND SECTOR

NEXTCELL:
   MOV   AX, DX
   DEC   AL
   IMUL  FDCINTR                     ; FIGURE OFFSET
   IDIV  BYTE PTR DS:[SI]            ; ALL WE REALLY WANT IS REMAINDER
   MOV   BL,AH

CELLTEST:
   CMP   BYTE PTR DS:[SI][BX], 0     ; IS THE CELL AVAILABLE?
   JE    CELLFREE
   INC   BX                          ; CHECK NEXT CELL
   JMP   CELLTEST
   
CELLFREE:

   MOV   BYTE PTR DS:[SI][BX],DL     ; SET THE TABLE
   
   INC   CX                          ; MORE SECTORS?
   INC   DX
   CMP   CX, DS:FStatus.sectorsPerTrack
   JBE   NEXTCELL

   MOV   AX,SECTORONE
   CMP   DS:currentSide, 0
   JE    SIDE0B
   CMP   DS:FStatus.secondSideCount, 0
   JE    SIDE0B
   ADD   AX, DS:FStatus.sectorsPerTrack   ; DOUBLE IF SIDE TWO   

 SIDE0B:
   MOV   BYTE PTR DS:[SI],AL         ; SET THE FIRST SECTOR

   POP   DI
   POP   SI
   POP   ES
   POP   DS
   POP   CX
   POP   BX
   POP   AX
   RET
SECTORSETUP   ENDP

$EJECT

;
;   Call Setup (trackNumber, pBuffer)
;   trackNumber : track number of track to format
;       pBuffer : Buffer to store address fields
;
; OnExit:
;   AX,CX,SI,DI Not Preserved   
;
;

trackNumber        EQU   WORD  PTR [BP+14]
pBuffer            EQU   DWORD PTR [BP+10]


SETUP PROC   NEAR
  PUSH  DS
  PUSH  ES      
  PUSH  BP
  PUSH  BX
  MOV   BP,SP                            ; SETUP FOR Stack Parameters

  MOV   AL, ddFDCInterleaveFactor
  MOV   FDCIntr,AL                       ; Setup FDCIntr for SectorSetup   
  MOV   CX, DS:FStatus.sectorsPerTrack  ;table length
  MOV   BL, DS:currentSide
;
;
; Setup Sector Interleave table based on Interleave Factor
;
;
  CALL  SECTORSETUP            

  LDS   SI,pBuffer                  ; POINT TO BUFFER
  MOV   AX, SEG Sector
  MOV   ES,AX
  MOV   DI, OFFSET Sector
           
;
;
; Store Address fields for floppy disk controller format
;
;

Table:
  MOV   AX,trackNumber
  MOV   BYTE PTR DS:[SI],AL         ; LOW(TrackNumber)
  MOV   BYTE PTR DS:[SI+1],BL       ; Head Number (0 or 1)
  MOV   AL,BYTE PTR ES:[DI]	   
  MOV   BYTE PTR DS:[SI+2], AL       ; Sector Number
  MOV   BYTE PTR DS:[SI+3], sectorSize   ; Bytes per Sector

  INC   DI
  ADD   SI, 4
  LOOP  Table
   
  POP   BX
  POP   BP
  POP   ES
  POP   DS      
  RET   6   
SETUP   ENDP 

CODE   ENDS

   END;
