home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / ZEN2.LBR / Z207DRVR.LIB < prev    next >
Text File  |  2000-06-30  |  32KB  |  1,475 lines

  1. ;***    Z207 DEVICE DRIVER
  2. ;
  3.  
  4. ;**    DRIVER ENTRY JUMP VECTORS
  5. ;
  6.  
  7. DRVR207:
  8.     JMP    SEL207            ;SELECT
  9.     JMP    RDT207            ;READ TRACK
  10.     JMP    WRT207            ;WRITE TRACK
  11.     JMP    MNT207            ;MOUNT
  12.     JMP    FMT207            ;FORMAT
  13.     JMP    WPC207            ;WRITE PROTECT CHECK
  14.  
  15.  
  16.  
  17.  
  18. ;**    INITIALIZE DRIVE TABLES
  19. ;
  20. ;    ENTRY:    NONE
  21. ;    EXIT:    NONE
  22. ;    USES:    ALL
  23. ;
  24.  
  25. IN207:
  26.  
  27. ;*    RESTORE THE HEAD ON EACH DRIVE TO DETERMINE IF IT EXISTS
  28.  
  29.     MOV    CX,4            ;# OF Z207 DRIVES
  30.     LEA    BP,DPEBASE        ;START ADDRESS OF Z207 DPE'S
  31.     ADD    BP,BBIOS
  32.     OR    DSKOP,DSKOPI        ;INDICATE INIT IN PROGRESS
  33.  
  34. IN2071:
  35.     PUSH    CX
  36.     CALL    DS207            ;SELECT DRIVE
  37.     CALL    RST207            ;RESTORE HEAD
  38.     TEST    AL,FDSTK0        ;Q. TRACK 0 INDICATION
  39.     JNZ    IN2073            ; BR IF YES
  40.  
  41.     OR    DPEFLG2[BP],DPEIMG    ;FLAG DRIVE AS IMAGINARY
  42.  
  43. IN2073:
  44.     TEST    DPEUNIT[BP],CONDS8    ;Q. 8" DRIVE
  45.     JNZ    IN2074            ; BR IF YES
  46.     IN    AL,FDAS            ;DETERMINE IF 5 1/4" DRIVE IS
  47.     TEST    AL,AS96T        ; 48 OR 96 TPI AND INDICATE THIS
  48.     JZ    IN2074            ;  IN TABLE
  49.     OR    DPEFLAG[BP],DPE96T
  50.  
  51. IN2074:
  52.     ADD    BP,DPEL            ;BUMP TO NEXT DRIVE TABLE
  53.     POP    CX
  54.     LOOP    IN2071            ;LOOP AND CHECK ALL DRIVES
  55.  
  56.     AND    DSKOP,NOT DSKOPI    ;INDICATE INIT DONE
  57.     CALL    DONE207            ;TURN OFF DRIVES
  58.  
  59. ;*    DO DRIVE MAPPING & REAL/IMAGINARY TABLE INITIALIZATION
  60.  
  61.     PUSH    ES
  62.     MOV    ES,.MTRDSEG        ;GET ADDRESS OF MONITOR DATA AREA
  63.     MOV    CL,ES: MTRBU        ;GET BOOT DEVICE UNIT #
  64.     MOV    AL,ES: MTRBI        ;GET BOOT DEVICE INDEX #
  65.     POP    ES
  66.  
  67.     CMP    AL,1            ;Q. BOOT DEVICE WAS 8" DRIVE
  68.     JE    IN2076            ; BR IF YES
  69.  
  70. ;    BOOT DEVICE WAS 5 1/4" DRIVE; BUILD 5 1/4" TABLES THEN 8" TABLES
  71.  
  72.     MOV    CH,2            ;# DRIVE TABLES
  73.     MOV    DH,0            ;START OF 5 1/4" TABLES
  74.     CALL    CBTFIL            ;FILL IN TABLES
  75.  
  76.     MOV    CL,0            ;UNIT #
  77.     MOV    CH,2            ;# DRIVE TABLES
  78.     MOV    DH,2            ;START OF 8" TABLES
  79.     CALL    CBTFIL            ;FILL IN TABLES
  80.  
  81.     RET
  82.  
  83. ;    BOOT DEVICE WAS 8" DRIVE; BUILD 8" TABLES THEN 5 1/4" TABLES
  84.  
  85. IN2076:
  86.     MOV    CH,2            ;# DRIVE TABLES
  87.     MOV    DH,2            ;START OF 8" TABLES
  88.     CALL    CBTFIL            ;FILL IN TABLES
  89.  
  90.     MOV    CL,0            ;UNIT #
  91.     MOV    CH,2            ;# DRIVE TABLES
  92.     MOV    DH,0            ;START OF 5 1/4" TABLES
  93.     CALL    CBTFIL            ;FILL IN TABLES
  94.  
  95.     RET
  96.  
  97.  
  98.  
  99.  
  100. ;**    SELECT DRIVE FOR 1ST LOGIN
  101. ;
  102. ;    ENTRY:    'PHYDPE'=ADDRESS OF DPE FOR DRIVE
  103. ;        (BX)=POINTER TO BUFFER HEADER INFO
  104. ;        'XLATES'=ADDRESS OF XLATE TABLE ADDRESSES
  105. ;    EXIT:    'PHYDPE'=STATUS
  106. ;            0=ERROR , OTHERWISE SAME AS ON ENTRY
  107. ;    USES:    AX,CX,BP,SI,DI
  108. ;
  109.  
  110. SEL207:
  111.     OR    DSKOP,DSKOPS        ;INDICATE SELECT OPERATION IN PROGRESS
  112.  
  113.     MOV    BP,BUFDPE[BX]
  114.     MOV    DPETRK[BP],DPEUNK    ;INDICATE DRIVE HEAD POSITION UNKNOWN
  115.  
  116.     TEST    DPEUNIT[BP],CONDS8    ;Q. 8" DRIVE
  117.     JZ    $+5
  118.     JMP    SEL2075            ; BR IF 8" DRIVE
  119.  
  120. ;*    SELECT ROUTINE FOR 5 1/4" DRIVES
  121.  
  122. ;    READ LABEL
  123.  
  124.     MOV    PHYTRK,0        ;LABEL IS ON TRACK 0
  125.     MOV    PHYSID,0        ; SIDE 0
  126.     MOV    PHYSEC,0        ;  1ST SECTOR
  127.     CALL    RDY2070            ;READY CHECK
  128.     CMP    BUFERR[BX],0        ;Q. DRIVE NOT READY
  129. ;    JE    SEL2079            ; BR IF NOT READY
  130.     JNE    $+5
  131.     JMP    SEL2079
  132.     MOV    BUFERR[BX],0        ;CLEAR ERROR FLAG
  133.     CALL    DS207            ;SELECT DRIVE
  134.     CALL    RST207            ;RESTORE HEAD
  135.     MOV    COUNT,1024        ;MAXIMUM SECTOR LENGTH
  136.     MOV    DI,BUFBUF[BX]        ;USE HOST BUFFER
  137.     CALL    RDS207            ;TRY READING LABEL AT DENSITY
  138.     TEST    AL,AL            ; CURRENTLY INDICATED IN TABLES
  139.     JZ    SEL2072            ;  BR IF ABLE TO READ LABEL SECTOR
  140.  
  141.     XOR    DEVCTL,CONSD        ;UNABLE TO READ LABEL SECTOR
  142.     MOV    AL,DEVCTL        ; CHANGE TO OTHER DENSITY
  143.     OUT    FDCON,AL
  144.     MOV    DI,BUFBUF[BX]        ;TRY TO READ LABEL SECTOR AGAIN
  145.     CALL    RDS207
  146.     TEST    AL,AL
  147. ;    JNZ    SEL2079            ; BR IF ERROR
  148.     JZ    $+5
  149.     JMP    SEL2079
  150.  
  151. SEL2072:
  152.     MOV    SI,BUFBUF[BX]        ;CHECK CHECKSUM OF LABEL
  153.     ADD    SI,LABEL
  154.     CALL    CHKLAB
  155. ;    JNZ    SEL2079            ; BR IF ERROR
  156.     JZ    $+5
  157.     JMP    SEL2079
  158.  
  159. ;    MOVE LABEL INFO TO DPE'S HEATH EXTENSIONS
  160.  
  161.     MOV    SI,BUFBUF[BX]
  162.  
  163.     AND    DPEFLAG[BP],DPETYPE+DPE96T
  164.     MOV    AL,LABHTH+(OFFSET DPEFLAG)-(OFFSET DPEHTH) [SI]
  165.     AND    AL,DPEDD+DPE2S
  166.     OR    DPEFLAG[BP],AL        ;FLAG BYTE #1
  167.  
  168.     MOV    AL,LABHTH+(OFFSET DPERPS)-(OFFSET DPEHTH) [SI]
  169.     MOV    DPERPS[BP],AL        ;CP/M RECORDS PER PHYSICAL SECTOR
  170.  
  171.     MOV    AL,LABHTH+(OFFSET DPERPAB)-(OFFSET DPEHTH) [SI]
  172.     MOV    DPERPAB[BP],AL        ;CP/M RECORDS PER ALLOCATION BLOCK
  173.  
  174.     AND    DPEFLG2[BP],NOT DPE96TM
  175.     MOV    AL,LABHTH+(OFFSET DPEFLG2)-(OFFSET DPEHTH) [SI]
  176.     AND    AL,DPE96TM
  177.     OR    DPEFLG2[BP],AL        ;FLAG BYTE #2
  178.  
  179. ;    IF LABEL INDICATES THAT THE MEDIA IS DOUBLE SIDED, THEN
  180. ;    CHECK OUT THE DRIVE FOR DOUBLE SIDED CAPABILITY
  181.  
  182.     TEST    DPEFLAG[BP],DPE2S    ;Q. DOUBLE SIDED MEDIA
  183.     JZ    SEL2073            ; BR IF NOT
  184.  
  185.     MOV    PHYSID,FDFSS1        ;TRY TO READ A SECTOR HEADER
  186.     LEA    DI,RDABUF        ; ON 2ND SIDE
  187.     CALL    RDA207
  188.     TEST    AL,AL
  189. ;    JNZ    SEL2079            ;  BR IF ERROR
  190.     JZ    $+5
  191.     JMP    SEL2079
  192.  
  193.     CMP    RDABUF+FDRASID,1    ;CHECK SIDE INFO
  194. ;    JNE    SEL2079            ; BR IF NOT 2ND SIDE
  195.     JE    $+5
  196.     JMP    SEL2079
  197.  
  198. ;    STEP IN 2 TRACKS, READ ADDRESS, AND STEP BACK OUT 2 TRACKS.
  199. ;    IF READ ADDRESS FINDS TRACK 1 INSTEAD OF TRACK 2,
  200. ;    THEN ASSUME 48 TPI MEDIA GENERATED
  201. ;    ON A 48 TPI DRIVE WAS INSERTED INTO THE 96 TPI DRIVE; THEREFOR,
  202. ;    USE AS A R/O DISK WITH DOUBLE STEPPING.
  203. ;
  204. ;    THERE ARE TWO 48 TPI MEDIA FORMATS THAT ARE SUPPORTED ON
  205. ;    A 96 TPI DRIVE.
  206. ;      1) MEDIA WAS FORMATTED ON A 96 TPI DRIVE AND ONLY USES
  207. ;         THE FIRST HALF OF THE DISK SURFACE.  (E.G. A 48 TPI MEDIA
  208. ;         IS DUPLICATED ONTO MEDIA IN A 96 TPI DRIVE)
  209. ;      2) MEDIA WAS FORMATTED ON A 48 TPI DRIVE.  THE HARDWARE
  210. ;         GROUP HAS INFORMED ME THAT THE 96 TPI DRIVE CAN RELIABLY
  211. ;         READ SUCH MEDIA BUT CANNOT WRITE ON IT.  TO GO BETWEEN
  212. ;         TRACKS IT IS NECESSARY TO DOUBLE THE NUMBER OF STEPS.
  213. ;
  214. ;    THE FOLLOWING ARE THE POSSIBLE OUTCOMES OF THE READ ADDRESS
  215. ;      MEDIA         DRIVE          DRIVE       OUTCOME
  216. ;        FORMAT     GENERATED ON    INSERTED IN     TRACK
  217. ;        ------     ------------    -----------    -------
  218. ;     48 TPI        48 TPI          48 TPI         2
  219. ;     48 TPI        48 TPI          96 TPI         1
  220. ;        48 TPI        96 TPI          48 TPI       ERROR
  221. ;        48 TPI        96 TPI          96 TPI         2
  222. ;        96 TPI        96 TPI          48 TPI       ERROR
  223. ;        96 TPI        96 TPI          96 TPI         2
  224. ;
  225.  
  226. SEL2073:
  227.     MOV    PHYTRK,2        ;STEP IN TWO TRACKS
  228.     CALL    SDT207
  229.  
  230.     MOV    PHYSID,0        ;DO READ ADDRESS
  231.     LEA    DI,RDABUF
  232.     CALL    RDA207
  233.     TEST    AL,AL
  234. ;    JNZ    SEL2079            ; BR IF ERROR
  235.     JZ    $+5
  236.     JMP    SEL2079
  237.  
  238.     CMP    RDABUF+FDRATRK,2    ;CHECK IF TRACK 2
  239.     JE    SEL2073A        ; BR IF YES
  240.                     ;  1) 48 TPI MEDIA GENERATED ON 48 TPI
  241.                     ;     DRIVE INSERTED INTO 48 TPI DRIVE
  242.                     ;  2) 48 TPI MEDIA GENERATED ON 96 TPI
  243.                     ;     DRIVE INSERTED INTO 96 TPI DRIVE
  244.                     ;  3) 96 TPI MEDIA INSERTED IN 96 TPI
  245.  
  246.     CMP    RDABUF+FDRATRK,1    ;CHECK IF TRACK 1
  247. ;    JNE    SEL2079            ; BR IF NOT (ERROR)
  248.     JE    $+5
  249.     JMP    SEL2079
  250.  
  251.     OR    DPEFLAG[BP],DPE48RO    ;SET FLAG TO INDICATE 48 TPI MEDIA
  252.                     ; GENERATED ON 48 TPI DRIVE INSERTED
  253.                     ; INTO 96 TPI DRIVE.  THE MEDIA
  254.                     ; IS TREATED AS R/O
  255.  
  256. SEL2073A:
  257.     CALL    RST207            ;STEP OUT TWO TRACKS BY DOING RESTORE
  258.  
  259. ;    MOVE LABEL INFO TO DISK PARAMETER BLOCK
  260.  
  261.     MOV    SI,BUFBUF[BX]
  262.     ADD    SI,LABDPB
  263.     MOV    DI,DPEDPB[BP]
  264.     MOV    CX,DPBL
  265.     CLD
  266.     REP    MOVSB
  267.  
  268.     JMP    SEL2078
  269.  
  270. ;*    SELECT FOR 8" DRIVE
  271.  
  272. SEL2075:
  273.     MOV    PHYTRK,2        ;ATTEMPT TO READ ADDRESS HEADER
  274.     MOV    PHYSID,0        ; ON PHYSICAL TRACK #2 SIDE 0
  275.     CALL    DS207            ;  AT THE CURRENT DENSITY IN
  276.     CALL    RST207            ;   THE DRIVE'S DPE
  277.     CALL    SDT207
  278.     LEA    DI,RDABUF
  279.     CALL    RDA207
  280.     TEST    AL,AL
  281.     JZ    SEL2076            ;BR IF ABLE TO READ
  282.  
  283.     XOR    DPEFLAG[BP],DPEDD    ;CHANGE TO OTHER DENSITY
  284.     XOR    DEVCTL,CONSD
  285.     MOV    AL,DEVCTL
  286.     OUT    FDCON,AL
  287.  
  288.     LEA    DI,RDABUF        ;ATTEMPT TO READ ADDRESS HEADER
  289.     CALL    RDA207            ; AT OTHER DENSITY
  290.     TEST    AL,AL
  291.     JNZ    SEL2079            ;BR IF ERROR
  292.  
  293. ;    UPDATE REST OF DPE
  294.  
  295. SEL2076:
  296.     AND    DPEFLAG[BP],0FFH-DPE2S    ;# OF SIDES
  297.     IN    AL,FDAS            ;ASK DRIVE HOW MANY SIDES
  298.     TEST    AL,AS2S
  299.     JZ    SEL2076A
  300.     OR    DPEFLAG[BP],DPE2S
  301.  
  302. SEL2076A:
  303.     MOV    SI,DPEDD+DPE2S        ;COMPUTE ADDRESS OF TABLE CONTAINING
  304.     AND    SI,WORD PTR DPEFLAG[BP]    ; INFO FOR UPDATE
  305.     IF    (DPEDD NE 2) OR (DPE2S NE 1)
  306. %:    DPEDD MUST BE 2 AND DPE2S MUST BE 1
  307.     ENDIF
  308.     SHL    SI,1
  309.     SHL    SI,1
  310.     XOR    AH,AH
  311.     MOV    AL,RDABUF+FDRASL
  312.     ADD    SI,AX
  313.     SHL    SI,1
  314.     MOV    SI,TBL207[SI]        ;GET ADDRESS OF UPDATE INFO
  315.     TEST    SI,SI            ;CHECK FOR NOT SUPPORTED FORMAT
  316.     JZ    SEL2079            ; BR IF NOT SUPPORTED
  317.  
  318.     XOR    AH,AH            ;XLATE TABLE ADDRESS
  319.     LODSB
  320.     SHL    AX,1
  321.     MOV    DI,XLATES
  322.     ADD    DI,AX
  323.     MOV    AX,ES:[DI]
  324.     MOV    DPEXLT[BP],AX
  325.  
  326.     LODSB                ;CP/M RECORDS PER PHYSICAL SECTOR
  327.     MOV    DPERPS[BP],AL
  328.  
  329.     LODSB                ;CP/M RECORDS PER ALLOCATION BLOCK
  330.     MOV    DPERPAB[BP],AL
  331.  
  332.     MOV    DI,DPEDPB[BP]        ;DPB
  333.     MOV    CX,DPBL
  334.     CLD
  335.     REP    MOVSB
  336.  
  337. ;*    DONE WITH SELECT OPERATION
  338.  
  339. SEL2078:
  340.     AND    DSKOP,NOT DSKOPS    ;INDICATE DONE WITH SELECT OPERATION
  341.     JMP    DONE207            ;RETURN VIA 'DONE207'
  342.  
  343. ;*    ERROR OCCURRED
  344.  
  345. SEL2079:
  346.     MOV    PHYDPE,0        ;INDICATE ERROR
  347.     JMPS    SEL2078
  348.  
  349.  
  350.  
  351.  
  352. ;**    READ TRACK
  353. ;
  354. ;    ENTRY:    (BX)=POINTER TO BUFFER HEADER INFO
  355. ;    EXIT:    'BUFERR[BX]'=STATUS
  356. ;            0=NO ERROR , 1=ERROR
  357. ;    USES:    AX,DI
  358. ;
  359.  
  360. RDT207:
  361.     CALL    SET207            ;SETUP
  362.     CALL    SDT207            ;SEEK DESIRED TRACK
  363.     CALL    S1S207            ;SET 1ST SECTOR TO READ
  364.     MOV    DI,BUFBUF[BX]        ;BUFFER ADDRESS
  365.     ADD    DI,AX
  366.  
  367. RDT2071:
  368.     CMP    PREREAD,0        ;Q. DOING PREREAD
  369.     JNE    RDT2072            ; BR IF YES
  370.     CMP    BUFERR[BX],0        ;Q. ABORT
  371.     JNE    RDT2073            ; BR IF YES
  372.  
  373. RDT2072:
  374.     CALL    RDS207            ;READ NEXT SECTOR
  375.  
  376. RDT2073:
  377.     ADD    DI,COUNT        ;BUMP BUFFER POINTER
  378.     INC    PHYSEC            ;BUMP PHYSICAL SECTOR #
  379.     MOV    AL,BYTE PTR PHYSEC    ;CHECK IF SECTOR # WRAPAROUND
  380.     CMP    AL,SECCNT
  381.     JB    RDT2074            ; BR IF NOT
  382.     XOR    AX,AX            ;  OTHERWISE START AT BEGINNING
  383.     MOV    PHYSEC,AX
  384.     MOV    DI,BUFBUF[BX]
  385.  
  386. RDT2074:
  387.     CMP    AL,SEC1ST        ;CHECK IF ALL OF TRACK READ
  388.     JNE    RDT2071            ; BR IF NOT
  389.  
  390.     JMP    DONE207            ;RETURN THRU 'DONE207'
  391.  
  392.  
  393.  
  394.  
  395.  
  396. ;**    WRITE TRACK
  397. ;
  398. ;    ENTRY:    (BX)=POINTER TO BUFFER HEADER INFO
  399. ;    EXIT:    'BUFERR[BX]'=STATUS
  400. ;            0=NO ERROR , 1=ERROR
  401. ;    USES:    AX,SI,DI
  402. ;
  403.  
  404. WRT207:
  405.     CALL    SET207            ;SETUP
  406.     CALL    SDT207            ;SEEK DESIRED TRACK
  407.     CALL    S1S207            ;SET 1ST SECTOR TO WRITE
  408.     MOV    SI,BUFBUF[BX]        ;BUFFER ADDRESS
  409.     ADD    SI,AX
  410.  
  411. WRT2071:
  412.     MOV    DI,BUFSECF[BX]        ;CHECK IF PHYSICAL SECTOR IS DIRTY
  413.     ADD    DI,PHYSEC
  414.     TEST    BYTE PTR [DI],1
  415.     JZ    WRT2073            ; BR IF IT IS NOT
  416.  
  417.     MOV    BYTE PTR [DI],0        ;CLEAR DIRTY SECTOR FLAG
  418.     CMP    BUFERR[BX],0        ;Q. ABORT
  419.     JNE    WRT2073            ; BR IF YES -- SKIP PHYSICAL WRITE
  420.     CALL    WRS207            ;WRITE SECTOR
  421.  
  422. WRT2073:
  423.     ADD    SI,COUNT        ;SKIP BUFFER POINTER TO NEXT SECTOR
  424.     INC    PHYSEC            ;BUMP PHYSICAL SECTOR #
  425.     MOV    AL,BYTE PTR PHYSEC    ;CHECK IF SECTOR # WRAPAROUND
  426.     CMP    AL,SECCNT
  427.     JB    WRT2074            ; BR IF NOT
  428.     XOR    AX,AX            ;  OTHERWISE SET TO START
  429.     MOV    PHYSEC,AX
  430.     MOV    SI,BUFBUF[BX]
  431.  
  432. WRT2074:
  433.     CMP    AL,SEC1ST        ;CHECK IF ALL OF TRACK WRITTEN
  434.     JNE    WRT2071            ; BR IF NOT
  435.  
  436.     CALL    WBS207            ;WAIT FOR WRITE GATE TURN OFF
  437.  
  438.     JMP    DONE207            ;RETURN THRU 'DONE207'
  439.  
  440.  
  441.  
  442.  
  443. ;**    MOUNT
  444. ;
  445. ;    ENTRY:    (BX)=POINTER TO BUFFER HEADER INFO
  446. ;    EXIT:    NONE
  447. ;    USES:    DI
  448. ;
  449.  
  450. MNT207:
  451.     MOV    DI,BUFDPE[BX]        ;SET TRACK POSITION TO UNKNOWN
  452.     MOV    DPETRK[DI],DPEUNK
  453.  
  454.     RET
  455.  
  456.  
  457.  
  458.  
  459.  
  460. ;**    FORMAT TRACK
  461. ;
  462. ;    ENTRY:    (BX)=POINTER TO BUFFER HEADER INFO
  463. ;        'FVFLG'=VERIFY FLAG
  464. ;        'DMAPTR'=ADDRESS OF TRACK IMAGE
  465. ;    EXIT:    'ERROR'=ERROR STATUS
  466. ;    USES:    AX,CX,DX,SI
  467. ;
  468.  
  469. FMT207:
  470.     CALL    SET207            ;SETUP
  471.     CALL    SDT207            ;SEEK DESIRED TRACK
  472.  
  473.     OR    DSKOP,DSKOPF        ;INDICATE FORMAT OPERATION IN PROGRESS
  474.     CALL    SRC207            ;SET RETRY COUNTER
  475.  
  476.     TEST    DPEUNIT[BP],CONDS8    ;Q. TIME FOR SPECIAL CHECK
  477.     JZ    FMT2071            ;    IF 8" DRIVE
  478.     CMP    PHYTRK,0        ;     TRACK 0
  479.     JNE    FMT2071            ;
  480.     CMP    PHYSID,FDFSS1        ;      SIDE 1
  481.     JNE    FMT2071            ;       BR IF NOT
  482.     IN    AL,FDAS            ;Q. IS DOUBLE SIDED DISKETTE INSERTED
  483.     TEST    AL,AS2S
  484.     JNZ    FMT2071            ; BR IF YES
  485.     MOV    AL,FDSNRD        ;  ELSE -- FLAGS AS NOT READY ERROR
  486.     JMPS    FMT2072
  487.  
  488. FMT2071:
  489.     MOV    AL,PHYSID        ;GET SIDE SELECT FLAG
  490.     OR    AL,FDCWRT        ; OR IN COMMAND
  491.     OR    AL,HLDDLYF        ;  OR IN DELAY FLAG
  492.     MOV    HLDDLYF,0        ;ZERO DELAY FLAG FOR NEXT I/O
  493.     MOV    SI,DMAPTR        ;GET ADDRESS OF TRACK IMAGE
  494.     MOV    CX,12000        ;USE LARGE COUNT
  495.     MOV    DX,ES            ;DATA SEGMENT TO USE
  496.     CALL    WR207            ;USE LOW LEVEL WRITE ROUTINE
  497.     TEST    AL,AL            ;Q. ERROR
  498.     JZ    FMT2073            ; BR IF NOT
  499.  
  500.     CALL    WBS207            ;WAIT BEFORE STEPPING
  501.  
  502. FMT2072:
  503.     CALL    ERR207            ;Q. SHOULD I RETRY
  504.     JNC    FMT2071            ; BR IF YES
  505.     AND    DSKOP,NOT DSKOPF    ;  OTHERWISE EXIT
  506.     JMP    FMT2074
  507.  
  508. FMT2073:
  509.     AND    DSKOP,NOT DSKOPF    ;INDICATE FORMAT OPERATION OVER
  510.     CMP    FVFLG,0            ;Q. SHOULD I VERIFY
  511.     JZ    FMT2074            ; BR IF NOT
  512.     MOV    PREREAD,0
  513.     CALL    RDT207            ;TRY READING TRACK
  514.  
  515. FMT2074:
  516.     JMP    DONE207
  517.  
  518.  
  519.  
  520.  
  521. ;**    WRITE PROTECT CHECK
  522. ;
  523. ;    ENTRY:    (BX)=ADDRESS OF BUFFER HEADER INFO
  524. ;    EXIT:    'BUFERR[BX]'=STATUS
  525. ;            0=R/W , 1=R/O
  526. ;    USES:    AL,BP
  527. ;
  528.  
  529. WPC207:
  530.     MOV    BP,BUFDPE[BX]        ;GET ADDRESS OF DPE
  531.     OR    DSKOP,DSKOPWP        ;INDICATE WRITE PROTECT OPERATION
  532.     CALL    DS207            ;SELECT DRIVE
  533.  
  534.     MOV    AL,FDCFI+FDFINI        ;FORCE TYPE 1 STATUS
  535.     OUT    FDCMD,AL
  536.     PUSH    AX
  537.     MOV    AX,(60+3)/4
  538.     CALL    WDLY
  539.     POP    AX
  540. WPC2071:
  541.     IN    AL,FDSTA        ;WAIT FOR CONTROLLER NOT BUSY
  542.     TEST    AL,FDSBSY
  543.     JNZ    WPC2071
  544.  
  545.     AND    AL,FDSWPV        ;ISOLATE WRITE PROTECT BIT
  546.     MOV    AL,0            ;ASSUME R/W
  547.     JZ    WPC2072            ; BR IF R/W
  548.     MOV    AL,1            ;INDICATE R/O
  549.  
  550. WPC2072:
  551.     MOV    BUFERR[BX],AL        ;RETURN VALUE
  552.  
  553.     AND    DSKOP,NOT DSKOPWP    ;INDICATE WRITE PROTECT OP DONE
  554.     JMP    DONE207            ;RET VIA 'DONE207'
  555.  
  556.  
  557.  
  558.  
  559. ;**    READY CHECK
  560. ;
  561. ;    ENTRY:    (BX)=ADDRESS OF BUFFER HEADER
  562. ;    EXIT:    'BUFERR[BX]'=STATUS  (0=NOT READY , 1=READY)
  563. ;    USES:    AL,DX,BP
  564. ;
  565.  
  566. RDY207:
  567.     MOV    BP,BUFDPE[BX]        ;GET ADDRESS OF DPE
  568.     CALL    RDY2070
  569.     JMP    DONE207
  570.  
  571. RDY2070:
  572.     MOV    BUFERR[BX],0        ;ASSUME NOT READY
  573.     OR    DSKOP,DSKOPRD        ;INDICATE READY CHECK IN PROGRESS
  574.     CALL    DS207            ;SELECT DRIVE
  575.  
  576.     MOV    DX,5000/TINTRVL+1    ;COMPUTE TIMEOUT COUNT (5 SEC)
  577.     ADD    DX,TICCNT
  578.  
  579.     MOV    AL,FDCFI+FDFII2        ;WAIT FOR INDEX HOLE TRANSITION
  580.     OUT    FDCMD,AL
  581.     PUSH    AX
  582.     MOV    AX,(60+3)/4
  583.     CALL    WDLY
  584.     POP    AX
  585.  
  586. RDY2071:
  587.     CMP    DX,TICCNT        ;Q. TIMEOUT
  588.     JE    RDY2073            ; BR IF YES
  589.     IN    AL,FDAS            ;Q. INDEX HOLE FOUND
  590.     TEST    AL,ASIRQ
  591.     JZ    RDY2071            ; BR IF NOT
  592.  
  593. RDY2072:
  594.     IN    AL,FDSTA        ;WAIT FOR 1797 TO GO NOT BUSY
  595.     TEST    AL,FDSBSY
  596.     JNZ    RDY2072
  597.  
  598.     MOV    BUFERR[BX],1        ;INDICATE DRIVE READY
  599.  
  600. RDY2073:
  601.     AND    DSKOP,NOT DSKOPRD    ;INDICATE READY CHECK DONE
  602.  
  603.     RET
  604.  
  605.  
  606.  
  607.  
  608.  
  609. ;*    READ SECTOR
  610. ;
  611. ;    ENTRY:    'PHYSEC'=SECTOR #
  612. ;        (DI)=BUFFER POINTER
  613. ;    EXIT:    (AL)=CONTROLLER STATUS
  614. ;    USES:    AL,CX
  615. ;
  616.  
  617. RDS207:
  618.     OR    DSKOP,DSKOPR        ;INDICATE READ OPERATION IN PROGRESS
  619.     CALL    SRC207            ;SET RETRY COUNTER
  620.     MOV    HSTPTR,DI        ;SAVE BUFFER POINTER
  621.  
  622.     MOV    AL,BYTE PTR PHYSEC    ;GET SECTOR #
  623.     INC    AL            ;PUT INTO RANGE 1 TO SPT
  624.     OUT    FDSEC,AL        ;TELL CONTROLLER
  625.  
  626. RDS2071:
  627.     MOV    AL,PHYSID        ;GET SIDE SELECT VALUE
  628.     OR    AL,FDCRDS+FDFSLF    ;FORM COMMAND
  629.     OR    AL,HLDDLYF        ; OR IN DELAY FLAG
  630.     MOV    HLDDLYF,0        ;ZERO DELAY FOR NEXT I/O
  631.     MOV    CX,COUNT        ;GET COUNT
  632.     MOV    DI,HSTPTR        ;GET BUFFER POINTER
  633.     CALL    RD207            ;USE LOW LEVEL READ ROUTINE
  634.     AND    AL,NOT FDSRTE        ;MASK ERROR CODE
  635.     TEST    AL,AL            ;CHECK FOR ERROR
  636.     JZ    RDS2073            ; BR IF NO ERROR
  637.  
  638.     CALL    ERR207            ;CHECK IF I SHOULD DO RETRY
  639.     JNC    RDS2071            ; BR IF YES
  640.  
  641.     CMP    PREREAD,0        ;Q. IS THIS A PREREAD OPERATION
  642.     JNE    RDS2074            ; BR IF YES
  643.     CALL    ABTIGN            ;HANDLE ABORT/IGNORE
  644.  
  645. RDS2074:
  646.     MOV    AL,ERRTYP        ;RESTORE ERROR CODE
  647.  
  648. RDS2073:
  649.     MOV    DI,HSTPTR        ;RESTORE BUFFER POINTER
  650.     AND    DSKOP,NOT DSKOPR    ;INDICATE READ OPERATION DONE
  651.     RET
  652.  
  653.  
  654.  
  655.  
  656. ;*    LOW LEVEL READ ROUTINE
  657. ;
  658. ;    ENTRY:    (AL)=COMMAND
  659. ;        (DI)=BUFFER POINTER
  660. ;        (CX)=COUNT
  661. ;    EXIT:    (AL)=CONTROLLER STATUS
  662. ;    USES:    AX,CX,DI
  663. ;
  664.  
  665. RD207:
  666.     MOV    AH,AL            ;SAVE COMMAND
  667.     IN    AL,FDDAT        ;CLEAR ANY PENDING DRQ
  668.  
  669.     IF    WAIT
  670.     MOV    AL,DEVCTL        ;ENABLE WAIT STATE I/O
  671.     OR    AL,CONWE
  672.     OUT    FDCON,AL
  673.     ENDIF
  674.  
  675.     CLD                ;FORWARD DIRECTION
  676.     CALL    EXDSES            ;NEED ES: TO POINT TO MY BANK
  677.  
  678.     PUSHF                ;DISABLE INTERRUPTS
  679.     CLI
  680.  
  681.     MOV    AL,AH            ;RESTORE COMMAND
  682.     OUT    FDCMD,AL        ;ISSUE COMMAND
  683.  
  684. RD2071:
  685.     IF    NOT WAIT
  686.     IN    AL,FDAS            ;WAIT FOR DRQ OR IRQ
  687.     TEST    AL,ASDRQ+ASIRQ
  688.     JZ    RD2071
  689.     ENDIF
  690.     IN    AL,FDDAT        ;GET DATA
  691.     STOSB                ;STORE IN BUFFER
  692.     LOOP    RD2071            ;LOOP AND READ
  693.  
  694.     POPF                ;RESTORE INTERRUPT STATUS
  695.  
  696.     CALL    EXDSES            ;RESTORE DS: AND ES:
  697.     CALL    WAIT2071        ;WAIT FOR COMMAND COMPLETION
  698.  
  699.     IF    WAIT
  700.     MOV    AH,AL            ;SAVE CONTROLLER STATUS
  701.     MOV    AL,DEVCTL        ;DISABLE WAIT STATE I/O
  702.     OUT    FDCON,AL
  703.     MOV    AL,AH            ;RESTORE CONTROLLER STATUS
  704.     ENDIF
  705.  
  706.     RET
  707.  
  708.  
  709.  
  710.  
  711. ;*    RDA207 - READ ADDRESS
  712. ;
  713. ;    ENTRY:    (DI)=BUFFER ADDRESS
  714. ;    EXIT:    (AL)=CONTROLLER STATUS
  715. ;    USES:    AL,CX,DI
  716. ;
  717.  
  718. RDA207:
  719.     OR    DSKOP,DSKOPRA        ;SHOW READ ADDR OP IN PROGRESS
  720.     MOV    HSTPTR,DI        ;SAVE BUFFER POINTER
  721.  
  722. RDA2071:
  723.     MOV    AL,PHYSID        ;GET SIDE FLAG VALUE
  724.     OR    AL,FDCRDA        ; OR IN COMMAND
  725.     OR    AL,HLDDLYF        ;  OR IN DELAY FLAG
  726.     MOV    HLDDLYF,0        ;ZERO DELAY FOR NEXT I/O
  727.     MOV    CX,FDRAL        ;COUNT
  728.     MOV    DI,HSTPTR        ;GET BUFFER POINTER
  729.     CALL    RD207            ;USE LOW LEVEL READ ROUTINE
  730.  
  731.     AND    DSKOP,NOT DSKOPRA    ;INDICATE READ ADDRESS OP DONE
  732.     RET
  733.  
  734.  
  735.  
  736.  
  737. ;*    S1S - SET 1ST SECTOR
  738. ;
  739. ;    ENTRY:    NONE
  740. ;    EXIT:    (AX)=BUFFER DISPLACEMENT
  741. ;        'PHYSEC','SEC1ST'=1ST SECTOR #
  742. ;    USES:    AX,DI
  743. ;
  744.  
  745. S1S207:
  746.     LEA    DI,RDABUF        ;USE READ ADDRESS BUFFER
  747.     CALL    RDA207            ; TO DO READ ADDRESS OPERATION
  748.     LEA    DI,RDABUF        ;GET ADDR OF READ ADDRESS INFO
  749.     TEST    AL,AL            ;CHECK IF READ ADDRESS RETURN ERROR
  750.     JZ    S1S2071            ; BR IF NO ERROR
  751.     MOV    BYTE PTR FDRASEC[DI],0    ;  OTHERWISE 0
  752.  
  753. S1S2071:
  754.     MOV    AL,FDRASEC[DI]        ;GET SECTOR #
  755.     CMP    AL,SECCNT        ;CHECK IF LAST SECTOR ON TRACK
  756.     JB    S1S2072            ; BR IF NOT
  757.     XOR    AL,AL            ;  OTHERWISE 0
  758.  
  759. S1S2072:
  760.     MOV    SEC1ST,AL        ;SAVE AS 1ST SECTOR #
  761.     CBW                ;SET 'PHYSEC'
  762.     MOV    PHYSEC,AX
  763.  
  764.     MUL    COUNT            ;COMPUTE DISPLACEMENT
  765.  
  766.     RET
  767.  
  768.  
  769.  
  770.  
  771. ;*    WRS207 - WRITE SECTOR
  772. ;
  773. ;    ENTRY:    'PHYSEC'=SECTOR #
  774. ;        (SI)=BUFFER POINTER
  775. ;    EXIT:    (AL)=CONTROLLER STATUS
  776. ;    USES:    AL,CX,DX
  777. ;
  778.  
  779. WRS207:
  780.     OR    DSKOP,DSKOPW        ;INDICATE WRITE OPERATION IN PROGRESS
  781.     CALL    SRC207            ;SET RETRY COUNTER
  782.     MOV    HSTPTR,SI        ;SAVE BUFFER POINTER
  783.  
  784.     MOV    AL,BYTE PTR PHYSEC    ;GET SECTOR #
  785.     INC    AL            ;PUT INTO RANGE 1 TO SPT
  786.     OUT    FDSEC,AL        ;TELL CONTROLLER
  787.  
  788. WRS2071:
  789.     MOV    AL,PHYSID        ;GET SIDE SELECT VALUE
  790.     OR    AL,FDCWRS+FDFSLF    ;FORM COMMAND
  791.     OR    AL,HLDDLYF        ; OR IN DELAY FLAG
  792.     MOV    HLDDLYF,0        ;ZERO DELAY FOR NEXT I/O
  793.     MOV    CX,COUNT        ;GET COUNT
  794.     MOV    SI,HSTPTR        ;GET BUFFER POINTER
  795.     MOV    DX,DS            ;DATA SEGMENT
  796.     CALL    WR207            ;USE LOW LEVEL WRITE ROUTINE
  797.     TEST    AL,AL            ;CHECK FOR ERROR
  798.     JZ    WRS2073            ; BR IF NO ERROR
  799.  
  800.     CALL    WBS207            ;WAIT FOR WRITE GATE TURN OFF
  801.     CALL    ERR207            ;CHECK IF I SHOULD DO RETRY
  802.     JNC    WRS2071            ; BR IF YES
  803.     CALL    ABTIGN            ;ASK ABOUT ABORTING
  804.     MOV    AL,ERRTYP        ;RESTORE ERROR CODE
  805.  
  806. WRS2073:
  807.     MOV    SI,HSTPTR        ;RESTORE BUFFER POINTER
  808.     AND    DSKOP,NOT DSKOPW    ;INDICATE WRITE OP DONE
  809.     RET
  810.  
  811.  
  812.  
  813.  
  814. ;*    WR207 - LOW LEVEL WRITE ROUTINE
  815. ;
  816. ;    ENTRY:    (AL)=COMMAND
  817. ;        (SI)=BUFFER POINTER
  818. ;        (CX)=COUNT
  819. ;    EXIT:    (AL)=CONTROLLER STATUS
  820. ;    USES:    AX,CX,SI
  821. ;
  822.  
  823. WR207:
  824.     MOV    AH,AL            ;SAVE COMMAND
  825.  
  826.     MOV    AL,FDSWPV        ;ASSUME WRITE PROTECT VIOLATION
  827.     TEST    DPEFLAG[BP],DPE48RO    ;CHECK FOR 48 TPI R/O DISK
  828.     JNZ    WR2072            ; BR IF IT IS
  829.  
  830.     IN    AL,FDDAT        ;CLEAR ANY PENDING DRQ
  831.  
  832.     IF    WAIT
  833.     MOV    AL,DEVCTL        ;ENABLE WAIT STATE I/O
  834.     OR    AL,CONWE
  835.     OUT    FDCON,AL
  836.     ENDIF
  837.  
  838.     PUSHF                ;DISABLE INTERRUPTS
  839.     CLI
  840.  
  841.     CLD                ;FORWARD DIRECTION
  842.     PUSH    DS            ;GET DATA SEGMENT
  843.     MOV    DS,DX
  844.  
  845.     MOV    AL,AH
  846.     OUT    FDCMD,AL        ;ISSUE COMMAND
  847.  
  848. WR2071:
  849.     IF    NOT WAIT
  850.     IN    AL,FDAS            ;WAIT FOR DRQ OR IRQ
  851.     TEST    AL,ASDRQ+ASIRQ
  852.     JZ    WR2071
  853.     ENDIF
  854.     LODSB                ;GET DATA
  855.     OUT    FDDAT,AL        ;SEND TO DISK
  856.     LOOP    WR2071            ;LOAD AND WRITE
  857.  
  858.     POP    DS            ;RESTORE DATA SEGMENT
  859.     POPF                ;RESTORE INTERRUPT STATUS
  860.  
  861.     CALL    WAIT2071        ;WAIT FOR COMMAND COMPLETION
  862.  
  863.     IF    WAIT
  864.     MOV    AH,AL            ;SAVE CONTROLLER STATUS
  865.     MOV    AL,DEVCTL        ;DISABLE WAIT STATE I/O
  866.     OUT    FDCON,AL
  867.     MOV    AL,AH            ;RESTORE CONTROLLER STATUS
  868.     ENDIF
  869.  
  870. WR2072:
  871.     RET
  872.  
  873.  
  874.  
  875.  
  876.  
  877. ;*    DONE WITH 207
  878. ;
  879. ;    ENTRY:    NONE
  880. ;    EXIT:    NONE
  881. ;    USES:    AL
  882. ;
  883.  
  884. DONE207:
  885.     MOV    AL,PHYSID        ;SAVE SIDE SELECT VALUE
  886.     CMP    BUFERR[BX],0        ;Q. DID ERROR OCCUR
  887.     JZ    DONE2071        ; BR IF NOT
  888.     MOV    AL,FDFSS1
  889. DONE2071:
  890.     MOV    SIDE207,AL
  891.  
  892.     XOR    AL,AL            ;DESELECT DRIVE
  893.     OUT    FDCON,AL
  894.     MOV    DEVCTL,AL
  895.  
  896.     TEST    DPEFLG2[BP],DPEHLS    ;Q. DRIVE HAS HEAD LOAD SELONOID
  897.     JZ    DONE2072        ; BR IF NOT
  898.     PUSH    AX
  899.     MOV    AX,35*250        ;WAIT DRIVE DESELECT TIME
  900.     CALL    WDLY
  901.     POP    AX
  902.  
  903. DONE2072:
  904.     RET
  905.  
  906.  
  907.  
  908.  
  909. ;*    SET UP DEVICE
  910. ;
  911. ;    ENTRY:    (BX)=POINTER TO BUFFER HEADER INFO
  912. ;    EXIT:    (BP)=ADDRESS OF DPE
  913. ;        'PHYTRK'=PHYSICAL TRACK #
  914. ;        'PHYSID'=PHYSICAL SIDE #
  915. ;        'SECCNT'=# SECTORS PER TRACK
  916. ;        'COUNT'=# BYTES PER SECTOR
  917. ;        DRIVE IS SELECTED
  918. ;    USES:    AX,BP,SI
  919. ;
  920.  
  921. SET207:
  922.     MOV    BP,BUFDPE[BX]        ;GET ADDRESS OF DPE
  923.  
  924. ;    COMPUTE PHYSICAL TRACK AND SIDE VALUES
  925.  
  926.     MOV    AL,BYTE PTR BUFTRK[BX]    ;GET CP/M TRACK #
  927.     MOV    PHYSID,0        ;ASSUME SIDE 0
  928.     MOV    PHYSIDN,0
  929.     TEST    DPEFLAG[BP],DPE2S
  930.     JZ    SET2071A        ;BR IF NOT DOUBLE SIDED MEDIA
  931.     SHR    AL,1            ;DIVIDE TRACK # BY 2
  932.     JNC    SET2071A        ;EVEN TRACKS ON SIDE 0
  933.     MOV    PHYSID,FDFSS1        ; ODD TRACKS ON SIDE 1
  934.     MOV    PHYSIDN,1
  935. SET2071A:
  936.     MOV    PHYTRK,0        ;INSURE HIGH ORDER BYTE IS 0
  937.     MOV    BYTE PTR PHYTRK,AL    ;SAVE PHYSICAL TRACK #
  938.  
  939. ;    CHECK FOR SPECIAL CASE OF 8" DRIVE, TRACK 0, SIDE 0
  940.  
  941.     CMP    BYTE PTR PHYTRK,0    ;CHECK IF TRACK 0
  942.     JNE    SET2072            ; BR IF NOT
  943.     CMP    PHYSID,0        ;CHECK IF SIDE 0
  944.     JNE    SET2072            ; BR IF NOT
  945.     TEST    DPEFLAG[BP],DPET0SD    ;CHECK IF TRACK 0 SINGLE DENSITY
  946.     JZ    SET2072            ; BR IF NOT
  947.  
  948.     MOV    SECCNT,26        ;26 PHYSICAL SECTORS PER TRACK
  949.     MOV    COUNT,128        ;128 BYTES PER PHYSICAL SECTOR
  950.     JMPS    SET2073
  951.  
  952. ;    COMPUTE NUMBER OF SECTORS PER TRACK
  953.  
  954. SET2072:
  955.     MOV    SI,DPEDPB[BP]
  956.     MOV    AX,DPBSPT[SI]
  957.     DIV    DPERPS[BP]
  958.     MOV    SECCNT,AL
  959.  
  960. ;    COMPUTE NUMBER OF BYTES PER SECTOR
  961.  
  962.     MOV    AL,128
  963.     MUL    DPERPS[BP]
  964.     MOV    COUNT,AX
  965.  
  966. ;
  967.     
  968. SET2073:
  969.     CALL    DS207            ;SELECT DRIVE
  970.  
  971. ;    SET TRACK REGISTER IN CONTROLLER
  972.  
  973.     MOV    AL,DPETRK[BP]        ;GET TRACK POSITION
  974.     OUT    FDTRK,AL        ;SET TRACK REGISTER
  975.     TEST    AL,DPEUNK        ;CHECK IF UNKNOWN
  976.     JZ    SET2074            ; BR IF KNOWN
  977.     CALL    RST207            ;RESTORE HEAD
  978.  
  979. ;
  980.  
  981. SET2074:
  982.     RET
  983.  
  984.  
  985.  
  986.  
  987.  
  988. ;*    SET I/O RETRY COUNTER
  989. ;
  990. ;    ENTRY:    NONE
  991. ;    EXIT:    'RETRIES' SET
  992. ;    USES:    NONE
  993. ;
  994.  
  995. SRC207:
  996.     MOV    RETRIES,12        ;ASSUME 12
  997.     TEST    DSKOP,DSKOPRA+DSKOPS    ;CHECK IF SPECIAL CASE
  998.     JZ    SRC2071            ; BR IF NOT
  999.     MOV    RETRIES,4        ;ALLOW ONLY 4 RETRIES
  1000. SRC2071:
  1001.     RET
  1002.  
  1003.  
  1004.  
  1005.  
  1006.  
  1007. ;*    DRIVE SELECT
  1008. ;
  1009. ;    ENTRY:    NONE
  1010. ;    EXIT:    DRIVE SELECTED AND UP TO SPEED
  1011. ;    USES:    AX,CX
  1012. ;
  1013.  
  1014. DS207:
  1015.     MOV    HLDDLYF,0        ;ASSUME ZERO DELAY
  1016.  
  1017. ;    FORM CONTROL WORD
  1018.  
  1019.     MOV    AL,DPEUNIT[BP]        ;GET UNIT SELECT FROM DPE
  1020.     OR    AL,CONDSEN        ;DRIVE SELECT ENABLE
  1021.     TEST    DPEFLAG[BP],DPEDD    ;Q. DOUBLE DENSITY
  1022.     JZ    DS2070            ; BR IF NOT
  1023.  
  1024.     CMP    BYTE PTR PHYTRK,0    ;CHECK FOR SPECIAL CASE
  1025.     JNE    DS2071            ; WHERE TRACK 0 SIDE 0
  1026.     CMP    PHYSID,0        ;  SINGLE DENSITY WHILE THE
  1027.     JNE    DS2071            ;   REST IS DOUBLE DENSITY
  1028.     TEST    DPEFLAG[BP],DPET0SD
  1029.     JZ    DS2071            ;BR IF NOT SPECIAL CASE
  1030.  
  1031. DS2070:
  1032.     OR    AL,CONSD        ;SET FOR SINGLE DENSITY
  1033.  
  1034. ;
  1035.  
  1036. DS2071:
  1037.     MOV    AH,AL            ;(AH)=NEW CONTROL WORD
  1038.  
  1039.     TEST    DPEFLG2[BP],DPEHLS    ;Q. DRIVE HAS HEAD LOAD SELONOID
  1040.     JZ    DS2071A            ; BR IF NOT
  1041.     AND    AL,CONDSEN+CONDS8+CONDS    ;ISOLATE DRIVE SELECT BITS IN NEW
  1042.     MOV    CL,DEVCTL        ;ISOLATE DRIVE SELECT
  1043.     AND    CL,CONDSEN+CONDS8+CONDS    ; BITS IN OLD CONTROL WORD
  1044.     CMP    AL,CL            ;Q. SAME DRIVE STILL SELECTED
  1045.     JE    DS2071A            ; BR IF YES
  1046.  
  1047.     IN    AL,FDTRK        ;NEW DRIVE SELECTED - CAUSE 1797
  1048.     OUT    FDDAT,AL        ; TO RESET HEAD LOAD DELAY TIMER
  1049.     MOV    AL,FDCSEK        ;  BY DOING ZERO LENGTH SEEK WITH
  1050.     CALL    WAIT207            ;   HEAD UNLOADED
  1051.     MOV    HLDDLYF,FDFDLF        ;USE DELAY FOR NEXT I/O
  1052.  
  1053. DS2071A:
  1054.     TEST    AH,CONDS8        ;CHECK IF SELECTING 8" DRIVE
  1055.     JNZ    DS2075            ; BR IF 8"
  1056.  
  1057. ;    SELECT 5 1/4" DRIVE
  1058.  
  1059.     AND    AH,NOT CONPC        ;ASSUME PRE-COMP
  1060.     TEST    DPEFLAG[BP],DPE96T    ;Q. 96 TPI DRIVE
  1061.     JNZ    DS2072            ; BR IF YES
  1062.     CMP    BYTE PTR PHYTRK,23    ;Q. TRACK >= 23 ON 48 TPI DRIVE
  1063.     JAE    DS2072            ; BR IF YES
  1064.     OR    AH,CONPC        ;DON'T USE PRE-COMP
  1065. DS2072:
  1066.  
  1067.     MOV    AL,AH            ;SELECT DRIVE
  1068.     OUT    FDCON,AL
  1069.  
  1070. ;    HANDLE MOTOR START UP DELAY FOR 5 1/4" DRIVE
  1071.  
  1072.     TEST    DSKOP,DSKOPWP+DSKOPI    ;Q. WAIT FOR MOTOR UP TO SPEED
  1073. ;    JNZ    DS2079            ; BR IF NO
  1074.     JZ    $+5
  1075.     JMP    DS2079
  1076.     MOV    AL,DEVCTL        ;CHECK IF A 5 1/4" DRIVE
  1077.     AND    AL,CONDSEN+CONDS8    ; IS ALREADY SELECTED
  1078.     CMP    AL,CONDSEN
  1079. ;    JE    DS2079            ;  BR IF YES
  1080.     JNE    $+5
  1081.     JMP    DS2079
  1082.     IN    AL,FDAS            ;SEE IF MOTOR STILL RUNNING
  1083.     TEST    AL,ASMO
  1084. ;    JNZ    DS2079            ; BR IF IT IS
  1085.     JZ    $+5
  1086.     JMP    DS2079
  1087.  
  1088.     MOV    CX,250/TINTRVL+1    ;WAIT FOR 250 mS
  1089.     TEST    DPESEK[BP],DPEMO    ;CHECK IF FAST MOTOR UP TO SPEED
  1090.     JNZ    DS2073            ; BR IF YES
  1091.     MOV    CX,1000/TINTRVL+1    ;WAIT FOR 1 SEC
  1092. DS2073:
  1093.     ADD    CX,TICCNT
  1094. DS2073A:
  1095.     CMP    CX,TICCNT
  1096.     JNE    DS2073A
  1097.  
  1098.     JMPS    DS2079
  1099.  
  1100. ;    SELECT 8" DRIVE
  1101. ;
  1102. ;    SINCE THE 1797 CHECKS THE DRIVE READY STATUS LINE BEFORE PLACING
  1103. ;    THE VALUE OF THE SIDE SELECT ON ITS OUTPUT PIN, IT MAY BE NECESSARY
  1104. ;    TO FORCE THE 1797 TO PLACE A SIDE SELECT VALUE ACCEPTABLE TO THE
  1105. ;    DRIVE BEFORE PRECEDING.  THIS SITUATION ARISES WHEN
  1106. ;      1. A PREVIOUS 1797 COMMAND SELECTED SIDE 1
  1107. ;      2. THE MEDIA IS NOT DOUBLE SIDED
  1108. ;    WHAT HAPPENS IS SOME DRIVES INDICATE DRIVE READY AS
  1109. ;      1. MEDIA INSERTED
  1110. ;      2. DOOR CLOSED
  1111. ;      3. SIDE SELECTED IS AVAILABLE
  1112.  
  1113. DS2075:
  1114.     MOV    AL,AH            ;SELECT DRIVE
  1115.     OUT    FDCON,AL
  1116.  
  1117.     TEST    DSKOP,DSKOPWP+DSKOPI+DSKOPRD    ;Q. SKIP
  1118.     JNZ    DS2079                ; BR IF YES
  1119.  
  1120.     CMP    PHYSID,FDFSS1        ;Q. WISH TO USE SIDE 1
  1121.     JE    DS2078
  1122.  
  1123.     IN    AL,FDAS            ;CHECK IF DOUBLE SIDED MEDIA
  1124.     TEST    AL,AS2S
  1125.     JNZ    DS2078            ; BR IF DOUBLE SIDED MEDIA
  1126.  
  1127.     CMP    SIDE207,FDFSS1        ;CHECK IF SIDE 1 SELECTED PREVIOUSLY
  1128.     JNE    DS2078            ; BR IF NOT
  1129.  
  1130.     XOR    AL,AL            ;DESELECT DRIVE
  1131.     OUT    FDCON,AL
  1132.  
  1133.     PUSH    AX
  1134.     MOV    AL,FDCRDA+FDFDLF    ;USE READ ADDRESS COMMAND
  1135.     OUT    FDCMD,AL        ; TO FORCE SIDE 0 SELECT
  1136.     MOV    AX,(60+3)/4        ;DELAY TO GIVE STATUS A CHANCE
  1137.     CALL    WDLY
  1138. DS2076:
  1139.     IN    AL,FDSTA        ;WAIT UNTIL 1797 GOES BUSY
  1140.     TEST    AL,FDSBSY
  1141.     JZ    DS2076
  1142.     MOV    AL,FDCFI+FDFINI        ;TERMINATE COMMAND
  1143.     OUT    FDCMD,AL
  1144.     MOV    AX,(60+3)/4        ;DELAY TO GIVE STATUS A CHANCE
  1145.     CALL    WDLY
  1146. DS2077:
  1147.     IN    AL,FDSTA        ;WAIT UNTIL 1797 GOES NOT BUSY
  1148.     TEST    AL,FDSBSY
  1149.     JNZ    DS2077
  1150.     IN    AL,FDDAT        ;FLUSH ANY DATA IN 1797
  1151.  
  1152.     POP    AX
  1153.     MOV    AL,AH            ;RESELECT DRIVE
  1154.     OUT    FDCON,AL
  1155.  
  1156. ;    WAIT FOR MOTOR UP TO SPEED.  DRIVE WILL INDICATE READY WHEN
  1157. ;    UP TO SPEED.  THIS IS DONE TO ACCOMODATE DRIVES WITH DC MOTORS.
  1158.  
  1159. DS2078:
  1160.     PUSH    AX
  1161.     MOV    AL,FDCFI+FDFINI        ;FORCE TYPE 1 STATUS
  1162.     OUT    FDCMD,AL
  1163.     MOV    AX,(60+3)/4        ;DELAY TO GIVE STATUS A CHANCE
  1164.     CALL    WDLY
  1165. DS2078A:
  1166.     IN    AL,FDSTA        ;WAIT UNITL 1797 GOES NOT BUSY
  1167.     TEST    AL,FDSBSY
  1168.     JNZ    DS2078A
  1169.  
  1170.     MOV    CX,1000/TINTRVL+1    ;WAIT 1 SEC MAX
  1171.     ADD    CX,TICCNT
  1172.  
  1173. DS2078B:
  1174.     CMP    CX,TICCNT        ;Q. TIME UP
  1175.     JE    DS2078C            ; BR IF YES
  1176.     IN    AL,FDSTA
  1177.     TEST    AL,FDSNRD        ;Q. DRIVE READY
  1178.     JNZ    DS2078B            ; BR IF NOT
  1179.  
  1180. DS2078C:
  1181.     POP    AX
  1182.  
  1183. ;
  1184.  
  1185. DS2079:
  1186.     MOV    DEVCTL,AH        ;SAVE CONTROL REGISTER IMAGE
  1187.  
  1188.     RET
  1189.  
  1190.  
  1191.  
  1192.  
  1193. ;*    ISSUE COMMAND AND WAIT FOR I/O COMPLETION
  1194. ;
  1195. ;    ENTRY:    (AL)=COMMAND
  1196. ;    EXIT:    (AL)=CONTROLLER STATUS
  1197. ;    USES:    AL
  1198. ;
  1199.  
  1200. WAIT207:
  1201.     OUT    FDCMD,AL        ;ISSUE COMMAND
  1202.     PUSH    AX            ;WAIT AT LEAST 60uS
  1203.     MOV    AX,(60+3)/4        ; BEFORE CHECKING STATUS
  1204.     CALL    WDLY
  1205.     POP    AX
  1206.  
  1207. WAIT2071:
  1208.     IN    AL,FDAS            ;WAIT FOR IRQ
  1209.     TEST    AL,ASIRQ
  1210.     JZ    WAIT2071
  1211.  
  1212. WAIT2073:
  1213.     IN    AL,FDSTA        ;GET CONTROLLER STATUS
  1214.     TEST    AL,FDSBSY        ;WAIT FOR NOT BUSY
  1215.     JNZ    WAIT2073
  1216.  
  1217.     RET
  1218.  
  1219.  
  1220.  
  1221.  
  1222. ;*    CHECK IF TO DO RETRIES
  1223. ;
  1224. ;    ENTRY:    (AL)=CONTROLLER STATUS
  1225. ;        'RETRIES'=RETRY COUNTER
  1226. ;    EXIT:    PSW/C=RETRY STATUS (0=RETRY , 1=NO RETRY)
  1227. ;    USES:    AL,DI
  1228. ;
  1229. ;    I/O RECOVERY PROCEDURE:
  1230. ;      1) RETRY I/O OPERATION
  1231. ;      2) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION
  1232. ;      3) RETRY I/O OPERATION
  1233. ;      4) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION
  1234. ;      5) RETRY I/O OPERATION
  1235. ;      6) RESTORE HEAD/RE-SEEK, THEN RETRY I/O OPERATION
  1236. ;      7) RETRY I/O OPERATION
  1237. ;      8) STEP HEAD IN/OUT 1 TRACK, THEN RETRY I/O OPERATION
  1238. ;      9) RETRY I/O OPERATION
  1239. ;     10) STEP HEAD OUT/IN 1 TRACK, THEN RETRY I/O OPERATION
  1240. ;     11) RETRY I/O OPERATION
  1241. ;     12) FLAG AS HARD ERROR
  1242. ;
  1243.  
  1244. ERR207:
  1245.     MOV    ERRTYP,AL        ;SAVE CONTROLLER STATUS AS ERROR TYPE
  1246.  
  1247.     TEST    AL,FDSNRD+FDSWPV    ;CHECK FOR NOT READY OR WRITE PROTECT
  1248.     JNZ    ERR2079            ; BR IF YES - NO RETRIES
  1249.  
  1250.     TEST    DSKOP,DSKOPS        ;IF NOT DOING A SELECT OPERATION
  1251.     JNZ    ERR2071
  1252.     MOV    DI,BBIOS        ; BUMP SOFT ERROR COUNTER
  1253.     INC    SECNT[DI]
  1254.  
  1255. ERR2071:
  1256.     DEC    RETRIES            ;UPDATE RETRY COUNTER
  1257.     JZ    ERR2079            ; BR IF EXHAUSTED RETRIES
  1258.  
  1259.     MOV    AL,RETRIES
  1260.     CMP    AL,6
  1261.     JA    ERR2072
  1262.     SUB    AL,6
  1263. ERR2072:
  1264.     JNZ    ERR2073            ;BR IF NOT TIME TO DO RESTORE HEAD
  1265.     CALL    RST207            ;RESTORE HEAD BEFORE TRYING AGAIN
  1266.     JMPS    ERR2077
  1267.  
  1268. ERR2073:
  1269.     CMP    AL,4            ;CHECK IF TIME TO STEP OUT
  1270.     JNE    ERR2074            ; BR IF NOT
  1271.     DEC    BYTE PTR PHYTRK        ;DECREMENT TO NEXT TRACK
  1272.     JS    ERR2073A        ; BR IF BEFORE TRACK 0
  1273.     CALL    SDT207            ;  OTHERWISE STEP OUT
  1274. ERR2073A:
  1275.     INC    BYTE PTR PHYTRK        ;RESTORE DESIRED TRACK
  1276.     JMPS    ERR2077
  1277.  
  1278. ERR2074:
  1279.     CMP    AL,2            ;CHECK IF TIME TO STEP IN
  1280.     JNE    ERR2078            ; BR IF NOT
  1281.     MOV    AL,NTRK837-1        ;GET MAXIMUM TRACK #
  1282.     TEST    DPEUNIT[BP],CONDS8
  1283.     JNZ    ERR2074A
  1284.     MOV    AL,NTRKD37-1
  1285.     TEST    DPEFLAG[BP],DPE96T
  1286.     JNZ    ERR2074A
  1287.     MOV    AL,NTRKS37-1
  1288. ERR2074A:
  1289.     INC    BYTE PTR PHYTRK        ;INCREMENT TO NEXT TRACK
  1290.     CMP    AL,BYTE PTR PHYTRK    ;CHECK IF MAX TRACK # >= NEXT TRACK
  1291.     JB    ERR2074B        ; BR IF IT IS
  1292.     CALL    SDT207            ;  OTHERWISE STEP IN
  1293. ERR2074B:
  1294.     DEC    BYTE PTR PHYTRK        ;RESTORE DESIRED TRACK
  1295.  
  1296. ERR2077:
  1297.     CALL    SDT207            ;SEEK DESIRED TRACK
  1298.  
  1299. ERR2078:
  1300.     CLC                ;INDICATE TRY AGAIN
  1301.     RET
  1302.  
  1303. ERR2079:
  1304.     MOV    BUFERR[BX],1        ;SET ERROR FLAG
  1305.     MOV    AL,ERRTYP        ;RECOVER CONTROLLER STATUS
  1306.  
  1307.     TEST    DSKOP,DSKOPR+DSKOPW    ;IF DOING READ OR WRITE OPERATION
  1308.     JZ    ERR2079B
  1309.     MOV    DI,BUFERRF[BX]        ; PLACE IN ERROR ARRAY
  1310.     ADD    DI,PHYSEC
  1311.     MOV    [DI],AL
  1312.     JMPS    ERR2079D
  1313.  
  1314. ERR2079B:
  1315.     TEST    DSKOP,DSKOPF        ;Q. FORMAT OPERATION
  1316.     JZ    ERR2079C        ; BR IF NO
  1317.     TEST    DEVCTL,CONDS8        ;Q. 8" DRIVE
  1318.     JZ    ERR2079C        ; BR IF NOT
  1319.     CMP    PHYTRK,0        ;Q. TRACK 0
  1320.     JNE    ERR2079C        ; BR IF NOT
  1321.     CMP    PHYSID,FDFSS1        ;Q. SIDE 1
  1322.     JNE    ERR2079C        ; BR IF NOT
  1323.     CMP    ERRTYP,FDSNRD        ;Q. NOT READY ERROR
  1324.     JE    ERR2079E        ; BR IF YES
  1325.  
  1326. ERR2079C:
  1327.     CALL    ERRRPT            ;  OTHERWISE REPORT ERROR IMMEDIATELY
  1328.  
  1329. ERR2079D:
  1330.     TEST    DSKOP,DSKOPS        ;IF NOT DOING A SELECT OPERATION
  1331.     JNZ    ERR2079E
  1332.     MOV    DI,BBIOS        ; COUNT HARD ERROR
  1333.     INC    HECNT[DI]
  1334.  
  1335. ERR2079E:
  1336.     STC                ;INDICATE DON'T TRY AGAIN
  1337.     RET
  1338.  
  1339.  
  1340.  
  1341.  
  1342. ;*    RESTORE HEAD
  1343. ;
  1344. ;    ENTRY:    NONE
  1345. ;    EXIT:    (AL)=CONTROLLER STATUS
  1346. ;    USES:    AX
  1347. ;
  1348.  
  1349. RST207:
  1350.     MOV    DPETRK[BP],0        ;INDICATE TRACK # 0
  1351.  
  1352.     TEST    DPESEK[BP],DPEFS    ;Q. CAN DRIVE FAST STEP
  1353.     JZ    RST2071            ; BR IF NOT
  1354.     MOV    AL,DEVCTL        ;SET UP FAST STEP
  1355.     OR    AL,CON5FS
  1356.     OUT    FDCON,AL
  1357.  
  1358. RST2071:
  1359.     MOV    AL,DPESEK[BP]        ;GET STEP RATE
  1360.     AND    AL,FDFSRM
  1361.     OR    AL,FDCRST        ;RESTORE HEAD COMMAND
  1362.     CALL    WAIT207            ;DO RESTORE
  1363.     PUSH    AX            ;WAIT FOR MECHANICAL DELAY
  1364.     MOV    AX,15*250
  1365.     CALL    WDLY
  1366.     POP    AX
  1367.     TEST    DSKOP,DSKOPI        ;Q. INIT OPERATION
  1368.     JZ    RST2072            ; BR IF NOT
  1369.     TEST    AL,FDSTK0        ;Q. AT TRACK 0
  1370.     JZ    RST2073            ; BR IF NOT
  1371.  
  1372. RST2072:
  1373.     MOV    AL,10            ;STEP IN 10 TRACKS
  1374.     CALL    SDT2077
  1375.  
  1376.     MOV    AL,FDCRST+FDFHLB+FDFS30    ;RESTORE HEAD COMMAND
  1377.     CALL    WAIT207            ;DO RESTORE
  1378.     PUSH    AX            ;WAIT FOR MECHANICAL DELAY
  1379.     MOV    AX,15*250
  1380.     CALL    WDLY
  1381.     POP    AX
  1382.  
  1383. RST2073:
  1384.     MOV    AH,AL            ;SAVE CONTROLLER STATUS
  1385.     MOV    AL,DEVCTL        ;TURN OFF FAST STEP
  1386.     OUT    FDCON,AL
  1387.     MOV    AL,AH            ;RESTORE CONTROLLER STATUS
  1388.  
  1389.     MOV    HLDDLYF,FDFDLF        ;USE DELAY FOR NEXT I/O
  1390.     RET
  1391.  
  1392.  
  1393.  
  1394.  
  1395. ;*    SEEK DESIRED TRACK
  1396. ;
  1397. ;    ENTRY:    'PHYTRK'=TRACK #
  1398. ;    EXIT:    NONE
  1399. ;    USES:    AL
  1400. ;
  1401.  
  1402. SDT207:
  1403.     MOV    AL,DPETRK[BP]        ;GET CURRENT TRACK
  1404.     CMP    AL,BYTE PTR PHYTRK    ;CHECK AGAINST DESIRED TRACK
  1405.     JE    SDT2072            ;ALREADY AT DESIRED TRACK
  1406.  
  1407.     TEST    DPESEK[BP],DPEFS    ;CHECK FOR FAST STEP
  1408.     JZ    SDT2070            ; BR IF NOT
  1409.     MOV    AL,DEVCTL        ;ENABLE FAST STEP
  1410.     OR    AL,CON5FS
  1411.     OUT    FDCON,AL
  1412.  
  1413. SDT2070:
  1414.     CALL    SDT2076            ;DO SEEK
  1415.  
  1416.     TEST    DPEFLAG[BP],DPE48RO    ;CHECK IF 48TPI R/O MEDIA
  1417.     JZ    SDT2071            ; BR IF NOT -- NO NEED TO DOUBLE STEP
  1418.  
  1419.     MOV    AL,DPETRK[BP]    ;GO THROUGH SEEK PROCEDURE AGAIN A SECOND TIME
  1420.     OUT    FDTRK,AL        ;RESET CONTROLLER'S TRACK REG
  1421.     CALL    SDT2076            ;DO 2ND SEEK
  1422.  
  1423. SDT2071:
  1424.     MOV    AL,BYTE PTR PHYTRK    ;OUTPUT DESIRED TRACK TO TRACK REG
  1425.     OUT    FDTRK,AL        ; THIS IS DONE IN CASE SEEK ABORTED
  1426.                     ; WHEN IT TRIED TO STEP TO NEGATIVE
  1427.                     ; TRACK LEAVING TRACK REGISTER
  1428.                     ; CONTAINING 0
  1429.  
  1430.     MOV    DPETRK[BP],AL        ;UPDATE IN MEMORY TRACK VALUE
  1431.  
  1432.     MOV    AL,DEVCTL        ;RESTORE CONTROL REGISTER
  1433.     OUT    FDCON,AL        ; INCASE I WAS FAST STEPPING
  1434.  
  1435. SDT2072:
  1436.     MOV    HLDDLYF,FDFDLF        ;USE DELAY FOR NEXT I/O
  1437.     RET
  1438.  
  1439. ;    DO SEEK
  1440.  
  1441. SDT2076:
  1442.     MOV    AL,BYTE PTR PHYTRK    ;TELL CONTROLLER DESIRED TRACK
  1443. SDT2077:
  1444.     OUT    FDDAT,AL
  1445.  
  1446.     MOV    AL,DPESEK[BP]        ;GET STEP RATE
  1447.     AND    AL,FDFSRM
  1448.     OR    AL,FDCSEK+FDFHLB    ; OR IN COMMAND
  1449.     CALL    WAIT207            ;DO I/O
  1450.  
  1451.     PUSH    AX            ;WAIT FOR MECHANICAL DELAY
  1452.     MOV    AX,15*250
  1453.     CALL    WDLY
  1454.     POP    AX
  1455.  
  1456.     RET
  1457.  
  1458.  
  1459.  
  1460.  
  1461. ;*    WAIT ~1.5 mS BEFORE STEPPING
  1462. ;
  1463. ;    ENTRY:    NONE
  1464. ;    EXIT:    NONE
  1465. ;    USES:    NONE
  1466. ;
  1467.  
  1468. WBS207:
  1469.     PUSH    AX
  1470.     MOV    AX,250*3/2+1
  1471.     CALL    WDLY
  1472.     POP    AX
  1473.     RET
  1474.  
  1475.