FileCore20 67.6 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
; 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.
;
; >FileCore20

        TTL     "Operations involving disc <-> drive mapping"

19 20
; SBP: 19 Aug 1997: Changed to be aware of the Zones2 field.

Neil Turton's avatar
Neil Turton committed
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 49 50 51 52 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
; Remove conditional assemblies from this file


; ========
; WhatDisc
; ========

; Return the disc record for a given drive
; Create a new record if unknown

; entry: R1 = drive number
; exit:
; IF error V set, R0 result
; ELSE
;        R1 = drive number
;        R2 = disc number
;        R3 = disc rec ptr
;
; Algorithm:
; discstate = PollChange( drive )
; if ( Uncertain:discstate )
;   determine uncertain disc( drive )
; else if ( Empty:discstate )
;   return DriveEmptyErr
; else if ( Bad:discstate )
;   disc bad, return drive error associated with drive
; else
;   disc good, return disc rec associated with drive

WhatDisc ROUT
        Push    "r0,r4,r5,r6,r10,lr"
        MOV     r10, #1
        B       WhatDiscCommon

WhatDiscType
        Push    "r0,r4,r5,r6,r10,lr"
        MOV     r10, #0
        ; Drop through to WhatDiscCommon

WhatDiscCommon
 [ Debug4 :LOR: DebugL

        DREG    R1, "<WhatDiscCommon(Drv=",cc
        DREG    R10, ",Opt=",cc
        DLINE   ")"
 ]

        BL      CheckDriveNumber
        BVS     %FT80

        ; Test the disc's presence in the drive
        MOV     r0, r1
        BL      PollChange      ;(R0->LR)

        ; Get to the drive record
        DrvRecPtr r4,r1

        ; Start with no error
        MOV     r0, #0

        TSTS    lr, #Uncertain
        BEQ     %FT10

        ;Uncertain
 [ DebugL

        DLINE   "Having to mount and determine.."
 ]
        BL      MountDiscOnDrive                ; (r1,r4->V+r0,r1,r2,r4,r5,r6)
        BVS     %FT80
        TEQ     r10, #0
        BLNE    DetermineDiscType               ; (r1,r2,r4,r5,r6->V+r0,r2,r5,r6)
        MOVVC   r3, r5
        MOVVC   r0, #0
        B       %FT80

