; 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. ; ; >Identify TTL "Identifying FileCore discs" ; change log: ; 15 May 1997: SBP: Changed SanityCheckEDiscRecord to support idlen up to 16. ; ============ ; IdentifyDisc (r0,r5->r0,r6) ; ============ ; ; Attempt to identify the specified disc ; ;entry ; r0 = drive number of drive which disc to be identified is in ; r5 -> disc record of disc to be identified ; ; exit ; r0 = FileType of disc image (FileType_Data if service call failed) ; r6 = readsectors cache ; V not possible ; IdentifyDisc ROUT Push "r1,r2,r3,r8,r9,lr" [ DebugL DREG R0, "Identifying drive ",cc DREG R5, " on record at " ] ; Ensure an empty read sectors cache MOV r6, #0 ; If LastDiscOpWasFormat then disc must be a data disc DrvRecPtr lr, r0 LDRB lr, [lr, #DrvFlags] TST lr, #LastDiscOpWasFormat MOVNE r1, #Service_IdentifyDisc BNE %FT50 LDR r9, [r5, #DiscRecord_Root] AND r9, r9, #DiscBits [ DebugL DREG r9, "Rootdir internally starts as: " ] ; Generate an initial root dir address MOV r1, r0, ASL #(32-3) EOR r1, r1, #bit31 ; Convert to external numbering [ DebugL DREG r1, "Setting initial root dir address to: " ] STR r1, [r5, #DiscRecord_Root] MOV r1, #Service_IdentifyDisc MOV r2, #0 ; buffer MOV r3, #0 ; buffer size LDR r8, PrivateWord BL DoXOS_ServiceCall ; Fake unserviced service on VS result MOVVS r1, #Service_IdentifyDisc CLRV LDR lr, [r5, #DiscRecord_Root] BIC lr, lr, #DiscBits ORR lr, lr, r9 STR lr, [r5, #DiscRecord_Root] [ DebugL DREG lr, "Restoring internal disc numbering of RootDir: " ] 50 ; If not serviced then disc is just so much random data! TEQ r1, #Service_Serviced ; Clear out DiscId and DiscName if mapping to FileType_Data MOVNE r0, #0 ASSERT DiscRecord_DiscId :MOD: 4 = 0 ASSERT DiscRecord_DiscName = DiscRecord_DiscId+2 STRNE r0, [r5, #DiscRecord_DiscId] LDRNE r0, =FileType_Data MOVEQ r0, r2 [ DebugL DREG R0, "Disc identified as type " ] 95 Pull "r1,r2,r3,r8,r9,pc" LTORG ; ==================== ; IdentifyFileCoreDisc ; ==================== ; ;entry ; R1 = Service_IdentifyDisc (&69) ; r2 = pointer to buffer for text ; r3 = length of buffer ; R5 = Pointer to disc record ; R6 = Sector cache handle ; R8 = Pointer to FileCore instance private word to use ; ;exit ;If the format has been identified: ; R1 = Service_Serviced ; R2 = Filetype number for given disc format. ; R5 = Pointer to disc record, which has been modified ; R6 = New sector cache handle ; R8 unchanged ;Otherwise: ; R1 = Service_IdentifyDisc ; R5 = Pointer to disc record, which may have been modified ; R6 = New sector cache handle ; R8 unchanged IdentifyFileCoreDisc ROUT Push "lr" [ DebugL DLINE "Identifying a disc" DREG R0, "Rin:",cc DREG R1, ",",cc DREG R2, ",",cc DREG R3, ",",cc DREG R4, ",",cc DREG R5, ",",cc DREG R6, ",",cc DREG R7, ",",cc DREG R8, ",",cc DREG R9, ",",cc DREG R10, ",",cc DREG R11, ",",cc MOV R12, R13 DREG R12, "," ] MOV r12, r8 [ DebugL DREG r8, "r8 in is " DREG r12, "Meaning ws is " Push "r0" LDRB r0, ReEntrance DREG r0, "ReEntrance into service call servicing:" Pull "r0" ] BL IdentifyFileCoreFloppyDisc TEQ r1, #Service_Serviced BLNE IdentifyFileCoreHardDisc [ DebugL Push "r0" LDRB r0, ReEntrance DREG r0, "ReEntrance out of service call servicing:" Pull "r0" TEQ r1, #Service_Serviced BNE %FT01 DREG r2, "Service claimed - disc type is " 01 DREG R0, "Rot:",cc DREG R1, ",",cc DREG R2, ",",cc DREG R3, ",",cc DREG R4, ",",cc DREG R5, ",",cc DREG R6, ",",cc DREG R7, ",",cc DREG R8, ",",cc DREG R9, ",",cc DREG R10, ",",cc DREG R11, ",",cc MOV R12,R13 DREG R12, "," ] Pull "pc" LTORG ; ========================== ; IdentifyFileCoreFloppyDisc ; ========================== ;entry ; r1 = Service_IdentifyDisc (&69) ; r5 = Pointer to disc record ; r6 = Sector cache handle ; r8 = Pointer to FileCore instance private word to use ; r12 = Pointer to FileCore instance private word to use ; ;exit ;If the format has been identified: ; r1 = Service_Serviced ; r2 = Filetype number for given disc format. ; r5 = Pointer to disc record, which has been modified ; r6 = New sector cache handle ; r8 unchanged ; r12 unchanged ;Otherwise: ; r1 = Service_IdentifyDisc ; r5 = Pointer to disc record, which may have been modified ; r6 = New sector cache handle ; r8 unchanged ; r12 unchanged IdentifyFileCoreFloppyDisc ROUT Push "r0,r1,r2,r3,r8,r12,lr" [ DebugL DLINE "Identifying a floppy disc" ] ; Don't even try to identify hard discs as floppy discs. LDR lr, [r5, #DiscRecord_Root] TST lr, #bit31 BNE %FT95 ; Sector numbers must start at 0 on a track LDRB r0, [r5, #DiscRecord_LowSector] ASSERT DiscRecord_LowSector_Shift = 0 AND lr, r0, #DiscRecord_LowSector_Mask TEQ lr, #0 [ DebugL BEQ %FT01 DLINE "Failed on sector numbering" 01 ] BNE %FT95 ; Must be two heads in reality, and turn off side sequencing and double stepping LDRB r0, [r5, #DiscRecord_LowSector] BIC r0, r0, #DiscRecord_DoubleStep_Flag STRB r0, [r5, #DiscRecord_LowSector] BL EnsureInterleavedSides ; Ensure 1(RAMFs) or 2(Others) heads on floppies TEQ r0, #1 TEQNE r0, #2 [ DebugL DREG r0,"Heads=" BEQ %FT01 DLINE "Failed on number of heads" 01 ] BNE %FT95 Push "R3" ; Check if it sanity checks as an E format floppy disc [ BigDisc MOV r2, #0 ; sector zero MOV r3, #4 ; byte offset 4 | MOV r2, #4 ; byte disc address 4 ] BL SanityCheckEFormat Pull "R3" BVS %FT20 [ DebugL DLINE "It must be E format!" ] LDR r2, [sp, #2*4] [ BigDir LDR lr, [r5, #DiscRecord_BigDir_DiscVersion] ; check if it's EX or FX TEQ lr, #0 BEQ %FT15 LDRB lr, [r5, #DiscRecord_Density] TEQ lr, #DensityQuad baddr r1, EXFormat_DescribeTag, NE baddr r1, FXFormat_DescribeTag, EQ BL CopyFormatName B %FT85 15 ] LDRB lr, [r5, #DiscRecord_Density] TEQ lr, #DensityQuad baddr r1, EFormat_DescribeTag, NE baddr r1, FFormat_DescribeTag, EQ BL CopyFormatName B %FT85 20 ; Turn side sequencing on for FileCore L format floppies BL EnsureSequencedSides ; Side sequencing only works with a correct disc size... ADD r0, r0, #1 ; Number of platters LDRB r1, [r5, #DiscRecord_Log2SectorSize] MOV r0, r0, ASL r1 ; Size of a cylinder-sector LDRB r1, [r5, #DiscRecord_SecsPerTrk] MUL r0, r1, r0 ; Size of a cylinder MOV r0, r0, ASL #4 ; *16 ADD r0, r0, r0, ASL #2 ; *5 =*80 STR r0, [r5, #DiscRecord_DiscSize] [ BigDisc MOV r0, #0 STR r0, [r5, #DiscRecord_BigMap_DiscSize2] [ BigShare STR r0, [r5, #DiscRecord_BigMap_ShareSize] ; sharing unit always 0 for floppies ] ] ; Check for L format (much more strict about what's OK) BL SanityCheckLFormat BVS %FT30 [ BigDisc LDR r0, [r5, #DiscRecord_BigMap_DiscSize2] MOVS r0, r0 BNE %FT30 ; can't be L format - far too big! ] LDR r0, [r5, #DiscRecord_DiscSize] LDR lr, =L_Size + 4*32*256 ; Allow up to 4 extra tracks worth - beyond that and a frigged format won't work CMP r0, lr LDRLS r2, [sp, #2*4] baddr r1, LFormat_DescribeTag, LS BLLS CopyFormatName BLS %FT85 30 ; Turn side interleaving on for checking FileCore D format floppies BL EnsureInterleavedSides ; Check for D (old map) format disc BL SanityCheckDFormat BVS %FT85 [ BigDisc LDR r0, [r5, #DiscRecord_BigMap_DiscSize2] MOVS r0, r0 BNE %FT75 ; too big ] LDR r0, [r5, #DiscRecord_DiscSize] LDR lr, =D_Size + 4*10*1024 ; Allow up to 4 extra tracks worth - beyond that and a frigged format won't work CMP r0, lr LDRLS r2, [sp, #2*4] baddr r1, DFormat_DescribeTag, LS BLLS CopyFormatName 75 SETV HI 85 BVS %FT95 [ DebugL DLINE "Its a floppy!" ] LDR r2, =FileType_FileCoreFloppyDisc STR r2, [sp, #2*4] ; Returned disc type MOV r0, #Service_Serviced STR r0, [sp, #1*4] 95 [ DebugL BVC %FT01 DLINE "Failed to check FileCore floppy disc" 01 ] CLRV Pull "r0,r1,r2,r3,r8,r12,pc" LTORG ; ======================== ; IdentifyFileCoreHardDisc ; ======================== ;entry ; r1 = Service_IdentifyDisc (&69) ; r5 = Pointer to disc record ; r6 = Sector cache handle ; r8 = Pointer to FileCore instance private word to use ; r12 = Pointer to FileCore instance private word to use ; ;exit ;If the format has been identified: ; r1 = Service_Serviced ; r2 = Filetype number for given disc format. ; r5 = Pointer to disc record, which has been modified ; r6 = New sector cache handle ; r8 unchanged ; r12 unchanged ;Otherwise: ; r1 = Service_IdentifyDisc ; r5 = Pointer to disc record, which may have been modified ; r6 = New sector cache handle ; r8 unchanged ; r12 unchanged IdentifyFileCoreHardDisc ROUT Push "r0,r2,r3,r4,r5,r7-r12,lr" [ DebugL DLINE "Identifying a hard disc" ] ; Convert disc record to non-sequenced sides BL EnsureInterleavedSides BL SanityCheckBadBlockList BVS %FT90 [ BigDisc LDRB lr, [r5, #DiscRecord_Log2SectorSize] ; for conversion from byte to sector MOV r3, #DefectListDiscAdd ; disc addr of boot block... MOV r2, r3, LSR lr ; ...in sector form SUB r3, r3, r2, LSL lr ; ADD r3, r3, #DefectStruc ; offset of disc record | LDR r2, =DefectListDiscAdd + DefectStruc ] BL SanityCheckEFormat LDRVC r2, [sp, #1*4] [ BigDir BVS %FT01 LDR lr, [r5, #DiscRecord_BigDir_DiscVersion] TEQS lr, #0 baddr r1, FFormat_DescribeTag, EQ baddr r1, FXFormat_DescribeTag, NE 01 | baddr r1, FFormat_DescribeTag, VC ] BLVC CopyFormatName LDRVC r2, =FileType_FileCoreHardDisc BVC %FT90 BL SanityCheckDFormat LDRVC r2, [sp, #1*4] baddr r1, DFormat_DescribeTag, VC BLVC CopyFormatName LDRVC r2, =FileType_FileCoreHardDisc 90 [ DebugL BVC %FT01 DLINE "Failed to check FileCore hard disc" B %FT02 01 DLINE "It's a hard disc!" 02 ] STRVC r2, [sp, #1*4] MOVVC r1, #Service_Serviced CLRV Pull "r0,r2,r3,r4,r5,r7-r12,pc" LTORG ; ============== ; CopyFormatName ; ============== ; ; entry ; r1 = pointer to tag ; r2 = buffer (0 if no buffer) ; r3 = buffer length ; ; exit ; flags etc preserved CopyFormatName ROUT Push "r0-r8,lr" SavePSR r8 TEQ r2, #0 BEQ %FT95 SUB sp, sp, #16 MOV r0, sp ADRL r1, message_filename MOV r2, #0 SWI XMessageTrans_OpenFile BVS %FT90 MOV r0, sp ADD lr, sp, #16+1*4 LDMIA lr, {r1-r3} MOV r4, #0 MOV r5, #0 MOV r6, #0 MOV r7, #0 SWI XMessageTrans_Lookup MOV r0, sp SWI XMessageTrans_CloseFile 90 ADD sp, sp, #16 95 RestPSR r8,,f Pull "r0-r8,pc" ; ======================= ; SanityCheckBadBlockList ; ======================= ; ; entry ; r5 = pointer to disc record ; r6 = sector cache handle ; r12 = Pointer to FileCore instance private word to use ; ; exit ; r6 = new sector cache handle ; r12 = Unchanged ; VC if OK ; VS if bad ; SanityCheckBadBlockList ROUT [ {TRUE} CLRV MOV pc,lr | Push "r0-r4,r5,r7-r12,lr" SUB sp, sp, #SzDefectList [ DebugL DLINE "Sanity checking bad block list" ] [ BigDisc :LAND: {FALSE} LDR r2, [r5, #DiscRecord_Root] ; to get drive number AND r2, r2, #DiscBits MOV r3, #DefectListDiscAdd ; disc addr of defect list LDRB lr, [r5, #DiscRecord_Log2SectorSize] ORR r2, r2, r3, LSR lr ; actual disc addr to read from MOV r4, r3, LSR lr ; sector align disc addr SUB r3, r3, r4, LSL lr ; extra transfer needed ADD r4, r3, #SzDefectList ; amount to transfer SUB sp, sp, r3 ; transfer addr Push "R3" MOV r3, sp BL SWI_SectorDiscOp_CachedReadSectors_Myself Pull "R3" ADD sp, sp, r3 | LDR r2, [r5, #DiscRecord_Root] AND r2, r2, #DiscBits ORR r2, r2, #DefectListDiscAdd MOV r3, sp MOV r4, #SzDefectList BL SWI_DiscOp_CachedReadSectors_Myself ] [ DebugL BVC %FT01 ADD r1, r0, #4 DSTRING r1, "Failed on reading:" 01 ] BVS %FT90 MOV r0, sp MOV r1, #SzDefectList BL CheckSum [ DebugL BVC %FT01 DLINE "Failed on check sum" 01 ] 90 [ DebugL BVC %FT01 DLINE "Failed to check bad block list" 01 ] ADD sp, sp, #SzDefectList Pull "r0-r4,r7-r12,pc" ] LTORG ; ================== ; SanityCheckEFormat ; ================== ; ; entry [ BigDisc ; r2 = disc address of sector containing boot record ; r3 = offset within sector of boot record (word aligned) | ; r2 = disc address of boot record (without disc number) ] ; r5 = pointer to disc record ; r6 = sector cache handle ; r12 = Pointer to FileCore instance private word to use ; ; exit ; r6 = new sector cache handle ; r12 = unchanged ; AND ; VC: Matches OK ; VS: Mismatch and r0 does _not_ point to an error ; SanityCheckEFormat ROUT Push "lr" [ DebugL DLINE "Sanity checking E format" [ BigDisc DREG r2, "Boot record sector=" DREG r3, "Boot record offset=" ] ] ; Sanity check disc record vs disc BL SanityCheckEDiscRecord ; Read and check map from disc BLVC SanityCheckNewMap 95 [ DebugL BVC %FT01 DLINE "Failed to check E format" B %FT02 01 DLINE "E format is the business!" 02 ] Pull "pc" LTORG ; ====================== ; SanityCheckEDiscRecord ; ====================== ; ; entry [ BigDisc ; r2 = disc address of sector containing boot record ; r3 = offset within sector of boot record (word aligned) | ; r2 = disc address of boot record (without disc number) ] ; r5 = pointer to disc record ; r6 = sector cache handle ; r12 = Pointer to FileCore instance private word to use ; ; exit ; r6 = new sector cache handle ; r12 = unchanged ; AND ; VC: Matches OK ; VS: Mismatch and r0 does _not_ point to an error ; SanityCheckEDiscRecord ROUT Push "r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r12,lr" [ BigDisc SUB sp, sp, #SzDiscRecSig2 SUB sp, sp, r3 ; adjust for disc record offset | SUB sp, sp, #SzDiscRecSig ] [ DebugL DLINE "Sanity checking E disc record" DREG r2, "Disc addr =" DREG r3, "Offset =" DREG sp, "SP =" ] MOV r1, #DiscOp_CachedReadSecs LDR r14, [r5, #DiscRecord_Root] AND r14, r14, #DiscBits ORR r2, r2, r14 [ BigDisc MOV r4, #SzDiscRecSig2 ; length we want ADD r4, r4, r3 ; actual transfer length to compensate for offset Push "R3" ADD r3, sp, #4 BL SWI_SectorDiscOp_CachedReadSectors_Myself Pull "R3" ADD sp, sp, r3 ; pointer to disc record actual data | MOV r3, sp MOV r4, #SzDiscRecSig BL SWI_DiscOp_CachedReadSectors_Myself ] [ DebugL BVC %FT01 ADD r1, r0, #4 DSTRING r1, "Failed on reading" 01 ] BVS %FT90 ; Sanity check disc record vs disc ; Check sectorsize, secpertrk, heads and density all match the real values ASSERT DiscRecord_Log2SectorSize :MOD: 4 = 0 ASSERT DiscRecord_SecsPerTrk = DiscRecord_Log2SectorSize+1 ASSERT DiscRecord_Heads = DiscRecord_SecsPerTrk+1 ASSERT DiscRecord_Density = DiscRecord_Heads+1 LDR r0, [r5, #DiscRecord_Log2SectorSize] LDR r1, [sp, #DiscRecord_Log2SectorSize] ; On floppy discs ignore SecsPerTrk to robustify against copy-protection schemes LDR lr, [r5, #DiscRecord_Root] TST lr, #bit31 EOR lr, r0, r1 BICNE lr, lr, #&0000ff00 TEQ lr, #0 [ DebugL BEQ %FT01 DREG r0,"Failed on mismatched sector sizes etc: Rec=",cc DREG r1, " boot=" 01 ] BNE %FT85 [ BigMaps ; Check 0 < idlen < 20 LDRB r0, [sp, #DiscRecord_IdLen] CMP r0, #19 [ DebugL BLS %FT01 DLINE "Failed on idlen >= 20" 01 ] | ; Check 0 < idlen < 16 LDRB r0, [sp, #DiscRecord_IdLen] CMP r0, #15 [ DebugL BLS %FT01 DLINE "Failed on idlen >= 16" 01 ] ] BHI %FT85 CMP r0, #0 [ DebugL BNE %FT01 DLINE "Failed on idlen = 0" 01 ] BEQ %FT85 ; Check sufficient link bits for max number of fragments LDRB r0, [sp, #DiscRecord_Log2SectorSize] MOV r1, #8 ; 8 bits per byte MOV r1, r1, ASL r0 ; bits per sector ASSERT DiscRecord_ZoneSpare :MOD: 4 = 2 LDR r0, [sp, #DiscRecord_ZoneSpare - 2] SUB r1, r1, r0, LSR #16 ; map bits per sector LDRB r0, [sp, #DiscRecord_IdLen] ADD r0, r0, #1 DivRem r2, r1, r0, lr ; r2 = max objects per zone [ BigMaps LDRB r0, [sp, #DiscRecord_NZones] LDRB r1, [sp, #DiscRecord_BigMap_NZones2] ; r1 is the target for the MUL below ADD r0, r0, r1, LSL #8 | LDRB r0, [sp, #DiscRecord_NZones] ] [ DebugL DREG r0, "zones: " ] MUL r1, r2, r0 ; r1 = max objects in map LDRB r0, [sp, #DiscRecord_IdLen] [ DebugL DREG r0, "idlen: " ] MOVS r14, r1, LSR r0 [ DebugL BEQ %FT01 DLINE "Failed on 2^idlen < Max Total objects" 01 ] BNE %FT85 ; If shifting right by idlen leaves a non-0 ; answer, then there aren't enough link bits! ; Check sufficient link bits for free space list in a sector LDRB r0, [sp, #DiscRecord_Log2SectorSize] ADD r0, r0, #3 ; 2^3 = 8 = bits per byte LDRB r2, [sp, #DiscRecord_IdLen] [ BigMaps ; if BigMaps then idlen can be more than MaxFreeLink, so test against ; MaxFreeLink (we're being paranoid here, since maximum sector is 1024 ; bytes, needing 13 link bits) CMP r2, #MaxFreeLinkBits MOVHI r2, #MaxFreeLinkBits ] CMP r2, r0 [ DebugL BHS %FT01 DLINE "Failed on idlen < Zone length in bits" 01 ] BLO %FT85 ; Definitely not enough ; Check DiscRecord_Skew not being silly LDRB r0, [sp, #DiscRecord_Skew] LDRB r2, [sp, #DiscRecord_SecsPerTrk] CMP r0, r2 [ DebugL BLO %FT01 DLINE "Failed on DiscRecord_Skew >= SecsPerTrk" 01 ] BHS %FT85 ; skew >= secspertrk is silly! [ BigShare ; Check RootDir is sensible: ; Must be &000002nn where nn=(2*Zones)>>ShareSize+1 [ BigMaps LDRB r1, [sp, #DiscRecord_IdLen] CMP r1, #15 BHI %FT10 LDRB r1, [sp, #DiscRecord_BigDir_DiscVersion] TEQS r1, #0 BNE %FT10 ; don't sanity check rootdir address ] [ BigMaps LDRB r1, [sp, #DiscRecord_NZones] LDRB r0, [sp, #DiscRecord_BigMap_NZones2] ; r0 due for corruption later ADD r1, r1, r0,LSL #8 | LDRB r1, [sp, #DiscRecord_NZones] ] MOV r1, r1, ASL #1 LDRB r0, [sp, #DiscRecord_BigMap_ShareSize] ; factor in sharesize MOV lr, #1 ADD r1, r1, lr, LSL r0 SUB r1, r1, #1 MOV r1, r1, LSR r0 ADD r1, r1, #1 ADD r1, r1, #&200 LDR r0, [sp, #DiscRecord_Root] TEQ r0, r1 | ; Check RootDir is sensible: must be &000002nn ; where nn = (2*Zones) + 1 [ BigMaps LDRB r1, [sp, #DiscRecord_NZones] LDRB r0, [sp, #DiscRecord_BigMap_NZones2] ; r0 due to be corrupted ADD r1, r1, r0, LSL #8 | LDRB r1, [sp, #DiscRecord_NZones] ] MOV r1, r1, ASL #1 ADD r1, r1, #1 ADD r1, r1, #&200 LDR r0, [sp, #DiscRecord_Root] TEQ r0, r1 ] [ DebugL BEQ %FT01 DREG r1, "Failed on RootDir != " 01 ] BEQ %FT10 ; or, another last ditch attempt if Zones=1 and density=0 ; where nn = ((bootblock + bootblocksize + (1<<DiscRecord_Log2SectorSize) - 1) >> DiscRecord_Log2SectorSize) + 1 [ BigMaps LDRB r1, [sp, #DiscRecord_NZones] LDRB r14, [sp, #DiscRecord_BigMap_NZones2] ORR r1, r1, r14, LSL #8 | LDRB r1, [sp, #DiscRecord_NZones] ] LDRB r14, [sp, #DiscRecord_Density] ORR r14, r1, r14, LSL #16 TEQ r14, #1 ; EQ iff density=0 zones=1 BNE %FT85 [ DebugL DLINE "Might be a 1 zone fixed disc" ] MOV r14, #1 LDRB r1, [sp, #DiscRecord_Log2SectorSize] MOV r14, r14, ASL r1 SUB r14, r14, #1 ADD r14, r14, #DefectListDiscAdd + SzDefectList MOV r14, r14, LSR r1 ADD r14, r14, #1 ORR r14, r14, #&200 TEQ r0, r14 [ DebugL BEQ %FT01 DREG r1, "Failed on RootDir != " 01 ] BNE %FT85 10 ; Check disc size: ; Must be > ((Zones-1)*(8<<DiscRecord_Log2SectorSize-ZoneSpare)-Zone0Bits)<<BitSize [ {FALSE} ; (this check should not be made as may be partitioned for UNIX) ; Must be < 512M (due to duff DiscOp interface) ] ; check for Big disc on Small filing system [ BigDisc LDRB r1, [sp, #DiscRecord_BigMap_Flags] ; check if its a big disc TSTS r1, #DiscRecord_BigMap_BigFlag BEQ %FT01 LDR r1, [r12] LDR r1, [r1,#:INDEX:FS_Flags] TST r1, #CreateFlag_BigDiscSupport BEQ %FT85 ; small filing system, big disc 01 ; not big or big on big filing system ] MOV r0, #8 LDRB r1, [sp, #DiscRecord_Log2SectorSize] MOV r0, r0, ASL r1 ASSERT DiscRecord_ZoneSpare :MOD: 4 = 2 LDR r1, [sp, #DiscRecord_ZoneSpare - 2] SUB r0, r0, r1, LSR #16 [ BigMaps LDRB r1, [sp, #DiscRecord_NZones] LDRB lr, [sp, #DiscRecord_BigMap_NZones2] ; lr is safe to use ADD r1, r1, lr, LSL #8 | LDRB r1, [sp, #DiscRecord_NZones] ] SUB r1, r1, #1 MUL r0, r1, r0 SUB r0, r0, #Zone0Bits LDRB r1, [sp, #DiscRecord_Log2bpmb] [ BigDisc ; first, get the comparison size in sectors LDRB lr, [sp, #DiscRecord_Log2SectorSize] SUBS r1, r1, lr MOVPL r0, r0, LSL r1 RSBMI r0, r0, #0 MOVMI r0, r0, LSR r1 ; then the disc size in sectors LDR r1, [sp, #DiscRecord_DiscSize] MOV r1, r1, LSR lr LDR r2, [sp, #DiscRecord_BigMap_DiscSize2] [ DebugL DREG r2, "Discsize2 was " ] RSB lr, lr, #32 ORR r1, r1, r2, LSL lr ; now full DiscSize in sectors in r1 CMP r1, r0 | MOV r0, r0, ASL r1 LDR r1, [sp, #DiscRecord_DiscSize] CMP r1, r0 ] [ DebugL BGT %FT01 DREG r0, "Failed on Disc Size (signed)<= " 01 ] BLE %FT85 [ {FALSE} ; Don't check for upper limit - its OK to be bigger CMP r1, #512*1024*1024 [ DebugL BLO %FT01 DLINE "Failed on Disc Size > 512M" 01 ] BHS %FT85 ] ; All checked out - this disc record is cool! ; Copy the info into the r5 disc record ; Those fields which must be left to later are: ; DiscId ; DiscName ; BootOpt (Although the byte which would be the BootOption is copied) ASSERT DiscRecord_IdLen :MOD: 4 = 0 ASSERT DiscRecord_Log2bpmb = DiscRecord_IdLen+1 ASSERT DiscRecord_Skew = DiscRecord_Log2bpmb+1 ASSERT DiscRecord_BootOpt = DiscRecord_Skew+1 LDR r0, [sp, #DiscRecord_IdLen] STR r0, [r5, #DiscRecord_IdLen] LDRB r0, [sp, #DiscRecord_NZones] STRB r0, [r5, #DiscRecord_NZones] [ BigMaps LDRB r0, [sp, #DiscRecord_BigMap_NZones2] STRB r0, [r5, #DiscRecord_BigMap_NZones2] ] LDRB r0, [sp, #DiscRecord_ZoneSpare] STRB r0, [r5, #DiscRecord_ZoneSpare] LDRB r0, [sp, #DiscRecord_ZoneSpare+1] STRB r0, [r5, #DiscRecord_ZoneSpare+1] LDR r0, [sp, #DiscRecord_Root] LDR r1, [r5, #DiscRecord_Root] AND r1, r1, #DiscBits ORR r0, r0, r1 [ DebugL DREG r1, "DiscBits from disc record are: " DREG r0, "Setting RootDir to: (Identify, 968) " ] STR r0, [r5, #DiscRecord_Root] LDR r0, [sp, #DiscRecord_DiscSize] STR r0, [r5, #DiscRecord_DiscSize] [ BigDisc LDR r0, [sp, #DiscRecord_BigMap_DiscSize2] STR r0, [r5, #DiscRecord_BigMap_DiscSize2] [ BigShare LDR r0, [sp, #DiscRecord_BigMap_ShareSize] STR r0, [r5, #DiscRecord_BigMap_ShareSize] ] ] [ BigDir LDR r0, [sp, #DiscRecord_BigDir_DiscVersion] STR r0, [r5, #DiscRecord_BigDir_DiscVersion] LDR r0, [sp, #DiscRecord_BigDir_RootDirSize] STR r0, [r5, #DiscRecord_BigDir_RootDirSize] ] CLRV B %FT90 85 SETV 90 [ DebugL BVC %FT01 DLINE "Failed to check E disc record" 01 ] [ BigDisc ADD sp, sp, #SzDiscRecSig2 | ADD sp, sp, #SzDiscRecSig ] 95 Pull "r0,r1,r2,r3,r4,r5,r7,r8,r9,r10,r11,r12,pc" LTORG ; ================= ; SanityCheckNewMap ; ================= ; ; entry ; r5 -> disc record (with data from disc signature filled in) ; r6 = cache handle ; r12 = Pointer to FileCore instance private word to use ; ; on exit ; r5 unchanged ; r6 = new cache handle ; r12 = unchanged ; VC => Map checked OK ; VS => Map duff ; SanityCheckNewMap ROUT Push "r0-r5,r7-r10,lr" [ DebugL DLINE "Sanity checking new map" ] LDRB r4, [r5, #DiscRecord_Log2SectorSize] MOV lr, #1 SUB sp, sp, lr, ASL r4 [ BigMaps LDRB r9, [r5, #DiscRecord_NZones] LDRB r7, [r5, #DiscRecord_BigMap_NZones2] ADD r9, r9, r7, LSL #8 | LDRB r9, [r5, #DiscRecord_NZones] ] LDRB r7, [r5, #DiscRecord_Log2SectorSize] BL MapDiscAdd MOV r7, r2 ; Offset to start of map block (chooses between the two map copies) MOV r8, #0 10 ; Sector offset within map copy MOV r9, #0 ; Current EOR of cross checks MOV r10, #0 20 ; Read a sector ADD r2, r7, r8 LDRB r4, [r5, #DiscRecord_Log2SectorSize] [ BigDisc ADD r2, r2, r9 | ADD r2, r2, r9, ASL r4 ] MOV r3, sp MOV lr, #1 MOV r4, lr, ASL r4 [ BigDisc BL SWI_SectorDiscOp_CachedReadSectors_Myself | BL SWI_DiscOp_CachedReadSectors_Myself ] [ DebugL BVC %FT01 ADD r1, r0, #4 DSTRING r1, "(Read failed:" 01 ] BVS %FT30 ; Make a simple test on the free link LDRB r0, [sp, #FreeLink+1] TST r0, #&80 [ DebugL BNE %FT01 DLINE "(Top bit of free link is clear)" 01 ] BEQ %FT30 ; Check it MOV r0, sp LDRB r1, [r5, #DiscRecord_Log2SectorSize] MOV lr, #1 MOV r1, lr, ASL r1 BL NewCheck [ DebugL BEQ %FT01 DLINE "(NewCheck failed)" 01 ] BNE %FT30 ; Construct the cross check LDRB r0, [sp, #CrossCheck] EOR r10, r10, r0 ; Advance to the next sector of the map ADD r9, r9, #1 [ BigMaps LDRB r0, [r5, #DiscRecord_NZones] LDRB r2, [r5, #DiscRecord_BigMap_NZones2] ; r2 should be ok here ADD r0, r0, r2, LSL #8 | LDRB r0, [r5, #DiscRecord_NZones] ] CMP r9, r0 BLO %BT20 ; Check the cross check TEQ r10, #&ff [ DebugL BEQ %FT01 DREG r10, "(Cross check failed):" 01 ] BEQ %FT40 30 ; A failure has happened ; If not on first copy of map, then map is bad, so give up! TEQ r8, #0 [ DebugL BEQ %FT01 DLINE "Failed on both map copies" 01 ] BNE %FT85 ; Try on the second map copy [ BigMaps LDRB r8, [r5, #DiscRecord_NZones] LDRB r0, [r5, #DiscRecord_BigMap_NZones2] ADD r8, r8, r0, LSL #8 | LDRB r8, [r5, #DiscRecord_NZones] ] LDRB r0, [r5, #DiscRecord_Log2SectorSize] [ BigDisc | MOV r8, r8, ASL r0 ] B %BT10 40 ; Map cross-checks OK ; Check the disc record in the first map sector against ; the disc's disc record. ADD r2, r7, r8 LDRB r4, [r5, #DiscRecord_Log2SectorSize] MOV r3, sp MOV lr, #1 MOV r4, lr, ASL r4 [ BigDisc BL SWI_SectorDiscOp_CachedReadSectors_Myself | BL SWI_DiscOp_CachedReadSectors_Myself ] [ DebugL BVC %FT01 ADD r1, r0, #4 DSTRING r1, "Failed on reread of 1st map block" 01 ] BVS %FT90 ; Cross check the boot disc record with the map 1st sector ; disc record. Those fields which should match are: ; sector size ; sectors per track ; heads ; density ; fragment id length ; bytes per map bit ; skew ; lowsector ; zones ; zone spare ; root directory ; disc size ; Those fields which don't match are: ; boot option ; disc id ; disc name ADD r4, sp, #ZoneHead MOV r14, r5 ASSERT DiscRecord_Log2SectorSize=0 ASSERT DiscRecord_SecsPerTrk=1 ASSERT DiscRecord_Heads=2 ASSERT DiscRecord_Density=3 ASSERT DiscRecord_IdLen=4 ASSERT DiscRecord_Log2bpmb=5 ASSERT DiscRecord_Skew=6 ASSERT DiscRecord_BootOpt=7 LDMIA r4!, {r0-r1} LDMIA r14!, {r2-r3} TEQ r0, r2 [ DebugL BEQ %FT01 DREG r0,"DHSS:",cc DREG r2,"!=" 01 ] EOR r0, r1, r3 BICS r0, r0, #&ff000000 ; Boot option missing from boot record (pervy eh?) [ DebugL BEQ %FT01 DREG r1,"BRBL:",cc DREG r3,"!=" 01 ] ASSERT DiscRecord_LowSector=8 ASSERT DiscRecord_NZones=9 ASSERT DiscRecord_ZoneSpare=10 ASSERT DiscRecord_Root=12 LDMEQIA r4!, {r0-r1} LDMEQIA r14!, {r2-r3} TEQEQ r0, r2 [ DebugL BEQ %FT01 DLINE ".",cc 01 ] BICEQ r3, r3, #DiscBits ; Test root dir modulo disc number TEQEQ r1, r3 [ DebugL BEQ %FT01 DLINE ".",cc 01 ] ASSERT DiscRecord_DiscSize=16 [ BigDisc ASSERT DiscRecord_BigMap_DiscSize2=36 ] LDREQ r0, [r4], #4 LDREQ r2, [r14], #4 TEQEQ r0, r2 [ BigDisc [ BigShare ASSERT DiscRecord_BigMap_ShareSize=40 ADDEQ r4,r4,#DiscRecord_BigMap_DiscSize2-DiscRecord_DiscSize-4 ADDEQ r14,r14,#DiscRecord_BigMap_DiscSize2-DiscRecord_DiscSize-4 LDMEQIA r4!, {r0-r1} LDMEQIA r14!, {r2-r3} TEQEQ r0, r2 TEQEQ r1, r3 | ADDEQ r4,r4,#DiscRecord_BigMap_DiscSize2-DiscSize-4 ADDEQ r14,r14,#DiscRecord_BigMap_DiscSize2-DiscSize-4 LDREQ r0, [r4], #4 LDREQ r2, [r14], #4 TEQEQ r0, r2 ] ] [ DebugL BEQ %FT01 DLINE ".",cc 01 ] [ DebugL BEQ %FT01 DLINE "Failed on disc record cross-check" 01 ] BNE %FT85 ; All hunky-dory, copy over DiscId, Boot Option and Disc Name ASSERT DiscRecord_DiscId :MOD: 4 = 0 ASSERT DiscRecord_DiscName = DiscRecord_DiscId+2 LDR r0, [sp, #ZoneHead + DiscRecord_DiscId] STR r0, [r5, #DiscRecord_DiscId] LDR r0, [sp, #ZoneHead + DiscRecord_DiscId+4] STR r0, [r5, #DiscRecord_DiscId+4] LDR r0, [sp, #ZoneHead + DiscRecord_DiscId+8] STR r0, [r5, #DiscRecord_DiscId+8] LDRB r0, [sp, #ZoneHead + DiscRecord_BootOpt] STRB r0, [r5, #DiscRecord_BootOpt] B %FT90 85 SETV 90 [ DebugL BVC %FT01 DLINE "Failed to check new map" 01 ] LDRB r4, [r5, #DiscRecord_Log2SectorSize] MOV lr, #1 ADD sp, sp, lr, ASL r4 95 Pull "r0-r5,r7-r10,pc" LTORG ; ================== ; SanityCheckLFormat ; ================== ; ; entry ; r5 = pointer to disc record ; r6 = sector cache handle ; r12 = Pointer to FileCore instance private word to use ; ; exit ; r6 = new sector cache handle ; r12 = unchanged ; AND ; VC: Matches OK ; VS: Mismatch and r0 does _not_ point to an error ; SanityCheckLFormat ROUT Push "r0,lr" [ DebugL DLINE "Sanity checking L format" ] ; Must be lowsector=0, 2 heads, 15x256 byte sectors, and double density LDRB r0, [r5, #DiscRecord_LowSector] ASSERT DiscRecord_LowSector_Shift = 0 AND r0, r0, #DiscRecord_LowSector_Mask TEQ r0, #0 BNE %FT90 BL EnsureSequencedSides TEQ r0, #1 [ DebugL BEQ %FT01 DREG r0,"Heads=" 01 ] BNE %FT90 LDRB r0, [r5, #DiscRecord_SecsPerTrk] TEQ r0, #16 [ DebugL BEQ %FT01 DREG r0,"SecsPerTrk=" 01 ] BNE %FT90 LDRB r0, [r5, #DiscRecord_Log2SectorSize] TEQ r0, #8 [ DebugL BEQ %FT01 DREG r0,"Log2SectorSize=" 01 ] BNE %FT90 LDRB r0, [r5, #DiscRecord_Density] TEQ r0, #DensityDouble [ DebugL BEQ %FT01 DREG r0,"Density=" 01 ] BNE %FT90 [ BigDisc ; Fake a disc size for sequence sides MOV r0, #640*1024 STR r0, [r5, #DiscRecord_DiscSize] ; Upper word of disc size MOV r0, #0 STR r0, [r5, #DiscRecord_BigMap_DiscSize2] ; r0 is already 0 for SanityCheckOldMap | ; Fake a disc size for sequence sides MOV r0, #640*1024 STR r0, [r5, #DiscRecord_DiscSize] ; Read and check map from disc MOV r0, #0 ] BL SanityCheckOldMap [ DebugL BVC %FT01 DLINE "OldMapBroken" 01 ] BVC %FT95 90 SETV 95 [ DebugL BVC %FT01 DLINE "Failed to check L format" B %FT02 01 DLINE "L format is the business!" 02 ] Pull "r0,pc" LTORG ; ================== ; SanityCheckDFormat ; ================== ; ; entry ; r5 = pointer to disc record ; r6 = sector cache handle ; r12 = Pointer to FileCore instance private word to use ; ; exit ; r6 = new sector cache handle ; r12 = unchanged ; AND ; VC: Matches OK ; VS: Mismatch and r0 does _not_ point to an error ; SanityCheckDFormat ROUT Push "lr" [ DebugL DLINE "Sanity checking D format" ] ; Read and check map from disc MOV r0, #1 BL SanityCheckOldMap 95 [ DebugL BVC %FT01 DLINE "Failed to check D format" B %FT02 01 DLINE "D format is the business!" 02 ] Pull "pc" LTORG ; ================= ; SanityCheckOldMap ; ================= ; ; entry ; r0 =flags: ; if <> 0 'Directories are large (77 entries)' and at D_Root ; r5 -> disc record (with data from disc signature filled in) ; r6 = cache handle ; r12 = Pointer to FileCore instance private word to use ; ; on exit ; r5 unchanged ; r6 = new cache handle ; r12 = unchanged ; VC => Map checked OK and disc name and size copied to disc record ; VS => Map duff ; SanityCheckOldMap ROUT Push "r0-r4,r7,lr" SUB sp, sp, #SzOldFs [ DebugL DLINE "Sanity checking old map" ] LDR r7, [r5, #DiscRecord_Root] AND r7, r7, #DiscBits ; Read the 1st map copy MOV r2, r7 MOV r3, sp MOV r4, #SzOldFs BL SWI_DiscOp_CachedReadSectors_Myself [ DebugL DLINE "Point A" BVC %FT01 ADD r1, r0, #4 DSTRING r1, "Failed on read map (1st copy):" 01 ] BVS %FT90 MOV r0, sp MOV r1, #SzOldFs/2 BL CheckSum [ DebugL DLINE "Point B" BVC %FT01 DLINE "Failed on check sum, 1st half" 01 ] BVS %FT90 ; CheckSum 2nd section of old map ADD r0, sp, #SzOldFs/2 MOV r1, #SzOldFs/2 BL CheckSum [ DebugL DLINE "Point D" BVC %FT01 DLINE "Failed on check sum, 2nd half" 01 ] BVS %FT90 ; CheckSum clean - sanity check free space list ; r0 = pointer into free list ; r1 = end of previous free block (starts at end of root dir) (in 256-bytes) ; r3 = disc size (in 256-bytes) ; r4 = Number of free space entries to go ADD r0, sp, #FreeStart LDR lr, [sp, #SzOldFs] TEQ lr, #0 MOVEQ r1, #L_Root + OldDirSize MOVNE r1, #D_Root + NewDirSize MOV r1, r1, LSR #8 SUB r1, r1, #1 ASSERT (OldSize :MOD: 4) = 0 LDR r3, [sp, #OldSize] BIC r3, r3, #&ff000000 ; r3 = disc size/256 CMP r3, #8+2 ; 2*256 for map, 8*256 for large (new) directory SETV LO [ DebugL BVC %FT01 DREG r3, "Disc size too small:" 01 ] BVS %FT90 LDRB r4, [sp, #FreeEnd] B %FT20 10 ; Construct Start LDRB r2, [r0, #0] LDRB lr, [r0, #1] ORR r2, r2, lr, ASL #8 LDRB lr, [r0, #2] ORR r2, r2, lr, ASL #16 ; If Start <= previous end then bad map CMP r2, r1 [ DebugL BHI %FT01 DREG r2, "Failed on Start(",cc DREG r1, ")<=Previous end(",cc DLINE ")" 01 ] SETV LS BVS %FT90 ; Construct End ADD r0, r0, #FreeLen - FreeStart LDRB lr, [r0, #0] ADD r1, r1, lr LDRB lr, [r0, #1] ADD r1, r1, lr, ASL #8 LDRB lr, [r0, #2] ADD r1, r1, lr, ASL #16 ADD r0, r0, #FreeStart - FreeLen + 3 ; If End>DiscSize then puke CMP r1, r3 [ DebugL BLS %FT01 DREG r1, "Failed on End(",cc DREG r3, ")>Disc size(",cc DLINE ")" 01 ] SETV HI BVS %FT90 20 ; Count down to the end SUBS r4, r4, #3 BHI %BT10 ; Copy OldBoot to BootOpt LDRB r0, [sp, #OldBoot] STRB r0, [r5, #DiscRecord_BootOpt] ; Copy the OldId to DiscId LDRB r0, [sp, #OldId+0] STRB r0, [r5, #DiscRecord_DiscId+0] LDRB r0, [sp, #OldId+1] STRB r0, [r5, #DiscRecord_DiscId+1] ; Copy the name to the disc record LDRB r0, [sp, #OldName0+0] STRB r0, [r5, #DiscRecord_DiscName+0] LDRB r0, [sp, #OldName1+0] STRB r0, [r5, #DiscRecord_DiscName+1] LDRB r0, [sp, #OldName0+1] STRB r0, [r5, #DiscRecord_DiscName+2] LDRB r0, [sp, #OldName1+1] STRB r0, [r5, #DiscRecord_DiscName+3] LDRB r0, [sp, #OldName0+2] STRB r0, [r5, #DiscRecord_DiscName+4] LDRB r0, [sp, #OldName1+2] STRB r0, [r5, #DiscRecord_DiscName+5] LDRB r0, [sp, #OldName0+3] STRB r0, [r5, #DiscRecord_DiscName+6] LDRB r0, [sp, #OldName1+3] STRB r0, [r5, #DiscRecord_DiscName+7] LDRB r0, [sp, #OldName0+4] STRB r0, [r5, #DiscRecord_DiscName+8] LDRB r0, [sp, #OldName1+4] STRB r0, [r5, #DiscRecord_DiscName+9] ; Copy disc size to disc record MOV r3, r3, ASL #8 STR r3, [r5, #DiscRecord_DiscSize] [ BigDisc MOV r3, #0 STR r3, [r5, #DiscRecord_BigMap_DiscSize2] ] 90 [ DebugL BVC %FT01 DLINE "Failed to check old map" B %FT02 01 DLINE "Old map is the business!" 02 ] ADD sp, sp, #SzOldFs 95 Pull "r0-r4,r7,pc" LTORG ; ==================== ; EnsureSequencedSides ; ==================== ; ; In ; R5 = pointer to disc record ; Out ; R0 = number of heads (adjusted for sequence sides) ; R5 = pointer to sequence sided disc record ; EnsureSequencedSides ROUT LDRB r0, [r5, #DiscRecord_LowSector] TST r0, #DiscRecord_SequenceSides_Flag ORR r0, r0, #DiscRecord_SequenceSides_Flag STRB r0, [r5, #DiscRecord_LowSector] LDRB r0, [r5, #DiscRecord_Heads] SUBEQ r0, r0, #1 STREQB r0, [r5, #DiscRecord_Heads] MOV pc, lr ; ====================== ; EnsureInterleavedSides ; ====================== ; ; In ; R5 = pointer to disc record ; Out ; R0 = number of heads (adjusted for interleaved sides) ; R5 = pointer to sequence sided disc record ; EnsureInterleavedSides ROUT LDRB r0, [r5, #DiscRecord_LowSector] TST r0, #DiscRecord_SequenceSides_Flag BIC r0, r0, #DiscRecord_SequenceSides_Flag STRB r0, [r5, #DiscRecord_LowSector] LDRB r0, [r5, #DiscRecord_Heads] ADDNE r0, r0, #1 STRNEB r0, [r5, #DiscRecord_Heads] MOV pc, lr ; =================================== ; SWI_DiscOp_CachedReadSectors_Myself ; =================================== ; ; In ; r2-r4 DiscOp parameters ; r5 = disc record ; r6 = cache ; r12 = private workspace pointer ; ; Out ; r12 = unchanged ; results of DiscOp ; SWI_DiscOp_CachedReadSectors_Myself ROUT Push "r1,r7-r12,lr" [ Debug2 :LOR: Debug2D DREG r1, "DiscOpMyself(",cc DREG r2, ",",cc DREG r3, ",",cc DREG r4, ",",cc DLINE ")" ] MOV r11, sp MOV r1, r2, LSR #29 BIC r2, r2, #DiscBits MOV lr, #0 Push "r1,r2,lr" MOV r8, r12 MOV r2, sp MOV r1, #DiscOp_CachedReadSecs :OR: DiscOp_Op_IgnoreEscape_Flag SWI XFileCore_DiscOp64 [ DebugL BVC %FT01 ADD r0, r0, #4 DSTRING r0, "Cached read sector error:" SUB r0, r0, #4 01 ] LDMIA r2, {r2, lr} BIC lr, lr, #DiscBits ORR r2, lr, r2, LSL #29 MOV sp, r11 Pull "r1,r7-r12,pc" ; =================================== ; SWI_DiscOp_CachedReadSectors_Myself ; =================================== ; ; In ; r2-r4 DiscOp parameters ; r5 = disc record ; r6 = cache ; r12 = private workspace pointer ; ; Out ; r12 = unchanged ; results of DiscOp ; SWI_SectorDiscOp_CachedReadSectors_Myself ROUT Push "r1,r7-r12,lr" [ Debug2 :LOR: Debug2D DREG r1, "SectorDiscOpMyself(",cc DREG r2, ",",cc DREG r3, ",",cc DREG r4, ",",cc DLINE ")" ] MOV r11, sp LDRB lr, [r5, #DiscRecord_Log2SectorSize] MOV r1, r2, LSR #29 BIC r2, r2, #DiscBits RSB r8, lr, #32 MOV r7, r2, LSL lr MOV lr, r2, LSR r8 Push "r1,r7,lr" MOV r8, r12 MOV r2, sp MOV r1, #DiscOp_CachedReadSecs :OR: DiscOp_Op_IgnoreEscape_Flag SWI XFileCore_DiscOp64 [ DebugL BVC %FT01 ADD r0, r0, #4 DSTRING r0, "Cached read sector error:" SUB r0, r0, #4 01 ] LDRB lr, [r5, #DiscRecord_Log2SectorSize] LDMIA r2, {r1, r2, r7} RSB r8, lr, #32 MOV r2, r2, LSR lr ORR r2, r2, r7, LSL r8 BIC r2, r2, #DiscBits ORR r2, r2, r1, LSL #29 MOV sp, r11 Pull "r1,r7-r12,pc" END