1 /***************************************************************************
3 * pisDOS FS support (r/o)
5 * Written by Ketmar Dark <ketmar@ketmar.no-ip.org>
6 * Used some information from HalfElf XiSD FAR plugin
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 3 of the License ONLY.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 **************************************************************************/
21 #ifndef PISDOS_FS_SUPPORT_H
22 #define PISDOS_FS_SUPPORT_H
24 #include "diskfs_p3dos.h"
27 // ////////////////////////////////////////////////////////////////////////// //
28 typedef struct __attribute__((packed
)) {
39 typedef struct __attribute__((packed
)) {
40 uint16_t parent_dir_block
;
52 typedef struct __attribute__((packed
)) {
56 union __attribute__((packed
)) {
64 typedef struct __attribute__((packed
)) {
70 uint16_t blocks_total
;
71 uint16_t rootdir_block
;
75 uint8_t sectors_per_track
;
78 PisDOS_DEFile isd_sys
;
79 uint8_t sector_table
[0x10]; // dunno
93 // doesn't modify time part
94 void pisdos_unpack_date (PisDOSDateTime
*dt
, uint16_t v
);
96 // doesn't modify date part
97 void pisdos_unpack_time (PisDOSDateTime
*dt
, uint16_t v
);
100 #define PISDOS_BLOCK_SIZE (256)
102 #define PISDOS_FLAG_USED (0x01)
103 #define PISDOS_FLAG_NO_READ (0x04)
104 #define PISDOS_FLAG_NO_WRITE (0x08)
105 #define PISDOS_FLAG_HIDDEN (0x10)
106 #define PISDOS_FLAG_DIR (0x20)
107 #define PISDOS_FLAG_CONTINUOUS (0x40)
108 #define PISDOS_FLAG_NO_DELETE (0x80)
111 // dummy DE for root dir
112 extern const PisDOS_DirEnt pisdos_deroot
;
115 static __attribute__((unused
)) inline int pisdos_is_dir (const PisDOS_DirEnt
*h
) {
116 return (h
->attr
!= 0xFF && h
->file
.sys_flag
!= 0xFF && (h
->attr
&PISDOS_FLAG_DIR
));
119 static __attribute__((unused
)) inline uint32_t pisdos_get_entry_size (const PisDOS_DirEnt
*h
) {
121 pisdos_is_dir(h
) ? h
->dir
.size
:
122 h
->file
.size
[0]|(h
->file
.size
[1]<<8)|(h
->file
.size
[2]<<16);
126 void pisdos_get_title (char fname
[14], const PisDOS_DPB
*dpb
);
128 void pisdos_get_name (char fname
[14], const PisDOS_DirEnt
*de
);
129 void pisdos_set_name (PisDOS_DirEnt
*de
, const char fname
[14]);
131 // return NULL if disk doesn't look like a good pisdos disk
132 const PisDOS_DPB
*pisdos_get_dpb (disk_t
*dsk
);
134 // return pointer to the given disk block data, or NULL
135 const void *pisdos_block_ptr (disk_t
*dsk
, int blknum
);
138 // ////////////////////////////////////////////////////////////////////////// //
141 typedef struct __attribute__((packed
)) {
142 uint16_t start_block
; // of this fragment data
143 uint8_t block_count
; // number of blocks in this fragment
148 uint8_t frag_count
; // number of fragments; if 1, the file is continuous
149 PisDOSFragInfo frags
[256]; // starting blocks of each fragment data
150 // for continuous files (files with one fragment are converted to this too)
151 uint16_t start_block
; // of this fragment data
152 uint16_t block_count
; // number of blocks in this fragment
153 // this is for file reading
154 uint8_t curr_frag
; // current active fragment (from 0)
155 uint16_t curr_block_idx
; // from the start of the current fragment
159 // to read pisdos file, find it, build frags, and keep calling
160 // `pisdos_next_block()` until you read enough 256-byte blocks
163 // build list of fragments for the given file
164 // return 0 on success, negative number on error
165 int pisdos_build_frags (disk_t
*dsk
, const PisDOS_DirEnt
*de
, PisDOSFragList
*list
);
167 // return pointer to the next file block
168 // if called right after `pisdos_build_frags`, return pointer to the first block
169 // return NULL on error or EOF (nobody cares what exactly happened anyway)
170 const void *pisdos_next_block (disk_t
*dsk
, PisDOSFragList
*list
);
173 // iterator callback for the next function
174 // return non-zero to stop
175 typedef int (*pisdor_dir_iterator_cb
) (const PisDOS_DirEnt
*de
, void *udata
);
177 // return iterator callback result or 0
178 // return negative number on error
179 int pisdos_dir_foreach (disk_t
*dsk
, const PisDOS_DirEnt
*dirde
,
180 pisdor_dir_iterator_cb cb
, void *udata
);
183 // return non-zero if the given path is a path to the root directory
184 // note that empty or NULL string considered as "root path"
185 int pisdos_is_root_path (const char *path
);
187 // walk down subdirs starting from `dirde` using `path`
188 // ignore last path entry (filename)
189 // return directory entry to look for the last path entry
190 // 'cmon, do you really care about all this shit?
191 const PisDOS_DirEnt
*pisdos_walk_path (disk_t
*dsk
, const PisDOS_DirEnt
*dirde
,
195 // ////////////////////////////////////////////////////////////////////////// //
199 const PisDOS_DirEnt
*dirde
;
200 const PisDOS_DirEnt
*delist
[256];
206 // exactly what you may thing
207 // supports wildcards
208 const PisDOS_DirEnt
*pisdos_findnext (PisDOSFindInfo
*fi
);
209 const PisDOS_DirEnt
*pisdos_findfirst (PisDOSFindInfo
*fi
, disk_t
*dsk
, const char *fname
);
212 // ////////////////////////////////////////////////////////////////////////// //
214 void pisdos_debug_dump_dpb (disk_t
*dsk
);