Commit 38a141ba authored by Robert Sprowson's avatar Robert Sprowson

Add support for 2k and 4k sector sizes

s/Commands:
Make sure the defect list (via *DEFECT) does a read/modify/write of the boot block on 2k and 4k drives.
The checksum generation code was largely common and although commented to be called as though it was common wasn't actually due to a cut and paste mistake on label 37. Deleted common/uncalled code.
s/DebugOpts; s/FileCore15:
Peripheral changes.
s/FileCore20:
Read in the defect list via an intermediate buffer then copy out into the dynamic area.
s/FileCore70:
Declare the buffer size as 4k to FileSwitch, internally FileCore expresses this in a single byte * 32 so is now at the limit of the range of FcbBufSz.
s/FileCore80:
Perform transfers in the foreground when the sector size exceeds FileCore's 1k buffers. It's not worth bothering.
s/FormSWIs; s/Identify:
Vet and reject attempts to layout invalid zone/sector size combos (see Doc/1Zone).
Doc/MiscOp:
Correct a couple of calculation mistakes.
Doc/1Zone:
New documentation detailing the possible valid combinations of a 1 zone fixed disc, and why for 2k and 4k sectors this is rejected.
Test/BigSectors:
Patch to apply to RAMFS to make it a 4k filing system. Note, the smallest 2 zone RAM disc with 4k sectors is 4052kB, in which case the map is at +3F0000; copy at +3F2000; root directory object at +3F4000.

