Adfs19 99.7 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
;>Adfs19
        SUBT    1772/765 Floppy Disk Driver Common Entry Points
;-----------------------------------------------------------------------;
; (C) Copyright 1990 Acorn Computers Limited,                           ;
; Fulbourn Road, Cambridge CB1 4JN, England.                            ;
; Telephone 0223 214411.                                                ;
;                                                                       ;
; All rights reserved.  The software code in this listing is proprietary;
; to Acorn Computers Ltd., and is covered by copyright protection.      ;
; The unauthorized copying, adaptation, distribution, use or display    ;
; is prohibited without prior consent.                                  ;
;-----------------------------------------------------------------------;
; Revision History:                                                     ;
; No.    Date    By     Reason                                          ;
;-----------------------------------------------------------------------;
;     25 Oct 90         Version 2.06 of ADFS                            ;
; 01  28 Nov 90  lrust  Added 82C710 floppy/IDE drivers                 ;
; 02  08 Mar 91  lrust  Alpha version                                   ;
; 03  15 Mar 91  lrust  RiscOS 2.09 release                             ;
; 04  28 May 91  lrust  Add seek track 3 after restore during init to   ;
;                       allow for drives shipped with head on -ve track ;
; 05  17 Sep 91  lrust  40 track drives don't double step when 40 track ;
;                       media bit in LowSector is set                   ;
; 06  16 Dec 91  lrust  Added portable power stuff                      ;
; 07  14 Jan 92  lrust  40 track detection algorithm fixed to cater for ;
;                       40T drives positioning to track 42              ;
; 08  05 Feb 92  lrust  DCB post processing re-enables IRQ's.           ;
;                       FlpErrNoIDs is not mapped by FlpADFSerror since ;
;                       the FDC status returned is invalid.             ;
;_______________________________________________________________________;
;
Adfs19Ed        * 08                    ; Edition number

        GBLL    Flp40Track
Robert Sprowson's avatar
Robert Sprowson committed
49
Flp40Track      SETL    {TRUE}          ; Enable 40 track drive detection
Neil Turton's avatar
Neil Turton committed
50 51

        GBLL    FlpPostIrqOn
Robert Sprowson's avatar
Robert Sprowson committed
52
FlpPostIrqOn    SETL    {TRUE}          ; Enable IRQ's in Post routines
Neil Turton's avatar
Neil Turton committed
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140


;-----------------------------------------------------------------------;
; This file provides the following common entry points for the 82C710   ;
; and the older 1772 based floppy disk driver:                          ;
;                                                                       ;
; 1) FlpInit                                                            ;
;       Initialize the driver, hardware and claim any vectors.  Invoked ;
;       when the module receives the initialization call.               ;
;                                                                       ;
; 2) FlpDie                                                             ;
;       Finalise the driver, calm the hardware and release any system   ;
;       resources. Invoked when the module receives a finalisation call ;
;                                                                       ;
; 3) FlpReset                                                           ;
;       Claim vectors.  Invoked when the module receives a post soft    ;
;       reset service call.                                             ;
;                                                                       ;
; 4) FlpLowLevel                                                        ;
;       Perform disk operations.  Invoked when the module receives a    ;
;       FileCore DiskOp call with a drive number in the range 0 to 3.   ;
;                                                                       ;
; 5) FlpMount                                                           ;
;       Invoked when the module receives a FileCore miscellaneous call  ;
;       with a reason code of 0 (R0 = 0, mount disk).                   ;
;                                                                       ;
; 6) DoPollChanged                                                      ;
;       Check for disk changed status                                   ;
;                                                                       ;
; 7) DoLockDrive                                                        ;
;       Turn drive motor on permanently                                 ;
;                                                                       ;
; 8) DoUnlockDrive                                                      ;
;       Allow drive motor to turn off                                   ;
;                                                                       ;
; In addition the following support routines are included:              ;
;                                                                       ;
; a) FlpBuildDCB                                                        ;
;       Builds a "Disk Control Block" (DCB) from information passed to  ;
;       FlpLowLevel.                                                    ;
;                                                                       ;
; b) FlpADFSerror                                                       ;
;       Maps a '765 FDC error to an ADFS error code and disk address    ;
;                                                                       ;
; c) FlpComplete                                                        ;
;       Informs FileCore of a completed background operation and        ;
;       releases FIQ's.                                                 ;
;                                                                       ;
; d) FlpLowNdataPost                                                    ;
;       DCB post routine for non-data transfer disc-ops.                ;
;                                                                       ;
; e) FlpLowDataPost                                                     ;
;       DCB post routine for data transfer type disc-ops.               ;
;_______________________________________________________________________;


