; 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. ; ;>Commands ; change log (added by SBP 14 May 1997) ; ; 14 May 1997: SBP: Incorporated old fix for *verify to work when verifying >2G discs (DoVerify) ; 19 Aug 1997: SBP: Changes for big free space maps. ; 13 Sep 2011: RPS: Fix *DEFECT aborting when object occupies defect address TTL "Command handling" FsCom bit (31-24) IntHelp * (International_Help:SHR:24) MACRO ComEntry $Com,$MinArgs,$MaxArgs,$GsTransBits,$HiBits ASSERT $MinArgs<=$MaxArgs Com$Com DCB "$Com",0 ALIGN DCD Do$Com - Module_BaseAddr = $MinArgs = $GsTransBits = $MaxArgs = $HiBits DCD Syn$Com - Module_BaseAddr DCD Help$Com - Module_BaseAddr MEND MACRO Config $Com DCB "$Com",0 ALIGN DCD Con$Com - Module_BaseAddr DCD 1 :SHL: 30 DCD 0 DCD ConHelp$Com - Module_BaseAddr MEND ComTab ;general star commands ;filing system star commands ComEntry Backup, 2,4,&F,FsCom:OR:IntHelp ComEntry Bye, 0,0,0,FsCom:OR:IntHelp ComEntry CheckMap, 0,1,1,FsCom:OR:IntHelp ComEntry Compact, 0,1,1,FsCom:OR:IntHelp ComEntry Defect, 2,2,3,FsCom:OR:IntHelp ComEntry Dismount, 0,1,1,FsCom:OR:IntHelp ComEntry Drive, 1,1,1,FsCom:OR:IntHelp ComEntry Free, 0,1,1,FsCom:OR:IntHelp ComEntry Map, 0,1,1,FsCom:OR:IntHelp ComEntry Mount, 0,1,1,FsCom:OR:IntHelp ComEntry NameDisc, 2,2,3,FsCom:OR:IntHelp ComEntry NameDisk, 2,2,3,FsCom:OR:IntHelp ComEntry Verify, 0,1,1,FsCom:OR:IntHelp ;status/configure options = 0 ALIGN ; ----- FILING SYSTEM STAR COMMANDS ----- ^ 0 ; Backup temporary workspace SrcDrv # 1 SrcDrvChar # 1 DestDrv # 1 DestDrvChar # 1 SameDrive # 1 BufOpt # 1 FirstTime # 1 # 1 FSColonColon # 4 DrvPlace # 4 TotalSectors # 4 UsedMap # 4 ReadSectors # 4 ; Where we're up to AmountRead # 4 ; How much was read this time round WriteSectors # 4 ; Where we're up to BufferGotten # 4 ; How much buffer we've got [ BigDisc SrcDiscRec # SzDiscRecSig2 | SrcDiscRec # SzDiscRecSig ] BackupWork # 0 ; >>>>>>>> ; DoBackup ; >>>>>>>> BC0 DCB "BC0",0 BC1 DCB "BC1",0 BC2 DCB "BC2",0 [ {FALSE} ; 'Same disc' error now redundent BC3 DCB "BC3",0 ] ALIGN DoBackup ROUT SemEntry Flag,Light ;leaves SB,LR stacked Push "R7-R11" SUB sp, sp, #BackupWork MOV r11, sp ; Clear out BufOpt to prevent unwanted return by OS_Exit MOV lr, #0 STRB lr, [r11, #BufOpt] ; Parse source drive MOV r1, r0 BL SkipSpaces ;(R1->R0,R1,C) TEQS r0, #DiscSpecChar ADDEQ r1, r1, #1 LDRB lr, [r1] STRB lr, [r11, #SrcDrvChar] BL ParseDrive ;(R1->R0,R1,V) source drive BVS BackupErrorExit ADD r1, r1, #1 STRB r0, [r11, #SrcDrv] MOV r6, r0 ; Parse dest drive BL SkipSpaces TEQS r0, #DiscSpecChar ADDEQ r1, r1, #1 LDRB lr, [r1] STRB lr, [r11, #DestDrvChar] BL ParseDrive ;(R1->R0,R1,V) dest drive BVS BackupErrorExit ADD r1, r1, #1 STRB r0, [r11, #DestDrv] ; Ensure neither drive is a winnie ANDS lr, r0, r6 TSTS lr, #4 MOVEQ r0, #BadDriveErr ;can't do winnies SETV EQ BVS BackupErrorExit ; Note down whether the drives are the same or not EORS r8, r0, r6 STRB r8, [r11, #SameDrive] ; Work out which buffers we're permitting ourselves (process Q option) MOVEQ r8, #(1:SHL:UseDirSpace) :OR: (1:SHL:UseWimpFree) :OR: (1:SHL:UseRmaHeap) :OR: (1:SHL:UseSysHeap) :OR: DiscOp_Op_ScatterList_Flag MOVNE r8, #(1:SHL:UseScratchSpace) :OR: (1:SHL:UseSpareScreen) :OR: (1:SHL:UseWimpFree) :OR: (1:SHL:UseRmaHeap) :OR: (1:SHL:UseSysHeap) :OR: DiscOp_Op_ScatterList_Flag BL SkipSpaces ;(R1->R0,R1,C) TEQS r0, #"Q" TEQNES r0, #"q" ORREQ r8, r8, #(1:SHL:UseApplicArea) ADDEQ r1, r1, #1 ;if Q skip it STRB r8, [r11, #BufOpt] ; Process Y option and Confirm if not present BL SkipSpaces ;(R1->R0,R1,C) CMPS r0, #"Y" CMPNES r0, #"y" BLNE Confirm ;(->R0,Z,V) BNE BackupErrorExit ; Parameters now read and understood ; Construct <FS>::<Drv>\n LDR r1, FS_Title BL strlen ADD r0, r3, #4+3 ; ::<drv>\n + round-up BIC r0, r0, #3 SUB sp, sp, r0 STR sp, [r11, #FSColonColon] MOV r2, r1 MOV r1, sp BL strcpy ADD r1, r1, r3 MOV r0, #":" STRB r0, [r1], #1 STRB r0, [r1], #1 STR r1, [r11, #DrvPlace] MOV r0, #0 STRB r0, [r1, #1] ; repeat MOV r0, #1 STRB r0, [r11, #FirstTime] MOV r0, #0 STR r0, [r11, #ReadSectors] STR r0, [r11, #WriteSectors] ; {source reading part} ; If source=dest: ; If first time round: ; Prompt user to write-protect source disc ; Prompt for source disc ; Wait for user key response ; {source disc now in source drive} ; If first time round ; read file parameters for source disc ; allocate space map for source disc ; read space map for source disc ; take a copy of the disc record for the source disc ; Claim memory for transfer ; read in source disc next part ; {dest writing part} ; If source=dest ; Prompt user for dest disc ; Wait for user key response ; {dest disc now in dest drive} ; If first time round ; read dest defect list ; If defect list not empty ; complain dest has defects ; read disc record for dest disc ; If dest disc record <> source disc record enough ; complain source and dest don't match ; Dismount dest disc ; {dest disc acceptable} ; Write out dest disc next part ; until no more to read BackupMainLoop ; If first time (0<r0) OR not finished (read<total) then do another step LDRB r0, [r11, #FirstTime] RSBS r0, r0, #0 LDRHS r0, [r11, #ReadSectors] LDRHS r1, [r11, #TotalSectors] CMPHS r0, r1 BHS BackupDone LDRB lr, [r11, #SameDrive] TEQ lr, #0 BNE BackupNoPromptSource ; Prompt for source disc LDRB lr, [r11, #FirstTime] TEQ lr, #0 baddr r0, BC0, NE ; PLEASE WRITE PROTECT SOURCE DISC BLNE message_gswrite0 baddr r3, BC1, VC ; Insert source disc in drive %0 then press SPACE bar LDRVCB r0, [r11, #SrcDrvChar] BLVC BackupPromptDisc BVS BackupErrorExit BackupNoPromptSource LDRB lr, [r11, #FirstTime] TEQ lr, #0 BEQ BackupScatterListPresent ; Read file parameters for source disc LDRB r1, [r11, #SrcDrv] [ DebugQ DREG r1, "Initial look at drive " ] BL WhatDisc BVS BackupErrorExit [ DebugQ DLINE "Drive OK" ] ; take a copy of the disc record for the source disc LDMIA r3, {r0-r2,r4-r8} ADD lr, r11, #SrcDiscRec STMIA lr, {r0-r2,r4-r8} [ BigDisc ; SBP: Thu 15th December 1994 - walked through, looks OK LDR r0, [r3,#DiscRecord_BigMap_DiscSize2] STR r0, [lr,#DiscRecord_BigMap_DiscSize2] ; Size/Log2SectorSize (rounding up) = total sectors ; bottom 32 bits LDR r0, [r3, #DiscRecord_DiscSize] LDRB lr, [r3, #DiscRecord_Log2SectorSize] MOV r0, r0, LSR lr Push "R1" ; top 32 bits LDR r1, [r3, #DiscRecord_BigMap_DiscSize2] RSB lr, lr, #32 ORR r0, r0, r1, LSL lr ; combine them Pull "R1" STR r0, [r11, #TotalSectors] | ; Size/DiscRecord_Log2SectorSize (rounding up) = total sectors LDR r0, [r3, #DiscRecord_DiscSize] LDRB lr, [r3, #DiscRecord_Log2SectorSize] MOV r0, r0, LSR lr STR r0, [r11, #TotalSectors] ] ; Work out how many words of stack space will be needed ADD r0, r0, #31 BIC r0, r0, #31 ; allocate space map for source disc SUB sp, sp, r0, LSR #3 STR sp, [r11, #UsedMap] ; Read space map for source disc MOV r5, r0, LSR #3 LDRB r0, [r11, #SrcDrvChar] LDR lr, [r11, #DrvPlace] STRB r0, [lr] MOV r0, #FSControl_UsedSpaceMap LDR r1, [r11, #FSColonColon] MOV r2, sp BL DoXOS_FSControl BVS BackupErrorExit ; Claim memory for transfer LDRB r0, [r11, #BufOpt] ; options MOV r1, #1024 ; min. = Largest sector size [ BigDisc; SBP: Thu 15th December 1994 - walked through, looks OK ; make sure don't ask for silly amount of memory LDR r2, [r11, #SrcDiscRec + DiscRecord_BigMap_DiscSize2] ; get top 32bits of disc size MOVS r2, r2 MOVNE r2, #2048*1024 ; limit max size BNE BackupNotGigantic LDR r2, [r11, #SrcDiscRec + DiscRecord_DiscSize] ; max CMP r2, #2048*1024 MOVHI r2, #2048*1024 ; limit max size BackupNotGigantic | LDR r2, [r11, #SrcDiscRec + DiscSize] ; max ] MOV r3, #1024 ; granularity BL FindBuffer ; (r0-r3,r0-r3,V) BVS BackupErrorExit LDRB lr, [r11, #SrcDiscRec + DiscRecord_Log2SectorSize] MOV r2, r2, LSR lr STR r2, [r11, #BufferGotten] ; in sectors BackupScatterListPresent ; Read in source disc next part LDRB r4, [r11, #SrcDrv] MOV r0, #DiscOp_ReadSecs LDR r1, [r11, #UsedMap] LDR r2, [r11, #ReadSectors] [ BigDisc; SBP: Thu 15th December 1994 - changed to use r5 as temp reg ; (r5 gets corrupted just below anyway) ; number of sectors to transfer LDR r3, [r11, #SrcDiscRec + DiscRecord_DiscSize] LDRB lr, [r11, #SrcDiscRec + DiscRecord_Log2SectorSize] MOV r3, r3, LSR lr LDR r5, [r11, #SrcDiscRec + DiscRecord_BigMap_DiscSize2] RSB lr, lr, #32 ORR r3, r3, r5, LSL lr | LDR r3, [r11, #SrcDiscRec + DiscRecord_DiscSize] LDRB lr, [r11, #SrcDiscRec + DiscRecord_Log2SectorSize] MOV r3, r3, LSR lr ] LDR lr, [r11, #BufferGotten] CMP r3, lr MOVHI r3, lr ADD r5, r11, #SrcDiscRec [ DebugQ DREG r11, "r11 into BackupReadWriteSections is " ] BL BackupReadWriteSections [ DebugQ DREG r11, "r11 out of BackupReadWriteSections is " ] BVS BackupErrorExit STR r2, [r11, #ReadSectors] STR r3, [r11, #AmountRead] BackupPromptDestDisc ; Prompt for Dest if same drive LDRB lr, [r11, #SameDrive] TEQ lr, #0 baddr r3, BC2, EQ ; Insert destination disc in drive %0 then press SPACE bar LDREQB r0, [r11, #DestDrvChar] [ DebugQ BNE %FT01 DLINE "About to prompt for destination" 01 ] BLEQ BackupPromptDisc [ DebugQ DLINE "Dest in drive" ] BVS BackupErrorExit LDRB lr, [r11, #FirstTime] TEQ lr, #0 BEQ BackupDestChecked ; Read dest defect list LDR lr, [r11, #DrvPlace] LDRB r0, [r11, #DestDrvChar] STRB r0, [lr] SUB sp, sp, #512 MOV r0, #FSControl_DefectList LDR r1, [r11, #FSColonColon] MOV r2, sp MOV r5, #512 BL DoXOS_FSControl BVS BackupErrorExit ; If defect list not empty LDR r0, [sp] TST r0, #DiscBits ; complain dest has defects MOVEQ r0, #DestDefectsErr SETV EQ BVS BackupErrorExit ADD sp, sp, #512 ; Read disc record for dest disc LDRB lr, [r11, #DestDrv] DrvRecPtr lr, lr LDRB lr, [lr, #DrvsDisc] DiscRecPtr lr, lr ; If dest disc same complain about same-discness ADD r0, r11, #SrcDiscRec [ {FALSE} ; 'Same disc' checks now redundent and undesirable. ; If dest disc record <> source disc record enough LDMIA r0!, {r1-r4} LDMIA lr!, {r6-r9} TEQ r1, r6 TEQEQ r2, r7 TEQEQ r3, r8 TEQEQ r4, r9 LDMEQIA r0, {r1-r4} LDMEQIA lr, {r6-r9} TEQEQ r1, r6 TEQEQ r2, r7 TEQEQ r3, r8 TEQEQ r4, r9 ; complain source and dest don't match BNE BackupDiscsDifferent baddr r0, BC3 BL message_gswrite0 BVS BackupErrorExit B BackupPromptDestDisc BackupDiscsDifferent ; Check discs enough alike to work SUB lr, lr, #4*4 SUB r0, r0, #4*4 ] LDRB r1, [lr, #DiscRecord_Log2SectorSize] LDRB r2, [r0, #DiscRecord_Log2SectorSize] TEQ r1, r2 LDREQB r1, [lr, #DiscRecord_SecsPerTrk] LDREQB r2, [r0, #DiscRecord_SecsPerTrk] TEQEQ r1, r2 LDREQB r1, [lr, #DiscRecord_Density] LDREQB r2, [r0, #DiscRecord_Density] TEQEQ r1, r2 LDREQB r1, [lr, #DiscRecord_LowSector] LDREQB r2, [r0, #DiscRecord_LowSector] BICEQ r1, r1, #DiscRecord_SequenceSides_Flag BICEQ r2, r2, #DiscRecord_SequenceSides_Flag TEQEQ r1, r2 MOVNE r0, #SizeErr SETV NE BVS BackupErrorExit ; Dismount dest disc LDRB r1, [r11, #DestDrv] DrvRecPtr r1, r1 LDRB r1, [r1, #DrvsDisc] BL ActiveDismountDisc BVS BackupErrorExit BackupDestChecked ; Write out dest disc next part LDRB r4, [r11, #DestDrv] MOV r0, #DiscOp_WriteSecs LDR r1, [r11, #UsedMap] LDR r2, [r11, #WriteSectors] LDR r3, [r11, #AmountRead] ADD r5, r11, #SrcDiscRec BL BackupReadWriteSections BVS BackupErrorExit STR r2, [r11, #WriteSectors] ; Note the next loop isn't first time MOV lr, #0 STRB lr, [r11, #FirstTime] B BackupMainLoop BackupDone ; Stamp the dest image now LDRB r0, [r11, #DestDrvChar] LDR lr, [r11, #DrvPlace] STRB r0, [lr] MOV r0, #FSControl_StampImage LDR r1, [r11, #FSColonColon] MOV r2, #1 BL DoXOS_FSControl BVS BackupErrorExit BackupErrorExit [ DebugQ ADD r0, r0, #4 DSTRING r0, "Error:" SUB r0, r0, #4 ] ; Free claimed resources BL ReturnBuffer LDRB lr, [r11, #BufOpt] TST lr, #1 :SHL: UseApplicArea BNE QuickBack BLVS FindErrBlock MOV sp, r11 ADD sp, sp, #BackupWork BL FileCoreExit Pull "r7-r11,SB,pc" QuickBack BVC %FT99 BL FindErrBlock ;(R0->R0,V) BL FileCoreExit SWI OS_GenerateError 99 LDR R1, ABEX MOV R2, #0 BL FileCoreExit SWI OS_Exit ABEX = "ABEX" ; BackupPromptDisc ; ; In ; r0 = drive number (ASCII char) ; r3 = message token ; ; Out ; r0 trashed ; disc prompted for and response received ; BackupPromptDisc ROUT Push "r0-r4,lr" ; r0 (drive char) gets nul-terminated for free MOV r0, r3 MOV r4, sp BL message_gswrite01 BVS %FT95 ; wait for a space 10 BL FlushAndReadChar BVS %FT95 TEQS R0, #" " BNE %BT10 95 STRVS r0, [sp] Pull "r0-r4,pc" ; BackupReadWriteSections ; ; In ; r0 = op (DiscOp_ReadSecs/DiscOp_WriteSecs) ; r1 = pointer to used space map ; r2 = position so far (in sectors) ; r3 = RAM limit (in sectors) ; r4 = drive ; r5 = disc record to use ; ; Out ; R0, V error possible ; r2 updated ; r3 = amount transfered ; BackupReadWriteSections ROUT Push "r0-r11,lr" [ DebugQ DREG r0, ">BackupReadWriteSections(",cc DREG r1, ",",cc DREG r2, ",",cc DREG r3, ",",cc DREG r4, ",",cc DREG r5, ",",cc DLINE ")" DREG sp, "SP at start=" ] BL InitScatter sbaddr r11, ScatterList MOV r10, #0 MOV r9, r0 MOV r8, r4 [ BigDisc; SBP: Thu 15th December 1994 - walked thru, push/pull r7 not needed ; get number of sectors on disc LDR r6, [r5, #DiscRecord_DiscSize] LDRB lr, [r5, #DiscRecord_Log2SectorSize] MOV r6, r6, LSR lr LDR r7, [r5,#DiscRecord_BigMap_DiscSize2] RSB lr, lr, #32 ORR r6, r6, r7, LSL lr | LDR r6, [r5, #DiscRecord_DiscSize] LDRB lr, [r5, #DiscRecord_Log2SectorSize] MOV r6, r6, LSR lr ] ; r1 - the map ; r2 - position so far ; r3 - RAM limit (sectors) ; r5 - the disc record ; r6 - the disc size (in sectors) ; r8 - drive ; r9 - the op ; r10 - amount transfered ; r11 - scatter rover BackupFindAnotherSection MOV lr, #1 BackupFindAnotherSectionLoop CMP r2, r6 BHS BackupSectionsExhausted LDRB r0, [r1, r2, LSR #3] [ DebugQ :LAND: {FALSE} DREG r0, ">",cc ] AND r4, r2, #7 ADD r2, r2, #1 TST r0, lr, ASL r4 BEQ BackupFindAnotherSectionLoop SUB r7, r2, #1 ; Start of section ; End where RAM or disc ends, whichever is lower ADD r9, r7, r3 CMP r6, r9 MOVLO r9, r6 ; Check if room for this section CMP r2, r9 SUBHI r2, r2, #1 BHI BackupSectionsExhausted BackupFindSectionEnd CMP r2, r9 BHS BackupSectionExhausted LDRB r0, [r1, r2, LSR #3] [ DebugQ DREG r0, "<",cc ] AND r4, r2, #7 ADD r2, r2, #1 TST r0, lr, ASL r4 BNE BackupFindSectionEnd BackupSectionExhausted ; Section end found - construct operation SUB lr, r2, r7 SUB r3, r3, lr ADD r10, r10, lr Push "r0-r4" LDR r9, [sp, #5*4 + 0*4] ; r0 in ORR r1, r9, #DiscOp_Op_ScatterList_Flag SUB r4, r2, r7 MOV r2, r7 MOV r3, r11 LDRB lr, [r5, #DiscRecord_Log2SectorSize] MOV r4, r4, ASL lr [ BigDisc;SBP: Thu 15th December 1994 - walked thru, OK | MOV r2, r2, ASL lr ] ORR r2, r2, r8, ASL #(32-3) [ DebugQ DREG r4, "Transfer length " DLINE "Scatter list",cc Push "r0-r2,r4" MOV r2, r3 01 LDMIA r2!, {r0,r1} DREG r0," (",cc DREG r1,",",cc DLINE ")",cc SUBS r4, r4, r1 STR lr, [r0] SUB r1, r1, #4 STR lr, [r0, r1] BGT %BT01 DLINE Pull "r0-r2,r4" ] [ DebugQ DREG r1, "Transfer:",cc DREG r2, ",",cc DREG r3, ",",cc DREG r4, ",",cc DREG r5, "," ] BL RetryDriveOp MOV r11, r3 STRVS r0, [sp] Pull "r0-r4" BVC BackupFindAnotherSection BackupSectionsExhausted STR r2, [sp, #2*4] STR r10, [sp, #3*4] STRVS r0, [sp] [ DebugQ DREG r1, "Advance:" DREG r10, "Transfer:" DREG sp, "SP at end=" ] Pull "r0-r11,pc" ; >>>>> ; DoBye ; >>>>> DoBye ROUT SemEntry Flag,Dormant ;leaves SB,LR stacked BL DoOsFunShutDown ;(->R0,V) BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "SB,PC" ; >>>>>>>>>> ; DoCheckMap ; >>>>>>>>>> CMC0 DCB "CMC0",0 CMC1 DCB "CMC1",0 CMC2 DCB "CMC2",0 CMC3 DCB "CMC3",0 ALIGN DoCheckMap SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R7-R11" TEQS R1, #0 BLEQ IdentifyCurrentDisc ;(->R0,R3,V) if disc param missing BLEQ DiscAddToRec ;(R3->LR) LDREQ R3, [LR, #DiscRecord_Root] MOVNE R1, R0 MOVNE R2, #MustBeDisc BLNE FullLookUp ;(R1,R2->R0-R6,V) BVS %FT80 ; Reject non-FileCore discs BL DiscMustBeFileCore ;(R3->V,R0) BVS %FT80 BL TestMap ;(R3->Z) BEQ %FT05 baddr r0, CMC0 ; Old Map BL message_gswrite0 B %FT80 05 MOV R1, #8 BL CloseAllByDisc ;(R1->R0,V) BVS %FT80 BL DiscAddToRec ;(R3->LR) MOV R6, LR LDRB LR, [R6, #DiscsDrv] CMPS LR, #8 BHS %FT15 ;IF we have a map in RAM invalidate it DrvRecPtr R7, LR [ DynamicMaps LDR R10,[R7,#DrvsFsMapAddr] | LDR R10,[R7, #DrvsFsMap] BIC R10,R10,#HiFsBits ] [ BigMaps LDRB LR, [R6, #DiscRecord_BigMap_NZones2] LDRB R8, [R6, #DiscRecord_NZones] ADD R8, R8, LR, LSL #8 LDRB LR, [R6, #DiscRecord_Log2SectorSize] | LDRB LR, [R6, #DiscRecord_Log2SectorSize] LDRB R8, [R6, #DiscRecord_NZones] ] ADD R9, R10,R8, LSL LR MOV LR, #0 10 ;loop to clear zone flags STRB LR, [R9], #1 SUBS R8, R8, #1 BPL %BT10 LDRB LR, [R6, #DiscFlags] BIC LR, LR, #AltMapFlag STRB LR, [R6, #DiscFlags] [ DynamicMaps MOV LR, #0 ; clear map flags STR R0, [R7, #DrvsFsMapFlags] | STR R10,[R7, #DrvsFsMap] ] 15 BL BeforeReadFsMap ;(R3->R0,V) BVS %FT80 ;can't recover new map if both copies broken MOV R0, #"$" BL DoXOS_WriteC BVS %FT70 20 ;RECURSE DOWN ENTRY POINT BL FindDir ;(R3->R0,R5,R6,V) BVS %FT70 [ BigDir BL GetDirFirstEntry ; (R3,R5->R4) BL TestBigDir ; (R3->LR,Z) SUBNE R4, R4, #NewDirEntrySz ; small dir SUBEQ R4, R4, #BigDirEntrySize; big dir | SUB R4, R5, #NewDirEntrySz-DirFirstEntry ] B %FT35 25 MOV R0, #"." BL DoXOS_WriteC BLVC TermCommon ;(R3,R4,R5->R10) BVS %FT70 BL ReadIndDiscAdd ;(R3,R4->LR) MOV R2, LR BL ReadIntAtts ;(R3,R4->LR) TSTS LR, #DirBit MOVNE R3, R2 BNE %BT20 ;recurse down if dir 30 [ fix_5 ; need to treat big dirs as a special case BL ReadIndDiscAdd ;(R3,R4->LR) MOV R1, LR BL ReadIntAtts ;check if it's a dir TSTS LR, #DirBit ;is it a dir? BICNE R1, R1, #&ff ;yes then need to pretend isn't for reading size BL MeasureFileAllocSize_GotMap ;(R1,R3,R4->R0) MOVS R1, R0 | BL ReadLen ;(R4->LR) MOVS R1, LR ] [ BigDir BL TestBigDir BNE %FT01 Push "R6" MOV R6, R4 BL ReturnWholeSpaceNotFudged ;(R1-R6->R0) Pull "R6" B %FT02 01 Push "R5" SUB R5, R4, #DirFirstEntry BL ReturnWholeSpace ;(R1-R5->R0) Pull "R5" 02 | Push "R5" SUB R5, R4, #DirFirstEntry BL ReturnWholeSpace ;(R1-R5->R0) Pull "R5" ] MOV R10,#DeleteChar BL UnTermCommon ;(R3,R4,R5,R10) MOV R0, #DeleteChar BL DoXOS_WriteC BVS %FT70 35 [ BigDir BL TestBigDir ; (R3->LR,Z) BNE %FT37 ; not big dir ; big dir ADD R4, R4, #BigDirEntrySize ; go to next entry BL BigDirFinished ; (R4,R5->Z) BNE %BT25 ; more to do B %FT38 ; finished 37 ; not big dir LDRB LR, [R4, #NewDirEntrySz] ! CMPS LR, #" " BHI %BT25 38 | LDRB LR, [R4, #NewDirEntrySz] ! CMPS LR, #" " BHI %BT25 ] MOV R7, R3 BL ToParent ;(R3,R6->R3) CMPS R3, R7 BEQ %FT45 ;V=0 end when back to root if no match found BL FindDir ;(R3->R0,R5,R6,V) BVS %FT70 BL AgeDir ;(R7) [ BigDir BL GetDirFirstEntry ; (R3,R5->R4) BL TestBigDir ; (R3->LR,Z) SUBNE R4, R4, #NewDirEntrySz SUBEQ R4, R4, #BigDirEntrySize | SUB R4, R5, #NewDirEntrySz-DirFirstEntry ] 40 [ BigDir BL TestBigDir ADDEQ R4, R4, #BigDirEntrySize ADDNE R4, R4, #NewDirEntrySz | LDRB LR, [R4, #NewDirEntrySz] ! ] BL ReadIndDiscAdd ;(R3,R4->LR) TEQS LR, R7 BNE %BT40 MOV R2, R7 B %BT30 45 MOV R0, #DeleteChar BL DoXOS_WriteC BVS %FT70 BL CritInitReadNewFs ;(->R10,R11) BL DiscAddToRec ;(R3->LR) [ BigMaps MOV R5, LR LDRB R0, [R5, #DiscRecord_NZones] LDRB LR, [R5, #DiscRecord_BigMap_NZones2] ADD R0, R0, LR, LSL #8 | MOV R5, LR LDRB R0, [R5, #DiscRecord_NZones] ] B %FT65 50 baddr r0, CMC1 ; Map inconsistent with directory tree BL message_gswrite0 B %FT70 55 BL InitZoneObj ;(R0,R10->R8,R9,R11,LR) MOV R1, LR 60 [ BigMaps CMPS R9,R11 ;gap? BNE %FT62 ; not gap ; gap BL FreeRdLenLinkBits ;(R10,R11->R7,R8) ADD R9, R11, R8 ADD R11, R11,R7 CMPS R11,R1 BLO %BT60 B %FT65 62 ; not gap BL FragRdLenLinkBits ;(R10,R11->R7,R8) BIC lr, r3, #DiscBits CMP R8, lr, LSR #8 ; is this the root dir? BEQ %FT63 ; it's root dir CMP R8, #2 ; is it the map/boot block fragment? BLS %FT63 ; it is so ok ; here if broken map [ DebugO DREG r8, "Fragment ID hanging around:" DREG r7, "BitLength:" DREG r0, "In zone:" DREG r11, "At bit offset:" DREG r9, "Next free fragment at bit offset:" ] B %BT50 63 ADD R11,R11,R7 CMPS R11,R1 BLO %BT60 B %FT65 | BL RdLenLinkBits ;(R10,R11->R7,R8) CMPS R9, R11 ADDEQ R9, R11,R8 CMPNES R8, #2 [ DebugO BLS %FT01 DREG r8, "Fragment ID hanging around:" DREG r7, "BitLength:" DREG r0, "In zone:" DREG r11, "At bit offset:" DREG r9, "Next free fragment at bit offset:" 01 ] BHI %BT50 ADD R11,R11,R7 CMPS R11,R1 BLO %BT60 ] 65 SUBS R0, R0, #1 BPL %BT55 BL UnlockMap BL BeforeReadFsMap ;(R3->R0,V) BVS %FT70 LDRB LR, [R5, #DiscFlags] TSTS LR, #AltMapFlag baddr R0, CMC3,EQ ; Map good baddr R0, CMC2,NE ; One copy of the map is corrupt. Overwrite it with the good copy (Y/N) ? BL message_gswrite0 BVS %FT70 LDRB LR, [R5, #DiscFlags] TSTS LR, #AltMapFlag BEQ %FT70 BL TerseConfirm ;(V->Z,V) BVS %FT70 BNE %FT70 MOV R1, #DiscOp_WriteSecs :OR: DiscOp_Op_IgnoreEscape_Flag [ BigMaps LDRB R7, [R5, #DiscRecord_BigMap_NZones2] LDRB R9, [R5, #DiscRecord_NZones] ADD R9, R9, R7, LSL #8 LDRB r7, [R5, #DiscRecord_Log2SectorSize] | LDRB R7, [R5, #DiscRecord_Log2SectorSize] LDRB R9, [R5, #DiscRecord_NZones] ] BL MapDiscAdd ;(R5,R7,R9->R2) MOV R3, R10 MOV R4, R9, LSL R7 BL RetryDiscOp ;(R1-R4->R0,R2-R4,V) LDRVC LR, [R5, #DiscFlags] BICVC LR, LR, #AltMapFlag STRVC LR, [R5, #DiscFlags] 70 BL UnlockMap 80 BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "R7-R11,SB,PC" ; >>>>>>>>> ; DoCompact ; >>>>>>>>> DoCompact SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R7-R11" TEQS R1, #0 MOV R1, R0 BLEQ IdentifyCurrentDisc ;(->R0,R3,V) if disc param missing MOVNE R2, #MustBeDisc BLNE FullLookUp ;(R1,R2->R0-R6,C,V) BLVC BeforeAlterFsMap ;(R3->R0,V) BVS %FT99 BL DiscWriteBehindWait ;(R3) ; Check for drive type based on drive number, not disc number MOV LR, R3, LSR #(32-3) DiscRecPtr LR, LR LDRB LR, [LR, #DiscFlags] TST LR, #FloppyFlag LDRB LR, Interlocks Push "LR" LDREQ R0, WinnieProcessBlk LDRNE R0, FloppyProcessBlk BL ClaimController ;(R0) BL TestMap ;(R3->Z) BL DiscAddToRec ;(R3->LR) BNE %FT03 [ BigMaps LDRB R0, [LR, #DiscRecord_NZones] LDRB LR, [LR, #DiscRecord_BigMap_NZones2] ADD R0, R0, LR, LSL #8 | LDRB R0, [LR,#DiscRecord_NZones] ] BL CritInitReadNewFs ;(->R10,R11) SUB R0, R0, #1 01 MOV R1, #8*K BL DefCompactZone ;(R0,R1,R10->R0,R2,V) BVS %FT02 SUBS R0, R0, #1 BPL %BT01 02 BL UnlockMap B %FT98 03 ^ 0 LenListPtr # 4 LenList # 0 ASSERT NewDirEntries>=OldDirEntries SUB SP, SP, #(NewDirEntries+1)*4+LenList ;space to sort lengths LDR R3, [LR,#DiscRecord_Root] MOV R7, R3 05 ;RECURSE DOWN COMES BACK TO HERE ; R7 disc address of parent dir ; R3 disc address of sub dir to enter BL GetDir ;(R3->R0,R5,R6,V) BVS %FT95 Push "R3" BL ToParent ;(R3,R6->R3) TEQS R7, R3 BLNE InvalidateBufDir MOVNE R3, R7 BLNE WriteParent ;(R3,R6) ensure parent ptr ok for return later Pull "R3" [ NewDirEntrySz=OldDirEntrySz ;init ptr to last sub dir Compacted SUB R6,R5,#NewDirEntrySz-DirFirstEntry | BL TestDir ;(R3->LR) SUBEQ R6, R5, #NewDirEntrySz-DirFirstEntry SUBNE R6, R5, #OldDirEntrySz-DirFirstEntry ] 10 ADD R1, SP, #LenList ;init ptr to sort buffer [ NewDirEntrySz=OldDirEntrySz SUB R4, R5, #NewDirEntrySz-DirFirstEntry | BL TestDir ;(R3->LR) MOVEQ R11,#NewDirEntrySz MOVNE R11,#OldDirEntrySz ADD R4, R5, #DirFirstEntry SUB R4, R4, R11 ] MOV R7, #0 ;init dir index B %FT20 15 CMPS R6, R4 ;dont consider moving dirs already scanned as BLO %FT16 ;parent ptrs to it would not be updated BL ReadIntAtts TSTS LR, #DirBit BNE %FT18 16 BL ReadLen ;(R3,R4->LR) MOVS R0, LR BLNE RoundUp ;(R0,R3->R0) ignore zero length files STRNE R0, [R1] ;note length STRNEB R7, [R1],#4 ;bottom byte = dir index 18 ADD R7, R7, #1 20 [ NewDirEntrySz=OldDirEntrySz LDRB LR, [R4,#NewDirEntrySz] ! | LDRB LR, [R4,R11] ! ] CMPS LR, #" " BHI %BT15 MOV LR, #0 STR LR, [R1] ADD R0, SP, #LenList BL Sort ;(R0,R1) B %FT50 25 STR R0, [SP,#LenListPtr] BIC R1, LR, #&FF ;rounded length AND R4, LR, #&FF ;dir index [ NewDirEntrySz=OldDirEntrySz ASSERT NewDirEntrySz=26 ADD LR, R4, R4, LSL #1 ;*3 ADD R4, R4, LR, LSL #2 ;*13 ADD R4, R5, R4, LSL #1 | ? ] ADD R4, R4, #DirFirstEntry BL InitReadOldFs ;(R3->R9,R10,R11) BL ReadIndDiscAdd ;(R3,R4->LR) MOV R2, LR ADD R0, R1, R2 ;end of file's reserved space MOV R9, #-1 ;init smallest gap bigger than file 30 BL NextOldFs ;(R3,R10,R11->R7,R8,R10,R11,Z) BEQ %FT48 ;files exhausted CMPS R8, R0 BHS %FT35 ;gap is after object CMPS R7, R9 MOVLO R9, R7 ADD LR, R8, R7 ;end of gap CMPS LR, R2 BEQ %FT40 BNE %BT30 35 ;if gap joins end of file is there a better gap for file ADDEQ LR, R1, R7 ;(file+gap) length CMPEQS R9, LR BHS %FT48 40 ;here if file worth moving BL ReturnWholeSpace;(R1,R2,R3->R0,V) [ Dev mess VS, "*** ReturnWholeSpace GAVE ERROR TO *Compact ***",NL ] MOV R8, R2 MOV R10,R1 ;size MOV R11,#fsfile_Create BL ClaimFreeSpace ;(R3,R10,R11->R0,R2,V) [ Dev mess VS,"*** ClaimFreeSpace GAVE ERROR TO *Compact ***",NL ] Push "R2-R4" MOV R0, #(1:SHL:UseScratchSpace) :OR: (1:SHL:UseSpareScreen) :OR: (1:SHL:UseWimpFree) :OR: (1:SHL:UseRmaHeap) :OR: (1:SHL:UseSysHeap) :OR: DiscOp_Op_ScatterList_Flag MOV R3, R1 ;size MOV R1, R8 ;source BL MoveData ;(R0-R3->R0-R3,V) Pull "R2-R4" BVS %FT95 MOV R0, R2 BL WriteIndDiscAdd ;(R0,R3,R4) sbaddr LR, FirstFcb-FcbNext B %FT42 41 ;deal with relocating open files LDR R0, [LR,#FcbIndDiscAdd] TEQS R0, R8 STREQ R2, [LR,#FcbIndDiscAdd] LDR R0, [LR,#FcbDir] TEQS R0, R8 STREQ R2, [LR,#FcbDir] 42 LDR LR, [LR,#FcbNext];get next FCB TST LR, #BadPtrBits BEQ %BT41 BL ReadIntAtts ;(R3,R4->LR) TSTS LR, #DirBit BEQ %FT48 ;skip if file ASSERT LibDir=UserRootDir+4 ;deal with side effects of moving dir ASSERT CurDir=LibDir+4 ASSERT BackDir=CurDir+4 sbaddr R0, UserRootDir ADD R1, R0, #BackDir-UserRootDir 43 LDR LR, [R0],#4 TEQS LR, R8 STREQ R2, [R0,#-4] CMPS R0, R1 BLS %BT43 sbaddr R0, RootCache MOV R1, R0 B %FT45 44 LDR LR, [R0,#CacheDir] TEQS LR, R8 STREQ R2, [R0,#CacheDir] 45 LDR R0, [R0,#CacheOlder] ADD R0, SB, R0 TEQS R0, R1 BNE %BT44 48 LDR R0, [SP,#LenListPtr] 50 LDR LR, [R0],#4 ;get next entry from sorted length table TEQS LR, #0 BNE %BT25 LDR LR, BufDir ;avoid unnecessary writing of map CMPS LR, #-1 ;for new floppy ids BL ClearV BLEQ WriteDirThenFsMap ;(->R0,V) BVS %FT95 ;SEARCH FOR NEXT SUB DIR [ NewDirEntrySz=OldDirEntrySz 55 LDRB LR, [R6,#NewDirEntrySz] ! | BL TestDir MOVEQ R0, #NewDirEntrySz MOVNE R0, #OldDirEntrySz 55 LDRB LR, [R6,R0] ! ] CMPS LR, #" " BLS %FT60 ;no more sub dirs MOV R4, R6 BL ReadIntAtts ;(R3,R4->LR) TSTS LR, #DirBit BEQ %BT55 ;loop if file BL ReadIndDiscAdd ;(R3,R4->LR) MOV R7, R3 MOV R3, LR B %BT05 ;recurse down dir 60 ;dir done, return to parent MOV R7, R3 BL TestDir ADDEQ R6, R5, #NewDirSize ADDNE R6, R5, #OldDirSize BL ToParent ;(R3,R6->R3) EORS R0, R3, R7 BEQ %FT90 ;if dir = parent then must be $ so done BL GetDir ;(R3->R0,R5,R6,V) BVS %FT95 BL AgeDir ;(R7) [ NewDirEntrySz=OldDirEntrySz ;init ptr to last sub dir Compacted SUB R4, R5, #NewDirEntrySz-DirFirstEntry | ? ] 65 [ NewDirEntrySz=OldDirEntrySz ;init ptr to last sub dir Compacted LDRB LR, [R4,#NewDirEntrySz] ! | ? ] BL ReadIndDiscAdd ;(R3,R4->LR) TEQS LR, R7 BNE %BT65 MOV R6, R4 B %BT10 90 BL SetVOnR0 95 BL UnlockMap ADD SP, SP, #LenList+(NewDirEntries+1)*4 ;return temp space 98 Pull "LR" STRB LR, Interlocks 99 BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "R7-R11,SB,PC" ; ====== ; AgeDir ; ====== ;entry R7 ind disc address of dir to age AgeDir Push "R0-R3,R11,LR" MOV R3, R7 BL TryCache ;(R3->R11,V) BVS %FT90 BL LockDirCache BL RemoveCacheDir ;(R11) ;LINK DIR AS OLDEST MOV R0, #:INDEX:RootCache ADD R1, SB, R0 LDR R2, [R1,#CacheYounger] ADD R3, SB, R2 BL InvalidateDirCache SUB LR, R11, SB STR R0, [R11,#CacheOlder] STR R2, [R11,#CacheYounger] STR LR, [R1, #CacheYounger] STR LR, [R3, #CacheOlder] STR R11,[R11,#CachePriority] ;restore non zero priority BL ValidateDirCache BL UnlockDirCache 90 STRVS R0, [sp] Pull "R0-R3,R11,PC" ; >>>>>>>> ; DoDefect ; >>>>>>>> DC0 DCB "DC0",0 DC1 DCB "DC1",0 ALIGN DoDefect SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R7-R11" MOV R1, R0 MOV R2, #MustBeDisc BL FullLookUp ;(R1,R2->R0-R6,V) BLVC DiscMustBeFileCore BVS %FT81 Push "r1" MOV r1, r3, LSR #(32-3) BL CloseAllByDisc ;(R1->R0,V) Pull "r1" BLVC BeforeAlterFsMap ;(R3->R0,V) BLVC SkipSpaces BLVC CritInitReadNewFs ;(->R10,R11) [ BigDisc ; SBP: XOS_ReadUnsigned will only work if defect is within 4G. Need to ; do >32bit number handling for big discs. Also need to watch for ; above loading of DiscSize. MOV r0, r1 ; pointer to disc addr string BL ReadHex64 ; (r0->r1,r2) ; check for sector alignment - ie shift right by sectorsize ; then shift left should not change ls word. LDRB LR,[R10,#ZoneHead+DiscRecord_Log2SectorSize] MOV R0, R1, LSR LR MOV R0, R0, LSL LR CMP R1, R0 BEQ %FT01 MOV R0, #BadParmsErr ; Bad Parameter (how user friendly!) BL SetV B %FT78 01 ; check that disc address is on the disc LDR LR, [R10, #ZoneHead+DiscRecord_DiscSize] SUBS R0, R1, LR LDR LR, [R10, #ZoneHead+DiscRecord_BigMap_DiscSize2] SBCS R0, R2, LR BMI %FT02 ; if -ve then OK MOV R0, #BadParmsErr BL SetV B %FT78 02 LDRB LR, [R10, #ZoneHead+DiscRecord_Log2SectorSize] MOV R0, R1, LSR LR RSB LR, LR, #32 ORR R0, R0, R2, LSL LR | MOVVC r0, #16 ; base 16 ORRVC r0, r0, #bit31 :OR: bit29 ; terminated and within range LDRVC r2, [r10, #ZoneHead+DiscSize] ; bound above by DiscSize-1 SUBVC r2, r2, #1 BLVC OnlyXOS_ReadUnsigned ;(R0-R2->R0-R2,V) BVS %FT78 ; Check also on a sector boundary MOV R0, R2 LDRB R1, [R10,#ZoneHead+DiscRecord_Log2SectorSize] MOV LR, R0, LSR R1 TEQS R0, LR, LSL R1 ;check disc address at sector boundary MOVNE R0, #BadParmsErr BLNE SetV BVS %FT78 ] BL DoDefectMapOut BVC %FT78 ; Don't summarise problem on old map discs BL TestMap BNE %FT78 ; Start summarising the problem CMPS R8, #2 ;V=0 MOVEQ R0, #DefectErr BLEQ SetV [ DebugQ DREG r3, "Entering dir tree scan on root ",cc DREG r2, " and defect " ] MOVVC R0, #"$" BLVC DoXOS_WriteC BVS %FT78 MOV R9, #0 ;clear found flag MOV R11,R2 ;defect disc add 54 ; >> RECURSE DOWN ENTRY POINT BL FindDir ;(R3->R0,R5,R6,V) BVS %FT78 [ BigDir BL GetDirFirstEntry ; (R3,R5->R4) BL TestBigDir ; (R3->LR,Z) SUBNE R4, R4, #NewDirEntrySz ; small dir SUBEQ R4, R4, #BigDirEntrySize; big dir | SUB R4, R5, #NewDirEntrySz-DirFirstEntry ] B %FT72 57 BL ReadIntAtts ;(R3,R4->LR) ANDS R7, LR, #DirBit BEQ %FT60 TEQS R9, #0 BNE %FT72 MOV R0, #"." BL DoXOS_WriteC BLVC TermCommon ;(R3,R4,R5->R10) print out directory object BVS %FT78 60 BL ReadIndDiscAdd ;(R3,R4->LR) MOV R1, LR BIC R0, LR, #DiscBits TEQS R8, R0, LSR #8 BNE %FT69 CMPS R7, #0 ;V=0 BNE %FT61 MOV R0, #"." BL DoXOS_WriteC BVS %FT78 BL TermCommon ;(R3,R4,R5->R10) print out filename 61 Push "R4,R5" BL ReadLen ;(R4->LR) MOV R0, LR MOV R5, #0 MOV R9, #-1 ;init pre gap map ptr, also match found flag 63 MOV R2, R1 BL FindFileFragment ;(R2,R5,R9->R2,R4,R9,LR) CMPS R4, R0 MOVHI R4, R0 BIC R2, R2, #DiscBits ADD LR, R2, R4 SUBS R2, R11, R2 CMPHS LR, R11 BHI %FT66 ;defect inside this object ADD R5, R5, R4 SUBS R0, R0, R4 BHI %BT63 Pull "R4,R5" baddr r0, DC0 ; must be moved BL message_gswrite0 BVC %FT69 BVS %FT78 66 ADD R0, R5, R2 Pull "R4,R5" SUB SP, SP, #12 MOV R1, SP MOV R2, #12 BL OnlyXOS_ConvertHex8 ;(R0-R2->R0-R2) 67 LDRB LR, [R0], #1 CMPS LR, #"0"+1 CMPLOS R0, R1 BLO %BT67 SUB R0, R0, #1 MOV r4, r0 baddr r0, DC1 ; has defect at offset %0 BL message_gswrite01 ADD SP, SP, #12 BVS %FT78 CMPS R7, #0 BNE %FT78 ;V=0 don't try to enter dir with defect 69 TEQS R7, #DirBit ; if it's a directory TEQEQS R9, #0 ; and no match found... MOVEQ R3, R1 BEQ %BT54 ; THEN RECURSE DOWN >> 72 [ BigDir BL TestBigDir ; (R3->LR,Z) BNE %FT01 ; not big dir ; big dir ADD R4, R4, #BigDirEntrySize ; go to next entry BL BigDirFinished ; (R4,R5->Z) BNE %BT57 ; more to do B %FT02 ; finished 01 ; not big dir LDRB LR, [R4, #NewDirEntrySz] ! CMPS LR, #" " BHI %BT57 02 | LDRB LR, [R4, #NewDirEntrySz] ! CMPS LR, #" " BHI %BT57 ] TEQS R9, #0 BNE %FT78 ;V=0 don't return to parent once match found MOV R7, R3 BL ToParent ;(R3,R6->R3) CMPS R3, R7 BEQ %FT78 ;V=0 end when back to root if no match found BL FindDir ;(R3->R0,R5,R6,V) BVS %FT78 BL AgeDir ;(R7) [ BigDir BL GetDirFirstEntry ; (R3,R5->R4) BL TestBigDir ; (R3->LR,Z) SUBNE R4, R4, #NewDirEntrySz SUBEQ R4, R4, #BigDirEntrySize | SUB R4, R5, #NewDirEntrySz-DirFirstEntry ] 75 [ BigDir BL TestBigDir ; (R3->LR,Z) ADDEQ R4, R4, #BigDirEntrySize ADDNE R4, R4, #NewDirEntrySz | LDRB LR, [R4, #NewDirEntrySz] ! ] BL ReadIndDiscAdd ;(R3,R4->LR) TEQS LR, R7 BNE %BT75 MOV R10,#DeleteChar BL UnTermCommon ;(R3,R4,R5,R10) MOV R0, #DeleteChar BL DoXOS_WriteC BVC %BT72 78 BL UnlockMap 81 BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "R7-R11,SB,PC" TermCommon ; Print out a name from a dir MOV R10,#0 UnTermCommon ; Unprint a name from a dir ; Entry R4 = pointer to entry within the directory ; BigDir R3 = disc address ; R5 = directory start ; Exit R10 corrupted for 'TermCommon' Push "R0,R2,R11,LR" [ BigDir BL TestBigDir ;(R3->LR,Z) BNE %FT47 ; when not a big dir use simpler code LDR R11, [R4, #BigDirObNameLen] BL GetBigDirName ; (R4,R5->LR) get the name ptr MOV R2, LR 45 LDRB LR, [R2], #1 MOVS R0, R10 MOVEQ R0, LR BL DoXOS_WriteC ADDVS SP, SP, #4*4 BVS %BT78 SUBS R11,R11,#1 BHI %BT45 Pull "R0,R2,R11,PC" 47 ] ADD R2, R4, #DirObName MOV R11,#NameLen 48 LDRB LR, [R2], #1 MOVS R0, R10 MOVEQ R0, LR CMPS LR, #DeleteChar CMPNES LR, #" " Pull "R0,R2,R11,PC",LS BL DoXOS_WriteC ADDVS SP, SP, #4*4 BVS %BT78 SUBS R11,R11,#1 BHI %BT48 Pull "R0,R2,R11,PC" ; ============== ; DoDefectMapOut ; ============== ; entry: ; r0 = disc address to be mapped out ; r3 = top 3 bits disc number ; Map for disc must be BeforeAlterFsMapped ; exit: ; V, r0=error possible ; r8 = extra info on error (in particular the obj Id containing the defect) DoDefectMapOut ROUT Push "R0-R11,LR" [ DebugQ DREG r0,"DoDefectMapOut(",cc DREG r3,",",cc DLINE ")" ] ; Can't map out defects on old maps - tough BL TestMap ;(R3->Z) MOVNE R0, #DefectErr BLNE SetV [ DebugQ BVC %FT01 DLINE "Wrong sort of map" 01 ] BVS %FT81 ; Get the parameters for this map BL CritInitReadNewFs ;(->R10,R11) ; Find the map ptr and zone for the defect LDR r0, [sp, #0*4] BL DiscAddToMapPtr ;(R0,R10->R11,LR) MOV R1, R11 MOV R0, LR ; Start wandering through that zone BL InitZoneObj ;(R0,R10->R8,R9,R11,LR) MOV R5, LR TEQS R9, R8 MOVEQ R9, #0 MOV R0, #bit31 ;rogue previous fragment B %FT12 06 TEQS R11,R9 BNE %FT09 [ BigMaps BL FreeRdLinkBits ;(R10,R11->R8,Z) | BL RdLinkBits ;(R10,R11->R8,Z) ] MOVEQ R9, #0 ADDNE R9, R11,R8 MOV R8, R11 09 MOV R0, R11 MOV R11,R4 12 [ BigMaps TEQS R11,R9 ;is it a gap? BLEQ FreeRdLenBits ; yes (R10,R11->R7) BLNE FragRdLenBits ; no (R10,R11->R7) | BL RdLenBits ;(R10,R11->R7) ] ADD R4, R11,R7 CMPS R4, R1 BLS %BT06 ;loop if not reached defect fragment TEQS R11,R9 BNE %FT51 ;defect not in a free space Push "R8,R9" [ BigMaps BL FreeRdLinkBits ;(R10,R11->R8,Z) | BL RdLinkBits ;(R10,R11->R8,Z) ] MOVEQ R9, #0 ADDNE R9, R11,R8 STR R9, [SP, #4] MOV R3, R11 BL AllocBitWidth ;(R10->LR) MOV R9, LR SUB LR, LR, #1 BIC R1, R1, LR ;round defect down to start of allocation unit ADD R6, R1, R9 ;earliest possible defect end BL MinMapObj ;(R10->LR) MOV R2, LR ; Registers here: ; R0 = previous fragment start - top bit set if none ; R1 = Defect start at allocation unit boundary ; R2 = MinMapObj ; R3 = Start of free object bad block was found in ; R4 = Start of fragment after free fragment containing bad block ; R5 = end of fragment list ; R6 = Earliest end of defect object (based on allocation width) 15 [ DebugQ DREG r1,"Trying defect from ",cc DREG r6," to " ] SUB LR, R1, R3 ; Space before defect CMPS LR, R2 BHS %FT18 ; Branch if enough gap before defect for a whole object ; Not enough room before defect to fit an object MOV R1, R3 MOVS R11,R0 [ BigMaps BLPL FragRdLenLinkBits ;(R10,R11->R7,R8) | BLPL RdLenLinkBits ;(R10,R11->R7,R8) ] TEQPLS R8, #1 MOVEQ R1, R0 ; EQ if previous object is a bad block object, ie ; if there's no room for free space before the defect ; and the previous object is a bad block then stretch ; that to cover the defect 18 SUB LR, R4, R6 ; Space after defect CMPS LR, R2 BHS %FT21 ; Branch if there's still room for another fragment ; There isn't room after the defect for an object and there's an object after ; the free fragment containing the defect MOV R6, R4 MOV R11,R4 ; Branch if there's not another fragment after this free fragment CMP R4, R5 BHS %FT21 ; If there is another fragment, is it a bad block fragment? [ BigMaps BL FragRdLenLinkBits ;(R10,R11->R7,R8) | BL RdLenLinkBits ;(R10,R11->R7,R8) ] TEQS R8, #1 ADDEQ R6, R4, R7 ; Object after defect is a bad block - stretch it down over the defect 21 ; Now check defect fragment is big enough SUB LR, R6, R1 CMPS LR, R2 BHS %FT24 ; Defect fragment isn't big enough, so stretch defect ; fragment up if possible, else stretch it down and try again... CMPS R6, R4 ADDLO R6, R6, R9 SUBHS R1, R1, R9 B %BT15 24 Pull "R8,R9" ; Write the defect fragment MOV R0, #1 [ BigMaps BL FragWrLinkBits ;(R0,R1,R10) | BL WrLinkBits ;(R0,R1,R10) ] SUB R0, R6, R1 [ DebugQ DREG R0, "Writing defect block length of " ] [ BigMaps BL FragWrLenBits ;(R0,R1,R10) | BL WrLenBits ;(R0,R1,R10) ] ; next free fragment SUBS R7, R1, R3 MOV R1, R8 MOVHI R0, R3 [ DebugQ BLS %FT01 DREG R0, "(a)Writing freelink to ",cc DREG R1, " at " 01 ] BLHI WrFreeNext ;(R0,R1,R10) MOVHI R0, R7 MOVHI R1, R3 [ DebugQ BLS %FT01 DREG R0, "(b)Writing length of ",cc DREG R1, " at " 01 ] [ BigMaps BLHI FreeWrLenBits ;(R0,R1,R10) | BLHI WrLenBits ;(R0,R1,R10) ] ; previous free fragment CMPS R4, R6 MOVHI R0, R6 [ DebugQ BLS %FT01 DREG R0, "(c)Writing freelink to ",cc DREG R1, " at " 01 ] BLHI WrFreeNext ;(R0,R1,R10) SUBHI R0, R4, R6 MOVHI R1, R6 [ DebugQ BLS %FT01 DREG R0, "(d)Writing length of ",cc DREG R1, " at " 01 ] [ BigMaps BLHI FreeWrLenBits ;(R0,R1,R10) | BLHI WrLenBits ;(R0,R1,R10) ] ; previous previous free fragment MOV R0, R9 [ DebugQ DREG R0, "(e)Writing freelink to ",cc DREG R1, " at " ] BL WrFreeNext ;(R0,R1,R10) ; Write the whole lot out [ DebugQ DLINE "Writing out the FsMap" ] BL WriteFsMap ;(->R0,V) [ DebugQ DLINE "FsMap now written out" ] BVS %FT78 27 ; Now update the bad block list (if present) ; Pick up bad block's address LDR r2, [sp, #0*4] ; r0in ; Base presence of defect list on presence of defect list LDR r3, [sp, #3*4] MOV LR, R3, LSR #(32-3) DiscRecPtr LR, LR LDRB LR, [LR, #DiscsDrv] DrvRecPtr LR, LR LDRB LR, [LR, #DrvFlags] TST LR, #HasDefectList BEQ %FT78 ; No defect list - sad [ BigDisc ;SBP: Thu 15th December 1994 - walked thru, looks OK BL UpdateBadBlockList ; UpdateBadBlockList now sep. routine B %FT78 51 ; Defect found in non-free block - has it already been mapped out? [ BigMaps BL FragRdLinkBits ;(R10,R11->R8,Z) | BL RdLinkBits ;(R10,R11->R8,Z) ] TEQS R8, #1 BEQ %BT27 ; Yes, already mapped out [ DebugQ DLINE "Not in free space" ] MOV r0, #DefectErr BL SetV STR r8, [sp, #8*4] 78 81 [ DebugQ DLINE "Defect map-out attempt complete" ] STRVS r0, [sp, #0*4] Pull "R0-R11,PC" | [ DebugQ DLINE "Updating the bad block list" ] MOV LR, R3, LSR #(32-3) DiscRecPtr LR, LR LDRB LR, [LR, #DiscsDrv] LDR R0, DefectSpace ADD R0, SB, R0 ASSERT SzDefectList = 1 :SHL: 9 ADD R0, R0, LR, LSL #9 SUB R1, R0, #4 30 LDR LR, [R1, #4]! CMPS LR, R2 BLO %BT30 [ DebugQ BNE %FT01 DLINE "Defect already in list" 01 ] BEQ %FT78 ;defect already in list MOV R4, R1 33 TSTS LR, #DiscBits LDREQ LR, [R4, #4]! BEQ %BT33 LDR LR, [R4, #4]! TEQS LR, #0 [ DebugQ BEQ %FT01 DLINE "Defect list full" 01 ] BNE %FT78 ;defect list full 36 LDR LR, [R4, #-4]! ;move up defect list STR LR, [R4, #4] CMPS R4, R1 BHI %BT36 STR R2, [R1] MOV R4, R0 MOV R1, #0 39 LDR LR, [R4], #4 TSTS LR, #DiscBits EOREQ R1, LR, R1, ROR #13 BEQ %BT39 EOR R1, R1, R1, LSR #16 EOR R1, R1, R1, LSR #8 STRB R1, [R4, #-4] MOV R1, #SzDefectList BL CheckSum ;(R0,R1->R0-R2,V) SUB R1, R1, #1 STRB R2, [R0, R1] MOV R1, #DiscOp_WriteSecs :OR: DiscOp_Op_IgnoreEscape_Flag AND R2, R3, #DiscBits ADD R2, R2, #DefectListDiscAdd MOV R3, R0 MOV R4, #SzDefectList BL DoDiscOp ;(R1-R4->R0,R2-R4,V) [ DebugQ DLINE "Bad block list now written out" ] B %FT78 51 ; Defect found in non-free block - has it already been mapped out? BL RdLinkBits ;(R10,R11->R8,Z) TEQS R8, #1 BEQ %BT27 ; Yes, already mapped out [ DebugQ DLINE "Not in free space" ] MOV r0, #DefectErr BL SetV STR r8, [sp, #8*4] 78 81 [ DebugQ DLINE "Defect map-out attempt complete" ] STRVS r0, [sp, #0*4] Pull "R0-R11,PC" ] ; BigDisc [ BigDisc ; ================== ; UpdateBadBlockList ; ================== ; entry: ; r2 = disc address to be mapped out ; r3 = top 3 bits disc number ; Map for disc must be BeforeAlterFsMapped ; exit: ; V, r0=error possible UpdateBadBlockList ROUT [ DebugQ DLINE "Updating the bad block list" ] ; keep disc record pointer in R5 MOV LR, R3, LSR #(32-3) DiscRecPtr R5, LR LDRB LR, [R5, #DiscsDrv] LDR R0, DefectSpace ADD R0, SB, R0 ASSERT SzDefectList = 1 :SHL: 9 ADD R0, R0, LR, LSL #9 MOV R4, #512*1024*1024 ; 512 meg LDRB LR, [R5, #DiscRecord_Log2SectorSize] ; get sector size MOV R4, R4, LSR LR CMP R2, R4 ; is the defect in the first or second list? BHS %FT50 ; in second defect list ; in first list. shift left to get byte address MOV R2, R2, LSL LR SUB R1, R0, #4 30 LDR LR, [R1, #4]! CMPS LR, R2 BLO %BT30 [ DebugQ BNE %FT01 DLINE "Defect already in list" 01 ] BEQ %FT81 ;defect already in list MOV R4, R1 33 TSTS LR, #DiscBits LDREQ LR, [R4, #4]! BEQ %BT33 ; found end of first list - is there a second list? [ UseBigFlag ; use BigFlag field for test LDRB LR, [R5,#DiscRecord_BigMap_Flags] TSTS LR, #DiscRecord_BigMap_BigFlag BNE %FT40 | ; use size of disc for test LDR LR, [R5, #DiscRecord_BigMap_DiscSize2] CMPS LR, #0 BNE %FT40 LDR LR, [R5, #DiscRecord_DiscSize] TSTS LR, #DiscBits BNE %FT40 ] ; no second defect list, use normal code 35 LDR LR, [R4, #4]! TEQS LR, #0 [ DebugQ BEQ %FT01 DLINE "Defect list full" 01 ] BNE %FT81 ;defect list full 36 LDR LR, [R4, #-4]! ;move up defect list STR LR, [R4, #4] CMPS R4, R1 BHI %BT36 STR R2, [R1] 37 MOV R4, R0 MOV R1, #0 39 LDR LR, [R4], #4 TSTS LR, #DiscBits EOREQ R1, LR, R1, ROR #13 BEQ %BT39 EOR R1, R1, R1, LSR #16 EOR R1, R1, R1, LSR #8 STRB R1, [R4, #-4] MOV R1, #SzDefectList BL CheckSum ;(R0,R1->R0-R2,V) SUB R1, R1, #1 STRB R2, [R0, R1] ; generate disc address LDRB R1, [R5, #DiscRecord_Log2SectorSize] MOV LR, #DefectListDiscAdd AND R2, R3, #DiscBits ADD R2, R2, LR, LSR R1 MOV R3, R0 MOV R4, #SzDefectList MOV R1, #DiscOp_WriteSecs :OR: DiscOp_Op_IgnoreEscape_Flag BL DoDiscOp ;(R1-R4->R0,R2-R4,V) [ DebugQ DLINE "Bad block list now written out" ] B %FT81 40 ; second defect list present. Have to find its end too, and bump it up if need be MOV R6, R4 LDR LR, [R6, #4]! 43 TSTS LR, #DiscBits LDREQ LR, [R6, #4]! BEQ %BT43 45 LDR LR, [R6, #4]! TEQS LR, #0 [ DebugQ BEQ %FT01 DLINE "Defect list full" 01 ] BNE %FT81 ;defect list full 46 LDR LR, [R6, #-4]! ;move up defect list STR LR, [R6, #4] CMPS R6, R1 BHI %BT46 STR R2, [R1] B %BT37 ;use original code to checksum list 50 ; here the defect is in the second defect list. Move to this list, ; and use similar code to that above to adjust the list, then ; jump back to 37 again to checksum. [ UseBigFlag ; for safety, check if second defect list actually present ; if not there then do nothing. (Could be unix disc) LDRB LR, [R5, #DiscRecord_BigMap_Flags] CLRV ; this is not an error condition TSTS LR, #DiscRecord_BigMap_BigFlag BEQ %FT81 ] ; first, find end of the first defect list MOV R6, R0 51 LDR LR, [R6], #4 TSTS LR, #DiscBits BEQ %BT51 ; R6 now points to start of 2nd defect list SUB R1, R6, #4 52 LDR LR, [R1, #4]! CMPS LR, R2 BLO %BT52 [ DebugQ BNE %FT01 DLINE "Defect already in list" 01 ] BEQ %FT81 ;defect already in list MOV R4, R1 53 TSTS LR, #DiscBits LDREQ LR, [R4, #4]! BEQ %BT53 LDR LR, [R4, #4]! TEQS LR, #0 [ DebugQ BEQ %FT01 DLINE "Defect list full" 01 ] BNE %FT81 ;defect list full 56 LDR LR, [R4, #-4]! ;move up defect list STR LR, [R4, #4] CMPS R4, R1 BHI %BT56 STR R2, [R1] MOV R4, R6 MOV R1, #0 59 LDR LR, [R4], #4 TSTS LR, #DiscBits EOREQ R1, LR, R1, ROR #13 BEQ %BT39 EOR R1, R1, R1, LSR #16 EOR R1, R1, R1, LSR #8 STRB R1, [R4, #-4] MOV R1, #SzDefectList BL CheckSum ;(R0,R1->R0-R2,V) SUB R1, R1, #1 STRB R2, [R0, R1] ; generate disc address (sector address) LDRB R1, [R5, #DiscRecord_Log2SectorSize] MOV LR, #DefectListDiscAdd AND R2, R3, #DiscBits ADD R2, R2, LR, LSR R1 MOV R3, R0 MOV R4, #SzDefectList MOV R1, #DiscOp_WriteSecs :OR: DiscOp_Op_IgnoreEscape_Flag BL DoDiscOp ;(R1-R4->R0,R2-R4,V) [ DebugQ DLINE "Bad block list now written out" ] B %FT81 81 [ DebugQ DLINE "Defect map-out attempt complete" ] STRVS r0, [sp, #0*4] Pull "R0-R11,PC" ] ; >>>>>>>>>> ; DoDismount ; >>>>>>>>>> DoDismount ROUT SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R0" [ DebugL DSTRING r0, "Dismount on " ] TEQS R1, #0 BNE %FT20 BL IdentifyCurrentDisc ;(->R0,R3,V) If no param dismount current disc 10 MOVVC R1, R3, LSR #(32-3) BLVC ActiveDismountDisc ;(R1->R0,V) B %FT95 20 MOV R1, R0 ;string ptr MOV R2, #MustBeDisc BLNE FullLookUp ;(R1,R2->R0-R6,V) BVC %BT10 ;If disc name parsed ok then dismount it TEQS R0, #AmbigDiscErr BNE %FT50 MOV R2, #0 ;clear error flag MOV R3, #0 sbaddr R4, DiscRecs+DiscRecord_DiscName 30 LDRB LR, [R4,#Priority - DiscRecord_DiscName] TEQS LR, #0 BEQ %FT40 ;unused disc rec BL TestDir ;(R3->LR,Z) MOVEQ R5, #&FF ;set up bit 7 chars mask MOVNE R5, #&7F BL LexEqv ;(R1,R4,R5->LO/EQ/HI) BNE %FT40 ;mismatch Push "R1" MOV R1, R3, LSR #(32-3) BL ActiveDismountDisc ;(R1->R0,V) MOVVS R2, R0 Pull "R1" 40 ADD R4, R4, #SzDiscRec ADDS R3, R3, #1 :SHL: (32-3) ;inc disc num bits BCC %BT30 ;loop for next disc rec B %FT60 50 MOV R2, R0 LDR R1, [SP] BL ParseDrive ;(R1->R0,V) BLVC DriveContentsUnknown ;(R0) 60 MOV R0, R2 BL SetVOnR0 95 BL FileCoreExit BLVS FindErrBlock ;(R0->R0,V) Pull "R1,SB,PC" ; ==================== ; DriveContentsUnknown ; ==================== ; force Drive contents unknown ; ; entry r0 = drive DriveContentsUnknown Push "r0,lr" [ Debug4 :LOR: DebugL DREG r0, "DriveContentsUnknown(",cc DLINE ")" ] BL UnlinkByDrive ;(R0) DrvRecPtr r0, r0 MOV lr, #Uncertain :OR: Unknown STRB lr, [r0, #DrvsDisc] LDRB lr, [r0, #DrvFlags] BIC lr, lr, #LastDiscOpWasFormat STRB lr, [r0, #DrvFlags] [ DebugL DLINE "LastDiscOpWasFormat clear (C)" ] Pull "r0,pc" ; ================== ; ActiveDismountDisc ; ================== ; entry R1 = disc ; exit If error V set, R0 error ; As DismountDisc, but this dismount is triggered by the user actively dismounting ; rather than the dismount happening behind the user's back. The main difference ; being that ActiveDismountDisc sends a Service_DismountDisc. ActiveDismountDisc ROUT Push "r1,r2,r3,r11,lr" MOV r11,sp ; Calculate length needed for a suitable stack frame and grab that LDR r1, FS_Title BL strlen ADD r3, r3, #2+NameLen+1+3 ; 2 for ::, NameLen for disc title, 1 for terminator, 3 for round-up BIC r3, r3, #3 SUB sp, sp, r3 ; Copy FS_Title MOV r2, sp 10 LDRB lr, [r1], #1 CMP lr, #" " STRHIB lr, [r2], #1 BHI %BT10 ; Copy :: MOV lr, #":" STRB lr, [r2], #1 STRB lr, [r2], #1 ; Generate disc name or drive number as appropriate LDR r1, [r11, #0*4] DiscRecPtr r3, r1 ADD r3, r3, #DiscRecord_DiscName LDRB lr, [r3], #1 CMP lr, #" " BLS %FT30 MOV r1, #NameLen 20 STRB lr, [r2], #1 LDRB lr, [r3], #1 CMP lr, #" " SUBHIS r1, r1, #1 BHI %BT20 B %FT40 30 LDRB lr, [r3, #DiscsDrv - DiscRecord_DiscName - 1] EOR lr, lr, #4 ; Convert to external numbering ADD lr, lr, #"0" STRB lr, [r2], #1 40 ; Terminate the string MOV lr, #0 STRB lr, [r2], #1 ; Do the service MOV r1, #Service_DiscDismounted MOV r2, sp [ DebugL DREG r1, "Issuing service ",cc DSTRING r2, " with r2=" ] BL DoXOS_ServiceCall LDRVC r1, [r11, #0*4] ; r1 in BLVC DismountDisc MOV sp, r11 Pull "r1,r2,r3,r11,pc" ; ============ ; DismountDisc ; ============ ; entry R1 = disc ; exit If error V set, R0 result DismountDisc Push "R0-R7,LR" ; Hold the disc in R6 MOV R6, R1 ; Check disc in use DiscRecPtr LR, R6 LDRB R0, [LR,#Priority] TEQS R0, #0 BEQ %FT95 MOV R5, #0 ; error accumulator BL CloseAllByDisc ;(R1->R0,V) MOVVS R5, R0 [ DebugL DREG R6, "Dismounting disc " ] ; Test for defect list presence properly DiscRecPtr LR, R6 LDRB R7, [LR, #DiscsDrv] [ DebugL DREG R7, " = drive " ] ; If not attached to a drive skip drive specific sequence TEQ R7, #8 BEQ %FT50 DrvRecPtr R2, R7 [ DynamicMaps ; get rid of any free space map area Push "R0-R8" MOV R0, #2 LDR R1, [R2, #DrvsFsMapArea] BL OnlyXOS_DynamicArea BVS %FT01 ; if error, then do nothing MOV R0, R1 RSB R1, R2, #0 ; amount to change size by BL OnlyXOS_ChangeDynamicArea ; do the change 01 Pull "R0-R8" MOV LR, #0 STR LR, [R2, #DrvsFsMapSize] ; mark the size as zero ] ; Clear the LastDiscOpWasFormat flag LDRB LR, [R2, #DrvFlags] BIC LR, LR, #LastDiscOpWasFormat STRB LR, [R2, #DrvFlags] [ DebugL DLINE "LastDiscOpWasFormat clear (D)" ] ; Park disc if has defect list, and is a hard disc TST LR, #HasDefectList BEQ %FT04 ; no parking needed DiscRecPtr LR, R6 ; get disc record ptr LDRB R0, [LR, #DiscRecord_Density] ; is it a hard disc TEQ R0, #0 BNE %FT04 ; if not, don't park it MOV R1, #DiscOp_Seek :OR: DiscOp_Op_IgnoreEscape_Flag;if winnie seek to park address given LDR R2, DefectSpace ;in defect Map ADD R2, SB, R2 ASSERT SzDefectList = (1 :SHL: 9) ADD R2, R2, R7, LSL #9 LDR R2, [R2,#ParkDiscAdd] [ BigDisc DiscRecPtr LR,R6 LDR R0, [LR, #DiscRecord_BigMap_DiscSize2] ; get discsize2 MOVS R0, R0 ; is it small (discsize < 2^29 bytes?) LDREQ R0, [LR, #DiscRecord_DiscSize] TSTEQS R0, #DiscBits ; if so then ParkDiscAdd is in bytes LDREQB LR, [LR,#DiscRecord_Log2SectorSize] ; so shift it down to a sector address MOVEQ R2, R2, LSR LR ; else it's in sectors, leave it alone ORR R2, R2, R6, LSL #(32-3) [ DebugL DREG R2, "Parking at address " ] BL DoDiscOp ;(R1-R4->R0-R4) 04 | ORR R2, R2, R6, LSL #(32-3) [ DebugL DREG R2, "Parking at address " ] BL DoDiscOp ;(R1-R4->R0-R4) ] 04 MOVVS R5, R0 50 MOV R0, R6 BL FreeDiscRec ;(R0) MOV R0, R5 95 BL SetVOnR0 STRVS R0, [SP] Pull "R0-R7,PC" ; >>>>>>> ; DoDrive ; >>>>>>> DoDrive ROUT SemEntry Flag,Dormant ;leaves SB,LR stacked MOV R1, R0 ;string ptr BL ParseAnyDrive ;(R1->R0,Z,C,V) STRVCB R0, Drive BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "SB,PC" ; ======= ; Confirm ; ======= ; exit V=1 <=> error ; Z=1 <=> confirmed TerseConfirm ROUT ;entry V=0 Push "R0,LR" B %FT10 ConfirmText = "AreYouSure",0 ALIGN Confirm ;entry V don't care Push "R0,LR" ADR r0, ConfirmText BL message_gswrite0 10 MOVVC r0, #15 MOVVC r1, #1 SWIVC XOS_Byte SWIVC XOS_Confirm BLVC ConvertEscapeToError SavePSR r1 SWIVC XOS_WriteC SWIVC XOS_NewLine ORRVS r1, r1, #V_bit BICVS r1, r1, #Z_bit ; NE on error RestPSR r1,,f STRVS R0, [SP] Pull "R0,PC" ; ================ ; FlushAndReadChar ; ================ ;In: ;Out: r0 = char read or VS and r0=error (includes escapes) FlushAndReadChar ROUT Push "R1,R2,LR" MOV R0, #15 MOV R1, #1 BL OnlyXOS_Byte BLVC DoXOS_ReadC BLVC ConvertEscapeToError Pull "R1,R2,PC" ; ==================== ; ConvertEscapeToError ; ==================== ; In: VC and C=escape was pressed ; Out: r0=escape error is CS in ConvertEscapeToError ROUT MOVCC pc, lr Push "r1,r2,lr" ; Acknowledge the escape MOV r0, #OsbyteAckEscape BL OnlyXOS_Byte ; Convert to error MOVVC r0, #ExtEscapeErr SETV Pull "r1,r2,pc" ; >>>>>> ; DoFree ; >>>>>> FC0 DCB "FC0",0 FC1 DCB "FC1",0 FCK0 DCB "FCK0",0 FCK1 DCB "FCK1",0 ALIGN DoFree ROUT SemEntry Flag, Dormant ;leaves SB,LR stacked MOV r5, sp MOV r1, r0 BL strlen MOV r2, r3 LDR r1, FS_Title BL strlen ADD r3, r3, r2 ADD r3, r3, #2 + 1 + 3 ; 2 for ::, one for terminator, 3 for round-up BIC r3, r3, #3 SUB sp, sp, r3 MOV r2, r1 ; FS_Title MOV r1, sp BL strcpy BL strlen ADD r1, r1, r3 MOV lr, #":" STRB lr, [r1], #1 ; : LDRB lr, [r0] ; 2nd : if disc specifier present CMP lr, #' ' MOVHI lr, #':' STRHIB lr, [r1], #1 MOV r2, r0 LDRB lr, [r2] ; disc specifier (excluding : prefix) TEQ lr, #":" ADDEQ r2, r2, #1 BL strcpy MOV r1, sp [ BigDisc MOV r6, r0 ; keep copy of command tail ptr MOV r0, #FSControl_ReadFreeSpace64 ; get the full free space info [ DebugQ DSTRING r1, "ReadFreeSpace on " ] BL DoXOS_FSControl BVC %FT01 ; if no error then do not try the other FSControl ; here, we have a FS which doesn't support FSControl_ReadFreeSpace64 - try ; FSControl_ReadFreeSpace MOV r0, #FSControl_ReadFreeSpace MOV r1, sp ; restore FS name MOV r2, r6 ; restore command tail BL DoXOS_FSControl ; now munge results MOV r4, #0 ; high 32 0 MOV r3, r2 ; low 32 MOV r2, r1 ; max object size MOV r1, #0 ; high 32 0 01 [ DebugQ DREG r0, "FreeSpace is (",cc DREG r1, "",cc DREG r2, ",",cc DREG r3, ",",cc DREG r4, "",cc DLINE ")" ] | MOV r0, #FSControl_ReadFreeSpace [ DebugQ DSTRING r1, "ReadFreeSpace on " ] BL DoXOS_FSControl [ DebugQ DREG r0, "FreeSpace is (",cc DREG R1, ",",cc DREG R2, ",",cc DLINE ")" ] ] MOV sp, r5 BVS %FT80 [ BigDisc ; first, determine whether big or not. By big here we mean >4G CMPS r4, #0 MOV r7, r4 BEQ %FT50 ; big disc SUBS r2, r3, r0 SBC r3, r4, r1 ; now r0,r1=free space and r2,r3=used space baddr r5, FCK0 BL %FT90 MOVVC r0, r2 MOVVC r1, r3 baddr r5, FCK1, VC BLVC %FT90 B %FT80 50 ; small disc SUB r3, r3, r0 baddr r5, FC0 BL %FT90 MOVVC r0, r3 MOVVC r1, #0 baddr r5, FC1, VC BLVC %FT90 | SUB r3, r2, r0 baddr r5, FC0 BL %FT90 MOVVC r0, r3 baddr r5, FC1, VC BLVC %FT90 ] 80 BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "SB,PC" [ BigDisc ; entry r0,r1=number to subst Hex16 into %0 and right justified formatted 4byte cardinal into %1 (Kbytes) ; r7!=0 implies big disc ; ==0 implies small disc ; r5 = tag ; exit r1,r4-r6 trashed | ; entry r0=number to subst Hex8 into %0 and right justified formatted 4byte cardinal into %1 ; r5 = tag ; exit r1-r2,r4-r6 trashed ] 90 [ BigDisc Push "r0,r2,lr" SUB sp, sp, #52 ; Make a frame to do the conversions into | Push "r0,lr" SUB sp, sp, #28 ; Make a frame to do the conversions into ] ; Convert into Hex and Decimal MOV r4, r0 [ BigDisc ; do hex number of bytes; do M.S. word first then tack on L.S. word MOV r6, r1 MOVS r7, r7 BEQ %FT10 MOV r0, r1 ADD r1, sp, #16 MOV r2, #12 SWI XOS_ConvertHex8 BVS %FT99 MOV r0, r4 ADD r1, sp, #24 MOV r2, #12 SWI XOS_ConvertHex8 B %FT20 10 MOV r0, r4 ADD r1, sp, #16 MOV r2, #12 SWI XOS_ConvertHex8 20 | ADD r1, sp, #16 MOV r2, #12 SWI XOS_ConvertHex8 ] [ BigDisc ; first generate number of Kbytes in r0 BVS %FT99 ; skip code that may corrupt VS state if already VS MOVS r7, r7 ; check for big/small MOVEQ r0, r4 ; if small then L.S only MOVNE r0, r4, LSR #10 ; else shift right by 10 and combine ORRNE r0, r0, r6, LSL #22 ; with L.S. word shifted ; now have either number of bytes or number of Kbytes as appropriate in r0 MOV r1, sp MOV r2, #16 BL ConvertFormattedCardinal4 BVS %FT99 | MOVVC r0, r4 MOVVC r1, sp MOVVC r2, #16 BLVC ConvertFormattedCardinal4 BVS %FT99 ] [ DebugQ DLINE "Conversions performed successfully" ] ; Copy decimal to end of buffer 92 LDRB lr, [r1], #-1 STRB lr, [r1, r2] CMP r1, r0 BHS %BT92 [ DebugQ DLINE "Copied to end of buffer" ] ; Pad before with spaces MOV lr, #" " 95 SUBS r2, r2, #1 STRHIB lr, [r1, r2] BHI %BT95 [ DebugQ DLINE "Padded" ] MOV r0, r5 ADD r4, sp, #16 ADD r5, sp, #2 ; Right justify into a 11-2=9 width field (11 = 12-1 for the terminator) BL message_gswrite02 99 [ BigDisc ADD sp, sp, #52 STRVS r0, [sp] Pull "r0,r2,pc" | ADD sp, sp, #28 STRVS r0, [sp] Pull "r0,pc" ] ConvertFormattedCardinal4 ROUT ; R0 is the value to convert ; R1 is the buffer to convert into ; R2 is the buffer size ; Returns ; R0 entry value of R1 ; R1 pointer to terminating zero ; R2 size remaining in buffer, R2'=R2-(R1'-R0') FormatFrameSize * 16 Push "r1, r2, r3, r4-r9, lr" ; R3 only there to make frame right DEC sp, FormatFrameSize ; Frame for doing the conversion into MOV r2, #FormatFrameSize - 1 FakeErrorCDATBufferOverflow MOV r1, sp SWI XOS_ConvertCardinal4 SUBVC r4, r1, r0 ; Calculate the number of digits returned MOVVC r0, #-1 ; Current territory MOVVC r1, #1 ; Thousands separator SWIVC XTerritory_ReadSymbols MOVVC r5, r0 ; Save pointer MOVVC r0, #-1 ; Current territory MOVVC r1, #2 ; Character grouping SWIVC XTerritory_ReadSymbols BVS ExitConvertFormatted MOV r6, r0 ; Save pointer SUB r7, r5, #1 ; Measure the separator string SeparatorCountLoop LDRB r0, [ r7, #1 ]! TEQ r0, #0 BNE SeparatorCountLoop SUB r7, r7, r5 ; Compute the length ; Work out how long the result will be MOV r8, r4 ; Length of result MOV r9, r6 ; Grouping format pointer MOV r2, #0 ; Current group size MOV r1, #0 ; Distance along the source FormatCountLoop LDRB r14, [ r9 ] TEQ r14, #0 MOVNE r2, r14 ; Use this grouping ADDNE r9, r9, #1 ; Ready for the next grouping TEQ r2, #0 ; Don't do anything if format defective BEQ FormatCountDone ADD r1, r1, r2 CMP r1, r4 ; Would this group put us beyond the string? ADDLT r8, r8, r7 ; Add the separator length to the string BLT FormatCountLoop FormatCountDone ADD r14, sp, #FormatFrameSize ; Entry R1 LDMIA r14, { r1, r2 } SUB r2, r2, r8 CMP r2, #1 ; Allow for the terminating zero MOVMI r2, #1 ; Make a buffer that is too small MOVMI r0, #100 ; For this result BMI FakeErrorCDATBufferOverflow ADD r1, r1, r8 ADD r14, sp, #FormatFrameSize + 4 ; Exit R1 STMIA r14, { r1, r2 } ADD r4, sp, r4 ; Trailing zero of converted source string MOV r2, #0 ; Current group size STRB r0, [ r1 ], #-1 ; Put the terminator on the destination FormatCopyLoop LDRB r14, [ r6 ] TEQ r14, #0 MOVNE r2, r14 ; Use this grouping ADDNE r6, r6, #1 ; Ready for the next grouping TEQ r2, #0 ; Don't do anything if format defective MOVEQ r2, #-1 MOV r9, r2 ; R2 is the number of chars to copy across CharacterCopyLoop LDRB r14, [ r4, #-1 ]! STRB r14, [ r1 ], #-1 TEQ r4, sp ; Have we reached the last character? BEQ FinishConvertFormatted SUBS r9, r9, #1 BNE CharacterCopyLoop MOVS r0, r7 ; Length of the separator BEQ CharacterCopyLoop ; No separator to copy SeparatorCopyLoop SUBS r0, r0, #1 LDRB r14, [ r5, r0 ] STRB r14, [ r1 ], #-1 BNE SeparatorCopyLoop B FormatCopyLoop ; Start back again FinishConvertFormatted CLRV ExitConvertFormatted INC sp, FormatFrameSize STRVS r0, [ sp, #0 ] Pull "r0, r1, r2, r4-r9, pc" ; >>>>> ; DoMap ; >>>>> MC0 DCB "MC0",0 MC1 DCB "MC1",0 MC2 DCB "MC2",0 MC3 DCB "MC3",0 MC4 DCB "MC4",0 MC5 DCB "MC5",0 MC6 DCB "MC6",0 ALIGN DoMap ROUT SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R7-R11" [ BigDisc SUB SP, SP, #40 ;string buffer | SUB SP, SP, #20 ;string buffer ] CMPS R1, #0 ;V=0 BLEQ IdentifyCurrentDisc ;(->R0,R3,V) BVS %FT95 BEQ %FT05 MOV R1, R0 MOV R2, #MustBeDisc BL FullLookUp ;(R1,R2->R0-R6,C,V) BVS %FT95 05 BL DiscMustBeFileCore ;(R3->V,R0) BVS %FT95 BL DiscAddToRec ;(R3->LR) [ BigDir LDR r2, [LR, #DiscRecord_BigDir_DiscVersion] TEQS r2, #0 MOVEQ r0, #0 MOVNE r0, #1 ; bit 0 is big dirs flag LDRB r2, [LR, #DiscRecord_IdLen] CMPS r2, #15 ORRHI r0, r0, #2 ; r0 = 0 - not a new filecore disc ; r0 = 1 - big dirs, small map ; r0 = 2 - big map, small dirs, this case is only valid for IdLen=16 ; r0 = 3 - bit map, big dirs TEQS r0, #1 baddr r0, MC4, EQ ;( start, length) new map, big directories BEQ %FT07 TEQS r0, #2 baddr r0, MC5, EQ ;( start, length) big map, new directories BEQ %FT07 TEQS r0, #3 baddr r0, MC6, EQ ;( start, length) big map, big directories BEQ %FT07 ] LDRB r2, [LR, #DiscFlags] TSTS r2, #OldMapFlag BNE %FT06 TST r2, #OldDirFlag baddr r0, MC3, EQ ;( start, length) new map, new directories baddr r0, MC2, NE ;( start, length) new map, old directories B %FT07 06 TST r2, #OldDirFlag baddr r0, MC1, EQ ;( start, length) old map, new directories baddr r0, MC0, NE ;( start, length) old map, old directories 07 BL message_gswrite0 [ BigDisc ; find the disc record BL DiscAddToRec ; get the disc record LDR R2, [LR, #DiscRecord_BigMap_DiscSize2] ; MOVS R2, R2 MOVNE R0, #28 ;field width (Big Disc) MOVEQ R0, #20 ;field width (Small Disc) MOV R2, #0 | MOV R2, #0 MOV R0, #20 ;field width ] BL ScreenFormat ;(R0->R9-R11) ADD R10,R10,#1 ;separating space BL %FT99 MOV LR, #1 STRB LR, LastReEnter 10 BL BeforeReadFsMap ;(R3->R0,V) BVS %FT95 LDRB LR, LastReEnter TEQS LR, #0 MOVNE LR, #0 STRNEB LR, LastReEnter BLNE InitReadFs ;(R3->R9-R11) 15 BL NextFs ;(R3,R9-R11->R7-R11,Z) BIC R8, R8, #DiscBits BLEQ UnlockMap BEQ %FT20 CMPS R8, R2 BLS %BT15 BL UnlockMap MOV R2, R8 MOV R1, R7 MOV R7, SP MOV LR, #"(" STRB LR, [R7],#1 MOV R0, R8 [ BigDisc ; SBP: Thu 15th December 1994 - walked thru, doesn't seem ; to support >4G discs. Changed to support them. Push "R1,R2" LDR R1, [R10, #ZoneHead+DiscRecord_BigMap_DiscSize2] ; discsize2 field MOVS R1, R1 BEQ %FT18 ; small disc LDRB LR,[R10,#ZoneHead+DiscRecord_Log2SectorSize] ; sector size MOV R1, R0,LSL LR RSB LR, LR, #32 MOVS R0, R0, LSR LR BEQ %FT16 ; don't print number - pad spaces BL PutHex2 MOV R0, R1 BL PutHexWord B %FT19 ; here when low address on big disc - pad with 8 spaces 16 MOV R0, #8 MOV LR, #' ' 17 STRB LR, [R7],#1 SUBS R0, R0, #1 BNE %BT17 MOV R0, R1 BL PutHex2 B %FT19 ; here when small disc 18 LDRB LR,[R10,#ZoneHead+DiscRecord_Log2SectorSize] ; sector size MOV R0, R0, LSL LR BL PutHex2 ; here when finished address and want to do length 19 Pull "R1,R2" | BL PutHex2 ;(R0,R7->R7) ] MOV R0, #"," STRB R0, [R7],#1 MOV R0, R1 BL PutHex2 ;(R0,R7->R7) MOV LR, #")" STRB LR, [R7],#1 MOV LR, #0 STRB LR, [R7],#1 MOV R7 ,SP BL WriteString ;(R7->R0,V) BL %FT99 BLVC NextField ;(R9-R11->R0,R11,V) BL %FT99 BVS %FT95 B %BT10 20 CMPS R4, R6 ;V=0 BLNE DoXOS_NewLine ;(->R0,V) 95 BLVS FindErrBlock ;(R0->R0,V) [ BigDisc ADD SP, SP, #40 | ADD SP, SP, #20 ] BL FileCoreExit Pull "R7-R11,SB,PC" 99 ;swap R4-R6 with R9-R11 Push "R4-R6,R9-R11,LR" Pull "R9-R11" Pull "R4-R6,PC" RootText = RootChar,0 ALIGN ; >>>>>>> ; DoMount ; >>>>>>> DoMount ROUT Push "lr" MOV r6, sp ; Initial SP [ DebugQ DREG r6, "r6 start " ] ; Convert no parameter to *mount <drive> TEQ r1, #0 LDREQ r12, [r12] LDREQB lr, Drive ASSERT ("0" :AND: 7)=0 EOREQ lr, lr, #"0" :EOR: 4 Push "lr", EQ MOVEQ r0, sp MOV r1, r0 ; Calculate the length required MOV r2, #?RootLibText + 1 + 3 ; includes 0 terminator, 1 for . and 3 for rounding up MOV r0, r1 10 LDRB lr, [r0], #1 CMP lr, #" " TEQHI lr, #DeleteChar ADDHI r2, r2, #1 BHI %BT10 ; Ensure enough space for the : prefix LDRB lr, [r1] TEQ lr, #":" ADDNE r2, r2, #1 BIC r2, r2, #3 SUB sp, sp, r2 MOV r2, sp ; :<disc> MOVNE lr, #":" STRNEB lr, [r2], #1 MOV r0, r1 20 LDRB lr, [r0], #1 CMP lr, #" " TEQHI lr, #DeleteChar STRHIB lr, [r2], #1 BHI %BT20 ; . MOV lr, #"." STRB lr, [r2], #1 ; Save position for later MOV r3, r2 ; $\0 MOV lr, #"$" STRB lr, [r2], #1 MOV lr, #0 STRB lr, [r2], #1 ; *Dir :<disc>.$ MOV r0, #FSControl_Dir MOV r1, sp [ DebugQ DSTRING r1, "*Dir " ] SWI XOS_FSControl BVS %FT90 baddr r0, RootLibText MOV r2, r3 30 LDRB lr, [r0], #1 STRB lr, [r2], #1 TEQ lr, #0 BNE %BT30 ; Junk errors returned from these calls... ; *Lib :<disc>.$ MOV r0, #FSControl_Lib MOV r1, sp [ DebugQ DSTRING r1, "*Lib " ] SWI XOS_FSControl ; *NoURD MOV r0, #FSControl_NoURD [ DebugQ DLINE "*NoURD" ] SWI XOS_FSControl CLRV 90 [ DebugQ DREG r6, "r6 end " ] MOV sp, r6 Pull "pc" ; >>>>>>>>>> ; DoNameDisc ; >>>>>>>>>> DoNameDisc ROUT DoNameDisk Push "r0-r4,lr" MOV r4, sp ; Find length of 1st string MOV r3, #0 MOV r1, r0 10 LDRB lr, [r1], #1 CMP lr, #" " ADDHS r3, r3, #1 BHS %BT10 ; Skip to 1st non-space 20 LDRB lr, [r1], #1 TEQ lr, #" " BEQ %BT20 SUB r1, r1, #1 ; Add length of 2nd string 30 LDRB lr, [r1], #1 CMP lr, #" " ADDHI r3, r3, #1 BHI %BT30 ; Add enough for an extra :, \0 terminators and 3 for the round-up ADD r3, r3, #1+1+1+3 BIC r3, r3, #3 SUB sp, sp, r3 ; Copy the 1st string, adding a : if there isn't one already MOV r2, sp LDRB lr, [r0] TEQ lr, #":" MOVNE lr, #":" STRNEB lr, [r2], #1 40 LDRB lr, [r0], #1 CMP lr, #" " STRHIB lr, [r2], #1 BHI %BT40 MOV lr, #0 STRB lr, [r2], #1 MOV r1, r2 ; Copy the 2nd string ; Skip to 1st non-space 60 LDRB lr, [r0], #1 TEQ lr, #" " BEQ %BT60 SUB r0, r0, #1 70 LDRB lr, [r0], #1 CMP lr, #" " STRHIB lr, [r1], #1 BHI %BT70 MOV lr, #0 STRB lr, [r1], #1 ; Do the FSControl MOV r0, #FSControl_NameDisc MOV r1, sp [ DebugQ DREG r0, "OS_FSControl(",cc DSTRING r1, ",",cc DSTRING r2, ",",cc DLINE ")" ] SWI XOS_FSControl MOV sp, r4 STRVS r0, [sp] Pull "r0-r4,pc" VerifyStr = "VC0",0 ;Verifying ... VerOk = "VC1",0 ;Verified OK VerRetries = "VC2",0 ;Verified with retries VerBad = "VC3",0 ;Verify failed ALIGN ; >>>>>>>> ; DoVerify ; >>>>>>>> DoVerify ROUT SemEntry Flag,Dormant ;leaves SB,LR stacked Push "R7-R11" TEQS R1, #0 BLEQ IdentifyCurrentDisc ;(->R0,R3,V) MOVNE R2, #MustBeDisc MOVNE R1, R0 BLNE FullLookUp ;(R1,R2->R0-R6,V) baddr R0, VerifyStr,VC BLVC message_gswrite0 MOVVC R1, #DiscOp_Restore AND R2, R3, #DiscBits BLVC DoDiscOp ;(R1-R4->R0,R2-R4,V) BVS %FT85 MOV R1, #DiscOp_Verify MOV R6, #0 ;clear error flag ; BL DiscMustBeFileCore ; check if not filecore disc. ; BVS %FT70 BL TestMap ;(R3->Z) BNE %FT50 ; Verify new map BL BeforeReadFsMap ;(R3->R0,V) BVS %FT85 BL CritInitReadNewFs ;(->R10,R11) SUBS R0, R0, R0 ;init zone = 0, Z=0, C=1, HS B %FT30 10 ADD R11,R11,R7 20 CMPS R11,R5 ADDHS R0, R0, #1 30 [ DebugQ DREG R0, "Verify zone " ] BLHS InitZoneObj ;(R0,R10->R8,R9,R11,LR) MOVHS R5, LR [ BigMaps LDRHSB LR, [R10,#ZoneHead+DiscRecord_NZones] LDRHSB R9, [R10,#ZoneHead+DiscRecord_BigMap_NZones2] ADDHS LR, LR, R9, LSL #8 | LDRHSB LR, [R10,#ZoneHead+DiscRecord_NZones] ] CMPHSS R0, LR MOVHS R7, #0 BHS %FT40 ; SBP: 06 Feb 1997: ***** Fix to prevent silly long transfers on large discs during *verify (-ve numbers problem!) [ {TRUE} MOV r9,r0 BL MapPtrToDiscAdd SUB r4,r0,r2 LDR lr,[r10,#ZoneHead+DiscRecord_Log2SectorSize] MOV r4,r4,LSL lr MOV r0,r9 CMP r4,#1024*1024*1024 MOV r7,#0 MOV r8,#1 BHS %ft40 ] ; SBP: 06 Feb 1997: ***** End of fix [ BigMaps BL FragRdLenLinkBits ;(R10,R11->R7,R8) ***************** nasty - fix it properly later | BL RdLenLinkBits ;(R10,R11->R7,R8) ] TEQS R8, #1 BNE %BT10 ; Not a bad block 40 ; Verify to 'here' MOV R9, R0 BL MapPtrToDiscAdd ;(R3,R10,R11->R0) ADD R11,R11,R7 [ BigDisc ;SBP: Thu 15th December 1994 - walked thru, looks OK SUBS R4, R0, R2 ;length to verify LDRB LR, [R10, #ZoneHead+DiscRecord_Log2SectorSize] MOV R4, R4, LSL LR ;get transfer length in bytes BLHI %FT90 ;verify this chunk | SUBS R4, R0, R2 ;length to verify BLHI %FT90 ;verify this chunk ] ; If bad block is last in zone skip ZoneSpare into next zone CMP R11, R5 ASSERT DiscRecord_ZoneSpare :MOD: 4 = 2 LDRHS LR, [R10, #ZoneHead + DiscRecord_ZoneSpare] ADDHS R11, R5, LR, LSR #16 ; Offset from R5 just in case R11 overhangs into the ZoneSpare BL MapPtrToDiscAdd ;(R3,R10,R11->R0) disc add after defect MOV R2, R0 MOV R0, R9 TEQS R8, #1 BEQ %BT20 CMPS R6, #1 baddr R0, VerOk, LO baddr R0, VerRetries, EQ baddr R0, VerBad, HI BL message_gswrite0 ALIGN B %FT80 50 BL SizeLessDefects ;(R3->LR) MOV R4, LR BL %FT90 60 CMPS R6, #1 baddr R0, VerOk, LO baddr R0, VerRetries, EQ baddr R0, VerBad, HI BL message_gswrite0 ALIGN B %FT85 80 ; DLINE "DoVerify: Calling UnlockMap" BL UnlockMap ; DLINE "DoVerify: Done UnlockMap" 85 BLVS FindErrBlock ;(R0->R0,V) BL FileCoreExit Pull "R7-R11,SB,PC" 90 Push "R0,R3,R5,R7-R9,LR" [ DebugQ DREG R1, "Verify chunk:",cc DREG R2, ",",cc DREG R4, "," ] BL DiscAddToRec ;(R3->LR) MOV R5, LR MOV R9, #-1 92 MOV R3, #0 BL DoDiscOp ;(R1-R4->R0-R4,V) BVC %FT99 [ NewErrors BICS LR, R0, #&FF TSTNES R0, #NewDiscErrorBit BEQ %FT99 | TSTS R0, #DiscErrorBit BEQ %FT99 ] Push "R1,R2" MOV R1, #DiscOp_Restore BL DoDiscOp ;(R1-R4->R0-R4,V) Pull "R1,R2" BVS %FT99 TEQS R2, R9 BEQ %FT96 ORR R6, R6, #1 MOV R8, #VerifyRetries MOV R9, R2 BL DoXOS_NewLine ;(->R0,V) BICVC R0, R2, #DiscBits [ BigDisc ;SBP: Thu 15th December 1994 Walked thru, push/pull of R1 not ; needed - use R3 instead LDRVCB LR, [R5,#DiscRecord_Log2SectorSize] MOVVC R3, R0, LSL LR ;bottom 32 bits of addr RSBVC LR, LR, #32 ;shift to get top 32 bits of addr MOVVC R0, R0, LSR LR ;top 32 bits BLVC WrHex ;(R0->R0,V) - do top 32 bits of number MOVVC R0,R3 ; - do bottom 32 bits ] BLVC WrHex ;(R0->R0,V) BLVC DoSpace ;(->R0,V) 94 MOVVC R0, #"?" BLVC DoXOS_WriteC ;(R0->R0,V) BVS %FT99 B %BT92 96 SUBS R8, R8, #1 BNE %BT94 ;V=0 ORR R6, R6, #2 MOV R8, #VerifyRetries BL FindErrBlock ;(R0->R0,V) ADD R7, R0, #4 ;also set error flag MOV R0, #CR BL DoXOS_WriteC ;(R0->R0,V) BLVC WriteString ;(R7->R0,V) BVS %FT99 LDRB LR, [R5,#DiscRecord_Log2SectorSize] MOV R0, #1 [ BigDisc ; SBP: Thu 15th December 1994 - walked thru, looks OK ADD R2, R2, R0 SUBS R4, R4, R0, LSL LR ;also V=0 | ADD R2, R2, R0, LSL LR SUBS R4, R4, R0, LSL LR ;also V=0 ] BGT %BT92 99 Pull "R0,R3,R5,R7-R9,PC",VC ADD SP, SP, #7*4 B %BT80 LTORG END