Version 3.63. Tagged as 'FileCore-3_63'
parent 784391d4
Placement of the boot block for 1 zone discs
============================================
The 15-bit free link in new map discs sets the maximum number of bits in a map block to 32768, hence bytes in a map block to 32768/8 = 4kB.
As a map block is a single sector, the sector also cannot exceed 4kB.
Assuming 256; 512; 1024; 2048; 4096 sector sizes it is therefore possible to enumerate all 10 layouts of the single zone case (where the map must fit in too).
Recall that old map discs have a fixed size free space map and don't have zones, so can be ignored here.
Recall the new map discs have the disc record at the start of zone 0, when the map is also in zone 0 it is lower capacity than usual.
From these tables it can be seen that new dir can only permit single zone layouts with boot blocks that use log2ss=8;9 and big dir can use log2ss=8;9;10.
FileCore therefore should detect and reject the invalid combinations.
For 2 or more zones there's no problem, since only the disc record needs to fit under the 0C00 limit.
For log2ss=8
------------
New dir Big dir
0000-00FF Map 1 0000-00FF Map 1
0100-01FF Map 2 0100-01FF Map 2
0200-09FF Root directory 0200-0BFF Gap (root is in object #3)
0A00-0BFF Gap 0C00 Boot block
0C00 Boot block
For log2ss=9
------------
New dir Big dir
0000-01FF Map 1 0000-01FF Map 1
0200-03FF Map 2 0200-03FF Map 2
0400-0BFF Root directory 0400-0BFF Gap (root is in object #3)
0C00 Boot block 0C00 Boot block
For log2ss=10
-------------
New dir Big dir
0000-03FF Map 1 0000-03FF Map 1
0400-07FF Map 2 0400-07FF Map 2
0800-1000 Root overlaps boot block! 0800-0BFF Gap (root is in object #3)
0C00 Invalid! 0C00 Boot block
For log2ss=11
-------------
New dir Big dir
0000-07FF Map 1 0000-07FF Map 1
0800-1000 Map 2 overlaps boot block! 0800-1000 Map 2 overlaps boot block!
0C00 Invalid! 0C00 Invalid!
For log2ss=12
-------------
New dir Big dir
0000-1000 Map 1 overlaps boot block! 0000-1000 Map 1 overlaps boot block!
0C00 Invalid! 0C00 Invalid!
......@@ -83,10 +83,10 @@ available from FileCore_MiscOp 6) that if the disc has a sector size of
2K or more (1K or more if long filenames are not used), that the disc can
only be allocated 2 or more zones.
A slightly higher limit on sector size is impose by the zone_spare field
A slightly higher limit on sector size is imposed by the zone_spare field
in the disc record. This must be able to represent any number up to
(nearly) the number of bits in a map block, and is itself a 16-bit field.
This limits map blocks, and therefore sectors, to 65536/8 = 8K.
(nearly) the number of bits in a map block, and is itself a 15-bit field.
This limits map blocks, and therefore sectors, to 32768/8 = 4K.
Re-entrancy
......
--- RAMFS.RAMFS.s.RamFS50 Revision-4.14
+++ RAMFS.RAMFS.s.RamFS50 Test-RAMFS-with-4k-sectors
@@ -19,8 +19,15 @@
TTL "Initialisation and FS star commands"
+ GBLL FourKay
+FourKay SETL {TRUE}
+
SkeletonDiscRec ; fields marked * need filling in
+ [ FourKay
+ DCB 12 ; Log2SectorSize
+ |
DCB 10 ; Log2SectorSize
+ ]
DCB 1 ; SecPerTrk (this is a RAM disc, after all)
DCB 1 ; Heads
DCB DensitySingle ; Density
@@ -117,7 +124,11 @@
MOV r4, #0
STMIA r2, {r0,r3,r4} ; byte address 0 on drive 0
MOV r3, #0
+ [ FourKay
+ MOV r4, #4096
+ |
MOV r4, #1024
+ ]
LDR r8, FileCorePrivate
SWI XFileCore_DiscOp64
ADD sp, sp, #SzExtendedDiscAddress
@@ -194,7 +205,11 @@
; r6 = number of bits in a zone
; r7 = number of allocation bits in the map
; r8 = ids per zone
+ [ FourKay
+Min_IdLen * 12+3 ; min allowed idlen (with 4096 byte zones)
+ |
Min_IdLen * 10+3 ; min allowed idlen (with 1024 byte zones)
+ ]
[ BigMaps
Max_IdLen * 19 ; max allowed idlen
|
@@ -204,7 +219,11 @@
Max_Log2bpmb * 12 ; max allowed bytes per map bit
Min_ZoneSpare * 32 ; min allowed zonespare
Max_ZoneSpare * 64 ; max allowed zonespare
+ [ FourKay
+Min_Zones * 2 ; min allowed zones
+ |
Min_Zones * 1 ; min allowed zones
+ ]
Max_Zones * 16 ; max allowed zones
MOV r0, #Min_Log2bpmb ; init log2bpmb
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "3.62"
Module_Version SETA 362
Module_MajorVersion SETS "3.63"
Module_Version SETA 363
Module_MinorVersion SETS ""
Module_Date SETS "18 Jul 2013"
Module_ApplicationDate SETS "18-Jul-13"
Module_Date SETS "20 Jul 2013"
Module_ApplicationDate SETS "20-Jul-13"
Module_ComponentName SETS "FileCore"
Module_ComponentPath SETS "castle/RiscOS/Sources/FileSys/FileCore"
Module_FullVersion SETS "3.62"
Module_HelpVersion SETS "3.62 (18 Jul 2013)"
Module_FullVersion SETS "3.63"
Module_HelpVersion SETS "3.63 (20 Jul 2013)"
END
/* (3.62)
/* (3.63)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 3.62
#define Module_MajorVersion_CMHG 3.63
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 18 Jul 2013
#define Module_Date_CMHG 20 Jul 2013
#define Module_MajorVersion "3.62"
#define Module_Version 362
#define Module_MajorVersion "3.63"
#define Module_Version 363
#define Module_MinorVersion ""
#define Module_Date "18 Jul 2013"
#define Module_Date "20 Jul 2013"
#define Module_ApplicationDate "18-Jul-13"
#define Module_ApplicationDate "20-Jul-13"
#define Module_ComponentName "FileCore"
#define Module_ComponentPath "castle/RiscOS/Sources/FileSys/FileCore"
#define Module_FullVersion "3.62"
#define Module_HelpVersion "3.62 (18 Jul 2013)"
#define Module_LibraryVersionInfo "3:62"
#define Module_FullVersion "3.63"
#define Module_HelpVersion "3.63 (20 Jul 2013)"
#define Module_LibraryVersionInfo "3:63"
......@@ -2013,7 +2013,7 @@ DoDefectMapOut ROUT
STRVS r0, [sp, #0*4]
Pull "R0-R11,PC"
|
| ; BigDisc
[ DebugQ
DLINE "Updating the bad block list"
......@@ -2079,6 +2079,7 @@ DoDefectMapOut ROUT
STRB R2, [R0, R1]
MOV R1, #DiscOp_WriteSecs :OR: DiscOp_Op_IgnoreEscape_Flag
AND R2, R3, #DiscBits
ASSERT :LNOT: BigSectors
ADD R2, R2, #DefectListDiscAdd
MOV R3, R0
MOV R4, #SzDefectList
......@@ -2196,42 +2197,13 @@ UpdateBadBlockList ROUT
STR LR, [R4, #4]
CMPS R4, R1
BHI %BT36
STR R2, [R1]
STR R2, [R1] ; Insert
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
B %FT59 ; Checksum it and write it out
40
; second defect list present. Have to find its end too, and bump it up if need be
MOV R6, R4
......@@ -2256,14 +2228,14 @@ UpdateBadBlockList ROUT
STR LR, [R6, #4]
CMPS R6, R1
BHI %BT46
STR R2, [R1]
B %BT37 ;use original code to checksum list
STR R2, [R1] ; Insert
MOV R4, R0
MOV R1, #0
B %FT59 ; Checksum it and write it out
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.
; and use similar code to that above to adjust the list.
; for safety, check if second defect list actually present
; if not there then do nothing. (Could be unix disc)
......@@ -2315,7 +2287,7 @@ UpdateBadBlockList ROUT
STR LR, [R4, #4]
CMPS R4, R1
BHI %BT56
STR R2, [R1]
STR R2, [R1] ; Insert
MOV R4, R6
MOV R1, #0
......@@ -2323,7 +2295,7 @@ UpdateBadBlockList ROUT
LDR LR, [R4], #4
TSTS LR, #DiscBits
EOREQ R1, LR, R1, ROR #13
BEQ %BT39
BEQ %BT59
EOR R1, R1, R1, LSR #16
EOR R1, R1, R1, LSR #8
STRB R1, [R4, #-4]
......@@ -2339,14 +2311,49 @@ UpdateBadBlockList ROUT
AND R2, R3, #DiscBits
ADD R2, R2, LR, LSR R1
[ BigSectors
; The defect list might not be on a sector boundary anymore
ASSERT (DefectListDiscAdd :MOD: 1024) = 0
CMP R1, #10
MOVLS R3, R0 ; Go direct
MOVLS R4, #SzDefectList
BLS %FT78
[ DebugQ
DLINE "Having to read/modify/write defect list"
]
Push "R0-R2"
ASSERT ?ScratchSpace >= SzDefectList
MOV R3, #ScratchSpace
ASSERT SzDefectList <= 1:SHL:11
MOV R4, #1
MOV R4, R4, LSL R1
MOV R1, #DiscOp_ReadSecs :OR: DiscOp_Op_IgnoreEscape_Flag
BL DoDiscOp ;(R1-R4->R0,R2-R4,V)
ADDVS sp, sp, #3*4
BVS %FT81
LDMIA sp, {R0-R1} ; R0 := src R1 := Log2SectorSize
MOV R14, #DefectListDiscAdd
MOV R2, R14, LSR R1
SUB R1, R14, R2, LSL R1 ; defect list addr MOD sector size
ADD R1, R1, #ScratchSpace ; dest
MOV R2, #SzDefectList ; len
ASSERT (SzDefectList :MOD: 256) = 0
BL Move256n ; (R0-R2->R0-R2)
Pull "R0-R2"
MOV R3, #ScratchSpace
MOV R4, #1
MOV R4, R4, LSL R1 ; ...and write back
78
|
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"
......
......@@ -31,6 +31,9 @@ BigMaps SETL {TRUE}
GBLL BigDir ; Big directories
BigDir SETL {TRUE}
GBLL BigSectors ; Allow sector sizes of 2kB and 4kB
BigSectors SETL {TRUE}
GBLL DynamicMaps ; Maps go in dynamic areas
DynamicMaps SETL {TRUE}
......
......@@ -997,7 +997,11 @@ RetryDriveOp ROUT
Pull "R0,R6-R8,PC"
; These emergency values are for the case where these fields are 0
[ BigSectors
Emergency_SectorSize * 12
|
Emergency_SectorSize * 10
]
Emergency_Heads * 1
Emergency_SecsPerTrk * 1
......
......@@ -425,7 +425,7 @@ DetermineDiscType ROUT
; disc is changed or not changed.
LDRB r0, [r5, #DiscFlags]
[ DebugL
DREG r0, "DiscFlags picked up to be "
DREG r0, "DiscFlags in DetermineDiscType are "
]
TST r1, #4
BICEQ r0, r0, #FloppyFlag
......@@ -959,18 +959,30 @@ ReadDefectList ROUT
]
; It's a FileCore hard disc, read the bad block list
MOV r4, #SzDefectList
LDR r3, DefectSpace
ADD r3, r3, SB
ASSERT SzDefectList = (1 :SHL: 9)
ADD r3, r3, r1, ASL #9
MOV r4, #SzDefectList
MOV r2, r1, ASL #(32-3)
[ BigSectors
; For 2k and 4k sector sizes the defect list isn't on a sector boundary
; any more, so read via an intermediate buffer
LDRB r2, [r5, #DiscRecord_Log2SectorSize]
ASSERT (DefectListDiscAdd :MOD: 1024) = 0
CMP r2, #10
ASSERT ?ScratchSpace >= SzDefectList
MOVHI r3, #ScratchSpace
ASSERT SzDefectList <= 1:SHL:11
MOVHI r4, #1
MOVHI r4, r4, LSL r2
]
MOV r2, r1, ASL #(32-3) ; Top 3 drive bits
MOV r1, #DiscOp_CachedReadSecs
[ BigDisc
Push "R10,R11"
LDRB r11, [r5, #DiscRecord_Log2SectorSize] ; get sector size
LDRB r11, [r5, #DiscRecord_Log2SectorSize]
MOV r10,#DefectListDiscAdd
ORR r2,r2,r10,LSR r11
ORR r2,r2,r10,LSR r11 ; Offset in sectors
Pull "R10,R11"
|
ORR r2, r2, #DefectListDiscAdd
......@@ -978,6 +990,7 @@ ReadDefectList ROUT
BL RetryDriveOp
BVS %FT90 ; Bog it, defect list didn't read
; Assume defect list is OK as it must have been checked in identifying the disc
; Restore r1,r2 and r4 (and r3 too, but don't care about that)
......@@ -993,6 +1006,22 @@ ReadDefectList ROUT
ADD r3, r3, SB
ASSERT SzDefectList = (1 :SHL: 9)
ADD r3, r3, r1, ASL #9
[ BigSectors
LDRB r0, [r5, #DiscRecord_Log2SectorSize]
CMP r0, #10
BLS %FT10 ; Was directly loaded
MOV r14, #DefectListDiscAdd
MOV r1, r14, LSR r0
SUB r0, r14, r1, LSL r0 ; R0 := defect list addr MOD sector size
ADD r0, r0, #ScratchSpace ; src
MOV r1, r3 ; dest
MOV r2, #SzDefectList ; len
ASSERT (SzDefectList :MOD: 256) = 0
BL Move256n ; (R0-R2->R0-R2)
10
]
ADD r3, r3, #DefectStruc
; Copy zones to our disc record
......@@ -1003,7 +1032,7 @@ ReadDefectList ROUT
STRB r0, [r5, #DiscRecord_BigMap_NZones2]
]
; If zones <> 0, then copy ZoneSpare and BitSize too for E format
; If zones <> 0, then copy ZoneSpare and Log2bpmb too for E format
TEQ r0, #0
LDRNEB r0, [r3, #DiscRecord_ZoneSpare]
STRNEB r0, [r5, #DiscRecord_ZoneSpare]
......@@ -1024,36 +1053,22 @@ ReadDefectList ROUT
DLINE "It's a floppy...no defect list to read"
]
[ BigDisc
; It's a FileCore floppy disc, read byte 2 to test bit 7 of it
; It's a FileCore floppy disc, read sector 0 byte 2 to test bit 7 of it
SUB sp, sp, #4
MOV r3, sp ; read to the stack
MOV r4, #4 ; 4 bytes to read
MOV r2, r1, ASL #(32-3)
MOV r1, #DiscOp_CachedReadSecs
BL RetryDriveOp
LDRB r0, [sp,#2]
LDRB r0, [sp,#FreeLink + 1]
ADD sp, sp, #4
|
; It's a FileCore floppy disc, read byte 2 to test bit 7 of it
SUB sp, sp, #4
MOV r3, sp ; read to the stack
MOV r4, #1 ; 1 byte to read
MOV r2, r1, ASL #(32-3)
ADD r2, r2, #2 ; byte 2
MOV r1, #DiscOp_CachedReadSecs
BL RetryDriveOp
LDRB r0, [sp]
ADD sp, sp, #4
]
; Restore r1,r2 and r4 (and r3 too, but don't care about that)
LDMIB sp, {r1-r4}
BVS %FT30 ; Byte 2 didn't read, but it is a floppy, hence it must be an E floppy
BVS %FT30 ; Byte 2 didn't read, but it is a floppy, assume it's an E floppy
; Might be E format
TST r0, #bit7
TST r0, #bit7 ; Check for FreeLink end bit
BNE %FT30
; It's a D or L format disc
......@@ -1299,7 +1314,7 @@ ReadFsMap ROUT
; Adjust DiscFlags in r11
LDRB r11, [r5, #DiscFlags]
[ DebugL
DREG r11, "DiscFlags picked up to be "
DREG r11, "DiscFlags in ReadFsMap are "
]
[ BigMaps
......
......@@ -464,8 +464,13 @@ MyOpenFile ROUT
MOVNE LR, #1
MOVNE LR, LR, LSL R1
BLEQ ReadAllocSize ;(R3->LR)
[ BigSectors
CMPS LR, #4*K
MOVHI LR, #4*K ; because FcbBufSz is only 1 byte
|
CMPS LR, #1*K
MOVHI LR, #1*K
]
MOV LR, LR, LSR #BufScale
STRB LR, [R9, #FcbBufSz]
......
......@@ -60,7 +60,12 @@ GetBytesEntry ROUT
CMPCC R5, #-1*K
BCS %FT03
]
[ BigSectors
; If sector size larger than buffer size, use foreground
LDRB R5, [r1, #FcbBufSz]
CMP R5, #1*K :SHR: BufSz
BHI %FT03
]
; Do in background if got some file buffers
LDRB R5, MaxFileBuffers
TEQS R5, #0
......@@ -991,7 +996,12 @@ PutBytesEntry ROUT
CMPCC R5, #-1*K
BCS %FT03
]
[ BigSectors
; If sector size larger than buffer size, use foreground
LDRB R5, [r1, #FcbBufSz]
CMP R5, #1*K :SHR: BufSz
BHI %FT03
]
; Do in background if got some file buffers
LDRB R5, MaxFileBuffers
TEQ R5, #0
......
......@@ -358,6 +358,34 @@ DoSwiLayoutStructure ROUT
LayoutBootBlock ROUT
Push "r0-r5,lr"
[ BigSectors
; Check the zones and sector size don't result in an invalid combination
[ BigMaps
LDRB r4, [r0, #DiscRecord_NZones]
LDRB r14, [r0, #DiscRecord_BigMap_NZones2]
ADD r4, r4, r14, LSL #8
|
LDRB r4, [r0, #DiscRecord_NZones]
]
TEQ r4, #1
BNE %FT10 ; Not the 1 zone case, all combinations valid
LDRB r4, [r0, #DiscRecord_Log2SectorSize]
CMP r4, #10
MOVHI r0, #MapFullErr ; For 2k and 4k the map overlaps the boot block
BHI %FT90
BCC %FT10 ; 256 & 512 are always safe
[ BigDir
LDR r14, [r0, #DiscRecord_BigDir_DiscVersion]
TEQ r14, #0
MOVEQ r0, #DirFullErr ; For 1k new dirs the root dir overlaps the boot block
BEQ %FT90 ; while big dirs are OK as the root is in another object
|
MOV r0, #DirFullErr
B %FT90
]
10
]
; Somewhere to construct the boot block
MOV r4, #ScratchSpace
......
......@@ -897,11 +897,15 @@ SanityCheckEDiscRecord ROUT
TEQ r14, #1 ; EQ iff density=0 zones=1
BNE %FT85
MOV r14, #1
LDRB r1, [sp, #DiscRecord_Log2SectorSize]
[ BigSectors
CMP r1, #10 ; Can't be 1 zone with 2k or 4k sectors
BHI %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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment