Mass storage groundwork. “Added ls/dir commands with FAT read support over USB mass storage” pulled the xHCI bring-up out of commands_usb.asm’s cmd_usb into a shared xhci_controller_init (caps parse, halt/reset, scratchpad, DCBAA, command+event ring, run — CF on failure) so the new commands_fs.asm could drive the same controller for bulk-only mass storage: Enable Slot → Address Device → GET_DESCRIPTOR → bulk CBW/CSW SCSI READ(10), one 512-byte sector at a time, feeding a FAT12/16/32 root-directory listing.
Filesystem support broadened fast, one commit per format. “Added exFAT support” added MBR partition-type detection plus a GPT path (header at LBA 1, 4 entries/sector, first entry that parses as a valid VBR wins) alongside “EXFAT “ OEM-ID detection. “Added NTFS support” added MFT-cluster/record-size parsing and an AML-free walk of root record 5’s INDEX_ROOT/INDEX_ALLOCATION B-tree entries. “Added cat command” threaded an fs_action/fs_cat_found flag through all three listing walkers (FAT, exFAT, NTFS) so the same traversal either prints every entry or stops at the first name match and streams that file’s clusters instead.
Write support, one format at a time. “Added FAT32 write support” added fs_write_sector (SCSI WRITE(10)) and echo-to-file: create-or-overwrite a root-directory entry, allocating a fresh cluster chain via the FAT. “Added FAT16 write support” reused the same path, adding a fs_is_fat16 mount-time branch (FAT12 vs FAT16 disambiguated by the classic <4085-cluster rule; FAT12’s packed 12-bit entries stayed explicitly unsupported). “Added exFAT write support” extended fs_build_target_name to track a display-cased name (fs_target_disp) alongside the raw match name, and added its own root-entry alloc/overwrite path capped at 15-char names. “Added NTFS write support” was the big one (~1500 lines) and the slowest by far — about 8 hours to get right: update-sequence fixup read/write (fs_write_fixup, inverse of the existing fixup-apply), MFT record allocation via $MFT’s $BITMAP, resident $DATA overwrite-in-place, and — for new files — a full FILE record build plus INDEX_ROOT insertion into record 5, gated to root-only files with no INDEX_ALLOCATION. The attached screenshot is an NTFS volume end to end: ls listing System Volume Information and test.txt, an echo ... > file.txt walking through the debug trace (search → create path → alloc ref → build record → indx-alloc insert → ok), and cat file.txt reading the freshly written content back.