===========================================================================
| 265 | |
| 266 | //=========================================================================== |
| 267 | bool Util_ProDOS_AddFile (uint8_t* pDiskBytes, const size_t nDiskSize, const char* pVolumeName, const uint8_t* pFileData, const size_t nFileSize, ProDOS_FileHeader_t &meta, const bool bAllowSparseFile = false) |
| 268 | { |
| 269 | assert( pFileData ); |
| 270 | |
| 271 | int iBase = ProDOS_BlockGetPathOffset( pDiskBytes, nullptr, "/" ); // On an empty disk this will be PRODOS_ROOT_OFFSET |
| 272 | int iDirBlock = iBase / PRODOS_BLOCK_SIZE; |
| 273 | |
| 274 | ProDOS_VolumeHeader_t tVolume; |
| 275 | ProDOS_VolumeHeader_t *pVolume = &tVolume; |
| 276 | memset( pVolume, 0, sizeof(ProDOS_VolumeHeader_t) ); |
| 277 | |
| 278 | ProDOS_GetVolumeHeader( pDiskBytes, pVolume, iDirBlock ); |
| 279 | |
| 280 | // Verify we have room in the current directory |
| 281 | int iFreeOffset = ProDOS_DirGetFirstFreeEntryOffset( pDiskBytes, pVolume, iBase ); |
| 282 | if (iFreeOffset <= 0) |
| 283 | return false; // disk full |
| 284 | |
| 285 | int iKind = PRODOS_KIND_DEL; |
| 286 | int nBlocksData = (int)((nFileSize + PRODOS_BLOCK_SIZE - 1) / PRODOS_BLOCK_SIZE); |
| 287 | int nBlocksIndex = 0; // Num Blocks needed for meta (Index) |
| 288 | int nBlocksTotal = 0; |
| 289 | int nBlocksFree = 0; |
| 290 | int iNode = 0; // Master Index, Single Index, or 0 if none |
| 291 | int iIndexBase = 0; // Single Index |
| 292 | int iMasterIndex = 0; // master block points to N IndexBlocks |
| 293 | |
| 294 | // Calculate size of meta blocks and kind of file |
| 295 | if (nFileSize <= 1*PRODOS_BLOCK_SIZE) // <= 512, 1 Block |
| 296 | { |
| 297 | iKind = PRODOS_KIND_SEED; |
| 298 | } |
| 299 | else |
| 300 | if (nFileSize > 256*PRODOS_BLOCK_SIZE) // >= 128K, 257-65536 Blocks |
| 301 | { |
| 302 | iKind = PRODOS_KIND_TREE; |
| 303 | nBlocksIndex = (nBlocksData + (PRODOS_BLOCK_SIZE/2-1)) / (PRODOS_BLOCK_SIZE / 2); |
| 304 | nBlocksIndex++; // include master index block |
| 305 | } |
| 306 | else |
| 307 | if( nFileSize > PRODOS_BLOCK_SIZE ) // <= 128K, 2-256 blocks |
| 308 | { |
| 309 | iKind = PRODOS_KIND_SAPL; |
| 310 | nBlocksIndex = 1; // single index = PRODOS_BLOCK_SIZE/2 = 256 data blocks |
| 311 | } |
| 312 | |
| 313 | // We simply can't set nBlocksTotal |
| 314 | // nBlocksTotal = nBlocksIndex + nBlocksData; |
| 315 | // Since we may have sparse blocks |
| 316 | nBlocksTotal = nBlocksIndex; |
| 317 | |
| 318 | for( int iBlock = 0; iBlock < nBlocksIndex; iBlock++ ) |
| 319 | { |
| 320 | // Blank Volume |
| 321 | // 0 ] Boot Apple //e |
| 322 | // 1 ] Boot Apple /// |
| 323 | // 2 \ Root Directory |
| 324 | // 3 | |
no test coverage detected