drive.txt (2893B) - raw
1 # Drive 2 3 The Drive struct offers a unified API to read and write to mass storage. It 4 does so in blocks of bytes of a definite size which we call "sector". Sectors 5 in the Drive API are organized in a linear manner (LBA, Logical Block 6 Addressing). If the underlying mass storage driver interfaces with a CHS 7 (cylinder, head, sector) system, it's the driver's responsibility to convert LBA 8 to CHS. 9 10 The /lib/drive unit contains utilities around the Drive structure. This unit in 11 split in two, between /lib/drivelo and lib/drive. /lib/drivelo is designed to be 12 used at boot time. /lib/drive complements it with additional features. 13 14 Fields: 15 16 secsz size in bytes of each sector read and written by the driver. 17 It's often 512. 18 seccnt Number of sectors in the drive 19 20 Methods: 21 22 :sec@ ( sec dst drv -- ) 23 Read sector "sec" in memory address "dst", which needs to be a buffer at least 24 "secsz" in size. "drv" is a pointer to a Drive structure. 25 26 :sec! ( sec src drv -- ) 27 Write sector "sec" from memory address "src". 28 29 ## SectorWindow 30 31 A SectorWindow is a buffer referencing one or more sectors and holding one 32 sector in memory. It manages the "dirty" status of the buffer and makes it easy 33 to seek within the window, automatically managing buffer status. 34 35 For example, one could open a SectorWindow of 4 512b sectors, starting at sector 36 $2a. The buffer would begin holding sector $2a in its :buf(. The user could 37 :seek relative address $212 within it, which would make it select sector $2b and 38 return address $12 relative to :buf(. If the dirty flag is set, the buffer 39 ensures that the contents is saved before loading a new one. 40 41 Fields: 42 43 drv Target Drive 44 fsec First sector of the window 45 cnt Number of sectors in the window 46 sec Sector currently in buffer 47 dirty Whether the buffer is dirty 48 49 Words: 50 51 :new ( drv -- secwin ) 52 Create a new buffer targeting Drive "drv", on sector 0, cnt 1. Current buffer 53 starts uninitialized. 54 55 :buf( ( self -- a ) 56 Address of the buffer. 57 58 :)buf ( self -- a ) 59 End of the buffer. 60 61 :move ( fsec cnt self -- ) 62 Move window to "fsec" with "cnt" sectors. This doesn't change or flush the 63 current buffer. 64 65 :fulldrv ( self -- ) 66 Move the window so that it spans the whole drive. 67 68 :load ( sec self -- ) 69 Load sector "sec" in the buffer. Aborts if outside the window. 70 71 :flush ( self -- ) 72 If buffer is dirty, save it. 73 74 :seek ( pos self -- a? n-or-0 ) 75 Load, if needed, the correct sector so that the position "pos", in bytes 76 relative to the beginning of "fsec", is available in the buffer. Returns its 77 address in "a" as well as the number of bytes that can be read before the end 78 of the buffer is reaches, as "n". If "pos" is outside the window, "n" is 0 and 79 "a" is absent. 80 81 :next ( self -- a? n-or-0 ) 82 :seek the first byte of the sector following the one currently in the buffer. 83 84 :dirty! ( self -- ) 85 Make the buffer dirty.