4.0 KiB
AGENT_TODO.MD — советы от ИИ-агента к рассмотрению
Копилка предложений от ИИ-агентов. По команде «сохрани совет» агент добавляет сюда новый раздел со сквозным номером. Нумерация не переиспользуется.
Совет #1. DIR_PATH_CHECK.gotoPath: заменить трюк с CHECK_SLASH на JP CHDIR
Статус: на рассмотрении (2026-07-19 применён другой вариант фикса — см. ниже)
Контекст. Баг: из C:\PASCAL после Open("SUB\A.TXT") любой следующий
вызов с относительным путём (Create, Open, ChDir) резолвил путь от
корня диска и падал с #04 PATH_NOT_FOUND. Причина: в DIR_PATH_CHECK.checkDir
при несовпадении, где WorkDirectory ⊋ CurrentDirectory (спуск в
подкаталог), HL входил в .gotoPath уже ЗА терминатором CurrentDirectory,
и FINDDIR.CHECK_SLASH дописывал \ после терминатора, а не вместо него.
SetPath_GetName(CurrentPath) видел C:\PASCAL без завершающего \,
выполнял только reroot через CHDISK и не доходил до CWD, возвращая CF=0.
Применённый вариант (в рабочем дереве): перенос INC DE/INC HL после
JR NZ,.gotoPath — HL остаётся на символе несовпадения (в случае-префиксе это
сам терминатор), CHECK_SLASH находит конец строки за одну итерацию CPIR.
Нулевая дельта по размеру и тактам, основной баг устраняет.
Предлагаемый альтернативный вариант: весь блок .gotoPath
(DSS/DOS_FS.ASM) заменить на:
.gotoPath: LD HL,CORE_BUFFERS.CurrentPath
JP CHDIR
CHDIR (DSS/API/ChDir.asm) уже реализует ровно нужную семантику «пройти
путь, включая последний компонент»: SetPath_GetName + OPENDIR(TMPNAME).
Трюк «дописать \ → пройти путь → стереть \» становится ненужен.
Плюсы относительно применённого варианта:
- ~20 байт → 6 байт (−14 байт); нет вызова
CHECK_SLASH/CPIRвовсе — экономия тактов на любом входе, а не только на баг-кейсе; - уходит зависимость
.gotoPathот входящих HL/BC/AF' (на входе со смены диска BC собирается из неинициализированного AF'); - уходит косяк с затиранием корня: в применённом варианте при
CurrentDirectory="\"и спуске в подкаталог epilogueDEC HL/LD (HL),0превращаетCurrentDirectoryв""(косметика: API #1E CURRDIR_FN вернёт пустую строку вместо"\", самолечится следующим ChDir; в старом коде тот же эффект был на входе со смены диска при CWD=корень).
Минусы/риски: большее семантическое изменение — ошибки возвращают
SetPath_GetName/OPENDIR напрямую, отдельный LD A,PATH_NOT_FOUND после
CHECK_SLASH удаляется; требуется прогон на эмуляторе/железе.
Связанное: удаление дублирующего сравнения диска в .forceCheck
(строки 262–266) — применено (JR NZ,.gotoPath сразу после CALL .checkDrive).