;-----------------------------------------------------------------------;
; FlpInit                                                               ;
;       Check type of FDC (original 1772 or later '765 in 82C710).      ;
;       Initialize the FDC hardware.                                    ;
;       Claim interrupt vectors.                                        ;
;                                                                       ;
; Input:                                                                ;
;       R3  = No. of floppies from CMOS                                 ;
;       R11 = -> Instantiation number, 0= first init                    ;
;       SB  = -> Local storage                                          ;
;       LR  = Return address                                            ;
;                                                                       ;
; Output:                                                               ;
;       R0 = 0, VC, No error                                            ;
;          = Error code, VS                                             ;
;       R1 = No. of responding drives                                   ;
;                                                                       ;
; Modifies:                                                             ;
;       R2                                                              ;
;_______________________________________________________________________;
;
FlpInit ROUT
        Push    "R5,LR"                 ; Save caller's regs
 [ Debug10
        DREG    R3,"FlpInit, Drives(R3): "
 ]

; Read drive step rates

        BL      ReadStep                ; (->R0,R5,V)
        STRB    R5, StepRates           ; Save for future use

141 142
02      LDR     R0, MachineID
 [ Support1772
Neil Turton's avatar
Neil Turton committed
143 144
        CMPS    R0, #MachHas1772        ; 1772 FDC?
        BEQ     FlpInit1772             ; Yes then jump
145
 ]
Neil Turton's avatar
Neil Turton committed
146 147 148 149 150 151 152 153 154 155 156 157 158
        CMPS    R0, #MachHas82710       ; 82C710 FDC?
        MOVNE   R1, #0                  ; No, then 0 floppies
        STRNEB  R1, Floppies
        BNE     %FT45

; Initialize '765 driver data structures

        MOV     LR, #0
        STR     LR, FlpDCBqueue         ; No DCB's queued
        STR     LR, FlpStateTimer       ; Disable all timers
        STR     LR, FlpMEMCstate        ; No MEMC state saved
        STRB    LR, Floppies            ; Assume no drives

159 160 161 162 163 164 165 166 167
        MOV     LR, #FlpDORirqEn+FlpDORreset
        STR     LR, FlpDORimage         ; Initialise all control reg images

 [ FloppyPCI
        Push    "R4"
        MOV     R0, #1:SHL:30
        MOV     R1, #&3F0
        MOV     R2, #8
        SWI     XPCI_LogicalAddress
168 169 170
        MOVVC   R0, R4
        STRVC   R4, FlpBase
        Pull    "R4"
171 172 173 174 175 176 177
        MOVVS   R0, #MachHasNoFDC
        STRVS   R0, MachineID
        BVS     %BT02
        MOV     LR, #-1
        STR     LR, FlpDMAHandle
        BL      Configure37C665
 |
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
 [ FloppyPodule
        Push    "R3"
        MOV     R0, #Podule_ReadInfo_EASILogical
        ADR     R1, FlpBase
        MOV     R2, #4
        MOV     R3, #0
        SWI     XPodule_ReadInfo
        Pull    "R3"
        MOVVS   R0, #MachHasNoFDC
        STRVS   R0, MachineID
        BVS     %BT02
        LDR     LR, FlpBase
        LDRB    R0, [LR]
        TEQ     R0, #&78
        MOVNE   R0, #MachHasNoFDC
        STRNE   R0, MachineID
        BNE     %BT02
        ADD     R0, LR, #&C00000
        STR     R0, FlpDACK_TC
197 198
        ADD     R0, LR, #&E00000
        ADD     LR, R0, #&3F0 * 4
199
        STR     LR, FlpBase
200
        BL      Configure37C665
Jeffrey Lee's avatar
Jeffrey Lee committed
201 202
 |
 [ HAL
203 204 205 206 207 208 209
        MOV     r0, #9
        MOV     r1, #34<<8
        SWI     XOS_Memory
        MOVVS   r1, #0
        CMP     r1, #0
        MOVEQ   r0, #MachHasNoFDC
        STREQ   r0, MachineID
Jeffrey Lee's avatar
Jeffrey Lee committed
210
        BEQ     %BT02
211
        ADD     r0, r1, #&3F0 * 4
212
        STR     r0, FlpBase
213
        ADD     r0, r1, #FlpDACK_Offset + FlpDACK_TC_Offset
214
        STR     r0, FlpDACK_TC
215
 |
216
        LDR     LR, =CnTbase + (&3F0 * 4)
217
        STR     LR, FlpBase
218
        LDR     LR, =CnTbase + FlpDACK_Offset + FlpDACK_TC_Offset
219
        STR     LR, FlpDACK_TC
220
 ]
Jeffrey Lee's avatar
Jeffrey Lee committed
221
 ]
222 223
 ]

Neil Turton's avatar
Neil Turton committed
224 225
        MOV     R0, #3                  ; Max drive number
        DrvRecPtr R1, R0                ; R1-> drive record
226 227
        MOV     LR, #MiscOp_PollChanged_EmptyWorks_Flag + MiscOp_PollChanged_MaybeChanged_Flag
        ORR     LR, LR, #MiscOp_PollChanged_ReadyWorks_Flag
Neil Turton's avatar
Neil Turton committed
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
05      STR     LR, [R1, #DrvFlags]     ; Update drive record
        SUB     R1, R1, #SzDrvRec       ; Next drive record
        SUBS    R0, R0, #1              ; Decr loop counter
        BPL     %BT05                   ; For all drives

        BL      FlpReset                ; Reset/init H/W and claim vectors

; Wait for FDC state system to become ready (FDC initialized)

        baddr   R0, FlpStateReset       ; R0->reset state handler
10      LDR     LR, FlpState            ; Get state
        TEQS    LR, R0                  ; '765 finished reset?
        BEQ     %BT10                   ; No then loop

        baddr   R0, FlpStateErr         ; Error state
        TEQS    LR, R0                  ; FDC error?
        BEQ     %FT99                   ; Yes then jump

; Check no. of floppies fitted and map physical to logical drive numbers

        MOV     R2, #0                  ; Start with physical drive 0
        sbaddr  R5, FlpDrvMap           ; R5-> drive map word
        MOV     LR, #&FFFFFFFF
        STR     LR, [R5]                ; Assume no logical drives

; Construct a "restore" DCB on the stack

        SUB     SP, SP, #FlpDCBsize     ; Allocate DCB on the stack
        MOV     R1, SP                  ; R1->DCB
        MOV     R0, #0
        STR     R0, [R1, #FlpDCBpost]   ; No post routine
        STRB    R0, [R1, #FlpDCBtimeOut] ; No DCB timeout == no spin-up
        MOV     R0, #FlpCCR1000K        ; Set for max clock
        STRB    R0, [R1, #FlpDCBselect] ; Set data rate

; Check if configured drive number found

15      LDRB    LR, Floppies            ; Number of floppy drives
        CMPS    R3, LR                  ; CMOS value less than that found?
        BLS     %FT40                   ; Yes then jump, don't test for any more

; Prepare a restore command

        MOV     R0, #1                  ; 1 retry
        STRB    R0, [R1, #FlpDCBretries]
        STRB    R0, [R1, #FlpDCBesc]    ; Disable escapes
        STRB    R2, [R1, #FlpDCBcdb+1]  ; Write drive/head data
        MOV     R0, #FlpCmdRecal        ; Recalibrate command code
        STRB    R0, [R1, #FlpDCBcdb]    ; Write command
        BL      FlpDoDCB                ; Process DCB (R1->R0,V)
        TEQS    R0, #0                  ; Good command
Robert Sprowson's avatar
Robert Sprowson committed
279
        BEQ     %FT17                   ; Yes, then continue as-is
Neil Turton's avatar
Neil Turton committed
280

Robert Sprowson's avatar
Robert Sprowson committed
281 282 283 284 285 286
        ;Hmm, is it a portable w/out floppy connected?
        ;If so, then it might be best to fake it...
        SWI     XPortable_Status
        BVS     %FT30                   ;Erky! Not a portable
        TST     R0, #PortableStatus_PrinterFloppy
        BNE     %FT30                   ;Eek! Drive already connected, so is error
Neil Turton's avatar
Neil Turton committed
287

Robert Sprowson's avatar
Robert Sprowson committed
288 289
        CMP     r2, #1                  ;UUURGH! Nasty fix 'cos FD0 is physical drive 1!!!!
        BEQ     %FT17                   ;Pretend this drive exists then
Neil Turton's avatar
Neil Turton committed
290 291

        B       %FT30                   ; It really _is_ a 'bad command', so jump
Neil Turton's avatar
Neil Turton committed
292 293 294

; Track 0 seen - drive is responding

Neil Turton's avatar
Neil Turton committed
295
17      STRB    R2, [R5], #1            ; Update drive map
Neil Turton's avatar
Neil Turton committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
        LDRB    R0, Floppies
        ADD     R0, R0, #1              ; 1 more floppy
        STRB    R0, Floppies
 [ Debug10
        DREG    R2, "Found drive: "
 ]

; Determine if drive is 40 track - First seek track 44

        MOV     R0, #FlpCmdSeek         ; Seek command code
        STRB    R0, [R1, #FlpDCBcdb]    ; Write command
 [ Flp40Track
        MOV     R0, #44
        STRB    R0, [R1, #FlpDCBcdb+2]  ; Write track no.
        BL      FlpDoDCB                ; Process DCB (R1->R0,V)
 ]
; Seek track 2 (step in 42 times - 3 more than necessary. Some 40Tdrives have 43 tracks!)

        MOV     R0, #2
        STRB    R0, [R1, #FlpDCBcdb+2]  ; Write track no.
        BL      FlpDoDCB                ; Process DCB (R1->R0,V)

; Check track 0 indication - Will be true for 40 track drives

 [ Flp40Track
        MOV     R0, #2                  ; 2 byte command
        STRB    R0, [R1, #FlpDCBcmdLen] ; Write command length
        MOV     R0, #FlpCmdSenseDrv     ; Sense drive status command code
        STRB    R0, [R1, #FlpDCBcdb]    ; Write command (no implied seek)
        BL      FlpDoDCB                ; Process DCB (R1->R0,V)
        DrvRecPtr R0, R2                ; Get-> drive record
        LDRB    LR, [R1, #FlpDCBresults] ; Get ST3
  [ {TRUE}
        TSTS    LR, #0                  ; Disable 40 track detection
  |
        TSTS    LR, #bit4               ; Track 0?
  ]
        LDRNE   LR, [R0, #DrvFlags]     ; Yes, get drive flags
334
        ORRNE   LR, LR, #MiscOp_PollChanged_40Track_Flag    ; And set 40 track bit
Neil Turton's avatar
Neil Turton committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
        STRNE   LR, [R0, #DrvFlags]     ; And save it
  [ Debug
        BEQ     %FT20
        DREG    R2, "40 track drive: "
20
  ]
 |
        DrvRecPtr R0, R2                ; Get-> drive record
 ]
        MOV     LR, #PositionUnknown
        STR     LR, [R0, #HeadPosition] ; Force restore on next op

; Try next drive

30      ADDS    R2, R2, #1              ; Next physical drive
        CMPS    R2, #4                  ; All done
        BLO     %BT15                   ; No then repeat

; All configured drives found

40      ADD     SP, SP, #FlpDCBsize     ; Deallocate DCB
        LDRB    R1, Floppies            ; Number of floppy drives detected

358 359
45      SUBS    R0, R0, R0              ; No error (R0 = 0, V clear)
        Pull    "R5,PC"                 ; Restore caller's regs and return
Neil Turton's avatar
Neil Turton committed
360 361 362 363 364 365 366 367 368 369 370


; '765 FDC hardware error - no interrupts from drive ready after reset

99      BL      FlpDie                  ; Uninstall
 [ Debug10
        DLINE   "FlpInit error, driver not installed"
 ]
        SUBS    R1, R1, R1              ; No floppies
        Pull    "R5,PC"

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
 [ FloppyPodule:LOR:FloppyPCI

ConfigSMCTable
 [ FloppyPCI
        DCB     &07, 0                  ; Access device 0 (FDC)
        DCB     &30, 1                  ; Enable device (default IO 03F0, DMA2)
        DCB     &70, 7                  ; IRQ7
        DCB     &BB                     ; Exit config mode
 |
        DCB     &01, 2_10000111         ; Enable config read, IRQ active low, parallel powered/extended, default addr.
        DCB     &02, 2_00011100         ; 2nd serial port disabled, 1st enabled at &3F8
        DCB     &03, &78                ; extra stuff for SMC
        DCB     &04, 2_00000011         ; allow extended parallel port modes
        DCB     &05, 0
        DCB     &06, &FF
        DCB     &07, 0
        DCB     &08, 0
        DCB     &09, 0
        DCB     &0A, 0
        DCB     &00, 2_10111011         ; Valid config, OSC/BR on, FDC enabled/powered, IDE AT,enabled
        DCB     &AA                     ; Exit config mode
 ]

        ALIGN

Configure37C665 Entry "r0-r2"
        SETPSR  I_bit + F_bit, lr,, r2  ; Disable FIQ and IRQ

; First try to configure the SMC665

 [ FloppyPCI
        MOV     lr, #&51
        STRB    lr, [r0, #0]            ; Write &51, &23 to &3F0
        MOV     lr, #&23
        STRB    lr, [r0, #0]
 |
        MOV     lr, #&55
        ADD     r0, r0, #&3F0*4
        STRB    lr, [r0, #0]            ; Write &55 to CRI711 twice
        STRB    lr, [r0, #0]            ; to enter configuration mode
 ]

        ADR     r1, ConfigSMCTable      ; R1-> SMC 665 configuration data
20
        LDRB    lr, [r1], #1            ; get config index
        STRB    lr, [r0, #0]
 [ FloppyPCI
        TEQ     lr, #&BB                ; end of table?
 |
        TEQ     lr, #&AA                ; end of table?
 ]
        LDRNEB  lr, [r1], #1            ; if not then get config data
        STRNEB  lr, [r0, #FlpReg_Spacing]; and write it
        BNE     %BT20

        RestPSR r2                      ; Restore IRQ/FIQ state

        EXIT
 ]
Neil Turton's avatar
Neil Turton committed
430 431 432 433 434

; Process a DCB (R1->R0,V)

FlpDoDCB        ROUT
        Push    "LR"
435 436 437 438 439
      [ {TRUE}
        MOV     R0, #256                ; For RPCEmu 0.8.9, the floppy controller is polled in a ratio
        BL      DoMicroDelay            ; to CPU instruction decode. Going too fast prevents rom init.
                                        ; Burn 128us of CPU cycles during each of the power on DCBs.
      ]
Neil Turton's avatar
Neil Turton committed
440 441 442 443 444 445 446
        BL      FlpAddDCB               ; Add DCB to queue (R1->R0,V)
10      LDR     R0, [R1, #FlpDCBstatus] ; Get command error
        CMPS    R0, #FlpDCBpending      ; DCB still pending?
        BEQ     %BT10                   ; Yes then loop
        Pull    "PC"


447 448
 [ Support1772

Neil Turton's avatar
Neil Turton committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
; Initialize 1772 FDC, as per V2.06

FlpInit1772     ROUT
 [ Debug10
        DLINE   "177X FDC found"
 ]
        STRB    R3, Floppies            ; Save no. of drives

        MOV     R0, #NotResetDiscChangedBit :OR: MotorBits :OR: SideBit :OR: DriveBits
        MOV     R1, #&FF
        BL      WrDiscLatch             ; Deselect all drives

        MOV     R0, #0
        MOV     R1, #FdcResetBit
        BL      WrSharedLatch           ; Reset the 1772

        MOV     R0, #75*2               ; 75 micro sec delay
        BL      SmallDelay

        MOV    R0, #FdcResetBit
        BL     WrSharedLatch            ; Release 1772 from reset

        BL      FlpReset                ; Claim interrupt vectors

        MOV     R1, R3                  ; Number of floppy drives from CMOS
474 475 476
        SUBS    R0, R0, R0              ; No error (R0 = 0, V clear)
        Pull    "R5,PC"                 ; Restore caller's regs and return
 ]
Neil Turton's avatar
Neil Turton committed
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503


;-----------------------------------------------------------------------;
; FlpDie                                                                ;
;       Check type of FDC (original 1772 or later '765 in 82C710).      ;
;       Calm the FDC hardware.                                          ;
;       Release interrupt vectors                                       ;
;                                                                       ;
; Input:                                                                ;
;       R11 = -> Instantiation number                                   ;
;       SB  = -> Local storage                                          ;
;       LR  = Return address                                            ;
;                                                                       ;
; Output:                                                               ;
;       None                                                            ;
;                                                                       ;
; Modifies:                                                             ;
;       None, preserves flags                                           ;
;_______________________________________________________________________;
;
FlpDie  ROUT
        Push    "R0-R2,LR"              ; Save caller's regs
 [ Debug10
        DREG    R11,"FlpDie, R11: "
 ]
        MOV     R2, SB                  ; R2-> local storage
        LDR     LR, MachineID           ; Get hardware ID
504
 [ Support1772
Neil Turton's avatar
Neil Turton committed
505 506
        CMPS    LR, #MachHas1772        ; 1772 FDC?
        BEQ     FlpDie1772              ; Yes then jump
507
 ]
Neil Turton's avatar
Neil Turton committed
508 509

        CMPS    LR, #MachHas82710       ; 82C710 FDC?
510
        Pull    "R0-R2,PC",NE           ; No, then exit
Neil Turton's avatar
Neil Turton committed
511 512 513 514

; Kill the '765 driver

        MOV     R0, #FlpIndex           ; Index pulse interrupt
515 516 517 518
 [ FloppyPodule
        Push    "R3,R4"
        LDR     R3, FlpDACK_TC
        SUB     R3, R3, #&800000
519 520 521
        LDRB    LR, [R3, #8]
        BIC     LR, LR, #bit2
        STRB    LR, [R3, #8]
522 523 524
        ADD     R3, R3, #4
        MOV     R4, #bit2
 ]
Neil Turton's avatar
Neil Turton committed
525 526
        baddr   R1, FlpIndexIRQ         ; Address of handler
        SWI     XOS_ReleaseDeviceVector ; Release vector (R0-R2->R0,V)
527
 [ FloppyPCI
528 529 530 531 532
        LDR     R0, FlpDMAHandle
        CMP     R0, #-1
        SWINE   XDMA_DeregisterChannel
        MOV     R0, #-1
        STR     R0, FlpDMAHandle
533
 ]
534

Neil Turton's avatar
Neil Turton committed
535 536
        MOV     R0, #FlpFintr           ; Floppy IRQ interrupt
        baddr   R1, Flp765IRQ           ; Address of handler
537 538
 [ FloppyPodule
        ADD     R3, R3, #&200000
539 540 541
        LDRB    LR, [R3, #8]
        BIC     LR, LR, #bit4
        STRB    LR, [R3, #8]
542 543
        MOV     R4, #bit4
 ]
Neil Turton's avatar
Neil Turton committed
544
        SWI     XOS_ReleaseDeviceVector ; Release vector (R0-R2->R0,V)
545 546
 [ FloppyPodule
        Pull    "R3,R4"
547 548
 ]
 [ FloppyPCI
549
 ]
Neil Turton's avatar
Neil Turton committed
550 551 552 553 554 555 556 557 558 559 560

        MOV     R0, #TickerV            ; 100Hz vector
        baddr   R1, FlpTickerV          ; Address of handler
        SWI     XOS_Release             ; Release vector (R0-R2->R0,V)

        MOV     R1, #-1                 ; De-Select all drives
        BL      FlpDrvSelect            ; All drives off

        MOV     R0, #0
        BL      FlpFDCcontrol           ; Disable FDC hardware

561 562 563
        CLRV
        Pull    "R0-R2,PC"              ; Restore regs and return - no error

Neil Turton's avatar
Neil Turton committed
564

565
 [ Support1772
Neil Turton's avatar
Neil Turton committed
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583

; Kill the 1772 driver, as per V2.06

FlpDie1772
 [ FileCache
        MOV     R0, #IrqV               ; Interrupt vector
        baddr   R1, IrqVentry           ; Address of our handler
        SWI     XOS_Release             ; Release vector (R0-R2->R0,V)
 ]
        MOV     R0, #TickerV            ; 100Hz vector
        baddr   R1, MyTickerV           ; Address of our handler
        SWI     XOS_Release             ; Release vector (R0-R2->R0,V)

; Deselect all drives

        MOV     R0, #&FF
        BL      SelectFloppy            ; Select no drive

584 585 586
        CLRV
        Pull    "R0-R2,PC"
 ]
Neil Turton's avatar
Neil Turton committed
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613


;-----------------------------------------------------------------------;
; FlpReset                                                              ;
;       Invoked when the module receives a post soft reset service call.;
;       Claims any vectors needed since these will have been destroyed  ;
;       by the reset.                                                   ;
;                                                                       ;
; Input:                                                                ;
;       R11 = -> Instantiation number                                   ;
;       SB  = -> Local storage                                          ;
;       LR  = Return address                                            ;
;                                                                       ;
; Output:                                                               ;
;       None                                                            ;
;                                                                       ;
; Modifies:                                                             ;
;       None                                                            ;
;_______________________________________________________________________;
;
FlpReset ROUT
        Push    "R0-R2,LR"              ; Save caller's regs
 [ Debug10
        DREG    R11,"FlpReset, R11: "
 ]
        MOV     R2, SB                  ; R2-> local storage
        LDR     LR, MachineID           ; Get hardware ID
614
 [ Support1772
Neil Turton's avatar
Neil Turton committed
615 616
        CMPS    LR, #MachHas1772        ; 1772 FDC?
        BEQ     FlpReset1772            ; Yes then jump
617
 ]
Neil Turton's avatar
Neil Turton committed
618 619

        CMPS    LR, #MachHas82710       ; 82C710 FDC?
620
        Pull    "R0-R2,PC",NE           ; No, then exit
Neil Turton's avatar
Neil Turton committed
621 622 623 624 625 626 627 628

; Claim vectors for '765 driver

        MOV     R0, #TickerV            ; Claim 100Hz Vector
        baddr   R1, FlpTickerV          ; Address of handler
        SWI     XOS_Claim               ; Claim vector (R0-R2->R0,V)

        MOV     R0, #FlpFintr           ; Floppy IRQ interrupt
629 630 631 632 633 634 635
 [ FloppyPodule
        Push    "R3,R4"
        LDR     R3, FlpDACK_TC
        SUB     R3, R3, #&600000
        ADD     R3, R3, #4
        MOV     R4, #bit4
 ]
Neil Turton's avatar
Neil Turton committed
636
        baddr   R1, Flp765IRQ           ; Address of handler
637 638 639
 [ Debug10
        DREG    R1,"Flp765IRQ is at "
 ]
Neil Turton's avatar
Neil Turton committed
640 641 642
        SWI     XOS_ClaimDeviceVector   ; Claim vector (R0-R2->R0,V)

        MOV     R0, #FlpIndex           ; Index pulse interrupt
643 644 645 646
 [ FloppyPodule
        SUB     R3, R3, #&200000
        MOV     R4, #bit2
 ]
Neil Turton's avatar
Neil Turton committed
647
        baddr   R1, FlpIndexIRQ         ; Address of handler
648 649 650
 [ Debug10
        DREG    R1,"FlpIndexIRQ is at "
 ]
Neil Turton's avatar
Neil Turton committed
651
        SWI     XOS_ClaimDeviceVector   ; Claim vector (R0-R2->R0,V)
652 653 654
 [ FloppyPodule
        Pull    "R3,R4"
 ]
655 656 657 658 659 660 661 662 663 664 665 666
 [ FloppyPCI
        LDR     R0, FlpDMAHandle
        CMP     R0, #-1
        SWINE   XDMA_DeregisterChannel
        Push    "R3-R5"
        baddr   R0, FlpDMAEnable
        baddr   R1, FlpDMADisable
        baddr   R2, FlpDMAStart
        baddr   R3, FlpDMACompleted
        baddr   R4, FlpDMASync
        ADR     R5, FlpDMAHandlers
        STMIA   R5, {R0-R4}
667
        BL      FlpRegisterDMAChannel
668 669
        Pull    "R3-R5"
 ]
Neil Turton's avatar
Neil Turton committed
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684

; Initialize the hardware

        MOV     R0, #1
        BL      FlpFDCcontrol           ; Enable FDC hardware (if portable)

        MOV     R1, #-1
        BL      FlpDrvSelect            ; Deselect all drives

        baddr   LR, FlpDriveOff
        STR     LR, FlpDrive            ; Drive idle (motor off) state
        BL      Flp765reset             ; Reset '765 FDC

; Enable interrupts for claimed vectors

685 686
        PHPSEI  R1, R2                  ; Disable IRQs

687 688
 [ HAL
      [ FloppyPodule
689 690 691 692 693 694 695 696 697 698 699
        LDR     R0, FlpDACK_TC
        SUB     R0, R0, #&600000
        LDRB    LR, [R0, #8]
        ORR     LR, LR, #bit4
        STRB    LR, [R0, #8]

        SUB     R0, R0, #&200000
        LDRB    LR, [R0, #8]
        ORR     LR, LR, #bit2
        STRB    LR, [R0, #8]

700 701
        ASSERT  FlpFintr = FlpIndex     ; Following code results in a double enable
      ]
702
        Push    "R1,R3,R8,R9"
703 704
        MOV     R0, #FlpFintr
        MOV     R8, #OSHW_CallHAL
705 706
        MOV     R9, #EntryNo_HAL_IRQEnable
        SWI     XOS_Hardware            ; corrupts R0-R3
707
        MOV     R0, #FlpIndex
708 709
        SWI     XOS_Hardware            ; corrupts R0-R3
        Pull    "R1,R3,R8,R9"
710 711 712 713 714 715 716 717 718 719
 |
        MOV     R0, #IOC                ; R0-> IOC registers
        LDRB    LR, [R0, #IOCIRQMSKB]   ; Get IRQB mask bits
        ORR     LR, LR, #IOMD_floppy_IRQ_bit
        STRB    LR, [R0, #IOCIRQMSKB]   ; Enable '765 FDC interrupts

        LDRB    LR, [R0, #IOCIRQMSKA]   ; Get IRQA mask bits
        ASSERT  FlpIndex < 8            ; Index IRQ in IOC IRQA
        ORR     LR, LR, #1:SHL:FlpIndex ; Set Index pulse mask bit
        STRB    LR, [R0, #IOCIRQMSKA]   ; Enable Index pulse interrupts
720 721 722
 ]

        PLP     R1
Neil Turton's avatar
Neil Turton committed
723

724
        Pull    "R0-R2,PC"              ; Restore regs and return
Neil Turton's avatar
Neil Turton committed
725

726
 [ Support1772
Neil Turton's avatar
Neil Turton committed
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746

; Claim vectors for 1772 driver, as per V2.06

FlpReset1772
        MOV     R0, #TickerV            ; Claim 100Hz Vector
        baddr   R1, MyTickerV           ; Address of handler
        SWI     XOS_Claim               ; Claim vector (R0-R2->R0,V)

 [ FileCache
        MOV     R0, #IrqV               ; Claim IRQ vector
        baddr   R1, IrqVentry           ; Address of handler
        SWI     XOS_Claim               ; Claim vector (R0-R2->R0,V)
 ]

; Tidy up drive status flags

        MOV     LR, #0
        STRB    LR, MotorLock           ; Unlock drive
        STRB    LR, FormatFlag          ; In case reset during format

747 748
        Pull    "R0-R2,PC"              ; Return to caller
 ]
Neil Turton's avatar
Neil Turton committed
749 750


751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
 [ FloppyPCI
;-----------------------------------------------------------------------;
; FlpRegisterDMAChannel                                                 ;
;       Invoked when the module receives a post soft reset service call.;
;       Claims any vectors needed since these will have been destroyed  ;
;       by the reset.                                                   ;
;                                                                       ;
; Input:                                                                ;
;       None                                                            ;
;                                                                       ;
; Output:                                                               ;
;       None                                                            ;
;                                                                       ;
; Modifies:                                                             ;
;       R0-R5                                                           ;
;_______________________________________________________________________;
;
FlpRegisterDMAChannel
        Push    "LR"
        MOV     R0, #0
Kevin Bracey's avatar
Kevin Bracey committed
771
        LDR     R1, =DMALC_Floppy
772 773 774 775 776 777 778 779 780 781 782 783
        MOV     R2, #0
        MOV     R3, #1
        ADR     R4, FlpDMAHandlers
        MOV     R5, SB
        SWI     XDMA_RegisterChannel
        MOVVS   R0, #-1
        STR     R0, FlpDMAHandle
        MOV     R0, #-1
        STR     R0, FlpDMATag
        Pull    "PC"
 ]

Kevin Bracey's avatar
Kevin Bracey committed
784 785
        LTORG

786

Neil Turton's avatar
Neil Turton committed
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808
;-----------------------------------------------------------------------;
; FlpBuildDCB                                                           ;
;       Builds a disk control block for the specified operation         ;
;                                                                       ;
; Input:                                                                ;
;       R0 = reason code                                                ;
;               0= verify, 1= read, 2= write sectors                    ;
;               3= verify track, 4= format track,                       ;
;               5= Seek, 6= Restore, 7= Step in, 8= Step out            ;
;               With background flag too                                ;
;       R1 -> DCB to build                                              ;
;       R2 = disc address (sector/track aligned), top 3 bits = drive    ;
;       R3 -> buffer address or scatter list for read/write ops         ;
;       R4 = Max transfer count in bytes, 0= 1 track                    ;
;       R5 -> disk record                                               ;
;       R12 = SB                                                        ;
;                                                                       ;
; Output:                                                               ;
;       R0 = 0, VC, No error                                            ;
;          = Error code, VS                                             ;
;                                                                       ;
; Modifies:                                                             ;
809
;       None                                                            ;
Neil Turton's avatar
Neil Turton committed
810 811 812
;_______________________________________________________________________;
;
FlpOpTable                              ; DiscOp to '765 command lookup
813 814 815
 [ FlpUseVerify
        DCB     FlpCmdVerify            ; 0= verify
 |
Neil Turton's avatar
Neil Turton committed
816
        DCB     FlpCmdRead              ; 0= verify
817
 ]
Neil Turton's avatar
Neil Turton committed
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
        DCB     FlpCmdRead              ; 1= read sectors
        DCB     FlpCmdWrite             ; 2= write sectors
        DCB     FlpCmdReadID            ; 3= read all IDs (track)
        DCB     FlpCmdFormat            ; 4= format track
        DCB     FlpCmdSeek              ; 5= Seek
        DCB     FlpCmdRecal             ; 6= Restore
        DCB     BadComErr               ; 7= StepIn, not supported
        DCB     BadComErr               ; 8= StepOut, not supported
        DCB     BadComErr               ; 9= StepInVerify, not supported
        DCB     BadComErr               ; A= StepOutVerify, not supported
        ASSERT  {PC}-FlpOpTable = UnusedFloppyOp

FlpGPLtable                             ; Mode/sector size to gap3 lookup
        DCB     &00, &0E, &1B, &1B      ; 128-1024 Bytes per sector
        DCB     &99, &C8, &C8, &00      ; 2048-16384 MFM
        GBLA    FlpGPLsize
FlpGPLsize      SETA {PC} - FlpGPLtable ; GPL table size for 1 mode
        DCB     &07, &09, &1B, &47      ; 128-1024
        DCB     &C8, &C8, &00, &00      ; 2048-16384 FM

FlpGPLFtable                            ; Format gap3 lookup
        DCB     &00, &32, &54, &54      ; 128-1024 Bytes per sector
        DCB     &FF, &FF, &FF, &00      ; 2048-16384 MFM
        DCB     &1B, &0C, &3A, &8A      ; 128-1024
        DCB     &FF, &FF, &00, &00      ; 2048-16384 FM

        ALIGN

FlpBuildDCB     ROUT
        Push    "R1,R6-R8,LR"           ; Save caller's regs
        MOV     R7, R1                  ; R7->DCB
        MOV     R8, R0                  ; Save Opcode
Robert Sprowson's avatar
Robert Sprowson committed
850
        AND     R0, R0, #DiscOp_Op_Mask
Neil Turton's avatar
Neil Turton committed
851 852 853 854 855 856 857 858 859 860 861 862
        CMPS    R0, #UnusedFloppyOp     ; Opcode valid?
        MOVHS   R0, #BadComErr          ; No then bad command
        BHS     %FT90                   ; and exit

; Lookup '765 command for requested operation

        baddr   R6, FlpOpTable
        LDRB    R0, [R6, R0]            ; Lookup '765 command code
        TEQS    R0, #BadComErr          ; Illegal?
        BEQ     %FT90                   ; Yes then exit

; Set bgnd
Robert Sprowson's avatar
Robert Sprowson committed
863
        ANDS    LR, R8, #DiscOp_Op_BackgroundOp_Flag
Neil Turton's avatar
Neil Turton committed
864 865 866 867 868 869 870 871
        MOVNE   LR, #&ff
        STRB    LR, [R7, #FlpDCBbgnd]
        MOV     LR, #0
        STR     LR, [R7, #FlpDCBtxbytes]

; Get data rate from disk record

        MOV     R6, R0                  ; Save '765 command code
872
        TEQS    R8, #DiscOp_WriteTrk    ; Format track? (never in background)
Neil Turton's avatar
Neil Turton committed
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
        TEQEQS  R3, #0                  ; And buffer address 0?
        LDREQB  LR, [R4, #DoFormatDensity] ; Yes, get density from format spec
        LDRNEB  LR, [R5, #Density]      ; Else get density from disk rec
        CMPS    LR, #Quad               ; Quad density?
        MOVEQ   R0, #FlpCCR500K         ; Yes
        MOVNE   R0, #-1                 ; Else unknown
        CMPS    LR, #Double             ; Double density?
        MOVEQ   R0, #FlpCCR250K         ; Yes
        CMPS    LR, #8                  ; Octal density?
        MOVEQ   R0, #FlpCCR1000K        ; Yes
        CMPS    LR, #Single             ; Single density?
        MOVEQ   R0, #FlpCCR250K + FlpCmdFM ; Yes
        CMPS    LR, #Double+1           ; Double density 360RPM?
        MOVEQ   R0, #FlpCCR300K         ; Yes

        CMPS    R0, #-1                 ; Unknown density?
        MOVEQ   R0, #BadParmsErr        ; Yes then error, bad parameters
        BEQ     %FT90                   ;   And jump, error

 [ FlpMediaCheck
; Check if clock rate supported by disk/drive, R0= CCR, LR= density

        CMPS    LR, #Double+1           ; Double density (300K) or less
        BLS     %FT10                   ; Yes then jump, all discs do 250K
Robert Sprowson's avatar
Robert Sprowson committed
897
        AND     LR, R8, #DiscOp_Op_Mask
Neil Turton's avatar
Neil Turton committed
898 899 900 901 902 903 904 905 906
        TEQS    LR, #WriteSecsOp        ; Write sectors
        TEQNES  LR, #WriteTrkOp         ; Or write track
        BNE     %FT10                   ; No, then don't check drive density

        MOV     LR, R2, LSR #(32-3)     ; Get drive number
        sbaddr  R1, FlpDrvMap
        LDRB    LR, [R1, LR]            ; Map logical to physical drive
        DrvRecPtr R1, LR                ; Get-> drive record
        LDR     LR, [R1, #DrvFlags]     ; Get drive flags
907
        TSTS    LR, #MiscOp_PollChanged_DensityWorks_Flag   ; Media ID works?
Neil Turton's avatar
Neil Turton committed
908 909
        BEQ     %FT10                   ; No, then jump

910
        TSTS    LR, #MiscOp_PollChanged_HiDensity_Flag      ; Is disc hi density?
Neil Turton's avatar
Neil Turton committed
911 912 913 914 915 916 917 918 919 920 921
        MOVEQ   R0, #BadParmsErr        ; No then bad parameters
        BEQ     %FT90                   ; Error exit
10
 ]
        STRB    R0, [R7, #FlpDCBselect] ; Set data rate
        TSTS    R0, #FlpCmdFM           ; FM mode?
        BICNE   R6, R6, #FlpCmdFM       ; Yes then clear FM bit
        STRB    R6, [R7, #FlpDCBcdb]    ; Write command to DCB

; Check for MultiFS style write track

922
        TEQS    R8, #DiscOp_WriteTrk    ; Format track?
Neil Turton's avatar
Neil Turton committed
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949
        TEQEQS  R3, #0                  ; And buffer address 0?
        BEQ     %FT60                   ; Yes then jump, MultiFS format

; Calculate drive/track/head/sector/amount

        BIC     R6, R2, #DiscBits       ; Remove drive no.
        LDRB    LR, [R5, #SectorSize]   ; Get Log2 sector size
        CMPS    LR, #16                 ; Sector size >= 2^16!?
        MOVHS   R0, #BadParmsErr        ; Yes, bad parameters
        BHS     %FT90                   ; Error exit

        MOV     R0, R6, LSR LR          ; Get sector no.
        SUBS    R6, R6, R0, LSL LR      ; Check address on sector boundary
        MOVNE   R0, #BadParmsErr        ; Error if not
        BNE     %FT90                   ; Error exit

        SUB     LR, LR, #7              ; Convert Log2 size to '765 size
        STRB    LR, [R7, #FlpDCBcdb+5]  ; N parameter

; Divide sector address by sectors per track to find track & sector

        LDRB    R1, [R5, #SecsPerTrk]   ; Sectors per track
        BL      Divide                  ; (R0/R1->R0,R1) R0= track, R1= sector
        LDRB    LR, [R5, #LowSector]    ; Get starting sector no.
        BIC     LR, LR, #bit7 + bit6    ; Discard sides/step
        ADD     R6, R1, LR              ; Real sector no.
        STRB    R6, [R7, #FlpDCBcdb+4]  ; R parameter
Robert Sprowson's avatar
Robert Sprowson committed
950
 [ {FALSE}
Neil Turton's avatar
Neil Turton committed
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965
        DREG    R6, "Sector ",cc
 ]
        LDRB    R1, [R5, #SecsPerTrk]   ; Sectors per track
        ADD     LR, R1, LR              ; Add starting sector no.
        SUB     R6, LR, R6              ; Calc. sectors available
        SUB     LR, LR, #1              ; Make into last sector number
        STRB    LR, [R7, #FlpDCBcdb+6]  ; EOT parameter

; Ensure transfer size <= bytes available on track

        LDRB    R1, [R5, #SectorSize]
        MOV     R6, R6, LSL R1          ; Calc. bytes available on track
        CMPS    R4, #0                  ; 1 track?
        CMPNES  R6, R4                  ; No, want less than remaining track?
        MOVHI   R6, R4                  ; Yes, transfer less
Robert Sprowson's avatar
Robert Sprowson committed
966
        AND     LR, R8, #DiscOp_Op_Mask
967
        CMPS    LR, #DiscOp_ReadSecs    ; Read or verify?
968
        ORRLS   R6, R6, #FlpDCBread     ; Yes then set read bit
Neil Turton's avatar
Neil Turton committed
969 970 971
        MOVLO   LR, #&FF                ; Verify?, set verify flag
        MOVEQ   LR, #0                  ; Else set read flag
        STRLSB  LR, [R7, #FlpDCBcdb+9]  ; Pass flag
Robert Sprowson's avatar
Robert Sprowson committed
972
        AND     LR, R8, #DiscOp_Op_Mask
973 974 975 976
        ASSERT  DiscOp_Verify < DiscOp_ReadTrk
        ASSERT  DiscOp_ReadSecs < DiscOp_ReadTrk
        ASSERT  DiscOp_WriteSecs < DiscOp_ReadTrk
        CMPS    LR, #DiscOp_ReadTrk     ; Data transfer op?
977
        ORRLO   R6, R6, #FlpDCBscatter  ; Yes then use scatter list
978
        TEQS    R8, #DiscOp_ReadTrk     ; Read track ID's?
Neil Turton's avatar
Neil Turton committed
979
        MOVEQ   R6, #64*4               ; Yes maximum 64 ID's
980
        ORREQ   R6, R6, #FlpDCBread     ; And read
Neil Turton's avatar
Neil Turton committed
981 982
        STR     R3, [R7, #FlpDCBbuffer] ; Pass buffer/scatter ptr
        STR     R6, [R7, #FlpDCBlength] ; Save transfer size
Robert Sprowson's avatar
Robert Sprowson committed
983
 [ {FALSE}
Neil Turton's avatar
Neil Turton committed
984 985 986 987 988 989 990 991 992 993
        DREG    R6, " Amount: ",cc
 ]

; Calculate head/track for sequenced or interleaved sides, R0=track

        MOV     LR, R2, LSR #(32-3)     ; Get drive number
        sbaddr  R1, FlpDrvMap
        LDRB    LR, [R1, LR]            ; Map logical to physical drive
        DrvRecPtr R1, LR                ; Get-> drive record
        LDR     LR, [R1, #DrvFlags]     ; Get drive flags
994
        TSTS    LR, #MiscOp_PollChanged_40Track_Flag        ; 40 track drive?
Neil Turton's avatar
Neil Turton committed
995 996 997 998 999
        MOVEQ   R1, #TrksPerSide        ; No, then default tracks per side
        MOVNE   R1, #40                 ; Else 40 tracks per side
        Push    "R1"                    ; Save tracks/drive

        LDRB    LR, [R5, #LowSector]    ; Get LowSector
Robert Sprowson's avatar
Robert Sprowson committed
1000
 [ {FALSE}
Neil Turton's avatar
Neil Turton committed
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027
        DREG    LR, "LowSector ",cc
 ]
        TSTS    LR, #bit6               ; Sequenced sides?
        MOVNE   R6, #1                  ; Yes, assume 1 head
        LDREQB  R6, [R5, #Heads]        ; Else get head count
        TSTS    LR, #bit7               ; 40 track media?
        MOVNE   R1, #40                 ; Yes then tracks per side=40
        MOVS    R6, R6, LSR #1          ; Set C if 1 head, =seq sides
        ANDCC   R6, R0, #1              ; If not seq sides head= LSB of track
        MOVCC   R0, R0, LSR #1          ;   and trk = track/2
        CMPCSS  R0, R1                  ; Else if track> tracks per side
        MOVCS   R6, #1                  ; Then head 1
        SUBCS   R0, R0, R1              ; and track -= tracks per side

; Check for double stepping, LR = LowSector

        STRB    R0, [R7, #FlpDCBcdb+2]  ; C parameter
        STRB    R6, [R7, #FlpDCBcdb+3]  ; H parameter
        Pull    "R1"                    ; Get tracks/drive
        TSTS    LR, #bit7               ; 40 track media?
        CMPNES  R1, #40                 ; And not 40 track drive
        ADDNE   R0, R0, R0              ; Yes, then double track no.

        STRB    R0, [R7, #FlpDCBtrack]  ; Set track # for implied seek
 [ Debug10T
        DREG    R0, " Track ",cc
 ]
Robert Sprowson's avatar
Robert Sprowson committed
1028
 [ {FALSE}
Neil Turton's avatar
Neil Turton committed
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
        DREG    R6, " Head "
 ]

; Setup drive/head bits

        MOV     R0, R2, LSR #32-3       ; Get drive no.
        sbaddr  LR, FlpDrvMap
        LDRB    R0, [LR, R0]            ; Map logical to physical drive
        TEQS    R6, #0                  ; Head 0?
        ORRNE   R0, R0, #FlpCmdHead     ; No then set head bit
        ORR     R0, R0, #bit7           ; Set implied seek bit
        STRB    R0, [R7, #FlpDCBcdb+1]  ; Write drive/head data

; Lookup GPL from FM/MFM mode and sector size

        baddr   R6, FlpGPLtable         ; R6-> lookup table
        LDRB    LR, [R7, #FlpDCBselect] ; Get clock rate
        TSTS    LR, #FlpCmdFM           ; FM mode?
        ADDNE   R6, R6, #FlpGPLsize     ; Yes then bump R6
        LDRB    LR, [R7, #FlpDCBcdb+5]  ; Get N (sector size) 0..
        LDRB    LR, [R6, LR]            ; Lookup GPL
        STRB    LR, [R7, #FlpDCBcdb+7]  ; Write GPL
1051 1052 1053 1054 1055
 [ FlpUseVerify

; Verify takes Sector Count in place of DTL

        LDRB    LR, [R7, #FlpDCBcdb]
1056
        ASSERT  DiscOp_Verify = 0
Robert Sprowson's avatar
Robert Sprowson committed
1057
        TSTS    R8, #DiscOp_Op_Mask
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
        MOVNE   LR, #&ff                ; DTL= &ff
        BNE     %FT45
        LDR     R0, [R7, #FlpDCBlength] ; Transfer length plus flags
        LDRB    R1, [R5, #SectorSize]
        MOV     LR, R0, LSR R1          ; Round down to sectors
        TEQ     R0, LR, LSL R1          ; Was it exact?
        ADDNE   LR, LR, #1              ; If not, round up
        TST     LR, #&ff                ; Avoid 0 (-> 256); round up to 1
        MOVEQ   LR, #1
45
 |
        MOV     LR, #&ff                ; DTL= &ff
 ]
        STRB    LR, [R7, #FlpDCBcdb+8]
Neil Turton's avatar
Neil Turton committed
1072 1073 1074

; Complete the DCB

Robert Sprowson's avatar
Robert Sprowson committed
1075
        AND     LR, R8, #DiscOp_Op_Mask
1076
        CMPS    LR, #DiscOp_ReadTrk     ; Read track?
Neil Turton's avatar
Neil Turton committed
1077 1078 1079 1080 1081 1082 1083 1084
        MOVEQ   LR, #2                  ; Yes, 2 byte ReadID command
        MOVLO   LR, #9                  ; 9 bytes for read/write sectors
        MOVHI   LR, #6                  ; Else 6 byte format track
        STRB    LR, [R7, #FlpDCBcmdLen] ; Write command length

        MOV     R0, #0                  ; No error
        STR     R0, [R7, #FlpDCBpost]   ; No post routine

1085
        CMPS    R8, #DiscOp_WriteTrk    ; Write track?
Neil Turton's avatar
Neil Turton committed
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184
        BNE     %FT90                   ; No then jump


; Old style format operation, R3-> track buffer, R5-> disk record
;----------------------------------------------------------------

        LDR     R0, [R7, #FlpDCBparam]  ; Get C, H, R, N
        LDRB    LR, [R5, #SecsPerTrk]   ; Sectors per track
        STRB    LR, [R7, #FlpDCBcdb+3]  ; Set SC
        MOV     R6, LR, LSL #2          ; Bytes to write
        STR     R6, [R7, #FlpDCBlength]

; Fill track buffer with ID's

        MOV     R6, #ScratchSpace       ; Use system space for track image
        STR     R6, [R7, #FlpDCBbuffer]
50      STR     R0, [R6], #4            ; Write ID to buffer
        ADD     R0, R0, #&10000         ; Next sector no.
        SUBS    LR, LR, #1
        BNE     %BT50                   ; For all sectors

; Set format parameters

        LDRB    R0, [R5, #SectorSize]   ; Get Log2 sector size
        SUB     R0, R0, #7              ; Adjust 0..
        STRB    R0, [R7, #FlpDCBcdb+2]  ; Set N parameter

; Lookup format GPL from FM/MFM mode and sector size

        baddr   R6, FlpGPLFtable        ; R6-> lookup table
        LDRB    LR, [R7, #FlpDCBselect] ; Get clock rate
        TSTS    LR, #FlpCmdFM           ; FM mode?
        MOVNE   LR, #&FF                ; Yes, fill byte= &FF
        MOVEQ   LR, #&5A                ; No, fill byte= &5A
        STRB    LR, [R7, #FlpDCBcdb+5]  ; Set D
        ADDNE   R6, R6, #FlpGPLsize     ; Yes then bump R6
        LDRB    LR, [R6, R0]            ; Lookup GPL
        STRB    LR, [R7, #FlpDCBcdb+4]  ; Write GPL
        MOV     R0, #0                  ; No errors
        B       %FT90                   ; Exit


; MultiFS style format, R4-> disk format specification structure
;---------------------------------------------------------------
60
; Calc. Log2 sector size

        LDR     R0, [R4, #DoFormatSectorSize] ; Get sector size
        TSTS    R0, #&7F                ; Check not odd size
        MOVNE   R0, #BadParmsErr        ; Error if so
        BNE     %FT90                   ; Error exit

        MOV     R1, #7                  ; Log2 of smallest sector size
62      MOVS    LR, R0, LSR R1
        MOVCS   R0, #BadParmsErr        ; Error if not power of 2
        BCS     %FT90                   ; Error exit
        TEQS    LR, #1                  ; R0 = 2^R1?
        ADDNE   R1, R1, #1              ; No then try next power of 2
        BNE     %BT62                   ; And repeat

; Calculate drive/track/head

        BIC     R6, R2, #DiscBits       ; Remove drive no.
        MOV     R0, R6, LSR R1          ; Get sector no.
        SUBS    R6, R6, R0, LSL R1      ; Check address on sector boundary
        MOVNE   R0, #BadParmsErr        ; Error if not
        BNE     %FT90                   ; Error exit

        SUB     R1, R1, #7              ; Convert Log2 size to '765 sector size
        STRB    R1, [R7, #FlpDCBcdb+2]  ; N parameter

; Divide sector address by sectors per track to find track#

        LDRB    R1, [R4, #DoFormatSectorsPerTrk] ; Sectors per track
        STRB    R1, [R7, #FlpDCBcdb+3]  ; SC parameter
        MOV     LR, R1, LSL #2          ; Bytes to write, no scatter list
        STR     LR, [R7, #FlpDCBlength]
        ADD     LR, R4, #DoFormatSectorList ; LR-> ID buffer
        STR     LR, [R7, #FlpDCBbuffer] ; Pass ID buffer ptr
        BL      Divide                  ; (R0/R1->R0,R1) R0= track, R1= sector
        TEQS    R1, #0                  ; Check address on track boundary
        MOVNE   R0, #BadParmsErr        ; Error if not
        BNE     %FT90                   ; Error exit

; Calculate head/track for sequenced or interleaved sides, R0=track

        LDRB    R1, [R4, #DoFormatOptions]
        MOVS    LR, R1, LSR #3          ; Set C if not alt sides
        MOVCCS  LR, R1, LSR #4          ;
        ANDCC   R6, R0, #1              ; If alt sides head= LSB of track
        MOVCC   R0, R0, LSR #1          ;   and trk = track/2
        MOVCS   R6, #0
        LDRCS   LR, [R4, #DoFormatCylindersPerDrive] ; Else get tracks per drive
        CMPCSS  R0, LR                  ; And if track> tracks per drive
        MOVCS   R6, #1                  ; Then head 1
        SUBCS   R0, R0, LR              ; and track -= tracks per drive

; Check for double stepping

1185
        TSTS    R1, #FormatOptDoubleStep   ; Double stepping?
Neil Turton's avatar
Neil Turton committed
1186 1187 1188 1189 1190 1191 1192
        BEQ     %FT70                   ; No then jump

        MOV     LR, R2, LSR #(32-3)     ; Get drive number
        sbaddr  R1, FlpDrvMap
        LDRB    LR, [R1, LR]            ; Map logical to physical drive
        DrvRecPtr R1, LR                ; Get-> drive record
        LDR     LR, [R1, #DrvFlags]     ; Get drive flags
1193
        TSTS    LR, #MiscOp_PollChanged_40Track_Flag        ; 40 track drive?
Neil Turton's avatar
Neil Turton committed
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
        ADDEQ   R0, R0, R0              ; No, then double track no.

70      STRB    R0, [R7, #FlpDCBtrack]  ; Set track # for implied seek
 [ Debug10T
        DREG    r0, "Format on track "
 ]

; Setup drive/head bits

        MOV     R0, R2, LSR #32-3       ; Get drive no.
        sbaddr  LR, FlpDrvMap
        LDRB    R0, [LR, R0]            ; Map logical to physical drive
        TEQS    R6, #0                  ; Head 0?
        ORRNE   R0, R0, #FlpCmdHead     ; No then set head bit
        ORR     R0, R0, #bit7           ; Set implied seek bit
        STRB    R0, [R7, #FlpDCBcdb+1]  ; Write drive/head data

; Complete remainder of DCB

        LDR     LR, [R4, #DoFormatGap3]   ; Lookup GPL
        STRB    LR, [R7, #FlpDCBcdb+4]  ; Write GPL
        LDRB    LR, [R4, #DoFormatFillValue]   ; Lookup fill byte
        STRB    LR, [R7, #FlpDCBcdb+5]  ; Write fill byte

        MOV     LR, #6                  ; 6 byte format track
        STRB    LR, [R7, #FlpDCBcmdLen] ; Write command length
        MOV     R0, #0                  ; No error
        STR     R0, [R7, #FlpDCBpost]   ; No post routine


; Return any error to caller
90
        Pull    "R1,R6-R8,LR"           ; Restore caller's regs
1227 1228
        CMPS    R0, #0                  ; Any error?
        MOVEQ   PC, LR                  ; Return V clear
Neil Turton's avatar
Neil Turton committed
1229 1230 1231 1232 1233 1234 1235 1236
 [ Debug10
        DREG    R0,"!!! FlpBuildDCB ERROR: ",cc
        DREG    R1, " ",cc
        DREG    R2, " ",cc
        DREG    R3, " ",cc
        DREG    R4, " ",cc
        DREG    R5, " "
 ]
1237
        RETURNVS                        ; Return V set == error
Neil Turton's avatar
Neil Turton committed
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253


;-----------------------------------------------------------------------;
; FlpADFSerror                                                          ;
;       Convert '765 status register values to an ADFS error code       ;
;                                                                       ;
; Input:                                                                ;
;       R0 = Error                                                      ;
;       R1 -> DCB                                                       ;
;       R2 = Disc address                                               ;
;       R12 = SB                                                        ;
;                                                                       ;
; Output:                                                               ;
;       R0 = ADFS error code                                            ;
;                                                                       ;
; Modifies:                                                             ;
1254
;       None                                                            ;
Neil Turton's avatar
Neil Turton committed
1255 1256 1257
;_______________________________________________________________________;
;
FlpADFSerror    ROUT
1258 1259 1260 1261 1262 1263
 [ NewErrors
        CMPS    R0, #MaxDiscErr
        BLO     %FT10
 ]
        CMPS    R0, #FlpDiscError       ; Controller status error?
        MOVNE   PC, LR                  ; No then return R0
Neil Turton's avatar
Neil Turton committed
1264 1265 1266 1267 1268 1269 1270 1271 1272

; Get base error code

        LDRB    R0, [R1, #FlpDCBresults] ; Get ST0
 [ Debug10
        DREG    R0,"!!! Controller Error ST0: "
 ]
        TEQS    R0, #&80                ; Invalid command?
        MOVEQ   R0, #BadComErr          ; Yes then bad command error
1273
        MOVEQ   PC, LR                  ; And exit
Neil Turton's avatar
Neil Turton committed
1274 1275 1276

        TEQS    R0, #&90                ; Version command status?
        MOVEQ   R0, #0                  ; Yes then no error
1277
        MOVEQ   PC, LR                  ; And exit
Neil Turton's avatar
Neil Turton committed
1278 1279 1280

        TSTS    R0, #bit4               ; Track 0 fault?
        MOVNE   R0, #FlpErrTrk0Fault    ; Yes then Track 0 error
1281
        MOVNE   PC, LR                  ; And exit
Neil Turton's avatar
Neil Turton committed
1282 1283 1284 1285 1286 1287

; Check ST1

        LDRB    R0, [R1, #FlpDCBresults+1] ; Get ST1
        TSTS    R0, #bit1               ; Write protect?
        MOVNE   R0, #WriteProtErr       ; Yes then error
1288
        MOVNE   PC, LR                  ; And exit
Neil Turton's avatar
Neil Turton committed
1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312

        TSTS    R0, #bit2               ; Sector not found?
        MOVNE   R0, #FlpErrNotFound     ; Yes then error
        BNE     %FT10                   ; Jump if error found

        TSTS    R0, #bit4               ; Overrun
        MOVNE   R0, #FlpErrLost         ; Yes then lost data
        BNE     %FT10                   ; Jump if found

        TSTS    R0, #bit5               ; CRC error?
        MOVNE   R0, #FlpErrCRC          ; Yes then error
        BNE     %FT10                   ; Jump if error found

        TSTS    R0, #bit0               ; Missing address mark?
        MOVNE   R0, #FlpErrNoAM         ; Yes then error
        BNE     %FT10                   ; Jump if error found

; Try ST2 for cause of error

        LDRB    R0, [R1, #FlpDCBresults+2] ; Get ST2
        TSTS    R0, #bit4+bit1          ; Seek error?
        MOVNE   R0, #FlpErrSeekFault    ; Yes then error
        MOVEQ   R0, #FlpErrSoft         ; Else non specific soft error

1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
10
 [ NewErrors
        Push    "R1,LR"
        MOV     R1, R0, LSL #8          ; shift error up to bit 8
        ORR     R1, R1, R2, LSR #(32-3) ; put drive number at bit 0
        BIC     LR, R2, #DiscBits       ; extract address
        ADR     R0, WinIDEErrorNo       ; store in error block
        STMIA   R0, {R1,LR}             ; (borrow IDE workspace)
        MOV     LR, #0
        STR     LR, [R0, #8]
        ORR     R0, R0, #NewDiscErrorBit
        Pull    "R1,PC"                 ; And exit
 |
        ORR     R0, R0, R2, LSR #8      ; Add disc address
        MOV     PC, LR                  ; And exit
 ]
Neil Turton's avatar
Neil Turton committed
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347


;-----------------------------------------------------------------------;
; FlpComplete                                                           ;
;       Calls filecore to acknowledge background completion and to      ;
;       return FIQ's.  Entered in SVC mode                              ;
;                                                                       ;
; Input:                                                                ;
;       R6 = Opcode                                                     ;
;       R12 = SB                                                        ;
;                                                                       ;
; Output:                                                               ;
;       None                                                            ;
;                                                                       ;
; Modifies:                                                             ;
;       None, preserves flags                                           ;
;_______________________________________________________________________;
;
FlpComplete     ROUT
1348
 [ No32bitCode
1349
        Push    "R0,R1,SB,LR"           ; Save caller's regs
1350
 |
1351
        Push    "R0,R1,R4,SB,LR"        ; Save caller's regs
1352
        SavePSR R4
1353 1354 1355
 ]
 [ FloppyPCI
        BL      FlpDMATerminate
1356
 ]
Robert Sprowson's avatar
Robert Sprowson committed
1357
        TSTS    R6, #DiscOp_Op_BackgroundOp_Flag ; Background operation?
Neil Turton's avatar
Neil Turton committed
1358 1359
        BEQ     %FT10                   ; No then jump

Robert Sprowson's avatar
Robert Sprowson committed
1360
; Tell FileCore that background op, if any, has completed
Neil Turton's avatar
Neil Turton committed
1361 1362 1363 1364 1365 1366

        ADD     SB, SB, # :INDEX: FileCorePrivate ; SB-> FileCore save area
        ASSERT  FloppyCallAfter = FileCorePrivate + 4
        MOV     LR, PC                  ; Set return address
        LDMIA   SB, {SB,PC}             ; Set SB & Call [FloppyCallAfter]

1367 1368 1369 1370 1371 1372 1373
 [ No32bitCode
        LDR     SB, [SP, #8]            ; Restore SB, assume R0 TOS
 |
        LDR     SB, [SP, #12]           ; Restore SB, assume R0 TOS
 ]

10
Neil Turton's avatar
Neil Turton committed
1374

1375
 [ :LNOT:FloppyPCI
Neil Turton's avatar
Neil Turton committed
1376 1377
; Release FIQ

1378
        LDR     R0, FiqRelease          ; Get address of release routine
Neil Turton's avatar
Neil Turton committed
1379 1380 1381
        LDR     SB, FileCorePrivate     ; FileCore's private data
        MOV     LR, PC                  ; Set return address
        MOV     PC, R0                  ; Call [FiqRelease]
1382
 ]
Neil Turton's avatar
Neil Turton committed
1383

1384
 [ No32bitCode
1385
        Pull    "R0,R1,SB,PC",,^        ; Restore caller's regs and exit
1386 1387
 |
        RestPSR R4,,f
1388
        Pull    "R0,R1,R4,SB,PC"        ; Restore caller's regs and exit
1389
 ]
Neil Turton's avatar
Neil Turton committed
1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405


;-----------------------------------------------------------------------;
; FlpLowNdataPost                                                       ;
;       Post routine for non-data DCB's submitted by FlpLowLevel        ;
;       Entered from IRQ mode normally                                  ;
;                                                                       ;
; Input:                                                                ;
;       R0 = completion status                                          ;
;       R1-> DCB                                                        ;
;       R12 = SB                                                        ;
;                                                                       ;
; Output:                                                               ;
;       None                                                            ;
;                                                                       ;
; Modifies:                                                             ;
1406
;       None                                                            ;
Neil Turton's avatar
Neil Turton committed
1407 1408 1409 1410 1411
;_______________________________________________________________________;
;
FlpLowNdataPost ROUT
        Push    "R2,LR"                 ; Save caller's regs
 [ FlpPostIrqOn
1412
        WritePSRc SVC_mode,LR,,R2       ; Switch to SVC mode, IRQ's enabled
Neil Turton's avatar
Neil Turton committed
1413
 |
1414
        WritePSRc SVC_mode+I_bit,LR,,R2 ; Switch to SVC mode, IRQ's disabled
Neil Turton's avatar
Neil Turton committed
1415
 ]
1416
        NOP                             ; Delay for mode change
Neil Turton's avatar
Neil Turton committed
1417 1418 1419 1420
        Push    "R2,R6,LR"              ; Save old mode and SVC LR on SVC stack

; Test for errors

1421
        TEQS    R0, #0                  ; An error?
Neil Turton's avatar
Neil Turton committed
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
        LDRNE   R2, FlpFgStatus+4       ; Yes get disc addre