10
        ; Disc not uncertain, but...

        ; It might be empty...
        TSTS    lr, #Empty
        MOVNE   r0, #DriveEmptyErr
        BNE     %FT80

        ; or, just possibly, it might be good...
        MOV     r2, lr
        DiscRecPtr r3, r2               ; It's good return the disc record


        ; If disc hasn't been identified and we're interested in that....
        TEQ     r10, #0
        LDRNE   lr, [r3, #DiscFlags]
        TSTNE   lr, #DiscNotIdentified
        BEQ     %FT80

 [ DebugL

        DLINE   "Having to determine..."
 ]
        BL      DetermineDiscType
        MOVVC   r3, r5
        MOVVC   r0, #0

80
        BL      SetVOnR0
 [ Debug4 :LOR: DebugL

128
        LDR     lr, [r3, #DiscRecord_Root]
129
        DREG    lr, "RootDir on Exit WhatDisc is: "
130

Neil Turton's avatar
Neil Turton committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
        DREG    R1, "<WhatDisc(Drv=",cc
        DREG    R2, ",Dsc=",cc
        DREG    R3, ",Rec=",cc
        DLINE   ")"
        DebugError "     WhatDisc error"
 ]
        STRVS   r0, [sp]
        Pull    "r0,r4,r5,r6,r10,pc"

; ================
; CheckDriveNumber
; ================
;
; Entry
;   r1 = internal drive number
; Exit
;   V, r0=error

CheckDriveNumber ROUT
        Push    "lr"
        CMP     r1, #4
        LDRLOB  lr, Winnies
        LDRHSB  lr, Floppies
        ADDHS   lr, lr, #4
        CMP     r1, lr
 [ Debug4
        BLO     %FT01

        DREG    r1, "Bad drive specified:"
01
 ]
        MOVHS   r0, #BadDriveErr
        SETV    HS
        Pull    "pc"

        LTORG

; =================
; DetermineDiscType (r1,r2,r4,r5,r6->V+r0,r2,r5,r6)
; =================

; Given that the drive doesn't know what type of disc is in it
; determine what it is. The disc is assumed mounted and certain.

; Entry:
;   r1 = drive number
;   r2 = disc number
;   r4 ->drive record
;   r5 ->disc record
;   r6 = read sectors cache
;
; Exit:
;   V and r0=error is possible
;   r2 = new disc number
;   r5 ->new disc record
;   r6 = read sectors cache discarded
;
; Algorithm:
;
; identify the disc (return error, keep cache)
; Search the disc records for a matching disc (not the same as the one we've got)
; if ( not found )
;   Fill in filetype in disc record
;   use the disc record we were allocated
; else if ( found )
;   detach allocated disc from this drive
;   free allocated disc
;   detach found disc from original drive
;   attach found disc to this drive
;   use found disc record
; If ( identity==FileCore_FloppyDisc or FileCore_HardDisc )
;   StartupFileCoreDisc
; else
;   StartupNonFileCoreDisc

DetermineDiscType ROUT
        Push    "r0,r1,r3,r4,r7,r11,lr"

 [ DebugL

        DLINE   "Determining disc type"
 ]

        MOV     r0, r1
        LDRB    r7, [r4, #DrvFlags]
        BL      IdentifyDisc            ; (r0,r5->r0,r6)
217
        STR     r0, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

        ; Disc now identified
        LDRB    lr, [r5, #DiscFlags]
        BIC     lr, lr, #DiscNotIdentified
        STRB    lr, [r5, #DiscFlags]

        ; If disc is data then don't attempt to match against other discs
        LDR     lr, =FileType_Data
        TEQ     r0, lr
        BNE     %FT02

        ; Disc failed to identify, so, if last disc op was format before
        ; identification then use those parameters
        TST     r7, #LastDiscOpWasFormat
        LDRNEB  lr, [r4, #PrevFormSectorSize]
233
        STRNEB  lr, [r5, #DiscRecord_Log2SectorSize]
Neil Turton's avatar
Neil Turton committed
234
        LDRNEB  lr, [r4, #PrevFormSecsPerTrk]
235
        STRNEB  lr, [r5, #DiscRecord_SecsPerTrk]
Neil Turton's avatar
Neil Turton committed
236
        LDRNEB  lr, [r4, #PrevFormHeads]
237
        STRNEB  lr, [r5, #DiscRecord_Heads]
Neil Turton's avatar
Neil Turton committed
238
        LDRNEB  lr, [r4, #PrevFormDensity]
239
        STRNEB  lr, [r5, #DiscRecord_Density]
Neil Turton's avatar
Neil Turton committed
240
        LDRNEB  lr, [r4, #PrevFormLowSector]
241
        STRNEB  lr, [r5, #DiscRecord_LowSector]
Neil Turton's avatar
Neil Turton committed
242
        LDRNE   lr, [r4, #PrevFormDiscSize]
243
        STRNE   lr, [r5, #DiscRecord_DiscSize]
Neil Turton's avatar
Neil Turton committed
244
 [ BigDisc
245
        LDRNE   lr, [r4, #PrevFormDiscSize2]
246
        STRNE   lr, [r5, #DiscRecord_BigMap_DiscSize2]
Neil Turton's avatar
Neil Turton committed
247 248
 ]

249
 [ DebugLm
250
        DLINE   "Blanking out disc name"
251 252
 ]

Neil Turton's avatar
Neil Turton committed
253 254
        ; Blank out the disc name
        MOV     lr, #0
255 256 257 258 259 260
        ASSERT  ?DiscRecord_DiscName = 10
        ASSERT  DiscRecord_DiscName :MOD: 4 = 2
        STRB    lr, [r5, #DiscRecord_DiscName+0]
        STRB    lr, [r5, #DiscRecord_DiscName+1]
        STR     lr, [r5, #DiscRecord_DiscName+2]
        STR     lr, [r5, #DiscRecord_DiscName+6]
Neil Turton's avatar
Neil Turton committed
261 262 263 264 265 266 267

        B       %FT60
02

 [ DebugLm

        Push    "r0"
268
        LDR     r0, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
269 270
        DREG    r0, "Disc identified...Type=",cc
        ASSERT  DiscId :MOD: 4 = 0
271
        LDR     r0, [r5, #DiscRecord_DiscId]
Neil Turton's avatar
Neil Turton committed
272 273 274
        MOV     r0, r0, ASL #16
        MOV     r0, r0, LSR #16
        DREG    r0, " DiscId=",cc
275
        ADD     r0, r5, #DiscRecord_DiscName
Neil Turton's avatar
Neil Turton committed
276 277 278 279 280 281 282 283 284
        DSTRING r0, " name=",cc
        LDR     r0, [r5, #DiscSize]
        DREG    r0, " DiscSize="
        DLINE   "trying to match against other records..."
        Pull    "r0"
 ]
 [ DebugLi
        Push    "r0"
        DREG    r2, "Mount: Id on Disc ",cc
285
        LDR     r0, [r5, #DiscRecord_DiscId]
Neil Turton's avatar
Neil Turton committed
286 287 288 289 290 291 292 293 294 295 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
        MOV     r0, r0, ASL #16
        MOV     r0, r0, LSR #16
        DREG    r0, " is "
        Pull    "r0"
 ]

        ; Find for a matching disc in the disc records array starting at
        ; the old disc record
        MOV     r7, #1
        B       %FT10

05
        ; Move to next disc record
        ADD     r7, r7, #1
        CMP     r7, #8
        BHS     %FT60

10
        EOR     r3, r7, r2
 [ DebugLm
        DREG    R3, "Matching against record ",cc
 ]
        DiscRecPtr r3, r3
 [ DebugLm
        DREG    R3, " at "
 ]
        LDRB    lr, [r3, #Priority]
        TEQ     lr, #0
 [ DebugLm

        BNE     %FT01
        DLINE   "Record empty"
01
 ]
        BEQ     %BT05           ; Disc record empty

        ; Compare the disc record. The fields which must match are:
323 324
        ; DiscType
        ; Log2SectorSize
Neil Turton's avatar
Neil Turton committed
325 326 327 328 329 330
        ; SecsPerTrk
        ; Heads
        ; Density
        ; LowSector
        ; DiscSize
 [ BigDisc
331
        ; DiscSize2
Neil Turton's avatar
Neil Turton committed
332 333
 ]
        ; DiscId
334 335 336
        ; DiscName
        LDR     r0, [r3, #DiscRecord_DiscType]
        LDR     lr, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
337
        TEQ     r0, lr
Jeffrey Lee's avatar
Jeffrey Lee committed
338
        ASSERT  (DiscRecord_Log2SectorSize :MOD: 4) = 0
339 340 341 342 343
        ASSERT  DiscRecord_SecsPerTrk = DiscRecord_Log2SectorSize+1
        ASSERT  DiscRecord_Heads = DiscRecord_SecsPerTrk+1
        ASSERT  DiscRecord_Density = DiscRecord_Heads+1
        LDREQB  r0, [r3, #DiscRecord_Log2SectorSize]
        LDREQB  lr, [r5, #DiscRecord_Log2SectorSize]
Neil Turton's avatar
Neil Turton committed
344
        TEQEQ   r0, lr
345 346
        LDREQB  r0, [r3, #DiscRecord_LowSector]
        LDREQB  lr, [r5, #DiscRecord_LowSector]
Neil Turton's avatar
Neil Turton committed
347 348
        TEQEQ   r0, lr

349 350
        LDREQ   r0, [r3, #DiscRecord_DiscSize]
        LDREQ   lr, [r5, #DiscRecord_DiscSize]
Neil Turton's avatar
Neil Turton committed
351 352
        TEQEQ   r0, lr
 [ BigDisc
353 354
        LDREQ   r0, [r3, #DiscRecord_BigMap_DiscSize2]
        LDREQ   lr, [r5, #DiscRecord_BigMap_DiscSize2]
Neil Turton's avatar
Neil Turton committed
355 356
        TEQEQ   r0, lr
 ]
357 358 359
        ASSERT  (DiscRecord_DiscId :MOD: 4) = 0
        LDREQ   r0, [r3, #DiscRecord_DiscId]
        LDREQ   lr, [r5, #DiscRecord_DiscId]
Neil Turton's avatar
Neil Turton committed
360 361 362 363 364 365 366 367 368 369 370
        EOREQ   r0, r0, lr
        MOVEQS  r0, r0, ASL #16
 [ DebugLm

        BEQ     %FT01
        DLINE   "Not a match - type, sectsize, lowsector, discsize, discsize2, discid"
01
 ]
        BNE     %BT05

        ; Check the disc name matches
371 372 373
        MOV     r11, #?DiscRecord_DiscName
        ADD     r3, r3, #DiscRecord_DiscName + ?DiscRecord_DiscName
        ADD     r5, r5, #DiscRecord_DiscName + ?DiscRecord_DiscName
Neil Turton's avatar
Neil Turton committed
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
11
        LDRB    lr, [r3, -r11]
        CMP     lr, #" "
        TEQHI   lr, #DeleteChar
        MOVLS   lr, #0
        LDRB    r0, [r5, -r11]
        CMP     r0, #" "
        TEQHI   r0, #DeleteChar
        MOVLS   r0, #0
        MOVLS   r11, #1         ; To terminate early
        TEQ     r0, lr
 [ DebugLm
        DREG    r0, "ChMatch:",cc
        MOV     r0, lr
        DREG    r0, "=?"
 ]
        BNE     %FT12
        SUBS    r11, r11, #1
        BNE     %BT11
12
394 395
        SUB     r3, r3, #DiscRecord_DiscName + ?DiscRecord_DiscName
        SUB     r5, r5, #DiscRecord_DiscName + ?DiscRecord_DiscName
Neil Turton's avatar
Neil Turton committed
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 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 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
 [ DebugLm

        BEQ     %FT01
        DLINE   "Not a match - discname"
01
 ]
        BNE     %BT05
 [ DebugLm

        DLINE   "It's a match"
 ]

        ; Disc found amoungst known discs

        ; Detach allocated disc from drive and free it
        MOV     r0, r2
        BL      FreeDiscRec

        ; Construct parameters for original disc
        EOR     r2, r7, r2      ; number
        MOV     r5, r3          ; record

        ; Detach found disc from its original drive
        MOV     r0, r2
        BL      UnlinkByDisc

        ; Adjust FloppyFlag in old record to match new drive
        ; Also set NeedNewIdFlag so that if this disc has just been seen
        ; by another machine and we now update it the sequence number gets
        ; updated too so that other machine doesn't get confused as to which
        ; disc is changed or not changed.
        LDRB    r0, [r5, #DiscFlags]
 [ DebugL
        DREG    r0, "DiscFlags picked up to be "
 ]
        TST     r1, #4
        BICEQ   r0, r0, #FloppyFlag
        ORRNE   r0, r0, #FloppyFlag
        ORR     r0, r0, #NeedNewIdFlag
 [ DebugL
        DREG    r0, "DiscFlags set to "
 ]
        STRB    r0, [r5, #DiscFlags]

        ; Adjust FcbFloppyFlag in Fcbs attached to old disc to match new drive
        LDR     r11, FirstFcb
        B       %FT25

15
        ; Reject if attached to a different disc
        LDR     r0, [r11, #FcbIndDiscAdd]
        TEQ     r2, r0, LSR #(32-3)
        BNE     %FT20

 [ DebugL
        LDR     r0, [r11, #FcbExtHandle]
        DREG    r0, "Adjusting disc type of file "
 ]

        ; Adjust FcbFlags to match
        LDRB    r0, [r11, #FcbFlags]
        TST     r1, #4
        BICEQ   r0, r0, #FcbFloppyFlag
        ORRNE   r0, r0, #FcbFloppyFlag
        STRB    r0, [r11, #FcbFlags]

20
        ; Next Fcb
        LDR     r11, [r11, #FcbNext]
25
        ; Test for end of Fcb list
        CMP     r11, #-1
        BNE     %BT15

        ; attach found disc to this drive
        STRB    r2, [r4, #DrvsDisc]
        STRB    r1, [r5, #DiscsDrv]

474
  [ DebugL
475 476
        DREG    r1, "************************ DiscsDrv set to ",cc
        DLINE   " in DetermineDiscType *****************************"
477 478
  ]

Neil Turton's avatar
Neil Turton committed
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
        ; Make sure it isn't discarded too soon!
        MOV     r0, r2
        BL      UpdatePriority

        ; If this is a non-FileCore disc poke all clients that they should
        ; update discid on update
        LDRB    r0, [r5, #DiscFlags]
        TST     r0, #DiscNotFileCore
        BEQ     %FT60

        ; Construct full path to root to do FSControl_StampImage

        Push    "r1,r2"

        MOV     r1, #FSControl_StampImage_NextUpdate
494
        ADD     r2, r5, #DiscRecord_DiscName
Neil Turton's avatar
Neil Turton committed
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
        BL      StampImage

        Pull    "r1,r2"

        ; Ignore any error at this point
        CLRV

        ; Drop through to startup disc

60
        ; Found, and have filled in a disc record for this disc
        ;
        ; Register at this moment are:
        ; r1 = drive number
        ; r2 = disc number
        ; r4 ->drive record
        ; r5 ->disc record
        ; r6 = read sectors cache

 [ DebugL

        DLINE   "Starting up disc..."
 ]

519
        LDR     r0, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
        LDR     lr, =FileType_FileCoreFloppyDisc
        TEQ     r0, lr
        LDRNE   lr, =FileType_FileCoreHardDisc
        TEQNE   r0, lr
        BNE     %FT70

        ; It's a FileCore disc
        BL      StartupFileCoreDisc
        B       %FT80

70
        BL      StartupNonFileCoreDisc

80
        ; Disc started (maybe): if error then disc is just so much random data
        ; An error shouldn't occur as the disc wouldn't have identified correctly
 [ DebugL
        BVC     %FT01
        DREG    r0, "Mapping to FileType_Data due to error:"
01
 ]
        LDRVS   r1, =FileType_Data
542
        STRVS   r1, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
543 544 545 546 547 548 549 550 551

        ; Disc in drive is now certain
        LDRVCB  r1, [r4, #DrvsDisc]
        BICVC   r1, r1, #Uncertain
        STRVCB  r1, [r4, #DrvsDisc]

        ; If disc remained unidentified then check read sectors cache for errors
        ; If we find an error then use that
        BVS     %FT90
552
        LDR     r1, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
        LDR     lr, =FileType_Data
        TEQ     lr, r1
        BNE     %FT90
        MOV     r1, r6
        B       %FT87
85
        LDR     r0, [r1, #SectorCache_Error]
        TEQ     r0, #0
 [ DebugL
        BEQ     %FT01
        DREG    r0, "Error found is "
01
 ]
        BLNE    SetV
        BVS     %FT90
        LDR     r1, [r1, #SectorCache_Next]
87
        TEQ     r1, #0
        BNE     %BT85

90
        STRVS   r0, [sp]

        ; Save V state over discard of readsectors cache (don't care if it fails)
577
        SavePSR r7
Neil Turton's avatar
Neil Turton committed
578
        BL      DoSwiDiscardReadSectorsCache
579
        RestPSR r7,,f
Neil Turton's avatar
Neil Turton committed
580

581
 [ DebugL
582
        DREG    R5, "Disc rec ptr now: "
583 584
 ]

Neil Turton's avatar
Neil Turton committed
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
        Pull    "r0,r1,r3,r4,r7,r11,pc"

        LTORG

; ==========
; StampImage
; ==========

; entry
;  r1 = type of stamp image
;  r2 = disc name of image

; exit
;  error possible
StampImage ROUT
        Push    "r0-r4,lr"

        MOV     r4, r1

        ; Construct full path to root to do FSControl_StampImage

        LDR     r1, FS_Title
        BL      strlen
608
        ADD     r3, r3, #?DiscRecord_DiscName + 2 + 1 + 3  ; <FS>::<DiscName>
Neil Turton's avatar
Neil Turton committed
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
        BIC     r3, r3, #3
        SUB     sp, sp, r3

        ; <FS>
        MOV     r0, sp
30
        LDRB    lr, [r1], #1
        STRB    lr, [r0], #1
        TEQ     lr, #0
        BNE     %BT30

        ; ::
        MOV     lr, #":"
        STRB    lr, [r0, #-1]
        STRB    lr, [r0], #1

        ; <DiscName>
626
        MOV     r1, #?DiscRecord_DiscName
Neil Turton's avatar
Neil Turton committed
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
35
        LDRB    lr, [r2], #1
        CMP     lr, #" "
        TEQHI   lr, #DeleteChar
        MOVLS   lr, #0
        MOVLS   r1, #1
        STRB    lr, [r0], #1
        SUBS    r1, r1, #1
        BNE     %BT35

        MOV     lr, #0
        STRB    lr, [r0], #1

        MOV     r0, #FSControl_StampImage
        MOV     r1, sp
        MOV     r2, r4
 [ DebugLi

        DSTRING r1, "FSControl_StampImage(",cc
        DREG    r2, ",",cc
        DLINE   ")"
 ]
        BL      DoXOS_FSControl

        ADD     sp, sp, r3
        STRVS   r0, [sp]
        Pull    "r0-r4,pc"



; ================
; MountDiscOnDrive (r1,r4->V+r0,r1,r2,r4,r5,r6)
; ================
;
; entry
;   r1 = drive number
;   r4 ->drive record
;
; exit
;   V, r0=error is possible
;   r1 = drive number
;   r2 = disc number
;   r4 ->drive record
;   r5 ->disc record
;   r6 = read sectors cache handle
;
; This routine mounts the disc in the given drive as a FileType_Data
; disc which is DiscNotFileCore. The drive's contents are assumed to be
; Uncertain. If the disc Mounts OK and a disc record is found for it,
; then the record will be filled in and attached to the drive.
;
; Algorithm:
; Get the old attached disc record's density
; Mark the FSMap as empty (for old map disc handling)
; Unlink the old disc from this drive
; Unlink defect list from drive
; Allocate a new disc record
; Store the density in the new record
; Set the drive to 'No defect list'
; Mount the disc
; Set the disc type to FileType_Data
; Set the disc to DiscNotFileCore and set FloppyFlag if appropriate
; Attach the record to the drive

MountDiscOnDrive ROUT
        Push    "r0,r3,r8,lr"

 [ DebugL
        DREG    r1, "Mounting ",cc
        DREG    r4, " on record "
 ]

        ; Get density of disc currently (but not for much longer) attached to drive
        LDRB    r8, [r4, #DrvsDisc]
        BIC     r8, r8, #Uncertain
        CMP     r8, #8
        MOVHS   r8, #0                  ; Start at Density=0 if no valid disc previously attached
        BHS     %FT10

 [ DebugL
        DREG    r8, "Old disc attached to drive:"
 ]

        ; Had a disc record attached
        DiscRecPtr lr, r8
712
        LDRB    r8, [lr, #DiscRecord_Density]      ; Density of disc last in this drive
Neil Turton's avatar
Neil Turton committed
713 714 715 716 717 718 719

        ; Mark FsMap for old map disc as Empty
        LDRB    r0, [lr, #DiscFlags]
 [ DebugL
        DREG    r0, "Old disc flags are "
 ]
        TST     r0, #DiscNotFileCore
720
        LDREQB  r0, [lr, #DiscRecord_NZones]
Neil Turton's avatar
Neil Turton committed
721
        TEQEQ   r0, #0
722
 [ BigMaps
723 724
        LDREQB  r0, [lr, #DiscRecord_BigMap_NZones2]
        TEQEQ   r0, #0
725 726 727 728 729 730
 ]
 [ DynamicMaps
        LDREQ   r0, [r4, #DrvsFsMapFlags]
        ORREQ   r0, r0, #EmptyFs
        STREQ   r0, [r4, #DrvsFsMapFlags]
 |
Neil Turton's avatar
Neil Turton committed
731 732 733
        LDREQ   r0, [r4, #DrvsFsMap]
        ORREQ   r0, r0, #EmptyFs
        STREQ   r0, [r4, #DrvsFsMap]
734
 ]
Neil Turton's avatar
Neil Turton committed
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756


        ; Unlink the old disc from this drive
        MOV     r0, r1
        BL      UnlinkByDrive

10
 [ DebugL
        DREG    r8, "Going to use initial density "
 ]

        ; Find a disc record
        BL      FindDiscRec
        BVS     %FT90
        MOV     r5, r3

 [ DebugL
        DREG    r2, "Found disc record ",cc
        DREG    r5, " at "
 ]

        ; Clear out fields which would cause problems if not cleared out:
757
        ; IdLen, Log2bpmb, Skew, BootOpt, Zones, ZoneSpare, DiscId, DiscName
Neil Turton's avatar
Neil Turton committed
758
        MOV     lr, #0
759 760 761 762 763
        ASSERT  DiscRecord_IdLen :MOD: 4 = 0
        ASSERT  DiscRecord_Log2bpmb = DiscRecord_IdLen + 1
        ASSERT  DiscRecord_Skew = DiscRecord_Log2bpmb + 1
        ASSERT  DiscRecord_BootOpt = DiscRecord_Skew + 1
        STR     lr, [r5, #DiscRecord_IdLen]
Neil Turton's avatar
Neil Turton committed
764

765
        STRB    lr, [r5, #DiscRecord_NZones]
766
 [ BigMaps
767
        STRB    lr, [r5, #DiscRecord_BigMap_NZones2]
768
 ]
769 770
        STRB    lr, [r5, #DiscRecord_ZoneSpare]
        STRB    lr, [r5, #DiscRecord_ZoneSpare+1]
Neil Turton's avatar
Neil Turton committed
771

772 773 774
        ASSERT  DiscRecord_DiscId :MOD: 4 = 0
        ASSERT  DiscRecord_DiscName = DiscRecord_DiscId + 2
        STR     lr, [r5, #DiscRecord_DiscId]
Neil Turton's avatar
Neil Turton committed
775
 [ BigDisc
776
        STR     lr, [r5,#DiscRecord_BigMap_DiscSize2]
Neil Turton's avatar
Neil Turton committed
777
 [ BigShare
778
        STR     lr, [r5,#DiscRecord_BigMap_ShareSize]
Neil Turton's avatar
Neil Turton committed
779 780 781
 ]
 ]

Neil Turton's avatar
Neil Turton committed
782 783 784 785 786 787

        ; Set up a sensible pre-guess at the RootDir
 [ DebugL
        DREG    r2, "Setting RootDir from "
 ]
        MOV     lr, r2, ASL #32-3
788
        STR     lr, [r5, #DiscRecord_Root]
Neil Turton's avatar
Neil Turton committed
789 790

        ; Fill in old density
791
        STRB    r8, [r5, #DiscRecord_Density]
Neil Turton's avatar
Neil Turton committed
792 793 794 795 796 797 798 799 800 801 802 803

        ; Mark drive as having no defect list
        LDRB    r0, [r4, #DrvFlags]
        BIC     r0, r0, #HasDefectList
        STRB    r0, [r4, #DrvFlags]

; as a hack to try to get floppies to mount - set DiscSize2 to 0

        ; Mount the disc
        Push    "r2,r4"
        MOVS    r2, r1, ASL #(32-3)
        EOR     r2, r2, #bit31          ; Convert to external drive numbering
804
        MOV     r3, #BadPtr             ; Bad address just in case the driver gets frisky
Neil Turton's avatar
Neil Turton committed
805 806 807 808 809 810 811 812 813 814 815 816
        MOV     r4, #0
        LDRPL   r0, WinnieProcessBlk
        MOVPL   r6, #WinnieLock
        LDRMI   r0, FloppyProcessBlk
        MOVMI   r6, #FloppyLock
        BL      Mount
        Pull    "r2,r4"
        BVS     %FT90

        ; Set disc record to data
        ; And attach disc and drive together
 [ DebugL
817
        LDR     r0, [r5, #DiscRecord_Log2SectorSize]
Neil Turton's avatar
Neil Turton committed
818 819 820 821 822 823 824 825 826 827 828
        DREG    r0, "Mounted OK - parameters from mount are:"
 ]
        MOV     r0, #DiscNotFileCore
        TST     r1, #bit2
        ORRNE   r0, r0, #FloppyFlag
        ORR     r0, r0, #DiscNotIdentified
 [ DebugL
        DREG    r0, "DiscFlags set to "
 ]
        STRB    r0, [r5, #DiscFlags]
        LDR     r0, =FileType_Data
829
        STR     r0, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
830 831 832 833 834
        MOV     r0, #0
        STRB    r0, [r5, #Priority]
        STRB    r0, [r5, #DiscUsage]
        STRB    r1, [r5, #DiscsDrv]
 [ DebugL
835 836
        DREG    r1, "************************* DiscsDrv set to",cc
        DLINE   " in MountDiscOnDrive *************************"
Neil Turton's avatar
Neil Turton committed
837 838 839
        DREG    r2, "DrvsDisc set to "
 ]
        STRB    r2, [r4, #DrvsDisc]
840 841 842 843
        ASSERT  DiscRecord_DiscName = DiscRecord_DiscId + 2
        STR     r0, [r5, #DiscRecord_DiscId]
        STR     r0, [r5, #DiscRecord_DiscName+2]
        STR     r0, [r5, #DiscRecord_DiscName+6]
Neil Turton's avatar
Neil Turton committed
844

845
 [ BigDir
846 847 848 849
        LDR     lr, [r5, #DiscRecord_Root]
        BIC     lr, lr, #DiscBits
        ORR     lr, lr, r2, LSL #(32-3)
        STR     lr, [r5, #DiscRecord_Root]
850 851
 ]

Neil Turton's avatar
Neil Turton committed
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 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 950
        ; Make sure this disc is thought to be used
        MOV     r0, r2
        BL      UpdatePriority

90
        STRVS   r0, [sp]
        Pull    "r0,r3,r8,pc"

; ===================
; StartupFileCoreDisc
; ===================

; Entry
;   r1 = drive number
;   r2 = disc number
;   r4 ->drive record
;   r5 ->disc record
;   r6 = read sectors cache
;
; Exit
;   r6 = new read sectors cache
;
; This routine initialises the DriveRec given that the disc is a FileCore disc
;

StartupFileCoreDisc ROUT
        Push    "r0-r5,r7-r11,lr"

 [ DebugL

        DLINE   "Starting up filecore disc"
        DREG    r1, "Drive=", cc
        DREG    r4, " at "
        DREG    r2, "Disc=",cc
        DREG    r5, " at "
        DREG    r6, "Cache = "

        LDRB    r11, [r5, #DiscFlags]
        DREG    r11, "Disc flags are "
 ]

        BL      ReadDefectList
 [ DebugL
        LDRB    r11, [r5, #DiscFlags]
        DREG    r11, "Disc flags are "
 ]


        BLVC    AdjustFsSpace
 [ DebugL
        LDRB    r11, [r5, #DiscFlags]
        DREG    r11, "Disc flags are "
 ]

        BLVC    ReadFsMap
        BVS     %FT90

        ; Make sure disc is FileCore
        LDRB    r11, [r5, #DiscFlags]
        TST     r11, #DiscNotFileCore
        BIC     r11, r11, #DiscNotFileCore
        ORRNE   r11, r11, #NeedNewIdFlag        ; Set NeedNewId if it is a fresh FileCore disc
 [ DebugL
        DREG    r11, "DiscFlags set to "
 ]
        STRB    r11, [r5, #DiscFlags]

90
        STRVS   r0, [sp]
 [ DebugL

        DLINE   "Starting of FileCore disc done"
        BVC     %FT01
        DREG    r0, "Error produced:"
01
 ]
        Pull    "r0-r5,r7-r11,pc"

; ==============
; ReadDefectList
; ==============

; Entry
;   r1 = drive number
;   r4 ->drive record
;   r5 ->disc record
;   r6 = read sectors cache
;
; Exit
;   V, r0=error is possible
;   r6 = new read sectors cache

; Reads DefectList, sets HasDefectList
; Copies Zones, ZoneSpare, BitSize to disc record

ReadDefectList ROUT
        Push    "r0-r4,r11,lr"

        LDR     lr, =FileType_FileCoreHardDisc
951
        LDR     r0, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
        TEQ     r0, lr
        BNE     %FT20

 [ DebugL

        DLINE   "It's a winnie...read defect list"
 ]

        ; It's a FileCore hard disc, read the bad block list
        LDR     r3, DefectSpace
        ADD     r3, r3, SB
        ASSERT  SzDefectList = (1 :SHL: 9)
        ADD     r3, r3, r1, ASL #9
        MOV     r4, #SzDefectList
        MOV     r2, r1, ASL #(32-3)
967
        MOV     r1, #DiscOp_CachedReadSecs
Neil Turton's avatar
Neil Turton committed
968
 [ BigDisc
969 970 971 972 973
        Push    "R10,R11"
        LDRB    r11, [r5, #DiscRecord_Log2SectorSize]           ; get sector size
        MOV     r10,#DefectListDiscAdd
        ORR     r2,r2,r10,LSR r11
        Pull    "R10,R11"
Neil Turton's avatar
Neil Turton committed
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
 |
        ORR     r2, r2, #DefectListDiscAdd
 ]
        BL      RetryDriveOp
        BVS     %FT90                   ; Bog it, defect list didn't read

        ; Assume defect list is OK as it must have been checked in identifying the disc

        ; Restore r1,r2 and r4 (and r3 too, but don't care about that)
        LDMIB   sp, {r1-r4}

        ; Flag against the drive that it has a bad block list
        LDRB    r0, [r4, #DrvFlags]
        ORR     r0, r0, #HasDefectList
        STRB    r0, [r4, #DrvFlags]

        ; Get address of disc record in bad block area
        LDR     r3, DefectSpace
        ADD     r3, r3, SB
        ASSERT  SzDefectList = (1 :SHL: 9)
        ADD     r3, r3, r1, ASL #9
        ADD     r3, r3, #DefectStruc

        ; Copy zones to our disc record
998 999
        LDRB    r0, [r3, #DiscRecord_NZones]
        STRB    r0, [r5, #DiscRecord_NZones]
1000
 [ BigMaps
1001 1002
        LDRB    r0, [r3, #DiscRecord_BigMap_NZones2]
        STRB    r0, [r5, #DiscRecord_BigMap_NZones2]
1003
 ]
Neil Turton's avatar
Neil Turton committed
1004 1005 1006

        ; If zones <> 0, then copy ZoneSpare and BitSize too for E format
        TEQ     r0, #0
1007 1008 1009 1010 1011 1012
        LDRNEB  r0, [r3, #DiscRecord_ZoneSpare]
        STRNEB  r0, [r5, #DiscRecord_ZoneSpare]
        LDRNEB  r0, [r3, #DiscRecord_ZoneSpare+1]
        STRNEB  r0, [r5, #DiscRecord_ZoneSpare+1]
        LDRNEB  r0, [r3, #DiscRecord_Log2bpmb]
        STRNEB  r0, [r5, #DiscRecord_Log2bpmb]
Neil Turton's avatar
Neil Turton committed
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031

 [ DebugL

        DLINE   "Defect list has read OK"
 ]
        B       %FT80

20
 [ DebugL

        DLINE   "It's a floppy...no defect list to read"
 ]

 [ BigDisc
        ; It's a FileCore floppy disc, read byte 2 to test bit 7 of it
        SUB     sp, sp, #4
        MOV     r3, sp                  ; read to the stack
        MOV     r4, #4                  ; 4 bytes to read
        MOV     r2, r1, ASL #(32-3)
1032
        MOV     r1, #DiscOp_CachedReadSecs
Neil Turton's avatar
Neil Turton committed
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
        BL      RetryDriveOp
        LDRB    r0, [sp,#2]
        ADD     sp, sp, #4
 |
        ; It's a FileCore floppy disc, read byte 2 to test bit 7 of it
        SUB     sp, sp, #4
        MOV     r3, sp                  ; read to the stack
        MOV     r4, #1                  ; 1 byte to read
        MOV     r2, r1, ASL #(32-3)
        ADD     r2, r2, #2              ; byte 2
1043
        MOV     r1, #DiscOp_CachedReadSecs
Neil Turton's avatar
Neil Turton committed
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
        BL      RetryDriveOp
        LDRB    r0, [sp]
        ADD     sp, sp, #4
 ]

        ; Restore r1,r2 and r4 (and r3 too, but don't care about that)
        LDMIB   sp, {r1-r4}

        BVS     %FT30                   ; Byte 2 didn't read, but it is a floppy, hence it must be an E floppy

        ; Might be E format
        TST     r0, #bit7
        BNE     %FT30

        ; It's a D or L format disc
        MOV     r0, #0
1060
        STRB    r0, [r5, #DiscRecord_NZones]
1061
 [ BigMaps
1062
        STRB    r0, [r5, #DiscRecord_BigMap_NZones2]
1063
 ]
Neil Turton's avatar
Neil Turton committed
1064 1065 1066 1067 1068 1069 1070
        B       %FT40

30
        CLRV    ; To make sure V from RetryDriveOp above doesn't cause problems

        ; It's an E format disc - frig up some values which work to read the map
        MOV     r0, #1
1071
        STRB    r0, [r5, #DiscRecord_NZones]
Neil Turton's avatar
Neil Turton committed
1072
        MOV     r0, #0
1073
 [ BigMaps
1074
        STRB    r0, [r5, #DiscRecord_BigMap_NZones2]
1075
 ]
1076 1077 1078
        STRB    r0, [r5, #DiscRecord_ZoneSpare]
        STRB    r0, [r5, #DiscRecord_ZoneSpare+1]
        STRB    r0, [r5, #DiscRecord_Log2bpmb]
Neil Turton's avatar
Neil Turton committed
1079 1080 1081 1082 1083 1084 1085 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

40
        ; It's a floppy - clear hasdefectlist and set need new id and floppy flag
        LDRB    r0, [r4, #DrvFlags]
        BIC     r0, r0, #HasDefectList
        STRB    r0, [r4, #DrvFlags]

80
        ; DefectList read OK

90
        STRVS   r0, [sp]
        Pull    "r0-r4,r11,pc"

; =============
; AdjustFsSpace
; =============

; Entry
;   r1 = drive number
;   r4 ->drive record
;   r5 ->disc record
;
; Exit
;   V, r0=error possible

; For the given disc adjust the FsSpace to be enough for the FsMap of an
; assumed FileCore disc.

AdjustFsSpace ROUT
        Push    "r0,r2,r3,r7-r10,lr"

        ; Work out the map's size
1112
        LDRB    r9, [r5, #DiscRecord_NZones]
1113
 [ BigMaps
1114 1115
        LDRB    r7, [r5, #DiscRecord_BigMap_NZones2]
        ADD     r9, r9, r7, LSL #8
1116
 ]
1117
        LDRB    r7, [r5, #DiscRecord_Log2SectorSize]
Neil Turton's avatar
Neil Turton committed
1118 1119 1120
        MOVS    r8, r9, LSL r7
        MOVEQ   r8, #SzOldFs

1121
 [ DynamicMaps
1122 1123
        LDR     lr, [r4, #DrvsFsMapSize]; get size of the free space map
        TEQS    r8, lr                  ; is space allocated for map right size ?
1124
 |
Neil Turton's avatar
Neil Turton committed
1125 1126 1127 1128 1129 1130 1131 1132
        ; Get the map space for this drive and test the required
        ; map space against it
        ASSERT  FloppySizes = WinnieSizes+4
        sbaddr  r10, WinnieSizes
        ADD     r10, r10, r1
        LDRB    lr, [r10]

        TEQS    r8, lr, LSL #8          ;is space claimed for map right size ?
1133 1134
 ]

Neil Turton's avatar
Neil Turton committed
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
 [ DebugL

        BNE     %FT01
        DLINE   "Stored map size and disc map size match"
        B       %FT02
01
        DLINE   "Stored and disc map map sizes differ"
        DREG    r8, "Disc:", cc
        MOV     r2, lr
        DREG    r2, " and map is:"
02
 ]
        ; Pick up the old map block, and skip replacing it if it's the right size
1148 1149 1150
 [ DynamicMaps
        LDR     r2, [r4, #DrvsFsMapAddr]
 |
Neil Turton's avatar
Neil Turton committed
1151 1152
        LDR     r2, [r4, #DrvsFsMap]
        BIC     r2, r2, #HiFsBits
1153
 ]
Neil Turton's avatar
Neil Turton committed
1154 1155 1156 1157
        BEQ     %FT20

        ; Must change stored map for something a different size

1158 1159
 [ DynamicMaps

1160
        ; find the actual allocated size
1161

1162
        Push    "R1, R3-r8"
1163

1164 1165 1166
        MOV     R0, #2
        LDR     R1, [R4, #DrvsFsMapArea]
        BL      OnlyXOS_DynamicArea             ; get the dynamic area size in bytes
1167 1168


1169
        Pull    "R1, R3-R8"
1170

1171 1172 1173
        LDRVS   lr, [r4, #DrvsFsMapFlags]       ; set the 'map memory error' bit
        ORRVS   lr, lr, #MemErrorFs             ;
        STRVSB  lr, [r4, #DrvsFsMapFlags]
1174

1175 1176
        BVS     %FT90
        ; work out the size the area must grow or shrink by
1177

1178
        ADD     r3, r8, r8, LSR #8              ; new size of wotsit
1179

1180
        Push    "R1"
1181

1182
        SUB     R1, R3, R2                      ; amount to change size by
1183
 [ DebugL
1184
        DREG    R1, "Area size to change by: "
1185
 ]
1186 1187
        LDR     R0, [R4, #DrvsFsMapArea]        ; area number
        BL      OnlyXOS_ChangeDynamicArea
1188 1189

 [ DebugL
1190 1191
        BVC     %FT01
        DebugError      "AdjustFsSpace - OS_ChangeDynamicarea error "
1192 1193 1194
01
 ]

1195 1196 1197 1198
        LDR     lr, [r4, #DrvsFsMapFlags]       ; set/clear the 'map memory error' bit
        ORRVS   lr, lr, #MemErrorFs             ;
        BICVC   lr, lr, #MemErrorFs             ;
        STR     lr, [r4, #DrvsFsMapFlags]       ;
1199

1200
        Pull    "R1"
1201

1202
        BVS     %FT90                           ; error!
1203

1204
        ; here, new space allocation is correct, so we're cool
1205

1206
        STR     r8, [R4, #DrvsFsMapSize]                ; store the new size
1207 1208

20
1209 1210 1211 1212
        TEQ     r9, #0
        MOVEQ   lr, #EmptyFs
        MOVNE   lr, #0
        STR     lr, [r4, #DrvsFsMapFlags]               ; store new flags0
1213 1214 1215

 | ; ELSE              (NOT Dynamic maps!)

Neil Turton's avatar
Neil Turton committed
1216 1217 1218 1219
        ; Cancel storage before freeing it - saves embarasment on Reset
        MOV     lr, #0
        STRB    lr, [r10]

1220

Neil Turton's avatar
Neil Turton committed
1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
        ; Free the storage
        MOV     r3, #0
        STR     r3, [r4, #DrvsFsMap]    ; Clear out to stop attempt to Free if problems
        TEQ     r2, #0
        MOVNE   r0, #ModHandReason_Free
        BLNE    OnlyXOS_Module  ;return old map buffer
 [ DebugL

        BVC     %FT01
        DLINE   "Discard map free error"
01
 ]
        ; 2 options here, soldier on using a broken heap, or:
        BVS     %FT90

        ; Claim enough for the zones, and one byte per zone
        ; (This assumes sectors size >= 256 bytes)
        ADD     r3, r8, r8, LSR #8      ;size needed
        MOV     r0, #ModHandReason_Claim
 [ DebugL
        DREG    r3, "Claim ",cc
        DREG    r8, " for map of size "
 ]
        BL      OnlyXOS_Module  ;claim workspace
 [ DebugL

        BVC     %FT01
        DLINE   "Map claim failed"
        B       %FT02
01
        DREG    r2, "Map claimed is at "
02
 ]
        BVS     %FT90           ; Bog it, didn't get space for the map!

20
        ; Flag old map as EmptyFs and attach memory to drive record
        TEQ     r9, #0
        ORREQ   r2, r2, #EmptyFs
        STR     r2, [r4, #DrvsFsMap]

        ; Record the map size we've now got, do this late
        ; as we wouldn't want to try using a duff map after Reset
        MOV     lr, r8, LSR #8
        STRB    lr, [r10]

1267 1268
 ] ;ENDIF DynamicMaps

Neil Turton's avatar
Neil Turton committed
1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
90
        STRVS   r0, [sp]
        Pull    "r0,r2,r3,r7-r10,pc"

; =========
; ReadFsMap
; =========

; Entry
;   r1 = drive number
;   r2 = disc number
;   r4 ->drive record
;   r5 ->disc record
;   r6 = read sectors cache
;
; Exit
;   V, r0=error possible
;   r6 = new read sectors cache

; Read the right sort of FsMap for the disc. Assumes the FsMap is OK if it reads as
; it has already been checked by the identification process. These fields are set if
1290
; necessary:IdLen, Log2bpmb, Skew, BootOpt, ZoneSpare, RootDir. These flags are adjusted:
Neil Turton's avatar
Neil Turton committed
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
; OldDirFlag, OldMapFlag, AltMapFlag, EmptyFs.

ReadFsMap ROUT
        Push    "r0-r4,r7,r9,r11,lr"

        ; Adjust DiscFlags in r11
        LDRB    r11, [r5, #DiscFlags]
 [ DebugL
        DREG    r11, "DiscFlags picked up to be "
 ]

1302
 [ BigMaps
1303 1304 1305 1306 1307
        LDRB    r7, [r5, #DiscRecord_BigMap_NZones2]
        LDRB    r9, [r5, #DiscRecord_NZones]
        ADD     r9, r9, r7, LSL #8
        ; Determine old/new-ness of map by number of zones recorded
        LDRB    r7, [r5, #DiscRecord_Log2SectorSize]
1308
 |
1309 1310
        ; Keep DiscRecord_Log2SectorSize in r7
        LDRB    r7, [r5, #DiscRecord_Log2SectorSize]
Neil Turton's avatar
Neil Turton committed
1311 1312

        ; Determine old/new-ness of map by number of zones recorded
1313
        LDRB    r9, [r5, #DiscRecord_NZones]
1314
 ]
Neil Turton's avatar
Neil Turton committed
1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
        TEQ     r9, #0
        BNE     %FT30

        ; Old map
 [ DebugL

        DLINE   "old map"
 ]

        ; Read map
1325 1326 1327
 [ DynamicMaps
        LDR     r3, [r4, #DrvsFsMapAddr]
 |
Neil Turton's avatar
Neil Turton committed
1328 1329
        LDR     r3, [r4, #DrvsFsMap]
        BIC     r3, r3, #HiFsBits
1330
 ]
Neil Turton's avatar
Neil Turton committed
1331 1332
        MOV     r4, #SzOldFs
        MOV     r2, r1, ASL #(32-3)
1333
        MOV     r1, #DiscOp_CachedReadSecs
Neil Turton's avatar
Neil Turton committed
1334 1335 1336 1337 1338 1339
        BL      RetryDriveOp
        BVS     %FT90                   ; Bog it, map didn't read

        ; Restore r1,r2 and r4 (and r3 too, but don't care about that)
        LDMIB   sp, {r1-r4}

1340 1341 1342 1343 1344
 [ DynamicMaps
        ; Map is now in
        LDR     r3, [r4, #DrvsFsMapFlags]
        BIC     r3, r3, #NewHiFsBits
        STR     r3, [r4, #DrvsFsMapFlags]
1345
        LDR     r3, [r4, #DrvsFsMapAddr]
1346
 |
Neil Turton's avatar
Neil Turton committed
1347 1348 1349 1350
        ; Map is now in
        LDR     r3, [r4, #DrvsFsMap]
        BIC     r3, r3, #HiFsBits
        STR     r3, [r4, #DrvsFsMap]
1351
 ]
Neil Turton's avatar
Neil Turton committed
1352 1353 1354 1355 1356

        ; Set OldMapFlag, OldDirFlag and AltMapFlag as appropriate:
        ; OldMapFlag set
        ; AltMapFlag clear
        ; OldDirFlag set only if Floppy, 256 bytes sectors and 16 sectors per track
1357
        LDR     lr, [r5, #DiscRecord_DiscType]
Neil Turton's avatar
Neil Turton committed
1358 1359
 [ BigDisc
        LDR     r0, FileType_FileCoreFloppyDiscStore
1360
        B       %FT01
Neil Turton's avatar
Neil Turton committed
1361
FileType_FileCoreFloppyDiscStore
1362
        DCD     FileType_FileCoreFloppyDisc
Neil Turton's avatar
Neil Turton committed
1363 1364 1365 1366 1367 1368 1369

01
 |
        LDR     r0, =FileType_FileCoreFloppyDisc
 ]
        TEQ     lr, r0
        TEQEQ   r7, #8          ; 256 byte sectors
1370
        LDREQB  lr, [r5, #DiscRecord_SecsPerTrk]
Neil Turton's avatar
Neil Turton committed
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
        TEQEQ   lr, #16         ; 16 sectors per track
 [ DebugL
        DREG    r11, "Adjusting DiscFlags from "
 ]
        ORREQ   r11, r11, #OldDirFlag
        BICNE   r11, r11, #OldDirFlag
        ORR     r11, r11, #OldMapFlag
        BIC     r11, r11, #AltMapFlag

        ; Set RootDir:
        ; Location &200 (L_Root) on old dir discs, &400 (D_Root) on new dir discs
        MOVEQ   r0, #L_Root
        MOVNE   r0, #D_Root
        ORR     r0, r0, r2, ASL #32-3
 [ DebugL
1386
        DREG    r0, "Setting RootDir to (FileCore20, 1394) "
Neil Turton's avatar
Neil Turton committed
1387
 ]
1388
        STR     r0, [r5, #DiscRecord_Root]
Neil Turton's avatar
Neil Turton committed
1389 1390

        ; Zap these fields to 0:
1391 1392 1393 1394 1395 1396 1397
        ASSERT  DiscRecord_IdLen :MOD: 4 = 0
        ASSERT  DiscRecord_Log2bpmb=DiscRecord_IdLen+1
        ASSERT  DiscRecord_Skew=DiscRecord_Log2bpmb+1
        ASSERT  DiscRecord_BootOpt=DiscRecord_Skew+1
        ASSERT  DiscRecord_NZones=9
        ASSERT  DiscRecord_ZoneSpare=10
        ; IdLen is critical because it determins the buffer size used for open files
Neil Turton's avatar
Neil Turton committed
1398
        MOV     r0, #0
1399 1400 1401
        STR     r0, [r5, #DiscRecord_IdLen]
        STRB    r0, [r5, #DiscRecord_ZoneSpare+0]
        STRB    r0, [r5, #DiscRecord_ZoneSpare+2]
Neil Turton's avatar
Neil Turton committed
1402 1403

        ; Set BootOpt from map
1404 1405 1406
 [ DynamicMaps
        LDR     r0, [r4, #DrvsFsMapAddr]
 |
Neil Turton's avatar
Neil Turton committed
1407 1408
        LDR     r0, [r4, #DrvsFsMap]
        BIC     r0, r0, #HiFsBits
1409
 ]
Neil Turton's avatar
Neil Turton committed
1410
        LDRB    r0, [r0, #OldBoot]
1411
        STRB    r0, [r5, #DiscRecord_BootOpt]
Neil Turton's avatar
Neil Turton committed
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428

        B       %FT80

30
        ; New map
 [ DebugL

        DLINE   "new map"
 ]

        ; Initialise the zone flags in the map to not valid
        MOV     r0, #0
        BL      SetAllZoneFlags

        BL      MapDiscAdd
        BIC     r2, r2, #DiscBits
        ORR     r2, r2, r1, ASL #32-3
1429
        MOV     r1, #DiscOp_CachedReadSecs
1430 1431 1432
 [ DynamicMaps
        LDR     r3, [r4, #DrvsFsMapAddr]
 |
Neil Turton's avatar
Neil Turton committed
1433
        LDR     r3, [r4, #DrvsFsMap]
1434
 ]