/kernel/trunk/sec_loader/trunk/boot/after_win/kordldr.win.txt |
---|
24,368 → 24,368 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Нет повести печальнее на свете, |
Чем повесть о заклинившем Reset'е... |
Íåò ïîâåñòè ïå÷àëüíåå íà ñâåòå, |
×åì ïîâåñòü î çàêëèíèâøåì Reset'å... |
Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает |
Windows, для носителей с размером сектора 512 байт. |
Çàãðóç÷èê äëÿ FAT- è NTFS-òîìîâ äëÿ ñëó÷àåâ, êîãäà îñíîâíîé áóòñåêòîð çàãðóæàåò |
Windows, äëÿ íîñèòåëåé ñ ðàçìåðîì ñåêòîðà 512 áàéò. |
===================================================================== |
Требования для работы: |
1) Все используемые файлы должны быть читабельны. |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 592K свободной базовой памяти. |
4) Пути к используемым файлам не должны содержать символических ссылок NTFS |
(жёсткие ссылки допускаются). |
5) Используемые файлы не должны быть сжатыми или разреженными файлами |
(актуально для NTFS, для FAT выполнено автоматически). |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè. |
4) Ïóòè ê èñïîëüçóåìûì ôàéëàì íå äîëæíû ñîäåðæàòü ñèìâîëè÷åñêèõ ññûëîê NTFS |
(æ¸ñòêèå ññûëêè äîïóñêàþòñÿ). |
5) Èñïîëüçóåìûå ôàéëû íå äîëæíû áûòü ñæàòûìè èëè ðàçðåæåííûìè ôàéëàìè |
(àêòóàëüíî äëÿ NTFS, äëÿ FAT âûïîëíåíî àâòîìàòè÷åñêè). |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 08.08.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys |
и file://C:/ntldr либо file://C:/bootmgr |
неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx |
официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx |
формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 08.08.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
ñïåöèôèêàöèÿ NTFS: file://C:/windows/system32/drivers/ntfs.sys |
è file://C:/ntldr ëèáî file://C:/bootmgr |
íåîôèöèàëüíîå îïèñàíèå NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
îôèöèàëüíîå îïèñàíèå bcdedit äëÿ Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx |
îôèöèàëüíîå îïèñàíèå ðàáîòû ñ áàçîé äàííûõ çàãðóç÷èêà Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx |
ôîðìàò òàáëèöû ðàçäåëîâ æ¸ñòêîãî äèñêà: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx |
===================================================================== |
Схема используемой памяти: |
600-2000 код загрузчика (и данные) |
2000-3000 стек |
3000-3200 сектор MBR |
3200-3400 бутсектор логического диска |
3400-3C00 информация о кэше для таблиц FAT16/FAT32: |
для FAT16 - массив на 0x100 байт, каждый байт равен |
0 или 1 в зависимости от того, загружен ли |
соответствующий сектор таблицы FAT16; |
для FAT32 - 100h входов по 8 байт: 4 байта |
(две ссылки - вперёд и назад) для организации L2-списка |
всех прочитанных секторов в порядке возрастания |
последнего времени использования + 4 байта для номера |
сектора; при переполнении кэша выкидывается элемент из |
головы списка, то есть тот, к которому дольше всех |
не было обращений |
3400-3440 информация о кэше для файловых записей NTFS в |
таком же формате, как и кэш для FAT32, но на 8 входов |
3480-34C0 заголовки для кэшей записей индекса NTFS |
3500-3D00 информация о кэшах записей индекса NTFS: с каждой |
файловой записью связан свой кэш для |
соответствующего индекса |
4000-8000 место для информации об атрибутах для NTFS |
60000-80000 таблица FAT12 / место под таблицу FAT16 / |
кэш для таблицы FAT32 / кэш для структур NTFS |
80000-90000 текущий рассматриваемый кластер |
90000-92000 FAT: кэш для корневой папки |
92000-... FAT: кэш для некорневых папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 7 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
600-2000 êîä çàãðóç÷èêà (è äàííûå) |
2000-3000 ñòåê |
3000-3200 ñåêòîð MBR |
3200-3400 áóòñåêòîð ëîãè÷åñêîãî äèñêà |
3400-3C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèö FAT16/FAT32: |
äëÿ FAT16 - ìàññèâ íà 0x100 áàéò, êàæäûé áàéò ðàâåí |
0 èëè 1 â çàâèñèìîñòè îò òîãî, çàãðóæåí ëè |
ñîîòâåòñòâóþùèé ñåêòîð òàáëèöû FAT16; |
äëÿ FAT32 - 100h âõîäîâ ïî 8 áàéò: 4 áàéòà |
(äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ îðãàíèçàöèè L2-ñïèñêà |
âñåõ ïðî÷èòàííûõ ñåêòîðîâ â ïîðÿäêå âîçðàñòàíèÿ |
ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ + 4 áàéòà äëÿ íîìåðà |
ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà âûêèäûâàåòñÿ ýëåìåíò èç |
ãîëîâû ñïèñêà, òî åñòü òîò, ê êîòîðîìó äîëüøå âñåõ |
íå áûëî îáðàùåíèé |
3400-3440 èíôîðìàöèÿ î êýøå äëÿ ôàéëîâûõ çàïèñåé NTFS â |
òàêîì æå ôîðìàòå, êàê è êýø äëÿ FAT32, íî íà 8 âõîäîâ |
3480-34C0 çàãîëîâêè äëÿ êýøåé çàïèñåé èíäåêñà NTFS |
3500-3D00 èíôîðìàöèÿ î êýøàõ çàïèñåé èíäåêñà NTFS: ñ êàæäîé |
ôàéëîâîé çàïèñüþ ñâÿçàí ñâîé êýø äëÿ |
ñîîòâåòñòâóþùåãî èíäåêñà |
4000-8000 ìåñòî äëÿ èíôîðìàöèè îá àòðèáóòàõ äëÿ NTFS |
60000-80000 òàáëèöà FAT12 / ìåñòî ïîä òàáëèöó FAT16 / |
êýø äëÿ òàáëèöû FAT32 / êýø äëÿ ñòðóêòóð NTFS |
80000-90000 òåêóùèé ðàññìàòðèâàåìûé êëàñòåð |
90000-92000 FAT: êýø äëÿ êîðíåâîé ïàïêè |
92000-... FAT: êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется |
размещением команды install=c:\kordldr.win в первой строке config.sys; |
при этом основной загрузчик системы загружает kordldr.win как обычный |
com-файл, в какой-то сегмент по смещению 100h и передаёт управление |
в начало кода (xxxx:0100). |
0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется |
добавлением строки наподобие c:\kordldr.win="KordOS" в секцию |
[operating systems] файла boot.ini; если загружаемый файл имеет размер |
не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' |
(в случае kordldr.win так и есть), то основной загрузчик каждой из |
этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт |
управление на адрес 0D00:0256. |
0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями |
с базой данных основного загрузчика через bcdedit и подробно описана в |
инструкции к kordldr.win; основной загрузчик загружает целиком |
kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. |
1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная |
им программа окажется в свою очередь загрузчиком, и в этом случае |
kordldr.win оказывается в условиях, когда основной загрузчик уже |
установил какое-то окружение, в частности, перехватил некоторые |
прерывания. Поэтому перед остальными действиями загрузчик должен |
восстановить систему в начальное состояние. (При загрузке под |
NT-линейкой такой проблемы не возникает, поскольку там основной |
загрузчик ничего в системе не трогает.) Поэтому перед собственно |
инициализацией KordOS при работе из-под DOS/9x производятся |
дополнительные действия. Первым делом kordldr проверяет, какой из |
случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт |
управление не на начало кода): определяет значение ip (команда call |
помещает в стек адрес следующей после call инструкции, команда pop si |
выталкивает его в регистр si), и если оно равно 100h, то kordldr |
загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения |
у пользователя (поскольку в этой схеме kordldr загружается всегда, |
он должен оставить возможность продолжить загрузку DOS/9x). Если |
пользователь хочет продолжить обычную загрузку, kordldr завершается. |
Иначе используется тот факт, что при выдаче прерывания перезагрузки |
int 19h система предварительно снимает все свои перехваты BIOSовских |
прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что |
kordldr устанавливает свой обработчик трассировочного прерывания, |
устанавливает флаг трассировки и передаёт управление DOSовскому |
обработчику. Обработчик трассировочного прерывания ничего не делает |
до тех пор, пока следующей инструкцией не оказывается int 19h, а |
в этот момент отбирает управление и продолжает загрузку KordOS. |
При этом BIOSовские обработчики восстановлены за исключением, |
быть может, прерывания таймера int 8, которое, возможно, восстановлено |
до команды jmp far на оригинальный обработчик. В последнем случае его |
нужно восстановить явно. |
2. Загрузчик перемещает свой код на адрес 0000:0600. |
3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, |
настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы |
все данные можно было адресовать через [bp+N] с однобайтовым N |
(в дальнейшем они так и будут адресоваться для освобождения ds и |
экономии на размере кода). Разрешает прерывания на случай, если |
они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся |
с весёлой рожицы (символ с ASCII-кодом 2). |
4. Определяет характеристики жёсткого диска, указанного в качестве |
загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), |
если LBA не поддерживается, то определяет геометрию - число дорожек |
и число секторов на дорожке (функция 8 прерывания 13h), эти параметры |
нужны функции чтения с диска. |
5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. |
Цель цикла - для каждого логического диска попытаться загрузиться с |
него (действия по загрузке с конкретного логического диска начинаются |
с метки not_extended), при ошибке загрузки управление передаётся |
назад этому циклу (метка next_partition), и поиск подходящего раздела |
продолжается. На выходе заполняется одна переменная partition_start, |
имеющая смысл начала текущего рассматриваемого логического диска, |
но по ходу дела из-за приколов таблиц разделов используются ещё четыре |
переменных. cur_partition_ofs - фактически счётчик цикла, формально |
указатель на текущий вход в текущей загрузочной записи. Сама |
загрузочная запись считывается в память начиная с адреса 3000h. |
Три оставшихся нужны для правильной работы с расширенными разделами. |
В каждой загрузочной записи помещается не более 4 записей о разделах. |
Поэтому главной загрузочной записи, размещающейся в первом физическом |
секторе диска, может не хватить, и обычно создаётся так называемый |
расширенный раздел с расширенными загрузочными записями, формат |
которых почти идентичен главной. Расширенный раздел может быть только |
один, но в нём может быть много логических дисков и расширенных |
загрузочных записей. Расширенные загрузочные записи организованы |
в односвязный список, в каждой такой записи первый вход указывает |
на соответствующий логический диск, а второй - на следующую расширенную |
загрузочную запись. |
При этом в главной загрузочной записи все адреса разделов являются |
абсолютными номерами секторов. В расширенных же записях адреса разделов |
относительны, причём с разными базами: адрес логического диска |
указывается относительно расширенной записи, а адрес следующей |
расширенной записи указывается относительно начала расширенного |
раздела. Такой разнобой выглядит несколько странно, но имеет место |
быть. Три оставшихся переменных содержат: extended_part_start - |
начало расширенного раздела; extended_parent - текущая рассматриваемая |
расширенная загрузочная запись; extended_part_cur - следующая |
загрузочная запись для рассмотрения. |
Цикл выглядит так: просматриваются все разделы, указанные в текущей |
(главной или расширенной) загрузочной записи; для нормальных разделов |
(они же логические диски) происходит переход на not_extended, где |
устанавливается partition_start и начинается собственно загрузка |
(последующие шаги); при встрече с разделом, тип которого указывает |
на расширенность (5 или 0xF), код запоминает начало этого раздела |
(в главной загрузочной записи такой тип означает расширенный раздел, |
в расширенной - только указатель на следующую расширенную запись, |
в обоих случаях он может встретиться только один раз в данной записи); |
когда код доходит до конца списка, все нормальные разделы, описываемые |
в этой записи, уже просмотрены, так что код с чистой совестью переходит |
к следующей расширенной записи. Если он её не встретил, значит, уже |
все логические разделы были подвергнуты попыткам загрузиться, и все |
безрезультатно, так что выводится ругательство и работа останавливается |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
0a. Çàãðóçêà èç-ïîä DOS è Win9x: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ |
ðàçìåùåíèåì êîìàíäû install=c:\kordldr.win â ïåðâîé ñòðîêå config.sys; |
ïðè ýòîì îñíîâíîé çàãðóç÷èê ñèñòåìû çàãðóæàåò kordldr.win êàê îáû÷íûé |
com-ôàéë, â êàêîé-òî ñåãìåíò ïî ñìåùåíèþ 100h è ïåðåäà¸ò óïðàâëåíèå |
â íà÷àëî êîäà (xxxx:0100). |
0á. Çàãðóçêà èç-ïîä WinNT/2000/XP: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ |
äîáàâëåíèåì ñòðîêè íàïîäîáèå c:\kordldr.win="KordOS" â ñåêöèþ |
[operating systems] ôàéëà boot.ini; åñëè çàãðóæàåìûé ôàéë èìååò ðàçìåð |
íå ìåíåå 8 Êá (0x2000 áàéò) è ïî ñìåùåíèþ 3 ñîäåðæèò ñèãíàòóðó 'NTFS' |
(â ñëó÷àå kordldr.win òàê è åñòü), òî îñíîâíîé çàãðóç÷èê êàæäîé èç |
ýòèõ ñèñòåì çàãðóæàåò kordldr.win ïî àäðåñó 0D00:0000 è ïåðåäà¸ò |
óïðàâëåíèå íà àäðåñ 0D00:0256. |
0â. Çàãðóçêà èç-ïîä Vista: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ ìàíèïóëÿöèÿìè |
ñ áàçîé äàííûõ îñíîâíîãî çàãðóç÷èêà ÷åðåç bcdedit è ïîäðîáíî îïèñàíà â |
èíñòðóêöèè ê kordldr.win; îñíîâíîé çàãðóç÷èê çàãðóæàåò öåëèêîì |
kordldr.win ïî àäðåñó 0000:7C00 è ïåðåäà¸ò óïðàâëåíèå â íà÷àëî êîäà. |
1. Ïðè çàãðóçêå èç-ïîä DOS/9x îñíîâíîé çàãðóç÷èê íå îæèäàåò, ÷òî çàãðóæåííàÿ |
èì ïðîãðàììà îêàæåòñÿ â ñâîþ î÷åðåäü çàãðóç÷èêîì, è â ýòîì ñëó÷àå |
kordldr.win îêàçûâàåòñÿ â óñëîâèÿõ, êîãäà îñíîâíîé çàãðóç÷èê óæå |
óñòàíîâèë êàêîå-òî îêðóæåíèå, â ÷àñòíîñòè, ïåðåõâàòèë íåêîòîðûå |
ïðåðûâàíèÿ. Ïîýòîìó ïåðåä îñòàëüíûìè äåéñòâèÿìè çàãðóç÷èê äîëæåí |
âîññòàíîâèòü ñèñòåìó â íà÷àëüíîå ñîñòîÿíèå. (Ïðè çàãðóçêå ïîä |
NT-ëèíåéêîé òàêîé ïðîáëåìû íå âîçíèêàåò, ïîñêîëüêó òàì îñíîâíîé |
çàãðóç÷èê íè÷åãî â ñèñòåìå íå òðîãàåò.) Ïîýòîìó ïåðåä ñîáñòâåííî |
èíèöèàëèçàöèåé KordOS ïðè ðàáîòå èç-ïîä DOS/9x ïðîèçâîäÿòñÿ |
äîïîëíèòåëüíûå äåéñòâèÿ. Ïåðâûì äåëîì kordldr ïðîâåðÿåò, êàêîé èç |
ñëó÷àåâ 0à è 0â èìååò ìåñòî (ñëó÷àé 0á îòëè÷àåòñÿ òåì, ÷òî ïåðåäà¸ò |
óïðàâëåíèå íå íà íà÷àëî êîäà): îïðåäåëÿåò çíà÷åíèå ip (êîìàíäà call |
ïîìåùàåò â ñòåê àäðåñ ñëåäóþùåé ïîñëå call èíñòðóêöèè, êîìàíäà pop si |
âûòàëêèâàåò åãî â ðåãèñòð si), è åñëè îíî ðàâíî 100h, òî kordldr |
çàãðóæåí êàê com-ôàéë èç-ïîä DOS/9x. Òîãäà îí ñïðàøèâàåò ïîäòâåðæäåíèÿ |
ó ïîëüçîâàòåëÿ (ïîñêîëüêó â ýòîé ñõåìå kordldr çàãðóæàåòñÿ âñåãäà, |
îí äîëæåí îñòàâèòü âîçìîæíîñòü ïðîäîëæèòü çàãðóçêó DOS/9x). Åñëè |
ïîëüçîâàòåëü õî÷åò ïðîäîëæèòü îáû÷íóþ çàãðóçêó, kordldr çàâåðøàåòñÿ. |
Èíà÷å èñïîëüçóåòñÿ òîò ôàêò, ÷òî ïðè âûäà÷å ïðåðûâàíèÿ ïåðåçàãðóçêè |
int 19h ñèñòåìà ïðåäâàðèòåëüíî ñíèìàåò âñå ñâîè ïåðåõâàòû BIOSîâñêèõ |
ïðåðûâàíèé, à ïîòîì â ñâîþ î÷åðåäü âûäà¸ò int 19h óæå BIOSó. Òàê ÷òî |
kordldr óñòàíàâëèâàåò ñâîé îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ, |
óñòàíàâëèâàåò ôëàã òðàññèðîâêè è ïåðåäà¸ò óïðàâëåíèå DOSîâñêîìó |
îáðàáîò÷èêó. Îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ íè÷åãî íå äåëàåò |
äî òåõ ïîð, ïîêà ñëåäóþùåé èíñòðóêöèåé íå îêàçûâàåòñÿ int 19h, à |
â ýòîò ìîìåíò îòáèðàåò óïðàâëåíèå è ïðîäîëæàåò çàãðóçêó KordOS. |
Ïðè ýòîì BIOSîâñêèå îáðàáîò÷èêè âîññòàíîâëåíû çà èñêëþ÷åíèåì, |
áûòü ìîæåò, ïðåðûâàíèÿ òàéìåðà int 8, êîòîðîå, âîçìîæíî, âîññòàíîâëåíî |
äî êîìàíäû jmp far íà îðèãèíàëüíûé îáðàáîò÷èê.  ïîñëåäíåì ñëó÷àå åãî |
íóæíî âîññòàíîâèòü ÿâíî. |
2. Çàãðóç÷èê ïåðåìåùàåò ñâîé êîä íà àäðåñ 0000:0600. |
3. (ìåòêà real_entry) Çàãðóç÷èê óñòàíàâëèâàåò ñåãìåíòíûå ðåãèñòðû ds = es = 0, |
íàñòðàèâàåò ñòåê ss:sp = 0000:3000 è óñòàíàâëèâàåò bp òàê, ÷òîáû |
âñå äàííûå ìîæíî áûëî àäðåñîâàòü ÷åðåç [bp+N] ñ îäíîáàéòîâûì N |
(â äàëüíåéøåì îíè òàê è áóäóò àäðåñîâàòüñÿ äëÿ îñâîáîæäåíèÿ ds è |
ýêîíîìèè íà ðàçìåðå êîäà). Ðàçðåøàåò ïðåðûâàíèÿ íà ñëó÷àé, åñëè |
îíè áûëè çàïðåùåíû. Âûäà¸ò ñîîáùåíèå î íà÷àëå çàãðóçêè, íà÷èíàþùååñÿ |
ñ âåñ¸ëîé ðîæèöû (ñèìâîë ñ ASCII-êîäîì 2). |
4. Îïðåäåëÿåò õàðàêòåðèñòèêè æ¸ñòêîãî äèñêà, óêàçàííîãî â êà÷åñòâå |
çàãðóçî÷íîãî: ïðîâåðÿåò ïîääåðæêó LBA (ôóíêöèÿ 41h ïðåðûâàíèÿ 13h), |
åñëè LBA íå ïîääåðæèâàåòñÿ, òî îïðåäåëÿåò ãåîìåòðèþ - ÷èñëî äîðîæåê |
è ÷èñëî ñåêòîðîâ íà äîðîæêå (ôóíêöèÿ 8 ïðåðûâàíèÿ 13h), ýòè ïàðàìåòðû |
íóæíû ôóíêöèè ÷òåíèÿ ñ äèñêà. |
5. (ìåòêà new_partition_ex) Óñòðàèâàåò öèêë ïî ðàçäåëàì æ¸ñòêîãî äèñêà. |
Öåëü öèêëà - äëÿ êàæäîãî ëîãè÷åñêîãî äèñêà ïîïûòàòüñÿ çàãðóçèòüñÿ ñ |
íåãî (äåéñòâèÿ ïî çàãðóçêå ñ êîíêðåòíîãî ëîãè÷åñêîãî äèñêà íà÷èíàþòñÿ |
ñ ìåòêè not_extended), ïðè îøèáêå çàãðóçêè óïðàâëåíèå ïåðåäà¸òñÿ |
íàçàä ýòîìó öèêëó (ìåòêà next_partition), è ïîèñê ïîäõîäÿùåãî ðàçäåëà |
ïðîäîëæàåòñÿ. Íà âûõîäå çàïîëíÿåòñÿ îäíà ïåðåìåííàÿ partition_start, |
èìåþùàÿ ñìûñë íà÷àëà òåêóùåãî ðàññìàòðèâàåìîãî ëîãè÷åñêîãî äèñêà, |
íî ïî õîäó äåëà èç-çà ïðèêîëîâ òàáëèö ðàçäåëîâ èñïîëüçóþòñÿ åù¸ ÷åòûðå |
ïåðåìåííûõ. cur_partition_ofs - ôàêòè÷åñêè ñ÷¸ò÷èê öèêëà, ôîðìàëüíî |
óêàçàòåëü íà òåêóùèé âõîä â òåêóùåé çàãðóçî÷íîé çàïèñè. Ñàìà |
çàãðóçî÷íàÿ çàïèñü ñ÷èòûâàåòñÿ â ïàìÿòü íà÷èíàÿ ñ àäðåñà 3000h. |
Òðè îñòàâøèõñÿ íóæíû äëÿ ïðàâèëüíîé ðàáîòû ñ ðàñøèðåííûìè ðàçäåëàìè. |
 êàæäîé çàãðóçî÷íîé çàïèñè ïîìåùàåòñÿ íå áîëåå 4 çàïèñåé î ðàçäåëàõ. |
Ïîýòîìó ãëàâíîé çàãðóçî÷íîé çàïèñè, ðàçìåùàþùåéñÿ â ïåðâîì ôèçè÷åñêîì |
ñåêòîðå äèñêà, ìîæåò íå õâàòèòü, è îáû÷íî ñîçäà¸òñÿ òàê íàçûâàåìûé |
ðàñøèðåííûé ðàçäåë ñ ðàñøèðåííûìè çàãðóçî÷íûìè çàïèñÿìè, ôîðìàò |
êîòîðûõ ïî÷òè èäåíòè÷åí ãëàâíîé. Ðàñøèðåííûé ðàçäåë ìîæåò áûòü òîëüêî |
îäèí, íî â í¸ì ìîæåò áûòü ìíîãî ëîãè÷åñêèõ äèñêîâ è ðàñøèðåííûõ |
çàãðóçî÷íûõ çàïèñåé. Ðàñøèðåííûå çàãðóçî÷íûå çàïèñè îðãàíèçîâàíû |
â îäíîñâÿçíûé ñïèñîê, â êàæäîé òàêîé çàïèñè ïåðâûé âõîä óêàçûâàåò |
íà ñîîòâåòñòâóþùèé ëîãè÷åñêèé äèñê, à âòîðîé - íà ñëåäóþùóþ ðàñøèðåííóþ |
çàãðóçî÷íóþ çàïèñü. |
Ïðè ýòîì â ãëàâíîé çàãðóçî÷íîé çàïèñè âñå àäðåñà ðàçäåëîâ ÿâëÿþòñÿ |
àáñîëþòíûìè íîìåðàìè ñåêòîðîâ. Â ðàñøèðåííûõ æå çàïèñÿõ àäðåñà ðàçäåëîâ |
îòíîñèòåëüíû, ïðè÷¸ì ñ ðàçíûìè áàçàìè: àäðåñ ëîãè÷åñêîãî äèñêà |
óêàçûâàåòñÿ îòíîñèòåëüíî ðàñøèðåííîé çàïèñè, à àäðåñ ñëåäóþùåé |
ðàñøèðåííîé çàïèñè óêàçûâàåòñÿ îòíîñèòåëüíî íà÷àëà ðàñøèðåííîãî |
ðàçäåëà. Òàêîé ðàçíîáîé âûãëÿäèò íåñêîëüêî ñòðàííî, íî èìååò ìåñòî |
áûòü. Òðè îñòàâøèõñÿ ïåðåìåííûõ ñîäåðæàò: extended_part_start - |
íà÷àëî ðàñøèðåííîãî ðàçäåëà; extended_parent - òåêóùàÿ ðàññìàòðèâàåìàÿ |
ðàñøèðåííàÿ çàãðóçî÷íàÿ çàïèñü; extended_part_cur - ñëåäóþùàÿ |
çàãðóçî÷íàÿ çàïèñü äëÿ ðàññìîòðåíèÿ. |
Öèêë âûãëÿäèò òàê: ïðîñìàòðèâàþòñÿ âñå ðàçäåëû, óêàçàííûå â òåêóùåé |
(ãëàâíîé èëè ðàñøèðåííîé) çàãðóçî÷íîé çàïèñè; äëÿ íîðìàëüíûõ ðàçäåëîâ |
(îíè æå ëîãè÷åñêèå äèñêè) ïðîèñõîäèò ïåðåõîä íà not_extended, ãäå |
óñòàíàâëèâàåòñÿ partition_start è íà÷èíàåòñÿ ñîáñòâåííî çàãðóçêà |
(ïîñëåäóþùèå øàãè); ïðè âñòðå÷å ñ ðàçäåëîì, òèï êîòîðîãî óêàçûâàåò |
íà ðàñøèðåííîñòü (5 èëè 0xF), êîä çàïîìèíàåò íà÷àëî ýòîãî ðàçäåëà |
(â ãëàâíîé çàãðóçî÷íîé çàïèñè òàêîé òèï îçíà÷àåò ðàñøèðåííûé ðàçäåë, |
â ðàñøèðåííîé - òîëüêî óêàçàòåëü íà ñëåäóþùóþ ðàñøèðåííóþ çàïèñü, |
â îáîèõ ñëó÷àÿõ îí ìîæåò âñòðåòèòüñÿ òîëüêî îäèí ðàç â äàííîé çàïèñè); |
êîãäà êîä äîõîäèò äî êîíöà ñïèñêà, âñå íîðìàëüíûå ðàçäåëû, îïèñûâàåìûå |
â ýòîé çàïèñè, óæå ïðîñìîòðåíû, òàê ÷òî êîä ñ ÷èñòîé ñîâåñòüþ ïåðåõîäèò |
ê ñëåäóþùåé ðàñøèðåííîé çàïèñè. Åñëè îí å¸ íå âñòðåòèë, çíà÷èò, óæå |
âñå ëîãè÷åñêèå ðàçäåëû áûëè ïîäâåðãíóòû ïîïûòêàì çàãðóçèòüñÿ, è âñå |
áåçðåçóëüòàòíî, òàê ÷òî âûâîäèòñÿ ðóãàòåëüñòâî è ðàáîòà îñòàíàâëèâàåòñÿ |
(jmp $). |
Может возникнуть вопрос, зачем нужна такая сложная схема и почему |
нельзя узнать нужный логический диск заранее или хотя бы ограничиться |
первым попавшимся логическим диском, не крутя цикл. Так вот, вариант |
с предварительным определением нужного раздела в данном случае не |
используется, поскольку повлёк бы за собой нетривиальные лишние |
действия по установке (в текущем виде установку можно провести вручную, |
и она сводится к указанию системному загрузчику на существование |
kordldr); кстати, в альтернативной версии загрузки после |
Windows-загрузчика, когда установка осуществляется не вручную, а |
специальной программой под Windows, используется модифицированная |
версия, в которой как раз начальный физический сектор нужного раздела |
прописывается установщиком. Сам kordldr не может установить, с какого |
раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан |
быть файлом на диске C:\). Вариант с первым попавшимся логическим |
диском был реализован в первой версии загрузчика, но по ходу дела |
обнаружилось, что таки нужно крутить цикл: во-вторых, может быть |
приятным, что сама система может стоять вовсе не на системном C:\, а и |
на других дисках; во-первых, диск C: может и не быть первым логическим |
разделом - Vista любит создавать скрытый первичный раздел перед |
системным, и тогда диск C: становится вторым логическим. |
6. Извещает пользователя о том, что происходит попытка загрузки с очередного |
логического диска. |
7. Читает первый сектор логического диска и определяет файловую систему. |
И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе |
и должно совпадать с характеристикой физического носителя, то есть |
200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число |
секторов в кластере и должно быть степенью двойки. |
Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со |
смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано |
быть ненулевым). |
Критерий FAT: загрузчик вычисляет число кластеров, определяет |
предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению |
+38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). |
После определения типа файловой системы извещает пользователя об |
определённом типе. Если файловая система не распознана, выдаёт |
соответствующее сообщение и переходит к следующему логическому диску. |
8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - |
константу '12'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT12-обработчик; считывает в память всю |
таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке |
чтения пытается использовать другие копии FAT. |
8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - |
константу '16'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию |
о кэше секторов FAT (массив байт с возможными значениями 0 и 1, |
означающими, был ли уже загружен соответствующий сектор - всего в |
таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не |
загружен, все байты нулевые. |
8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - |
константу '32'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию |
о кэше секторов FAT (формат информации описан выше, в распределении |
используемой загрузчиком памяти) - ни один сектор ещё не загружен. |
8г. Общее для FAT-томов: определяет значения служебных переменных |
root_start (первый сектор корневого каталога в FAT12/16, игнорируется |
при обработке FAT32-томов), data_start (начало данных с поправкой, |
вводимой для того, чтобы кластер N начинался с сектора |
N*sectors_per_cluster+data_start), root_clus (первый кластер корневого |
каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию |
загрузки файла на FAT-обработчик. |
8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - |
константу 'nt'; определяет значение служебной переменной frs_size |
(размер в байтах файловой записи, File Record Segment), для полной |
корректности проверяет, что это значение (равное 0x400 байт на всех |
реальных NTFS-томах - единственный способ изменить его заключается |
в пересоздании всех системных структур вручную) не превосходит 0x1000 |
и кратно размеру сектора 0x200 байт; инициализирует кэш файловых |
записей - ничего ещё не загружено; считывает первый кластер $MFT |
и загружает информацию о расположении на диске всей таблицы $MFT |
(атрибут 0x80, $Data); устанавливает указатель на функцию загрузки |
файла на NTFS-обработчик. |
9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного |
загрузчика. При обнаружении ошибки переходит на обработчик ошибок с |
соответствующим сообщением. |
10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), |
ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), |
может быть изменён путём модификации константы в исходнике или |
специальным установщиком), bx=идентификатор файловой системы (берётся |
из стека, куда ранее был засунут на шаге 8), ds:si=указатель на |
callback-функцию. |
11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. |
Ìîæåò âîçíèêíóòü âîïðîñ, çà÷åì íóæíà òàêàÿ ñëîæíàÿ ñõåìà è ïî÷åìó |
íåëüçÿ óçíàòü íóæíûé ëîãè÷åñêèé äèñê çàðàíåå èëè õîòÿ áû îãðàíè÷èòüñÿ |
ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì äèñêîì, íå êðóòÿ öèêë. Òàê âîò, âàðèàíò |
ñ ïðåäâàðèòåëüíûì îïðåäåëåíèåì íóæíîãî ðàçäåëà â äàííîì ñëó÷àå íå |
èñïîëüçóåòñÿ, ïîñêîëüêó ïîâë¸ê áû çà ñîáîé íåòðèâèàëüíûå ëèøíèå |
äåéñòâèÿ ïî óñòàíîâêå (â òåêóùåì âèäå óñòàíîâêó ìîæíî ïðîâåñòè âðó÷íóþ, |
è îíà ñâîäèòñÿ ê óêàçàíèþ ñèñòåìíîìó çàãðóç÷èêó íà ñóùåñòâîâàíèå |
kordldr); êñòàòè, â àëüòåðíàòèâíîé âåðñèè çàãðóçêè ïîñëå |
Windows-çàãðóç÷èêà, êîãäà óñòàíîâêà îñóùåñòâëÿåòñÿ íå âðó÷íóþ, à |
ñïåöèàëüíîé ïðîãðàììîé ïîä Windows, èñïîëüçóåòñÿ ìîäèôèöèðîâàííàÿ |
âåðñèÿ, â êîòîðîé êàê ðàç íà÷àëüíûé ôèçè÷åñêèé ñåêòîð íóæíîãî ðàçäåëà |
ïðîïèñûâàåòñÿ óñòàíîâùèêîì. Ñàì kordldr íå ìîæåò óñòàíîâèòü, ñ êàêîãî |
ðàçäåëà åãî çàãðóçèë Windows-çàãðóç÷èê (è âîîáùå ïîä NT/2000/XP îáÿçàí |
áûòü ôàéëîì íà äèñêå C:\). Âàðèàíò ñ ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì |
äèñêîì áûë ðåàëèçîâàí â ïåðâîé âåðñèè çàãðóç÷èêà, íî ïî õîäó äåëà |
îáíàðóæèëîñü, ÷òî òàêè íóæíî êðóòèòü öèêë: âî-âòîðûõ, ìîæåò áûòü |
ïðèÿòíûì, ÷òî ñàìà ñèñòåìà ìîæåò ñòîÿòü âîâñå íå íà ñèñòåìíîì C:\, à è |
íà äðóãèõ äèñêàõ; âî-ïåðâûõ, äèñê C: ìîæåò è íå áûòü ïåðâûì ëîãè÷åñêèì |
ðàçäåëîì - Vista ëþáèò ñîçäàâàòü ñêðûòûé ïåðâè÷íûé ðàçäåë ïåðåä |
ñèñòåìíûì, è òîãäà äèñê C: ñòàíîâèòñÿ âòîðûì ëîãè÷åñêèì. |
6. Èçâåùàåò ïîëüçîâàòåëÿ î òîì, ÷òî ïðîèñõîäèò ïîïûòêà çàãðóçêè ñ î÷åðåäíîãî |
ëîãè÷åñêîãî äèñêà. |
7. ×èòàåò ïåðâûé ñåêòîð ëîãè÷åñêîãî äèñêà è îïðåäåëÿåò ôàéëîâóþ ñèñòåìó. |
È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +11 ñîäåðæèò ÷èñëî áàéò â ñåêòîðå |
è äîëæíî ñîâïàäàòü ñ õàðàêòåðèñòèêîé ôèçè÷åñêîãî íîñèòåëÿ, òî åñòü |
200h áàéò. È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +13 ñîäåðæèò ÷èñëî |
ñåêòîðîâ â êëàñòåðå è äîëæíî áûòü ñòåïåíüþ äâîéêè. |
Êðèòåðèé NTFS: ïîëå ñî ñìåùåíèåì +3 ñîäåðæèò ñòðîêó NTFS è ïîëå ñî |
ñìåùåíèåì +16 íóëåâîå (â FAT îíî ñîäåðæèò ÷èñëî òàáëèö FAT è îáÿçàíî |
áûòü íåíóëåâûì). |
Êðèòåðèé FAT: çàãðóç÷èê âû÷èñëÿåò ÷èñëî êëàñòåðîâ, îïðåäåëÿåò |
ïðåäïîëîæèòåëüíûé òèï (FAT12/FAT16/FAT32) è ïðîâåðÿåò áàéò ïî ñìåùåíèþ |
+38 äëÿ FAT12/16, +66 äëÿ FAT32 (îí äîëæåí áûòü ðàâåí 0x29). |
Ïîñëå îïðåäåëåíèÿ òèïà ôàéëîâîé ñèñòåìû èçâåùàåò ïîëüçîâàòåëÿ îá |
îïðåäåë¸ííîì òèïå. Åñëè ôàéëîâàÿ ñèñòåìà íå ðàñïîçíàíà, âûäà¸ò |
ñîîòâåòñòâóþùåå ñîîáùåíèå è ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó. |
8a. Äëÿ FAT12-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '12'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT12-îáðàáîò÷èê; ñ÷èòûâàåò â ïàìÿòü âñþ |
òàáëèöó FAT12 (îíà íå ïðåâîñõîäèò 0x1800 áàéò = 6 Êá), ïðè îøèáêå |
÷òåíèÿ ïûòàåòñÿ èñïîëüçîâàòü äðóãèå êîïèè FAT. |
8á. Äëÿ FAT16-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '16'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ |
î êýøå ñåêòîðîâ FAT (ìàññèâ áàéò ñ âîçìîæíûìè çíà÷åíèÿìè 0 è 1, |
îçíà÷àþùèìè, áûë ëè óæå çàãðóæåí ñîîòâåòñòâóþùèé ñåêòîð - âñåãî â |
òàáëèöå FAT16 íå áîëåå 0x100 ñåêòîðîâ) - íè îäèí ñåêòîð åù¸ íå |
çàãðóæåí, âñå áàéòû íóëåâûå. |
8â. Äëÿ FAT32-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '32'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ |
î êýøå ñåêòîðîâ FAT (ôîðìàò èíôîðìàöèè îïèñàí âûøå, â ðàñïðåäåëåíèè |
èñïîëüçóåìîé çàãðóç÷èêîì ïàìÿòè) - íè îäèí ñåêòîð åù¸ íå çàãðóæåí. |
8ã. Îáùåå äëÿ FAT-òîìîâ: îïðåäåëÿåò çíà÷åíèÿ ñëóæåáíûõ ïåðåìåííûõ |
root_start (ïåðâûé ñåêòîð êîðíåâîãî êàòàëîãà â FAT12/16, èãíîðèðóåòñÿ |
ïðè îáðàáîòêå FAT32-òîìîâ), data_start (íà÷àëî äàííûõ ñ ïîïðàâêîé, |
ââîäèìîé äëÿ òîãî, ÷òîáû êëàñòåð N íà÷èíàëñÿ ñ ñåêòîðà |
N*sectors_per_cluster+data_start), root_clus (ïåðâûé êëàñòåð êîðíåâîãî |
êàòàëîãà â FAT32, 0 â FAT12/16); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ |
çàãðóçêè ôàéëà íà FAT-îáðàáîò÷èê. |
8ä. Äëÿ NTFS-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó 'nt'; îïðåäåëÿåò çíà÷åíèå ñëóæåáíîé ïåðåìåííîé frs_size |
(ðàçìåð â áàéòàõ ôàéëîâîé çàïèñè, File Record Segment), äëÿ ïîëíîé |
êîððåêòíîñòè ïðîâåðÿåò, ÷òî ýòî çíà÷åíèå (ðàâíîå 0x400 áàéò íà âñåõ |
ðåàëüíûõ NTFS-òîìàõ - åäèíñòâåííûé ñïîñîá èçìåíèòü åãî çàêëþ÷àåòñÿ |
â ïåðåñîçäàíèè âñåõ ñèñòåìíûõ ñòðóêòóð âðó÷íóþ) íå ïðåâîñõîäèò 0x1000 |
è êðàòíî ðàçìåðó ñåêòîðà 0x200 áàéò; èíèöèàëèçèðóåò êýø ôàéëîâûõ |
çàïèñåé - íè÷åãî åù¸ íå çàãðóæåíî; ñ÷èòûâàåò ïåðâûé êëàñòåð $MFT |
è çàãðóæàåò èíôîðìàöèþ î ðàñïîëîæåíèè íà äèñêå âñåé òàáëèöû $MFT |
(àòðèáóò 0x80, $Data); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ çàãðóçêè |
ôàéëà íà NTFS-îáðàáîò÷èê. |
9. (ìåòêà load_secondary) Âûçûâàåò ôóíêöèþ çàãðóçêè ôàéëà äëÿ ôàéëà âòîðè÷íîãî |
çàãðóç÷èêà. Ïðè îáíàðóæåíèè îøèáêè ïåðåõîäèò íà îáðàáîò÷èê îøèáîê ñ |
ñîîòâåòñòâóþùèì ñîîáùåíèåì. |
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='h' (æ¸ñòêèé äèñê), |
ah=íîìåð äèñêà (äëÿ ãîòîâîãî áèíàðíèêà - 0 (BIOS-èäåíòèôèêàòîð 80h), |
ìîæåò áûòü èçìåí¸í ïóò¸ì ìîäèôèêàöèè êîíñòàíòû â èñõîäíèêå èëè |
ñïåöèàëüíûì óñòàíîâùèêîì), bx=èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû (áåð¸òñÿ |
èç ñòåêà, êóäà ðàíåå áûë çàñóíóò íà øàãå 8), ds:si=óêàçàòåëü íà |
callback-ôóíêöèþ. |
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó äàëüíèì ïåðåõîäîì íà 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
Чтение файла: |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным |
кодом должна указывать на 0:dat. |
2. Разбирает переданные параметры и вызывает процедуру загрузки файла. |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
×òåíèå ôàéëà: |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:3000, bp=dat: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:dat. |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò ïðîöåäóðó çàãðóçêè ôàéëà. |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры. |
Процедура чтения секторов (read): |
на входе должно быть установлено: |
Âñïîìîãàòåëüíûå ïðîöåäóðû. |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:dat |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор (относительно начала логического диска) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, |
флаг CF установлен, если возникла ошибка чтения |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя номер первого сектора логического диска, |
найденный при переборе дисков. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ íîìåð ïåðâîãî ñåêòîðà ëîãè÷åñêîãî äèñêà, |
íàéäåííûé ïðè ïåðåáîðå äèñêîâ. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура обработки ошибок (find_error_si и find_error_sp): |
на входе: указатель на сообщение об ошибке в si либо на верхушке стека |
0. Если вызывается find_error_si, она помещает переданный указатель в стек. |
1. Если ошибка произошла в процессе работы callback-функции, то |
(метка error_in_callback) обработчик просто возвращает управление |
вызвавшему коду, рапортуя о ненайденном файле. |
2. Если же ошибка произошла до передачи управления вторичному загрузчику, |
обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" |
и (восстановив стек) переходит к следующему логическому диску. |
Ïðîöåäóðà îáðàáîòêè îøèáîê (find_error_si è find_error_sp): |
íà âõîäå: óêàçàòåëü íà ñîîáùåíèå îá îøèáêå â si ëèáî íà âåðõóøêå ñòåêà |
0. Åñëè âûçûâàåòñÿ find_error_si, îíà ïîìåùàåò ïåðåäàííûé óêàçàòåëü â ñòåê. |
1. Åñëè îøèáêà ïðîèçîøëà â ïðîöåññå ðàáîòû callback-ôóíêöèè, òî |
(ìåòêà error_in_callback) îáðàáîò÷èê ïðîñòî âîçâðàùàåò óïðàâëåíèå |
âûçâàâøåìó êîäó, ðàïîðòóÿ î íåíàéäåííîì ôàéëå. |
2. Åñëè æå îøèáêà ïðîèçîøëà äî ïåðåäà÷è óïðàâëåíèÿ âòîðè÷íîìó çàãðóç÷èêó, |
îáðàáîò÷èê âûâîäèò ñîîáùåíèå òèïà "Error: <òåêóùèé îáúåêò>: <îøèáêà>" |
è (âîññòàíîâèâ ñòåê) ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó. |
Процедура чтения файла/атрибута по известному размещению на диске |
Ïðîöåäóðà ÷òåíèÿ ôàéëà/àòðèáóòà ïî èçâåñòíîìó ðàçìåùåíèþ íà äèñêå |
(read_file_chunk): |
на входе должно быть установлено: |
ds:si = указатель на информацию о размещении |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
ecx = лимит числа секторов для чтения, старшее слово должно быть 0 |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, |
флаг CF установлен, если возникла ошибка чтения |
1. Определяет, является ли атрибут резидентным (возможно только в NTFS |
и означает, что данные файла/атрибута уже были целиком прочитаны при |
обработке информации о файле) или нерезидентным (означает, что данные |
хранятся где-то на диске, и имеется информация о том, где именно). |
2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует |
данные по месту назначения (с учётом указанного лимита). |
3. Для нерезидентных атрибутов информация состоит из пар <размер очередного |
фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура |
читает фрагменты, пока файл не закончится или пока не будет достигнут |
указанный лимит. |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ds:si = óêàçàòåëü íà èíôîðìàöèþ î ðàçìåùåíèè |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
ecx = ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ, ñòàðøåå ñëîâî äîëæíî áûòü 0 |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ |
1. Îïðåäåëÿåò, ÿâëÿåòñÿ ëè àòðèáóò ðåçèäåíòíûì (âîçìîæíî òîëüêî â NTFS |
è îçíà÷àåò, ÷òî äàííûå ôàéëà/àòðèáóòà óæå áûëè öåëèêîì ïðî÷èòàíû ïðè |
îáðàáîòêå èíôîðìàöèè î ôàéëå) èëè íåðåçèäåíòíûì (îçíà÷àåò, ÷òî äàííûå |
õðàíÿòñÿ ãäå-òî íà äèñêå, è èìååòñÿ èíôîðìàöèÿ î òîì, ãäå èìåííî). |
2. Äëÿ ðåçèäåíòíûõ àòðèáóòîâ (ìåòêà read_file_chunk.resident) ïðîñòî êîïèðóåò |
äàííûå ïî ìåñòó íàçíà÷åíèÿ (ñ ó÷¸òîì óêàçàííîãî ëèìèòà). |
3. Äëÿ íåðåçèäåíòíûõ àòðèáóòîâ èíôîðìàöèÿ ñîñòîèò èç ïàð <ðàçìåð î÷åðåäíîãî |
ôðàãìåíòà ôàéëà â êëàñòåðàõ, ñòàðòîâûé êëàñòåð ôðàãìåíòà>; ïðîöåäóðà |
÷èòàåò ôðàãìåíòû, ïîêà ôàéë íå çàêîí÷èòñÿ èëè ïîêà íå áóäåò äîñòèãíóò |
óêàçàííûé ëèìèò. |
Процедура просмотра кэша (cache_lookup): |
на входе должно быть установлено: |
eax = искомое значение |
ss:si = указатель на структуру-заголовок кэша |
на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение |
было только что добавлено, и сброшен, если оно уже было в кэше. |
1. Просматривает кэш в поисках указанного значения. Если значение найдено |
(при этом флаг CF оказывается сброшенным), переходит к шагу 4. |
2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в |
голове двусвязного списка), иначе добавляет к кэшу ещё один вход. |
3. Устанавливает в полученном входе указанное значение. Устанавливает флаг |
CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. |
4. Удаляет вход из списка. |
5. Добавляет сектор в конец списка (самый новый вход). |
Ïðîöåäóðà ïðîñìîòðà êýøà (cache_lookup): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
eax = èñêîìîå çíà÷åíèå |
ss:si = óêàçàòåëü íà ñòðóêòóðó-çàãîëîâîê êýøà |
íà âûõîäå: ss:di = óêàçàòåëü íà âõîä â êýøå; ôëàã CF óñòàíîâëåí, åñëè çíà÷åíèå |
áûëî òîëüêî ÷òî äîáàâëåíî, è ñáðîøåí, åñëè îíî óæå áûëî â êýøå. |
1. Ïðîñìàòðèâàåò êýø â ïîèñêàõ óêàçàííîãî çíà÷åíèÿ. Åñëè çíà÷åíèå íàéäåíî |
(ïðè ýòîì ôëàã CF îêàçûâàåòñÿ ñáðîøåííûì), ïåðåõîäèò ê øàãó 4. |
2. Åñëè êýø óæå çàïîëíåí, óäàëÿåò èç êýøà ñàìûé ñòàðûé âõîä (îí íàõîäèòñÿ â |
ãîëîâå äâóñâÿçíîãî ñïèñêà), èíà÷å äîáàâëÿåò ê êýøó åù¸ îäèí âõîä. |
3. Óñòàíàâëèâàåò â ïîëó÷åííîì âõîäå óêàçàííîå çíà÷åíèå. Óñòàíàâëèâàåò ôëàã |
CF, ïîñëåäóþùèå øàãè íå ìåíÿþò ñîñòîÿíèÿ ôëàãîâ. Ïåðåõîäèò ê øàãó 5. |
4. Óäàëÿåò âõîä èç ñïèñêà. |
5. Äîáàâëÿåò ñåêòîð â êîíåö ñïèñêà (ñàìûé íîâûé âõîä). |
/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.txt |
---|
26,393 → 26,393 |
Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? |
Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. |
(ISO-9660 и её расширения - стандарт для CD; DVD может использовать |
либо ISO-9660, либо UDF.) |
Áóòñåêòîð äëÿ çàãðóçêè ñ CD/DVD ñ ôàéëîâîé ñèñòåìîé ISO-9660. |
(ISO-9660 è å¸ ðàñøèðåíèÿ - ñòàíäàðò äëÿ CD; DVD ìîæåò èñïîëüçîâàòü |
ëèáî ISO-9660, ëèáî UDF.) |
===================================================================== |
Требования для работы: |
1) Сам бутсектор и все используемые файлы должны быть читабельны. |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 452K свободной базовой памяти. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð è âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 452K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 14.09.2008): |
стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf |
стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 14.09.2008): |
ñòàíäàðò ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf |
ñòàíäàðò çàãðóçî÷íîãî CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Схема используемой памяти: |
1000-1800 временный буфер для чтения одиночных секторов |
...-7C00 стек |
7C00-8400 код бутсектора |
8400-8A00 информация о кэше для папок: массив входов следующего |
формата: |
dw следующий элемент в L2-списке закэшированных папок, |
упорядоченном по времени использования |
(голова списка - самый старый); |
dw предыдущий элемент в том же списке; |
dd первый сектор папки; |
dw размер папки в байтах; |
dw сегмент кэша |
60000-... содержимое Path Table, если она используется |
+ кэш для папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
1000-1800 âðåìåííûé áóôåð äëÿ ÷òåíèÿ îäèíî÷íûõ ñåêòîðîâ |
...-7C00 ñòåê |
7C00-8400 êîä áóòñåêòîðà |
8400-8A00 èíôîðìàöèÿ î êýøå äëÿ ïàïîê: ìàññèâ âõîäîâ ñëåäóþùåãî |
ôîðìàòà: |
dw ñëåäóþùèé ýëåìåíò â L2-ñïèñêå çàêýøèðîâàííûõ ïàïîê, |
óïîðÿäî÷åííîì ïî âðåìåíè èñïîëüçîâàíèÿ |
(ãîëîâà ñïèñêà - ñàìûé ñòàðûé); |
dw ïðåäûäóùèé ýëåìåíò â òîì æå ñïèñêå; |
dd ïåðâûé ñåêòîð ïàïêè; |
dw ðàçìåð ïàïêè â áàéòàõ; |
dw ñåãìåíò êýøà |
60000-... ñîäåðæèìîå Path Table, åñëè îíà èñïîëüçóåòñÿ |
+ êýø äëÿ ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip |
равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает |
дальний прыжок на самого себя с целью получить cs=0 (в некоторых |
местах используется адресация переменных загрузчика через cs, поскольку |
и ds, и es могут быть заняты под другие сегменты). |
2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) |
и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления |
и разрешённые прерывания. Сохраняет идентификатор загрузочного диска |
в специальную переменную. |
3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять |
LBA-функции. |
4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту |
ISO9660 со смещения 10h начинается цепочка описателей тома, |
завершающаяся специальным описателем (Volume Descriptor Set |
Terminator). Код по очереди считывает все сектора, пока не наткнётся |
либо на искомый описатель, либо на терминатор. Во втором случае |
выдаётся соответствующее сообщение, и загрузка прекращается. |
Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD |
располагается в последней сессии. И спецификация ElTorito загрузочного |
CD оперирует также с последней сессией. Однако на практике оказывается, |
что: во-первых, реальные BIOSы не понимают мультисессионных CD и |
всегда используют первую сессию; во-вторых, BIOSовский int 13h просто |
не позволяет получить информацию о последней сессии. В связи с этим |
загрузчик также использует первую сессию. (В-третьих, в одной из BIOS |
обнаружилась заготовка, которая в случае запроса сектора 10h, в котором |
во всех нормальных случаях и располагается PVD, перенаправляет его |
на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с |
последней сессии, то благодаря заготовке загрузчик без всяких |
модификаций также читал бы последнюю сессию.) |
5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во |
внутренние переменные: размер логического блока (согласно спецификации, |
должен быть степенью двойки от 512 до размера логического сектора, |
равного 2048 для CD и DVD); положение на диске корневой папки; |
вычисляет число блоков в секторе (из предыдущего примечания следует, |
что оно всегда целое и само является степенью двойки). |
6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет |
размер пространства, которое может использовать загрузчик (от |
адреса 6000:0000 до конца доступной памяти). |
7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит |
базовую информацию обо всех папках на диске. Если таблица слишком |
велика (больше 62K или больше половины доступной памяти), то она |
игнорируется. Если таблица путей недоступна, то запрос типа |
dir1/dir2/dir3/file приведёт к последовательному разбору корневой |
папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать |
саму таблицу путей (где записано положение папки dir1/dir2/dir3) |
и папку dir3. Если таблица загружена, то соответственно уменьшается |
объём оставшейся доступной памяти и увеличивается указатель на |
свободную область. |
8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 |
доступная память отводится под этот кэш). |
9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке |
печатает соответствующее сообщение и прекращает загрузку с CD. |
10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует |
тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' |
идентифицирует файловую систему ISO-9660; ds:si указывает на |
callback-функцию, которую может вызывать вторичный загрузчик. |
11. Передаёт управление вторичному загрузчику, совершая дальний прыжок |
на адрес, куда kord/loader был загружен. |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Ïðè ïåðåäà÷å óïðàâëåíèÿ çàãðóçî÷íîìó êîäó â ñëó÷àå CD/DVD ïàðà cs:ip |
ðàâíà íå 0:7C00, à íà 07C0:0000. Ïîýòîìó ñíà÷àëà çàãðóç÷èê äåëàåò |
äàëüíèé ïðûæîê íà ñàìîãî ñåáÿ ñ öåëüþ ïîëó÷èòü cs=0 (â íåêîòîðûõ |
ìåñòàõ èñïîëüçóåòñÿ àäðåñàöèÿ ïåðåìåííûõ çàãðóç÷èêà ÷åðåç cs, ïîñêîëüêó |
è ds, è es ìîãóò áûòü çàíÿòû ïîä äðóãèå ñåãìåíòû). |
2. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (íåïîñðåäñòâåííî ïåðåä îñíîâíûì êîäîì) |
è ñåãìåíòíûå ðåãèñòðû ds=es=0. Ôîðñèðóåò ñáðîøåííûé ôëàã íàïðàâëåíèÿ |
è ðàçðåø¸ííûå ïðåðûâàíèÿ. Ñîõðàíÿåò èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà |
â ñïåöèàëüíóþ ïåðåìåííóþ. |
3. Ïðîâåðÿåò ïîääåðæêó LBA. Äëÿ CD/DVD íîñèòåëÿ BIOS îáÿçàíà ïðåäîñòàâëÿòü |
LBA-ôóíêöèè. |
4. Èùåò îïèñàòåëü òîìà CD (Primary Volume Descriptor, PVD): ïî ñòàíäàðòó |
ISO9660 ñî ñìåùåíèÿ 10h íà÷èíàåòñÿ öåïî÷êà îïèñàòåëåé òîìà, |
çàâåðøàþùàÿñÿ ñïåöèàëüíûì îïèñàòåëåì (Volume Descriptor Set |
Terminator). Êîä ïî î÷åðåäè ñ÷èòûâàåò âñå ñåêòîðà, ïîêà íå íàòêí¸òñÿ |
ëèáî íà èñêîìûé îïèñàòåëü, ëèáî íà òåðìèíàòîð. Âî âòîðîì ñëó÷àå |
âûäà¸òñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå, è çàãðóçêà ïðåêðàùàåòñÿ. |
Âîîáùå ãîâîðÿ, â ñëó÷àå ìóëüòèñåññèîííûõ CD îñíîâíîé êàòàëîã ñîäåðæèìîãî CD |
ðàñïîëàãàåòñÿ â ïîñëåäíåé ñåññèè. È ñïåöèôèêàöèÿ ElTorito çàãðóçî÷íîãî |
CD îïåðèðóåò òàêæå ñ ïîñëåäíåé ñåññèåé. Îäíàêî íà ïðàêòèêå îêàçûâàåòñÿ, |
÷òî: âî-ïåðâûõ, ðåàëüíûå BIOSû íå ïîíèìàþò ìóëüòèñåññèîííûõ CD è |
âñåãäà èñïîëüçóþò ïåðâóþ ñåññèþ; âî-âòîðûõ, BIOSîâñêèé int 13h ïðîñòî |
íå ïîçâîëÿåò ïîëó÷èòü èíôîðìàöèþ î ïîñëåäíåé ñåññèè.  ñâÿçè ñ ýòèì |
çàãðóç÷èê òàêæå èñïîëüçóåò ïåðâóþ ñåññèþ. (Â-òðåòüèõ, â îäíîé èç BIOS |
îáíàðóæèëàñü çàãîòîâêà, êîòîðàÿ â ñëó÷àå çàïðîñà ñåêòîðà 10h, â êîòîðîì |
âî âñåõ íîðìàëüíûõ ñëó÷àÿõ è ðàñïîëàãàåòñÿ PVD, ïåðåíàïðàâëÿåò åãî |
íà ñåêòîð 10h+(íà÷àëî ñåññèè). Åñëè áû ýòîò BIOS åù¸ è ãðóçèëñÿ ñ |
ïîñëåäíåé ñåññèè, òî áëàãîäàðÿ çàãîòîâêå çàãðóç÷èê áåç âñÿêèõ |
ìîäèôèêàöèé òàêæå ÷èòàë áû ïîñëåäíþþ ñåññèþ.) |
5. (ìåòêà pvd_found) Ñ÷èòûâàåò èç PVD íåêîòîðóþ èíôîðìàöèþ î òîìå âî |
âíóòðåííèå ïåðåìåííûå: ðàçìåð ëîãè÷åñêîãî áëîêà (ñîãëàñíî ñïåöèôèêàöèè, |
äîëæåí áûòü ñòåïåíüþ äâîéêè îò 512 äî ðàçìåðà ëîãè÷åñêîãî ñåêòîðà, |
ðàâíîãî 2048 äëÿ CD è DVD); ïîëîæåíèå íà äèñêå êîðíåâîé ïàïêè; |
âû÷èñëÿåò ÷èñëî áëîêîâ â ñåêòîðå (èç ïðåäûäóùåãî ïðèìå÷àíèÿ ñëåäóåò, |
÷òî îíî âñåãäà öåëîå è ñàìî ÿâëÿåòñÿ ñòåïåíüþ äâîéêè). |
6. Ïîëó÷àåò ðàçìåð áàçîâîé ïàìÿòè âûçîâîì int 12h; íà åãî îñíîâå âû÷èñëÿåò |
ðàçìåð ïðîñòðàíñòâà, êîòîðîå ìîæåò èñïîëüçîâàòü çàãðóç÷èê (îò |
àäðåñà 6000:0000 äî êîíöà äîñòóïíîé ïàìÿòè). |
7. Çàãðóæàåò òàáëèöó ïóòåé CD (Path Table) - îáëàñòü äàííûõ, êîòîðàÿ ñîäåðæèò |
áàçîâóþ èíôîðìàöèþ îáî âñåõ ïàïêàõ íà äèñêå. Åñëè òàáëèöà ñëèøêîì |
âåëèêà (áîëüøå 62K èëè áîëüøå ïîëîâèíû äîñòóïíîé ïàìÿòè), òî îíà |
èãíîðèðóåòñÿ. Åñëè òàáëèöà ïóòåé íåäîñòóïíà, òî çàïðîñ òèïà |
dir1/dir2/dir3/file ïðèâåä¸ò ê ïîñëåäîâàòåëüíîìó ðàçáîðó êîðíåâîé |
ïàïêè è ïàïîê dir1,dir2,dir3; åñëè äîñòóïíà, òî äîñòàòî÷íî ðàçîáðàòü |
ñàìó òàáëèöó ïóòåé (ãäå çàïèñàíî ïîëîæåíèå ïàïêè dir1/dir2/dir3) |
è ïàïêó dir3. Åñëè òàáëèöà çàãðóæåíà, òî ñîîòâåòñòâåííî óìåíüøàåòñÿ |
îáú¸ì îñòàâøåéñÿ äîñòóïíîé ïàìÿòè è óâåëè÷èâàåòñÿ óêàçàòåëü íà |
ñâîáîäíóþ îáëàñòü. |
8. Çàïîìèíàåò îáùèé ðàçìåð è íà÷àëî êýøà äëÿ ïàïîê (âñÿ îñòàâøàÿñÿ ïîñëå ï.7 |
äîñòóïíàÿ ïàìÿòü îòâîäèòñÿ ïîä ýòîò êýø). |
9. Âûäà¸ò çàïðîñ íà ÷òåíèå ôàéëà âòîðè÷íîãî çàãðóç÷èêà kord/loader. Ïðè îøèáêå |
ïå÷àòàåò ñîîòâåòñòâóþùåå ñîîáùåíèå è ïðåêðàùàåò çàãðóçêó ñ CD. |
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='c' èäåíòèôèöèðóåò |
òèï óñòðîéñòâà - CD/DVD; ah=BIOS-èäåíòèôèêàòîð äèñêà; bx='is' |
èäåíòèôèöèðóåò ôàéëîâóþ ñèñòåìó ISO-9660; ds:si óêàçûâàåò íà |
callback-ôóíêöèþ, êîòîðóþ ìîæåò âûçûâàòü âòîðè÷íûé çàãðóç÷èê. |
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó, ñîâåðøàÿ äàëüíèé ïðûæîê |
íà àäðåñ, êóäà kord/loader áûë çàãðóæåí. |
Функция обратного вызова для вторичного загрузчика (callback): |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
Перенаправляет запрос соответствующей локальной процедуре (load_file при |
первом запросе на загрузку файла, loadloop.loadnew при последующих |
запросах на продолжение загрузки файла). |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà (callback): |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
Ïåðåíàïðàâëÿåò çàïðîñ ñîîòâåòñòâóþùåé ëîêàëüíîé ïðîöåäóðå (load_file ïðè |
ïåðâîì çàïðîñå íà çàãðóçêó ôàéëà, loadloop.loadnew ïðè ïîñëåäóþùèõ |
çàïðîñàõ íà ïðîäîëæåíèå çàãðóçêè ôàéëà). |
Вспомогательные процедуры. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения секторов (read_sectors): |
на входе должно быть установлено: |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор |
cx = число секторов |
на выходе: |
es:bx указывает на конец буфера, в который были прочитаны данные |
если произошла ошибка чтения, флаг CF установлен |
1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации |
число читаемых секторов не превосходило 7Fh (требование спецификации |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð |
cx = ÷èñëî ñåêòîðîâ |
íà âûõîäå: |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí |
1.  öèêëå (øàãè 2-4) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå ñïåöèôèêàöèè |
EDD BIOS). |
2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, |
устанавливает CF=1 и выходит из процедуры. |
Очищает стек от пакета, сформированного на предыдущем шаге. |
5. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 2. |
2. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
3. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
4. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, î÷èùàåò ñòåê, |
óñòàíàâëèâàåò CF=1 è âûõîäèò èç ïðîöåäóðû. |
Î÷èùàåò ñòåê îò ïàêåòà, ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
5.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 2. |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
Процедура загрузки файла (load_file): |
на входе: |
ds:di = указатель на информационную структуру, описанную в спецификации |
на загрузчик, а также в комментариях к коду |
на выходе: |
bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, |
2=файл не найден, 3=ошибка чтения |
dx:ax = размер файла, 0xFFFFFFFF, если файл не найден |
1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, |
иначе переходит сразу к шагу 4, установив eax = начальный блок |
корневой папки. |
2. Устанавливает es:di на начало таблицы путей. Ограничение на размер |
гарантирует, что вся таблица помещается в сегменте 6000h. |
Инициализирует dx (в котором будет хранится номер текущего входа в |
таблице, считая с 1), cx (размер оставшегося участка таблицы), |
bx (номер входа, соответствующего родительской папке для текущего |
рассматриваемого участка пути). |
3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы |
таблицы путей упорядочены (подробно о порядке написано в спецификации), |
так что если родительский элемент для очередного входа больше нужного, |
то нужного входа в таблице нет совсем, и в этом случае происходит |
выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, |
соответствующий очередной папке в запрошенном пути, то на рассмотрение |
выносится следующая компонента пути. Если эта компонента последняя, |
то осталось найти файл в папке, и код переходит к пункту 4, |
установив eax = начальный блок этой папки. Если же нет, то эта |
компонента должна задавать имя папки, и код возвращается к пункту 3, |
скорректировав указатель на имя ds:si и номер родительского входа bx. |
4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax |
и указатель на имя файла относительно этой папки в ds:si. Если |
папку искали по таблице путей, то имя файла уже не содержит подпапок; |
если же нет, то подпапки вполне возможны. |
5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый |
из которых задаётся отдельным входом в папке. Информация обо всех |
таких кусках при просмотре папки запоминается в области, начинающейся |
с адреса 0000:2000. Переменная cur_desc_end содержит указатель на |
конец этой области, он же указатель, куда будет помещена информация |
при обнаружении следующего входа. (Папки, согласно спецификации, |
должны задаваться одним куском.) |
6. Код сначала ищет запрошенную папку в кэше папок. |
7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, |
отсортированного по давности последнего обращения и код переходит к |
п.15. (Следующим действием станет добавление папки в конец списка.) |
8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать |
с диска. Сначала загружается первый сектор (физический сектор, |
содержащий первый логический блок). При ошибке ввода/вывода |
происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. |
Первый элемент папки содержит информацию о самой этой папке, конкретно |
загрузчик интересуется её размером. |
9. Если размер папки слишком большой (больше или равен 64K либо больше половины |
общего размера кэша), то кэшироваться она не будет. В этом случае код |
считывает папку посекторно во временный буфер (0000:1000) и посекторно |
сканирует на наличие запрошенного имени, пока не найдёт такого имени |
или пока не кончатся данные. (Цикл начинается со сканирования, |
поскольку первая часть данных уже прочитана.) В конце код переходит |
к п.17. |
10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно |
обеспечить достаточное количество свободного места. Для этого может |
понадобиться выкинуть какое-то количество старых данных (цикл |
parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, |
свободное пространство окажется разорванным на несколько фрагментов. |
Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает |
все следующие за ней данные назад по памяти и соответственно |
корректирует информацию о местонахождении данных в информации о кэше. |
При этом новое пространство всегда добавляется в конец доступной |
памяти. Цикл выкидывания продолжается, пока не освободится место, |
достаточное для хранения папки. Из-за ограничений на размер кэшируемых |
папок в конце концов место найдётся. |
11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы |
организуются в единый список свободных элементов; если он непуст, |
то очередной элемент берётся из этого списка; если же пуст, то |
берётся совсем новый элемент из области памяти, предназначенной для |
элементов кэша. |
12. В новом элементе заполняются поля начального блока, сегмента с данными, |
размера в байтах. |
13. Уже прочитанные данные первого физического сектора пересылаются на |
законное место в кэше. |
14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся |
данные с диска. При ошибке чтения, как и раньше, происходит выход из |
процедуры с bx=3, ax=dx=0xFFFF. |
15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов |
кэша. |
16. Загрузчик ищет запрошенное имя в загруженных данных папки. |
(Из-за ограничений на размер кэшируемой папки все данные располагаются |
в одном сегменте.) |
17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено |
никаких кусков файла, то cur_desc_end такой же, каким был вначале. |
В этом случае процедура рапортует о ненайденном файле и выходит. |
18. (filefound) Пропускает текущую компоненту имени. Если она была не последней |
(то есть подпапкой, в которой нужно производить дальнейший поиск), |
то код проверяет, что найденный вход - действительно подпапка, |
устанавливает новый стартовый блок и возвращается к п.4. |
Если же последней, то код проверяет, что найденный вход - регулярный |
файл и начинает загрузку файла. |
19. Нормализует указатель, по которому требуется прочитать файл. Под |
нормализацией понимается преобразование типа |
1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, |
но гарантирует отсутствие переполнений: в приведённом примере попытка |
переслать 400h байт по rep movsb приведёт к тому, что последние 8 |
байт запишутся не в нужное место, а на 64K раньше. Далее нормализация |
будет производиться после каждой пересылки. В cur_limit помещает |
предельный размер для чтения в байтах. |
20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты |
(пункты 21-27). |
21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое |
нужно пропустить с начала фрагмента. |
22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего |
шага, либо напрямую из callback-процедуры при запросе на продолжение |
чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - |
при продолжении чтения, прервавшегося из-за конца буфера посередине |
фрагмента, там будет записано соответствующее значение. |
23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента |
и максимальной длины остатка. Если второе строго меньше, то |
запоминает, что файл слишком большой и прочитан только частично. |
Определяет новое значение числа прочитанных байт во фрагменте |
для возможных будущих вызовов [cur_start]. |
24. Переводит пропускаемое число байт в число логических блоков и байт |
в первом блоке, последнее число записывает в переменную [first_byte], |
откуда её позднее достанет read_many_bytes.with_first. |
25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код |
определяет начальный блок фрагмента и вызывает вспомогательную функцию |
чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) |
и выходит из цикла к п.28. |
26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала |
код пропускает нужное количество непрерывных частей, а потом |
в цикле загружает непрерывные части с помощью той же функции, |
в промежутках между частями увеличивая номер начального блока. |
Пока не кончится фрагмент или пока не наберётся запрошенное число байт. |
При ошибке чтения делает то же самое, что и в предыдущем случае. |
27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер |
ещё не достигнут, переходит к следующему фрагменту и п.20. В противном |
случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли |
переполнение в п.23. |
28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех |
фрагментов. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
íà âõîäå: |
ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó, îïèñàííóþ â ñïåöèôèêàöèè |
íà çàãðóç÷èê, à òàêæå â êîììåíòàðèÿõ ê êîäó |
íà âûõîäå: |
bx = ñòàòóñ: 0=óñïåõ, 1=ôàéë ñëèøêîì áîëüøîé, ïðî÷èòàíà òîëüêî ÷àñòü, |
2=ôàéë íå íàéäåí, 3=îøèáêà ÷òåíèÿ |
dx:ax = ðàçìåð ôàéëà, 0xFFFFFFFF, åñëè ôàéë íå íàéäåí |
1. Åñëè ïîäãîòîâèòåëüíûé êîä çàãðóçèë òàáëèöó ïóòåé, òî èùåò ïàïêó â òàáëèöå, |
èíà÷å ïåðåõîäèò ñðàçó ê øàãó 4, óñòàíîâèâ eax = íà÷àëüíûé áëîê |
êîðíåâîé ïàïêè. |
2. Óñòàíàâëèâàåò es:di íà íà÷àëî òàáëèöû ïóòåé. Îãðàíè÷åíèå íà ðàçìåð |
ãàðàíòèðóåò, ÷òî âñÿ òàáëèöà ïîìåùàåòñÿ â ñåãìåíòå 6000h. |
Èíèöèàëèçèðóåò dx (â êîòîðîì áóäåò õðàíèòñÿ íîìåð òåêóùåãî âõîäà â |
òàáëèöå, ñ÷èòàÿ ñ 1), cx (ðàçìåð îñòàâøåãîñÿ ó÷àñòêà òàáëèöû), |
bx (íîìåð âõîäà, ñîîòâåòñòâóþùåãî ðîäèòåëüñêîé ïàïêå äëÿ òåêóùåãî |
ðàññìàòðèâàåìîãî ó÷àñòêà ïóòè). |
3. Â öèêëå èùåò âõîä ñ íóæíûì ðîäèòåëüñêèì ýëåìåíòîì è íóæíûì èìåíåì. Ýëåìåíòû |
òàáëèöû ïóòåé óïîðÿäî÷åíû (ïîäðîáíî î ïîðÿäêå íàïèñàíî â ñïåöèôèêàöèè), |
òàê ÷òî åñëè ðîäèòåëüñêèé ýëåìåíò äëÿ î÷åðåäíîãî âõîäà áîëüøå íóæíîãî, |
òî íóæíîãî âõîäà â òàáëèöå íåò ñîâñåì, è â ýòîì ñëó÷àå ïðîèñõîäèò |
âûõîä èç ïðîöåäóðû ñ bx=2, ax=dx=0xFFFF. Åñëè îáíàðóæèëñÿ ýëåìåíò, |
ñîîòâåòñòâóþùèé î÷åðåäíîé ïàïêå â çàïðîøåííîì ïóòè, òî íà ðàññìîòðåíèå |
âûíîñèòñÿ ñëåäóþùàÿ êîìïîíåíòà ïóòè. Åñëè ýòà êîìïîíåíòà ïîñëåäíÿÿ, |
òî îñòàëîñü íàéòè ôàéë â ïàïêå, è êîä ïåðåõîäèò ê ïóíêòó 4, |
óñòàíîâèâ eax = íà÷àëüíûé áëîê ýòîé ïàïêè. Åñëè æå íåò, òî ýòà |
êîìïîíåíòà äîëæíà çàäàâàòü èìÿ ïàïêè, è êîä âîçâðàùàåòñÿ ê ïóíêòó 3, |
ñêîððåêòèðîâàâ óêàçàòåëü íà èìÿ ds:si è íîìåð ðîäèòåëüñêîãî âõîäà bx. |
4. (parse_dir) Íà ýòîì øàãå çàäàíû íà÷àëüíûé ëîãè÷åñêèé áëîê ïàïêè â eax |
è óêàçàòåëü íà èìÿ ôàéëà îòíîñèòåëüíî ýòîé ïàïêè â ds:si. Åñëè |
ïàïêó èñêàëè ïî òàáëèöå ïóòåé, òî èìÿ ôàéëà óæå íå ñîäåðæèò ïîäïàïîê; |
åñëè æå íåò, òî ïîäïàïêè âïîëíå âîçìîæíû. |
5. Ôàéëû â ISO-9660 ìîãóò ñîñòîÿòü èç íåñêîëüêèõ êóñêîâ (File Section), êàæäûé |
èç êîòîðûõ çàäà¸òñÿ îòäåëüíûì âõîäîì â ïàïêå. Èíôîðìàöèÿ îáî âñåõ |
òàêèõ êóñêàõ ïðè ïðîñìîòðå ïàïêè çàïîìèíàåòñÿ â îáëàñòè, íà÷èíàþùåéñÿ |
ñ àäðåñà 0000:2000. Ïåðåìåííàÿ cur_desc_end ñîäåðæèò óêàçàòåëü íà |
êîíåö ýòîé îáëàñòè, îí æå óêàçàòåëü, êóäà áóäåò ïîìåùåíà èíôîðìàöèÿ |
ïðè îáíàðóæåíèè ñëåäóþùåãî âõîäà. (Ïàïêè, ñîãëàñíî ñïåöèôèêàöèè, |
äîëæíû çàäàâàòüñÿ îäíèì êóñêîì.) |
6. Êîä ñíà÷àëà èùåò çàïðîøåííóþ ïàïêó â êýøå ïàïîê. |
7. (parse_dir.found) Åñëè ïàïêà óæå åñòü â êýøå, òî îíà óäàëÿåòñÿ èç ñïèñêà, |
îòñîðòèðîâàííîãî ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ è êîä ïåðåõîäèò ê |
ï.15. (Ñëåäóþùèì äåéñòâèåì ñòàíåò äîáàâëåíèå ïàïêè â êîíåö ñïèñêà.) |
8. (parse_dir.notfound) Åñëè æå ïàïêè íåò â êýøå, òî å¸ ïðèä¸òñÿ çàãðóæàòü |
ñ äèñêà. Ñíà÷àëà çàãðóæàåòñÿ ïåðâûé ñåêòîð (ôèçè÷åñêèé ñåêòîð, |
ñîäåðæàùèé ïåðâûé ëîãè÷åñêèé áëîê). Ïðè îøèáêå ââîäà/âûâîäà |
ïðîèñõîäèò íåìåäëåííûé âûõîä èç ïðîöåäóðû ñ bx=3, dx=ax=0xFFFF. |
Ïåðâûé ýëåìåíò ïàïêè ñîäåðæèò èíôîðìàöèþ î ñàìîé ýòîé ïàïêå, êîíêðåòíî |
çàãðóç÷èê èíòåðåñóåòñÿ å¸ ðàçìåðîì. |
9. Åñëè ðàçìåð ïàïêè ñëèøêîì áîëüøîé (áîëüøå èëè ðàâåí 64K ëèáî áîëüøå ïîëîâèíû |
îáùåãî ðàçìåðà êýøà), òî êýøèðîâàòüñÿ îíà íå áóäåò.  ýòîì ñëó÷àå êîä |
ñ÷èòûâàåò ïàïêó ïîñåêòîðíî âî âðåìåííûé áóôåð (0000:1000) è ïîñåêòîðíî |
ñêàíèðóåò íà íàëè÷èå çàïðîøåííîãî èìåíè, ïîêà íå íàéä¸ò òàêîãî èìåíè |
èëè ïîêà íå êîí÷àòñÿ äàííûå. (Öèêë íà÷èíàåòñÿ ñî ñêàíèðîâàíèÿ, |
ïîñêîëüêó ïåðâàÿ ÷àñòü äàííûõ óæå ïðî÷èòàíà.)  êîíöå êîä ïåðåõîäèò |
ê ï.17. |
10. (parse_dir.yescache) Åñëè ïðèíÿòî ðåøåíèå î êýøèðîâàíèè ïàïêè, òî íóæíî |
îáåñïå÷èòü äîñòàòî÷íîå êîëè÷åñòâî ñâîáîäíîãî ìåñòà. Äëÿ ýòîãî ìîæåò |
ïîíàäîáèòüñÿ âûêèíóòü êàêîå-òî êîëè÷åñòâî ñòàðûõ äàííûõ (öèêë |
parse_dir.freeloop). Íî åñëè ïðîñòî âûêèäûâàòü, òî, âîîáùå ãîâîðÿ, |
ñâîáîäíîå ïðîñòðàíñòâî îêàæåòñÿ ðàçîðâàííûì íà íåñêîëüêî ôðàãìåíòîâ. |
Ïîýòîìó ïðè âûêèäûâàíèè êàêîé-òî ïàïêè èç êýøà çàãðóç÷èê ïåðåìåùàåò |
âñå ñëåäóþùèå çà íåé äàííûå íàçàä ïî ïàìÿòè è ñîîòâåòñòâåííî |
êîððåêòèðóåò èíôîðìàöèþ î ìåñòîíàõîæäåíèè äàííûõ â èíôîðìàöèè î êýøå. |
Ïðè ýòîì íîâîå ïðîñòðàíñòâî âñåãäà äîáàâëÿåòñÿ â êîíåö äîñòóïíîé |
ïàìÿòè. Öèêë âûêèäûâàíèÿ ïðîäîëæàåòñÿ, ïîêà íå îñâîáîäèòñÿ ìåñòî, |
äîñòàòî÷íîå äëÿ õðàíåíèÿ ïàïêè. Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìûõ |
ïàïîê â êîíöå êîíöîâ ìåñòî íàéä¸òñÿ. |
11. Âûäåëÿåòñÿ íîâûé ýëåìåíò êýøà. Âñå óäàë¸ííûå íà øàãå 10 ýëåìåíòû |
îðãàíèçóþòñÿ â åäèíûé ñïèñîê ñâîáîäíûõ ýëåìåíòîâ; åñëè îí íåïóñò, |
òî î÷åðåäíîé ýëåìåíò áåð¸òñÿ èç ýòîãî ñïèñêà; åñëè æå ïóñò, òî |
áåð¸òñÿ ñîâñåì íîâûé ýëåìåíò èç îáëàñòè ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ |
ýëåìåíòîâ êýøà. |
12.  íîâîì ýëåìåíòå çàïîëíÿþòñÿ ïîëÿ íà÷àëüíîãî áëîêà, ñåãìåíòà ñ äàííûìè, |
ðàçìåðà â áàéòàõ. |
13. Óæå ïðî÷èòàííûå äàííûå ïåðâîãî ôèçè÷åñêîãî ñåêòîðà ïåðåñûëàþòñÿ íà |
çàêîííîå ìåñòî â êýøå. |
14. Åñëè âñå äàííûå íå èñ÷åðïûâàþòñÿ ïåðâûì ñåêòîðîì, òî äîãðóæàþòñÿ îñòàâøèåñÿ |
äàííûå ñ äèñêà. Ïðè îøèáêå ÷òåíèÿ, êàê è ðàíüøå, ïðîèñõîäèò âûõîä èç |
ïðîöåäóðû ñ bx=3, ax=dx=0xFFFF. |
15. (parse_dir.scan) Íîâûé ýëåìåíò äîáàâëÿåòñÿ â êîíåö ñïèñêà âñåõ ýëåìåíòîâ |
êýøà. |
16. Çàãðóç÷èê èùåò çàïðîøåííîå èìÿ â çàãðóæåííûõ äàííûõ ïàïêè. |
(Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìîé ïàïêè âñå äàííûå ðàñïîëàãàþòñÿ |
â îäíîì ñåãìåíòå.) |
17. (parse_dir.scandone) Åñëè â ïðîöåññå ñêàíèðîâàíèÿ ïàïêè íå áûëî íàéäåíî |
íèêàêèõ êóñêîâ ôàéëà, òî cur_desc_end òàêîé æå, êàêèì áûë âíà÷àëå. |
 ýòîì ñëó÷àå ïðîöåäóðà ðàïîðòóåò î íåíàéäåííîì ôàéëå è âûõîäèò. |
18. (filefound) Ïðîïóñêàåò òåêóùóþ êîìïîíåíòó èìåíè. Åñëè îíà áûëà íå ïîñëåäíåé |
(òî åñòü ïîäïàïêîé, â êîòîðîé íóæíî ïðîèçâîäèòü äàëüíåéøèé ïîèñê), |
òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - äåéñòâèòåëüíî ïîäïàïêà, |
óñòàíàâëèâàåò íîâûé ñòàðòîâûé áëîê è âîçâðàùàåòñÿ ê ï.4. |
Åñëè æå ïîñëåäíåé, òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - ðåãóëÿðíûé |
ôàéë è íà÷èíàåò çàãðóçêó ôàéëà. |
19. Íîðìàëèçóåò óêàçàòåëü, ïî êîòîðîìó òðåáóåòñÿ ïðî÷èòàòü ôàéë. Ïîä |
íîðìàëèçàöèåé ïîíèìàåòñÿ ïðåîáðàçîâàíèå òèïà |
1234:FC08 -> (1234+0FC0):0008, êîòîðîå íå ìåíÿåò ñóììàðíîãî àäðåñà, |
íî ãàðàíòèðóåò îòñóòñòâèå ïåðåïîëíåíèé: â ïðèâåä¸ííîì ïðèìåðå ïîïûòêà |
ïåðåñëàòü 400h áàéò ïî rep movsb ïðèâåä¸ò ê òîìó, ÷òî ïîñëåäíèå 8 |
áàéò çàïèøóòñÿ íå â íóæíîå ìåñòî, à íà 64K ðàíüøå. Äàëåå íîðìàëèçàöèÿ |
áóäåò ïðîèçâîäèòüñÿ ïîñëå êàæäîé ïåðåñûëêè. Â cur_limit ïîìåùàåò |
ïðåäåëüíûé ðàçìåð äëÿ ÷òåíèÿ â áàéòàõ. |
20. (loadloop) Â öèêëå ïî íàéäåííûì ôðàãìåíòàì ôàéëà çàãðóæàåò ýòè ôðàãìåíòû |
(ïóíêòû 21-27). |
21. Îáíóëÿåò ïåðåìåííóþ [cur_start], èìåþùóþ ñìûñë ÷èñëà áàéò, êîòîðîå |
íóæíî ïðîïóñòèòü ñ íà÷àëà ôðàãìåíòà. |
22. (loadloop.loadnew) Íà ýòó ìåòêó óïðàâëåíèå ìîæåò ïîïàñòü ëèáî ñ ïðåäûäóùåãî |
øàãà, ëèáî íàïðÿìóþ èç callback-ïðîöåäóðû ïðè çàïðîñå íà ïðîäîëæåíèå |
÷òåíèÿ. Äëÿ ýòîãî è íóæíà âûøåóïîìÿíóòàÿ ïåðåìåííàÿ [cur_start] - |
ïðè ïðîäîëæåíèè ÷òåíèÿ, ïðåðâàâøåãîñÿ èç-çà êîíöà áóôåðà ïîñåðåäèíå |
ôðàãìåíòà, òàì áóäåò çàïèñàíî ñîîòâåòñòâóþùåå çíà÷åíèå. |
23. Îïðåäåëÿåò òåêóùóþ äëèíó (õðàíèòñÿ â esi) êàê ìèíèìóì èç äëèíû ôðàãìåíòà |
è ìàêñèìàëüíîé äëèíû îñòàòêà. Åñëè âòîðîå ñòðîãî ìåíüøå, òî |
çàïîìèíàåò, ÷òî ôàéë ñëèøêîì áîëüøîé è ïðî÷èòàí òîëüêî ÷àñòè÷íî. |
Îïðåäåëÿåò íîâîå çíà÷åíèå ÷èñëà ïðî÷èòàííûõ áàéò âî ôðàãìåíòå |
äëÿ âîçìîæíûõ áóäóùèõ âûçîâîâ [cur_start]. |
24. Ïåðåâîäèò ïðîïóñêàåìîå ÷èñëî áàéò â ÷èñëî ëîãè÷åñêèõ áëîêîâ è áàéò |
â ïåðâîì áëîêå, ïîñëåäíåå ÷èñëî çàïèñûâàåò â ïåðåìåííóþ [first_byte], |
îòêóäà å¸ ïîçäíåå äîñòàíåò read_many_bytes.with_first. |
25. Åñëè ôðàãìåíò çàïèñàí â îáû÷íîì ðåæèìå (non-interleaved mode), òî êîä |
îïðåäåëÿåò íà÷àëüíûé áëîê ôðàãìåíòà è âûçûâàåò âñïîìîãàòåëüíóþ ôóíêöèþ |
÷òåíèÿ áëîêîâ. Ïðè îøèáêå ÷òåíèÿ óñòàíàâëèâàåò bx=3 (êîä îøèáêè ÷òåíèÿ) |
è âûõîäèò èç öèêëà ê ï.28. |
26. Åñëè ôðàãìåíò çàïèñàí â ÷åðåäóåìîì ðåæèìå (interleaved mode), òî ñíà÷àëà |
êîä ïðîïóñêàåò íóæíîå êîëè÷åñòâî íåïðåðûâíûõ ÷àñòåé, à ïîòîì |
â öèêëå çàãðóæàåò íåïðåðûâíûå ÷àñòè ñ ïîìîùüþ òîé æå ôóíêöèè, |
â ïðîìåæóòêàõ ìåæäó ÷àñòÿìè óâåëè÷èâàÿ íîìåð íà÷àëüíîãî áëîêà. |
Ïîêà íå êîí÷èòñÿ ôðàãìåíò èëè ïîêà íå íàáåð¸òñÿ çàïðîøåííîå ÷èñëî áàéò. |
Ïðè îøèáêå ÷òåíèÿ äåëàåò òî æå ñàìîå, ÷òî è â ïðåäûäóùåì ñëó÷àå. |
27. (loadloop.loadcontinue) Åñëè ôðàãìåíòû åù¸ íå êîí÷èëèñü è ïðåäåëüíûé ðàçìåð |
åù¸ íå äîñòèãíóò, ïåðåõîäèò ê ñëåäóþùåìó ôðàãìåíòó è ï.20. Â ïðîòèâíîì |
ñëó÷àå óñòàíàâëèâàåò bx=0 ëèáî bx=1 â çàâèñèìîñòè îò òîãî, áûëî ëè |
ïåðåïîëíåíèå â ï.23. |
28. (loadloop.calclen) Ïîäñ÷èòûâàåò îáùóþ äëèíó ôàéëà, ñóììèðóÿ äëèíû âñåõ |
ôðàãìåíòîâ. |
Процедура проверки, является ли текущая компонента имени файла последней |
Ïðîöåäóðà ïðîâåðêè, ÿâëÿåòñÿ ëè òåêóùàÿ êîìïîíåíòà èìåíè ôàéëà ïîñëåäíåé |
(is_last_component): |
на входе: ds:si = указатель на имя |
на выходе: флаг CF установлен, если есть последующие компоненты |
В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, |
то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF |
и выходит. |
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ |
íà âûõîäå: ôëàã CF óñòàíîâëåí, åñëè åñòü ïîñëåäóþùèå êîìïîíåíòû |
 öèêëå çàãðóæàåò ñèìâîëû èìåíè â ïîèñêàõ íóëåâîãî è '/'; åñëè íàø¸ëñÿ ïåðâûé, |
òî âûõîäèò (ïðè ýòîì CF=0); åñëè íàø¸ëñÿ âòîðîé, òî óñòàíàâëèâàåò CF |
è âûõîäèò. |
Процедуры проверки на совпадение текущей компоненты имени файла с именем |
текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): |
на входе: ds:si = указатель на имя, es:di = указатель на элемент |
таблицы путей для test_filename1, папки для test_filename2 |
на выходе: CF установлен, если имена не совпадают |
В цикле проверяет совпадение приведённых к верхнему регистру очередных символов |
имён файла и элемента. Условия выхода из цикла: закончилось имя файла |
в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение |
возможно только в ситуации типа имени "filename.ext" и элемента |
"filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми |
именами в папке отсортированы по убыванию версий); |
несовпадение символов - означает, что имена не совпадают; |
закончилось имя элемента - нужно проверить, закончилось ли при этом имя |
файла, и в зависимости от этого принимать решение о совпадении. |
Ïðîöåäóðû ïðîâåðêè íà ñîâïàäåíèå òåêóùåé êîìïîíåíòû èìåíè ôàéëà ñ èìåíåì |
òåêóùåãî ýëåìåíòà (test_filename1 äëÿ òàáëèöû ïóòåé, test_filename2 äëÿ ïàïêè): |
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ, es:di = óêàçàòåëü íà ýëåìåíò |
òàáëèöû ïóòåé äëÿ test_filename1, ïàïêè äëÿ test_filename2 |
íà âûõîäå: CF óñòàíîâëåí, åñëè èìåíà íå ñîâïàäàþò |
 öèêëå ïðîâåðÿåò ñîâïàäåíèå ïðèâåä¸ííûõ ê âåðõíåìó ðåãèñòðó î÷åðåäíûõ ñèìâîëîâ |
èì¸í ôàéëà è ýëåìåíòà. Óñëîâèÿ âûõîäà èç öèêëà: çàêîí÷èëîñü èìÿ ôàéëà |
â ds:si (òî åñòü, î÷åðåäíîé ñèìâîë - íóëåâîé ëèáî '/') - ñîâïàäåíèå |
âîçìîæíî òîëüêî â ñèòóàöèè òèïà èìåíè "filename.ext" è ýëåìåíòà |
"filename.ext;1" (â ISO9660 ";1" - âåðñèÿ ôàéëà, ýëåìåíòû ñ îäèíàêîâûìè |
èìåíàìè â ïàïêå îòñîðòèðîâàíû ïî óáûâàíèþ âåðñèé); |
íåñîâïàäåíèå ñèìâîëîâ - îçíà÷àåò, ÷òî èìåíà íå ñîâïàäàþò; |
çàêîí÷èëîñü èìÿ ýëåìåíòà - íóæíî ïðîâåðèòü, çàêîí÷èëîñü ëè ïðè ýòîì èìÿ |
ôàéëà, è â çàâèñèìîñòè îò ýòîãî ïðèíèìàòü ðåøåíèå î ñîâïàäåíèè. |
Процедура приведения символа в верхний регистр (toupper): |
на входе: ASCII-символ |
на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к |
нему неприменимо) |
Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', |
остальные символы не трогает. |
Ïðîöåäóðà ïðèâåäåíèÿ ñèìâîëà â âåðõíèé ðåãèñòð (toupper): |
íà âõîäå: ASCII-ñèìâîë |
íà âûõîäå: òîò æå ñèìâîë â âåðõíåì ðåãèñòðå (îí ñàì, åñëè ïîíÿòèå ðåãèñòðà ê |
íåìó íåïðèìåíèìî) |
Èç ñèìâîëîâ â äèàïàçîíå 'a' - 'z' âêëþ÷èòåëüíî âû÷èòàåò êîíñòàíòó 'a'-'A', |
îñòàëüíûå ñèìâîëû íå òðîãàåò. |
Процедура поиска файла в данных папки (scan_for_filename_in_sector): |
на входе: |
ds:si = указатель на имя файла |
es:bx = указатель на начало данных папки |
es:dx = указатель на конец данных папки |
на выходе: |
CF сброшен, если найден финальный фрагмент файла |
(и дальше сканировать папку не нужно) |
в область для информации о фрагментах файла записывается найденное |
В цикле просматривает все входы папки, пропуская те, у которых установлен |
бит Associated (это специальные входы, дополняющие основные). Если |
имя очередного входа совпадает с именем файла, то запоминает новый |
фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), |
то код выходит с CF=0. Если достигнут конец данных, то код выходит |
с CF=1. Если очередной вход нулевой (первый байт настоящего входа |
содержит длину и не может быть нулём), то процедура переходит к |
рассмотрению следующего логического блока. При этом потенциально |
возможно переполнение при добавлении размера блока; поскольку такой |
сценарий означает, что процедура вызвана для кэшированной папки |
с размером почти 64K и началом данных bx=0 (это свойство вызывающего |
кода), а размер блока - степень двойки, то после переполнения всегда |
bx=0, так что это можно обнаружить по взведённому ZF после сложения; |
в этом случае также происходит выход (а после переполнения CF=1). |
Ïðîöåäóðà ïîèñêà ôàéëà â äàííûõ ïàïêè (scan_for_filename_in_sector): |
íà âõîäå: |
ds:si = óêàçàòåëü íà èìÿ ôàéëà |
es:bx = óêàçàòåëü íà íà÷àëî äàííûõ ïàïêè |
es:dx = óêàçàòåëü íà êîíåö äàííûõ ïàïêè |
íà âûõîäå: |
CF ñáðîøåí, åñëè íàéäåí ôèíàëüíûé ôðàãìåíò ôàéëà |
(è äàëüøå ñêàíèðîâàòü ïàïêó íå íóæíî) |
â îáëàñòü äëÿ èíôîðìàöèè î ôðàãìåíòàõ ôàéëà çàïèñûâàåòñÿ íàéäåííîå |
 öèêëå ïðîñìàòðèâàåò âñå âõîäû ïàïêè, ïðîïóñêàÿ òå, ó êîòîðûõ óñòàíîâëåí |
áèò Associated (ýòî ñïåöèàëüíûå âõîäû, äîïîëíÿþùèå îñíîâíûå). Åñëè |
èìÿ î÷åðåäíîãî âõîäà ñîâïàäàåò ñ èìåíåì ôàéëà, òî çàïîìèíàåò íîâûé |
ôðàãìåíò. Åñëè ôðàãìåíò ôèíàëüíûé (íå óñòàíîâëåí áèò Multi-Extent), |
òî êîä âûõîäèò ñ CF=0. Åñëè äîñòèãíóò êîíåö äàííûõ, òî êîä âûõîäèò |
ñ CF=1. Åñëè î÷åðåäíîé âõîä íóëåâîé (ïåðâûé áàéò íàñòîÿùåãî âõîäà |
ñîäåðæèò äëèíó è íå ìîæåò áûòü íóë¸ì), òî ïðîöåäóðà ïåðåõîäèò ê |
ðàññìîòðåíèþ ñëåäóþùåãî ëîãè÷åñêîãî áëîêà. Ïðè ýòîì ïîòåíöèàëüíî |
âîçìîæíî ïåðåïîëíåíèå ïðè äîáàâëåíèè ðàçìåðà áëîêà; ïîñêîëüêó òàêîé |
ñöåíàðèé îçíà÷àåò, ÷òî ïðîöåäóðà âûçâàíà äëÿ êýøèðîâàííîé ïàïêè |
ñ ðàçìåðîì ïî÷òè 64K è íà÷àëîì äàííûõ bx=0 (ýòî ñâîéñòâî âûçûâàþùåãî |
êîäà), à ðàçìåð áëîêà - ñòåïåíü äâîéêè, òî ïîñëå ïåðåïîëíåíèÿ âñåãäà |
bx=0, òàê ÷òî ýòî ìîæíî îáíàðóæèòü ïî âçâåä¸ííîìó ZF ïîñëå ñëîæåíèÿ; |
â ýòîì ñëó÷àå òàêæå ïðîèñõîäèò âûõîä (à ïîñëå ïåðåïîëíåíèÿ CF=1). |
Процедура перевода логического блока в номер сектора: |
на входе: eax = логический блок |
на выходе: eax = физический сектор, dx = номер логического блока в секторе |
Осуществляет обычное деление 32-битного числа на 32-битное (число логических |
блоков в секторе, хранящееся во внутренней переменной). |
Ïðîöåäóðà ïåðåâîäà ëîãè÷åñêîãî áëîêà â íîìåð ñåêòîðà: |
íà âõîäå: eax = ëîãè÷åñêèé áëîê |
íà âûõîäå: eax = ôèçè÷åñêèé ñåêòîð, dx = íîìåð ëîãè÷åñêîãî áëîêà â ñåêòîðå |
Îñóùåñòâëÿåò îáû÷íîå äåëåíèå 32-áèòíîãî ÷èñëà íà 32-áèòíîå (÷èñëî ëîãè÷åñêèõ |
áëîêîâ â ñåêòîðå, õðàíÿùååñÿ âî âíóòðåííåé ïåðåìåííîé). |
Процедура загрузки физического сектора, содержащего указанный логический блок |
Ïðîöåäóðà çàãðóçêè ôèçè÷åñêîãî ñåêòîðà, ñîäåðæàùåãî óêàçàííûé ëîãè÷åñêèé áëîê |
(load_phys_sector_for_lb_force): |
на входе: eax = логический блок; |
si - индикатор, задающий, следует ли читать данные в случае, |
если логический блок начинается с начала физического: |
si = 0 - не нужно, si ненулевой - нужно |
на выходе: |
физический сектор загружен по адресу 0000:1000 |
si указывает на данные логического блока |
CF установлен при ошибке чтения |
Преобразует предыдущей процедурой номер логического блока в номер физического |
сектора и номер логического блока внутри сектора; если последняя |
величина нулевая и никаких действий в этом случае не запрошено (si=0), |
то ничего и не делает; иначе устанавливает si в соответствии с ней |
и читает сектор. |
íà âõîäå: eax = ëîãè÷åñêèé áëîê; |
si - èíäèêàòîð, çàäàþùèé, ñëåäóåò ëè ÷èòàòü äàííûå â ñëó÷àå, |
åñëè ëîãè÷åñêèé áëîê íà÷èíàåòñÿ ñ íà÷àëà ôèçè÷åñêîãî: |
si = 0 - íå íóæíî, si íåíóëåâîé - íóæíî |
íà âûõîäå: |
ôèçè÷åñêèé ñåêòîð çàãðóæåí ïî àäðåñó 0000:1000 |
si óêàçûâàåò íà äàííûå ëîãè÷åñêîãî áëîêà |
CF óñòàíîâëåí ïðè îøèáêå ÷òåíèÿ |
Ïðåîáðàçóåò ïðåäûäóùåé ïðîöåäóðîé íîìåð ëîãè÷åñêîãî áëîêà â íîìåð ôèçè÷åñêîãî |
ñåêòîðà è íîìåð ëîãè÷åñêîãî áëîêà âíóòðè ñåêòîðà; åñëè ïîñëåäíÿÿ |
âåëè÷èíà íóëåâàÿ è íèêàêèõ äåéñòâèé â ýòîì ñëó÷àå íå çàïðîøåíî (si=0), |
òî íè÷åãî è íå äåëàåò; èíà÷å óñòàíàâëèâàåò si â ñîîòâåòñòâèè ñ íåé |
è ÷èòàåò ñåêòîð. |
Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков |
(read_many_bytes и read_many_bytes.with_first): |
на входе: |
eax = логический блок |
esi = число байт для чтения |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
cur_limit = размер буфера (не меньше esi) |
на выходе: |
es:bx указывает на конец буфера, в который были прочитаны данные |
если произошла ошибка чтения, флаг CF установлен |
cur_limit соответствующим образом уменьшен |
Отличие двух процедур: вторая дополнительно принимает во внимание переменную |
[first_byte], начиная чтение первого блока со смещения [first_byte]; |
соответственно, первая читает блок с начала, обнуляя [first_byte] |
при входе. |
1. Отдельно считывает первый физический сектор во временную область 0000:1000, |
если первый логический блок начинается не с начала сектора. При |
ошибке чтения выходит из процедуры. |
2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, |
в буфер. Нормализует указатель на буфер. |
3. Если все необходимые данные уже прочитаны, выходит из процедуры. |
4. Дальнейшие данные находятся в нескольких физических секторах, при этом, |
возможно, последний сектор считывать нужно не целиком. |
5. Если в буфере есть место для считывания всех секторов, то сразу читаются |
все сектора, после чего указатель на буфер нужным образом уменьшается. |
6. Если же нет, то считываются все сектора, кроме последнего, после чего |
последний сектор считывается отдельно во временную область, и уже |
оттуда нужная часть данных копируется в буфер. |
Ïðîöåäóðû ÷òåíèÿ íóæíîãî ÷èñëà áàéò èç íåïðåðûâíîé öåïî÷êè ëîãè÷åñêèõ áëîêîâ |
(read_many_bytes è read_many_bytes.with_first): |
íà âõîäå: |
eax = ëîãè÷åñêèé áëîê |
esi = ÷èñëî áàéò äëÿ ÷òåíèÿ |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
cur_limit = ðàçìåð áóôåðà (íå ìåíüøå esi) |
íà âûõîäå: |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí |
cur_limit ñîîòâåòñòâóþùèì îáðàçîì óìåíüøåí |
Îòëè÷èå äâóõ ïðîöåäóð: âòîðàÿ äîïîëíèòåëüíî ïðèíèìàåò âî âíèìàíèå ïåðåìåííóþ |
[first_byte], íà÷èíàÿ ÷òåíèå ïåðâîãî áëîêà ñî ñìåùåíèÿ [first_byte]; |
ñîîòâåòñòâåííî, ïåðâàÿ ÷èòàåò áëîê ñ íà÷àëà, îáíóëÿÿ [first_byte] |
ïðè âõîäå. |
1. Îòäåëüíî ñ÷èòûâàåò ïåðâûé ôèçè÷åñêèé ñåêòîð âî âðåìåííóþ îáëàñòü 0000:1000, |
åñëè ïåðâûé ëîãè÷åñêèé áëîê íà÷èíàåòñÿ íå ñ íà÷àëà ñåêòîðà. Ïðè |
îøèáêå ÷òåíèÿ âûõîäèò èç ïðîöåäóðû. |
2. Ïåðåñûëàåò íóæíóþ ÷àñòü äàííûõ (âîçìîæíî, 0 áàéò), ïðî÷èòàííûõ â ï.1, |
â áóôåð. Íîðìàëèçóåò óêàçàòåëü íà áóôåð. |
3. Åñëè âñå íåîáõîäèìûå äàííûå óæå ïðî÷èòàíû, âûõîäèò èç ïðîöåäóðû. |
4. Äàëüíåéøèå äàííûå íàõîäÿòñÿ â íåñêîëüêèõ ôèçè÷åñêèõ ñåêòîðàõ, ïðè ýòîì, |
âîçìîæíî, ïîñëåäíèé ñåêòîð ñ÷èòûâàòü íóæíî íå öåëèêîì. |
5. Åñëè â áóôåðå åñòü ìåñòî äëÿ ñ÷èòûâàíèÿ âñåõ ñåêòîðîâ, òî ñðàçó ÷èòàþòñÿ |
âñå ñåêòîðà, ïîñëå ÷åãî óêàçàòåëü íà áóôåð íóæíûì îáðàçîì óìåíüøàåòñÿ. |
6. Åñëè æå íåò, òî ñ÷èòûâàþòñÿ âñå ñåêòîðà, êðîìå ïîñëåäíåãî, ïîñëå ÷åãî |
ïîñëåäíèé ñåêòîð ñ÷èòûâàåòñÿ îòäåëüíî âî âðåìåííóþ îáëàñòü, è óæå |
îòòóäà íóæíàÿ ÷àñòü äàííûõ êîïèðóåòñÿ â áóôåð. |
/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.txt |
---|
24,337 → 24,337 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Встречаются вирус и FAT. |
- Привет, ты кто? |
- Я? Вирус. |
- A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... |
Âñòðå÷àþòñÿ âèðóñ è FAT. |
- Ïðèâåò, òû êòî? |
- ß? Âèðóñ. |
- A ÿ AFT, òî åñòü TAF, òî åñòü FTA, ÷åðò, ñîâñåì çàïóòàëñÿ... |
Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. |
Áóòñåêòîð äëÿ FAT12/FAT16-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò. |
===================================================================== |
Есть две версии в зависимости от того, поддерживает ли носитель LBA, |
выбор осуществляется установкой константы use_lba в первой строке исходника. |
Требования для работы: |
1) Сам бутсектор, первая копия FAT и все используемые файлы |
должны быть читабельны. |
2) Минимальный процессор - 80186. |
3) В системе должно быть как минимум 592K свободной базовой памяти. |
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA, |
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû |
äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80186. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè âàëèäíû íà ìîìåíò íàïèñàíèÿ ýòîãî ôàéëà, 15.05.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер |
занимает 12 бит в таблице FAT, так что общий размер не превосходит |
0x17EE = 6126 байт. Вся таблица помещается в памяти. |
Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый |
кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит |
0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в |
этом случае несколько нецелесообразно считывать всю таблицу, поскольку |
на практике нужна только небольшая её часть. Поэтому место в памяти |
резервируется, но данные считываются только в момент, когда к ним |
действительно идёт обращение. |
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT12-òîìå - 0xFF4 = 4084; êàæäûé êëàñòåð |
çàíèìàåò 12 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò |
0x17EE = 6126 áàéò. Âñÿ òàáëèöà ïîìåùàåòñÿ â ïàìÿòè. |
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT16-òîìå - 0xFFF4 = 65524; êàæäûé |
êëàñòåð çàíèìàåò 16 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò |
0x1FFE8 = 131048 áàéò. Âñÿ òàáëèöà òàêæå ïîìåùàåòñÿ â ïàìÿòè, îäíàêî â |
ýòîì ñëó÷àå íåñêîëüêî íåöåëåñîîáðàçíî ñ÷èòûâàòü âñþ òàáëèöó, ïîñêîëüêó |
íà ïðàêòèêå íóæíà òîëüêî íåáîëüøàÿ å¸ ÷àñòü. Ïîýòîìó ìåñòî â ïàìÿòè |
ðåçåðâèðóåòñÿ, íî äàííûå ñ÷èòûâàþòñÿ òîëüêî â ìîìåíò, êîãäà ê íèì |
äåéñòâèòåëüíî èä¸ò îáðàùåíèå. |
Схема используемой памяти: |
...-7C00 стек |
7C00-7E00 код бутсектора |
7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) |
8200-8300 список загруженных секторов таблицы FAT16 |
(1 = соответствующий сектор загружен) |
60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 |
80000-90000 текущий кластер текущей рассматриваемой папки |
90000-92000 кэш для корневой папки |
92000-... кэш для некорневых папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 7 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
...-7C00 ñòåê |
7C00-7E00 êîä áóòñåêòîðà |
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f1x) |
8200-8300 ñïèñîê çàãðóæåííûõ ñåêòîðîâ òàáëèöû FAT16 |
(1 = ñîîòâåòñòâóþùèé ñåêòîð çàãðóæåí) |
60000-80000 çàãðóæåííàÿ òàáëèöà FAT12 / ìåñòî äëÿ òàáëèöû FAT16 |
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè |
90000-92000 êýø äëÿ êîðíåâîé ïàïêè |
92000-... êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед |
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало |
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - |
это освобождает ds и экономит на размере кода). |
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h |
прерывания 13h. Если нет, переходит на код обработки ошибок с |
сообщением об отсутствии LBA. |
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и |
записывает полученные данные поверх BPB. Если вызов завершился ошибкой, |
предполагает уже существующие данные корректными. |
3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки |
и начальный сектор данных. Кладёт их в стек; впоследствии они |
всегда будут лежать в стеке и адресоваться через bp. |
4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых |
секторов - минимум из размера корневой папки, указанного в BPB, и 16 |
(размер кэша для корневой папки - 2000h байт = 16 секторов). |
5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если |
он оказывается папкой, или если файл имеет нулевую длину - |
переходит на код обработки ошибок с сообщением о |
ненайденном загрузчике. |
Замечание: на этом этапе загрузки искать можно только в корневой |
папке и только имена, заданные в формате файловой системе FAT |
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны |
быть заглавными, при необходимости имя и расширение дополняются |
пробелами, разделяющей точки нет, завершающего нуля нет). |
6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт |
ему управление. При этом в регистрах dx:ax оказывается абсолютный |
номер первого сектора kordldr.f1x, а в cx - число считанных секторов |
(равное размеру кластера). |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä |
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî |
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] - |
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). |
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h |
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ |
ñîîáùåíèåì îá îòñóòñòâèè LBA. |
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è |
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé, |
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè. |
3. Âû÷èñëÿåò íåêîòîðûå ïàðàìåòðû FAT-òîìà: íà÷àëüíûé ñåêòîð êîðíåâîé ïàïêè |
è íà÷àëüíûé ñåêòîð äàííûõ. Êëàä¸ò èõ â ñòåê; âïîñëåäñòâèè îíè |
âñåãäà áóäóò ëåæàòü â ñòåêå è àäðåñîâàòüñÿ ÷åðåç bp. |
4. Ñ÷èòûâàåò íà÷àëî êîðíåâîé ïàïêè ïî àäðåñó 9000:0000. ×èñëî ñ÷èòûâàåìûõ |
ñåêòîðîâ - ìèíèìóì èç ðàçìåðà êîðíåâîé ïàïêè, óêàçàííîãî â BPB, è 16 |
(ðàçìåð êýøà äëÿ êîðíåâîé ïàïêè - 2000h áàéò = 16 ñåêòîðîâ). |
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f1x. Åñëè íå íàõîäèò, èëè åñëè |
îí îêàçûâàåòñÿ ïàïêîé, èëè åñëè ôàéë èìååò íóëåâóþ äëèíó - |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î |
íåíàéäåííîì çàãðóç÷èêå. |
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé |
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT |
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû |
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ |
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò). |
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f1x ïî àäðåñó 0:7E00 è ïåðåäà¸ò |
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðàõ dx:ax îêàçûâàåòñÿ àáñîëþòíûé |
íîìåð ïåðâîãî ñåêòîðà kordldr.f1x, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ |
(ðàâíîå ðàçìåðó êëàñòåðà). |
Вспомогательные процедуры бутсектора. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения секторов (read_sectors и read_sectors2): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors è read_sectors2): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
dx:ax = стартовый сектор (относительно начала логического диска |
для read_sectors, относительно начала данных для read_sectors2) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные |
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора |
в номер относительно начала логического диска, прибавляя номер сектора |
начала данных, хранящийся в стеке как [bp-8]. |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя значение соответствующего поля из BPB. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
dx:ax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà |
äëÿ read_sectors, îòíîñèòåëüíî íà÷àëà äàííûõ äëÿ read_sectors2) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà |
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà |
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-8]. |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура поиска элемента по имени в уже прочитанных данных папки |
Ïðîöåäóðà ïîèñêà ýëåìåíòà ïî èìåíè â óæå ïðî÷èòàííûõ äàííûõ ïàïêè |
(scan_for_filename): |
на входе должно быть установлено: |
ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, |
3 на расширение, все буквы заглавные, если имя/расширение |
короче, оно дополняется до максимума пробелами) |
es = сегмент данных папки |
cx = число элементов в прочитанных данных |
на выходе: ZF определяет, нужно ли продолжать разбор данных папки |
(ZF=1, если либо найден запрошенный элемент, либо достигнут |
конец папки); CF определяет, удалось ли найти элемент с искомым именем |
(CF=1, если не удалось); если удалось, то es:di указывает на него. |
scan_for_filename считает, что данные папки размещаются начиная с es:0. |
Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки |
проверяет имена. |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (11 áàéò, 8 íà èìÿ, |
3 íà ðàñøèðåíèå, âñå áóêâû çàãëàâíûå, åñëè èìÿ/ðàñøèðåíèå |
êîðî÷å, îíî äîïîëíÿåòñÿ äî ìàêñèìóìà ïðîáåëàìè) |
es = ñåãìåíò äàííûõ ïàïêè |
cx = ÷èñëî ýëåìåíòîâ â ïðî÷èòàííûõ äàííûõ |
íà âûõîäå: ZF îïðåäåëÿåò, íóæíî ëè ïðîäîëæàòü ðàçáîð äàííûõ ïàïêè |
(ZF=1, åñëè ëèáî íàéäåí çàïðîøåííûé ýëåìåíò, ëèáî äîñòèãíóò |
êîíåö ïàïêè); CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ýëåìåíò ñ èñêîìûì èìåíåì |
(CF=1, åñëè íå óäàëîñü); åñëè óäàëîñü, òî es:di óêàçûâàåò íà íåãî. |
scan_for_filename ñ÷èòàåò, ÷òî äàííûå ïàïêè ðàçìåùàþòñÿ íà÷èíàÿ ñ es:0. |
Ïåðâîé êîìàíäîé ïðîöåäóðà îáíóëÿåò di. Çàòåì ïðîñòî â öèêëå ïî ýëåìåíòàì ïàïêè |
ïðîâåðÿåò èìåíà. |
Процедура поиска элемента в корневой папке (lookup_in_root_dir): |
на входе должно быть установлено: |
Ïðîöåäóðà ïîèñêà ýëåìåíòà â êîðíåâîé ïàïêå (lookup_in_root_dir): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
ds:si = указатель на имя файла в формате FAT (см. выше) |
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то |
CF сброшен и es:di указывает на элемент папки |
Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле |
сканирует элементы; если по результатам сканирования обнаруживает, |
что нужно читать папку дальше, то считывает не более 0x10000 = 64K |
байт (ограничение введено по двум причинам: во-первых, чтобы заведомо |
не вылезти за пределы используемой памяти, во-вторых, сканирование |
предполагает, что все обрабатываемые элементы располагаются в одном |
сегменте) и продолжает цикл. |
Сканирование прекращается в трёх случаях: обнаружен искомый элемент; |
кончились элементы в папке (судя по числу элементов, указанному в BPB); |
очередной элемент папки сигнализирует о конце (первый байт нулевой). |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå) |
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî |
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè |
Íà÷èíàåò ñ ïðîñìîòðà êýøèðîâàííîé (íà÷àëüíîé) ÷àñòè êîðíåâîé ïàïêè.  öèêëå |
ñêàíèðóåò ýëåìåíòû; åñëè ïî ðåçóëüòàòàì ñêàíèðîâàíèÿ îáíàðóæèâàåò, |
÷òî íóæíî ÷èòàòü ïàïêó äàëüøå, òî ñ÷èòûâàåò íå áîëåå 0x10000 = 64K |
áàéò (îãðàíè÷åíèå ââåäåíî ïî äâóì ïðè÷èíàì: âî-ïåðâûõ, ÷òîáû çàâåäîìî |
íå âûëåçòè çà ïðåäåëû èñïîëüçóåìîé ïàìÿòè, âî-âòîðûõ, ñêàíèðîâàíèå |
ïðåäïîëàãàåò, ÷òî âñå îáðàáàòûâàåìûå ýëåìåíòû ðàñïîëàãàþòñÿ â îäíîì |
ñåãìåíòå) è ïðîäîëæàåò öèêë. |
Ñêàíèðîâàíèå ïðåêðàùàåòñÿ â òð¸õ ñëó÷àÿõ: îáíàðóæåí èñêîìûé ýëåìåíò; |
êîí÷èëèñü ýëåìåíòû â ïàïêå (ñóäÿ ïî ÷èñëó ýëåìåíòîâ, óêàçàííîìó â BPB); |
î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå (ïåðâûé áàéò íóëåâîé). |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
===================================================================== |
Работа вспомогательного загрузчика kordldr.f1x: |
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. |
В зависимости от этого устанавливает смещения используемых процедур |
бутсектора. Критерий проверки: scan_for_filename должна начинаться |
с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может |
с равным успехом ассемблироваться и как 33 FF, но fasm генерирует |
именно такую форму). |
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска |
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с |
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента |
место должно быть, отсюда ограничение в 592 Kb (94000h байт). |
Замечание: этот размер не может превосходить 0A0000h байт и |
на практике оказывается немного (на 1-2 килобайта) меньшим из-за |
наличия дополнительной области данных BIOS "вверху" базовой памяти. |
3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной |
спецификации от Microsoft (версия 1.03 спецификации датирована, |
к слову, 06 декабря 2000 года), разрядность FAT определяется |
исключительно числом кластеров: максимальное число кластеров на |
FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 |
может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, |
а число 0xFF7 не может быть корректным номером кластера. |
Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается |
по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает |
явно неверно, считая, что 0xFF6 (или меньше) кластеров означает |
FAT12-том, в результате получается, что последний кластер |
(в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe |
[встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик |
[бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы |
лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили |
в соответствии со спецификацией. Linux при определении FAT12/FAT16 |
честно следует спецификации. |
Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT |
Microsoft если и будет исправлять ошибки, то согласно собственному |
описанию. |
4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. |
Если размер, указанный в BPB, превосходит 12 секторов, |
это означает, что заявленный размер слишком большой (это не считается |
ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 |
заведомо влезает в такой объём данных). |
Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор |
FAT не загружен (они будут подгружаться позднее, когда понадобятся |
и только те, которые понадобятся). |
5. Если кластер равен сектору, то бутсектор загрузил только часть файла |
kordldr.f1x, и загрузчик подгружает вторую свою часть, используя |
значения регистров на входе в kordldr.f1x. |
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не |
найден, или оказался папкой, или оказался слишком большим, то переходит |
на код обработки ошибок из бутсектора с сообщением |
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f1x: |
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà. |
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð |
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: scan_for_filename äîëæíà íà÷èíàòüñÿ |
ñ èíñòðóêöèè 'xor di,di' ñ êîäîì 31 FF (âîîáùå-òî ýòà èíñòðóêöèÿ ìîæåò |
ñ ðàâíûì óñïåõîì àññåìáëèðîâàòüñÿ è êàê 33 FF, íî fasm ãåíåðèðóåò |
èìåííî òàêóþ ôîðìó). |
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà |
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ |
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà |
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò). |
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è |
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà |
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè. |
3. Îïðåäåëÿåò òèï ôàéëîâîé ñèñòåìû: FAT12 èëè FAT16. Ñîãëàñíî îôèöèàëüíîé |
ñïåöèôèêàöèè îò Microsoft (âåðñèÿ 1.03 ñïåöèôèêàöèè äàòèðîâàíà, |
ê ñëîâó, 06 äåêàáðÿ 2000 ãîäà), ðàçðÿäíîñòü FAT îïðåäåëÿåòñÿ |
èñêëþ÷èòåëüíî ÷èñëîì êëàñòåðîâ: ìàêñèìàëüíîå ÷èñëî êëàñòåðîâ íà |
FAT12-òîìå ðàâíî 4094 = 0xFF4. Ñîãëàñíî çäðàâîìó ñìûñëó, íà FAT12 |
ìîæåò áûòü 0xFF5 êëàñòåðîâ, íî íå áîëüøå: êëàñòåðû íóìåðóþòñÿ ñ 2, |
à ÷èñëî 0xFF7 íå ìîæåò áûòü êîððåêòíûì íîìåðîì êëàñòåðà. |
Win95/98/Me ñëåäóåò çäðàâîìó ñìûñëó: ðàçãðàíè÷åíèå FAT12/16 äåëàåòñÿ |
ïî ìàêñèìóìó 0xFF5. Äðàéâåð FAT â WinNT/2k/XP/Vista âîîáùå ïîñòóïàåò |
ÿâíî íåâåðíî, ñ÷èòàÿ, ÷òî 0xFF6 (èëè ìåíüøå) êëàñòåðîâ îçíà÷àåò |
FAT12-òîì, â ðåçóëüòàòå ïîëó÷àåòñÿ, ÷òî ïîñëåäíèé êëàñòåð |
(â ñëó÷àå 0xFF6) íåàäðåñóåì. Îñíîâíîé çàãðóç÷èê osloader.exe |
[âñòðîåí â ntldr] äëÿ NT/2k/XP äåëàåò òàê æå. Ïåðâè÷íûé çàãðóç÷èê |
[áóòñåêòîð FAT12/16 çàãðóæàåò ïåðâûé ñåêòîð ntldr, è ðàçáîð FAT-òàáëèöû |
ëåæèò íà í¸ì] â NT/2k ïîäâåðæåí òîé æå îøèáêå.  XP å¸ òàêè èñïðàâèëè |
â ñîîòâåòñòâèè ñî ñïåöèôèêàöèåé. Linux ïðè îïðåäåëåíèè FAT12/FAT16 |
÷åñòíî ñëåäóåò ñïåöèôèêàöèè. |
Çäåñü êîä îñíîâàí âñ¸ æå íà ñïåöèôèêàöèè. 9x ìåðòâà, à â ëèíåéêå NT |
Microsoft åñëè è áóäåò èñïðàâëÿòü îøèáêè, òî ñîãëàñíî ñîáñòâåííîìó |
îïèñàíèþ. |
4. Äëÿ FAT12: çàãðóæàåò â ïàìÿòü ïåðâóþ êîïèþ òàáëèöû FAT ïî àäðåñó 6000:0000. |
Åñëè ðàçìåð, óêàçàííûé â BPB, ïðåâîñõîäèò 12 ñåêòîðîâ, |
ýòî îçíà÷àåò, ÷òî çàÿâëåííûé ðàçìåð ñëèøêîì áîëüøîé (ýòî íå ñ÷èòàåòñÿ |
îøèáêîé ôàéëîâîé ñèñòåìû), è ÷èòàþòñÿ òîëüêî 12 ñåêòîðîâ (òàáëèöà FAT12 |
çàâåäîìî âëåçàåò â òàêîé îáú¸ì äàííûõ). |
Äëÿ FAT16: èíèöèàëèçèðóåò âíóòðåííèå äàííûå, óêàçûâàÿ, ÷òî íèêàêîé ñåêòîð |
FAT íå çàãðóæåí (îíè áóäóò ïîäãðóæàòüñÿ ïîçäíåå, êîãäà ïîíàäîáÿòñÿ |
è òîëüêî òå, êîòîðûå ïîíàäîáÿòñÿ). |
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà |
kordldr.f1x, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ |
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f1x. |
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå |
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò |
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì |
"Fatal error: cannot load the secondary loader". |
Замечание: на этом этапе имя файла уже можно указывать вместе с путём |
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов |
по-прежнему нет. |
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. |
Это нужно, чтобы последующие обращения к коду бутсектора в случае |
ошибок чтения не выводил соответствующее сообщение с последующей |
перезагрузкой, а рапортовал об ошибке чтения, которую мог бы |
как-нибудь обработать вторичный загрузчик. |
8. Если загрузочный диск имеет идентификатор меньше 0x80, |
то устанавливает al='f' ("floppy"), ah=идентификатор диска, |
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). |
Устанавливает bx='12', если тип файловой системы - FAT12, и |
bx='16' в случае FAT16. Устанавливает si=смещение функции обратного |
вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. |
9. Передаёт управление по адресу 1000:0000. |
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì |
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ |
ïî-ïðåæíåìó íåò. |
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err. |
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå |
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé |
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîã áû |
êàê-íèáóäü îáðàáîòàòü âòîðè÷íûé çàãðóç÷èê. |
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80, |
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà, |
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà). |
Óñòàíàâëèâàåò bx='12', åñëè òèï ôàéëîâîé ñèñòåìû - FAT12, è |
bx='16' â ñëó÷àå FAT16. Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî |
âûçîâà. Ïîñêîëüêó â ýòîò ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ. |
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным |
кодом должна указывать на 0:7C00, а -8 берётся от того, что |
инициализирующий код бутсектора уже поместил в стек 2 двойных слова, |
и они должны сохраняться в неизменности. |
2. Разбирает переданные параметры, выясняет, какое действие запрошено, |
и вызывает нужную вспомогательную процедуру. |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:(7C00-8), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -8 áåð¸òñÿ îò òîãî, ÷òî |
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 2 äâîéíûõ ñëîâà, |
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû, âûÿñíÿåò, êàêîå äåéñòâèå çàïðîøåíî, |
è âûçûâàåò íóæíóþ âñïîìîãàòåëüíóþ ïðîöåäóðó. |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры kordldr.f1x. |
Процедура получения следующего кластера в FAT (get_next_cluster): |
1. Вспоминает разрядность FAT, вычисленную ранее. |
Для FAT12: |
2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана |
вся таблица FAT. |
3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте |
слова, задающего следующий кластер. Загружает слово по этому адресу. |
4. Если кластер имеет нечётный номер, то соответствующий ему элемент |
располагается в старших 12 битах слова, и слово нужно сдвинуть вправо |
на 4 бита; в противном случае - в младших 12 битах, и делать ничего не |
надо. |
5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: |
номера нормальных кластеров меньше, и флаг CF устанавливается; |
специальные значения EOF и BadClus сбрасывают флаг CF. |
Для FAT16: |
2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных |
в таблице FAT. |
3. Если сектор ещё не загружен, то загружает его. |
4. Вычисляет смещение данных для конкретного кластера относительно начала |
сектора. |
5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. |
6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг |
CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. |
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f1x. |
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster): |
1. Âñïîìèíàåò ðàçðÿäíîñòü FAT, âû÷èñëåííóþ ðàíåå. |
Äëÿ FAT12: |
2. Óñòàíàâëèâàåò ds = 0x6000 - ñåãìåíò, êóäà ðàíåå áûëà ñ÷èòàíà |
âñÿ òàáëèöà FAT. |
3. Ïîäñ÷èòûâàåò si = (êëàñòåð) + (êëàñòåð)/2 - ñìåùåíèå â ýòîì ñåãìåíòå |
ñëîâà, çàäàþùåãî ñëåäóþùèé êëàñòåð. Çàãðóæàåò ñëîâî ïî ýòîìó àäðåñó. |
4. Åñëè êëàñòåð èìååò íå÷¸òíûé íîìåð, òî ñîîòâåòñòâóþùèé åìó ýëåìåíò |
ðàñïîëàãàåòñÿ â ñòàðøèõ 12 áèòàõ ñëîâà, è ñëîâî íóæíî ñäâèíóòü âïðàâî |
íà 4 áèòà; â ïðîòèâíîì ñëó÷àå - â ìëàäøèõ 12 áèòàõ, è äåëàòü íè÷åãî íå |
íàäî. |
5. Âûäåëÿåò èç ïîëó÷èâøåãîñÿ ñëîâà 12 áèò. Ñðàâíèâàåò èõ ñ ïðåäåëîì 0xFF7: |
íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã CF óñòàíàâëèâàåòñÿ; |
ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò ôëàã CF. |
Äëÿ FAT16: |
2. Âû÷èñëÿåò àäðåñ ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ ñîîòâåòñòâóþùåãî ñåêòîðà äàííûõ |
â òàáëèöå FAT. |
3. Åñëè ñåêòîð åù¸ íå çàãðóæåí, òî çàãðóæàåò åãî. |
4. Âû÷èñëÿåò ñìåùåíèå äàííûõ äëÿ êîíêðåòíîãî êëàñòåðà îòíîñèòåëüíî íà÷àëà |
ñåêòîðà. |
5. Çàãðóæàåò ñëîâî â ax èç àäðåñà, âû÷èñëåííîìó íà øàãàõ 1 è 3. |
6. Ñðàâíèâàåò åãî ñ ïðåäåëîì 0xFFF7: íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã |
CF óñòàíàâëèâàåòñÿ; ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò CF. |
Процедура загрузки файла (load_file): |
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. |
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты |
разделяются символом '/') в FAT-формат 8+3. Если это невозможно |
(больше 8 символов в имени, больше 3 символов в расширении или |
больше одной точки), возвращается с ошибкой. |
3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой |
папки используется процедура из бутсектора. Для остальных папок: |
a) Проверяет, есть ли такая папка в кэше некорневых папок. |
(Идентификация папок осуществляется по номеру начального кластера.) |
Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, |
выкидывает папку, к которой дольше всего не было обращений. (Для |
каждого элемента кэша хранится метка от 0 до (размер кэша)-1, |
определяющая его номер при сортировке по давности последнего обращения. |
При обращении к какому-то элементу его метка становится нулевой, |
а те метки, которые меньше старого значения, увеличиваются на единицу.) |
б) Просматривает в поисках запрошенного имени все элементы из кэша, |
используя процедуру из бутсектора. Если обнаруживает искомый элемент, |
переходит к шагу 4. Если обнаруживает конец папки, возвращается из |
процедуры с ошибкой. |
в) В цикле считывает папку посекторно. При этом пропускает начальные |
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый |
прочитанный сектор копирует в кэш, если там ещё остаётся место, |
и просматривает в нём все элементы. Работает, пока не случится одно из |
трёх событий: найден искомый элемент; кончились кластеры (судя по |
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце |
(первый байт нулевой). В двух последних случаях возвращается с ошибкой. |
4. Проверяет тип найденного элемента (файл/папка): последний элемент в |
запрошенном имени должен быть файлом, все промежуточные - папками. |
Если текущий компонент имени - промежуточный, продвигает текущую |
рассматриваемую папку и возвращается к пункту 2. |
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный |
при вызове буфер последовательными вызовами функции бутсектора; |
при этом если несколько кластеров файла расположены на диске |
последовательно, то их чтение объединяется в одну операцию. |
Следит за тем, чтобы не превысить указанный при вызове процедуры |
лимит числа секторов для чтения. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4. |
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû |
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî |
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè |
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé. |
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. Äëÿ êîðíåâîé |
ïàïêè èñïîëüçóåòñÿ ïðîöåäóðà èç áóòñåêòîðà. Äëÿ îñòàëüíûõ ïàïîê: |
a) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå íåêîðíåâûõ ïàïîê. |
(Èäåíòèôèêàöèÿ ïàïîê îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) |
Åñëè òàêîé ïàïêè åù¸ íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, |
âûêèäûâàåò ïàïêó, ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ |
êàæäîãî ýëåìåíòà êýøà õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, |
îïðåäåëÿþùàÿ åãî íîìåð ïðè ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. |
Ïðè îáðàùåíèè ê êàêîìó-òî ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, |
à òå ìåòêè, êîòîðûå ìåíüøå ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.) |
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà, |
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò, |
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç |
ïðîöåäóðû ñ îøèáêîé. |
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå |
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé |
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî, |
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç |
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî |
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå |
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé. |
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â |
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè. |
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ |
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2. |
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé |
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà; |
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå |
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ. |
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû |
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ. |
Процедура продолжения загрузки файла (continue_load_file): встроена |
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее |
сохранённые из load_file) и продолжает шаг 5. |
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà |
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå |
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5. |
/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.txt |
---|
24,310 → 24,310 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Читай между строк - там никогда не бывает опечаток. |
×èòàé ìåæäó ñòðîê - òàì íèêîãäà íå áûâàåò îïå÷àòîê. |
Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. |
Áóòñåêòîð äëÿ FAT32-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò. |
===================================================================== |
Есть две версии в зависимости от того, поддерживает ли носитель LBA, |
выбор осуществляется установкой константы use_lba в первой строке исходника. |
Требования для работы: |
1) Сам бутсектор, первая копия FAT и все используемые файлы |
должны быть читабельны. (Если дело происходит на носителе с разбиением на |
разделы и загрузочный код в MBR достаточно умный, то читабельности резервной |
копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности |
самого бутсектора). |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 584K свободной базовой памяти. |
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA, |
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû |
äîëæíû áûòü ÷èòàáåëüíû. (Åñëè äåëî ïðîèñõîäèò íà íîñèòåëå ñ ðàçáèåíèåì íà |
ðàçäåëû è çàãðóçî÷íûé êîä â MBR äîñòàòî÷íî óìíûé, òî ÷èòàáåëüíîñòè ðåçåðâíîé |
êîïèè áóòñåêòîðà (ñåêòîð íîìåð 6 íà òîìå) äîñòàòî÷íî âìåñòî ÷èòàáåëüíîñòè |
ñàìîãî áóòñåêòîðà). |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 584K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 15.05.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 15.05.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Схема используемой памяти: |
...-7C00 стек |
7C00-7E00 код бутсектора |
7E00-8200 вспомогательный файл загрузчика (kordldr.f32) |
8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 |
байт: 4 байта (две ссылки - вперёд и назад) для |
организации L2-списка всех прочитанных секторов в |
порядке возрастания последнего времени использования |
+ 4 байта для номера сектора; при переполнении кэша |
выкидывается элемент из головы списка, то есть тот, |
к которому дольше всех не было обращений |
60000-80000 кэш для таблицы FAT (100h секторов) |
80000-90000 текущий кластер текущей рассматриваемой папки |
90000-... кэш для содержимого папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 8 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
...-7C00 ñòåê |
7C00-7E00 êîä áóòñåêòîðà |
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f32) |
8400-8C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèöû FAT: 100h âõîäîâ ïî 8 |
áàéò: 4 áàéòà (äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ |
îðãàíèçàöèè L2-ñïèñêà âñåõ ïðî÷èòàííûõ ñåêòîðîâ â |
ïîðÿäêå âîçðàñòàíèÿ ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ |
+ 4 áàéòà äëÿ íîìåðà ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà |
âûêèäûâàåòñÿ ýëåìåíò èç ãîëîâû ñïèñêà, òî åñòü òîò, |
ê êîòîðîìó äîëüøå âñåõ íå áûëî îáðàùåíèé |
60000-80000 êýø äëÿ òàáëèöû FAT (100h ñåêòîðîâ) |
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè |
90000-... êýø äëÿ ñîäåðæèìîãî ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 8 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед |
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало |
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - |
это освобождает ds и экономит на размере кода). Сохраняет в стеке |
идентификатор загрузочного диска для последующего обращения |
через byte [bp-2]. |
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h |
прерывания 13h. Если нет, переходит на код обработки ошибок с |
сообщением об отсутствии LBA. |
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и |
записывает полученные данные поверх BPB. Если вызов завершился ошибкой, |
предполагает уже существующие данные корректными. |
3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего |
обращения через dword [bp-10]. В процессе вычисления узнаёт начало |
первой FAT, сохраняет и его в стек для последующего обращения через |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä |
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî |
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] - |
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). Ñîõðàíÿåò â ñòåêå |
èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà äëÿ ïîñëåäóþùåãî îáðàùåíèÿ |
÷åðåç byte [bp-2]. |
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h |
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ |
ñîîáùåíèåì îá îòñóòñòâèè LBA. |
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è |
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé, |
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè. |
3. Âû÷èñëÿåò íà÷àëî äàííûõ FAT-òîìà, ñîõðàíÿåò åãî â ñòåê äëÿ ïîñëåäóþùåãî |
îáðàùåíèÿ ÷åðåç dword [bp-10].  ïðîöåññå âû÷èñëåíèÿ óçíà¸ò íà÷àëî |
ïåðâîé FAT, ñîõðàíÿåò è åãî â ñòåê äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç |
dword [bp-6]. |
4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 |
для последующего обращения через dword [bp-14] - инициализация |
переменной, содержащей текущий сектор, находящийся в кэше FAT |
(-1 не является валидным значением для номера сектора FAT). |
5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на |
код обработки ошибок с сообщением о ненайденном загрузчике. |
Замечание: на этом этапе загрузки искать можно только в корневой |
папке и только имена, заданные в формате файловой системе FAT |
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны |
быть заглавными, при необходимости имя и расширение дополняются |
пробелами, разделяющей точки нет, завершающего нуля нет). |
6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт |
ему управление. При этом в регистре eax оказывается абсолютный |
номер первого сектора kordldr.f32, а в cx - число считанных секторов |
(равное размеру кластера). |
4. (Çàêàí÷èâàÿ òåìó ïàðàìåòðîâ â ñòåêå) Ïîìåùàåò â ñòåê dword-çíà÷åíèå -1 |
äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç dword [bp-14] - èíèöèàëèçàöèÿ |
ïåðåìåííîé, ñîäåðæàùåé òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT |
(-1 íå ÿâëÿåòñÿ âàëèäíûì çíà÷åíèåì äëÿ íîìåðà ñåêòîðà FAT). |
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f32. Åñëè íå íàõîäèò - ïåðåõîäèò íà |
êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î íåíàéäåííîì çàãðóç÷èêå. |
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé |
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT |
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû |
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ |
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò). |
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f32 ïî àäðåñó 0:7E00 è ïåðåäà¸ò |
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðå eax îêàçûâàåòñÿ àáñîëþòíûé |
íîìåð ïåðâîãî ñåêòîðà kordldr.f32, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ |
(ðàâíîå ðàçìåðó êëàñòåðà). |
Вспомогательные процедуры бутсектора. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения кластера (read_cluster): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ êëàñòåðà (read_cluster): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = номер кластера |
на выходе: ecx = число прочитанных секторов (размер кластера), |
es:bx указывает на конец буфера, в который были прочитаны данные, |
eax и старшие слова других 32-битных регистров разрушаются |
Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора |
и переходит к следующей процедуре. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = íîìåð êëàñòåðà |
íà âûõîäå: ecx = ÷èñëî ïðî÷èòàííûõ ñåêòîðîâ (ðàçìåð êëàñòåðà), |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
eax è ñòàðøèå ñëîâà äðóãèõ 32-áèòíûõ ðåãèñòðîâ ðàçðóøàþòñÿ |
Çàãðóæàåò â ecx ðàçìåð êëàñòåðà, ïåðåêîäèðóåò íîìåð êëàñòåðà â íîìåð ñåêòîðà |
è ïåðåõîäèò ê ñëåäóþùåé ïðîöåäóðå. |
Процедура чтения секторов (read_sectors32 и read_sectors2): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors32 è read_sectors2): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор (относительно начала логического диска |
для read_sectors32, относительно начала данных |
для read_sectors2) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные |
старшие слова 32-битных регистров могут разрушиться |
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора |
в номер относительно начала логического диска, прибавляя номер сектора |
начала данных, хранящийся в стеке как [bp-10]. |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя значение соответствующего поля из BPB. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà |
äëÿ read_sectors32, îòíîñèòåëüíî íà÷àëà äàííûõ |
äëÿ read_sectors2) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
ñòàðøèå ñëîâà 32-áèòíûõ ðåãèñòðîâ ìîãóò ðàçðóøèòüñÿ |
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà |
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà |
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-10]. |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура поиска элемента в папке (lookup_in_dir): |
на входе должно быть установлено: |
Ïðîöåäóðà ïîèñêà ýëåìåíòà â ïàïêå (lookup_in_dir): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
ds:si = указатель на имя файла в формате FAT (см. выше) |
eax = начальный кластер папки |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå) |
eax = íà÷àëüíûé êëàñòåð ïàïêè |
bx = 0 |
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то |
CF сброшен и es:di указывает на элемент папки |
В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных |
данных. Для чтения кластера использует уже описанную процедуру read_clusters, |
для продвижения по цепочке кластеров - описанную далее процедуру |
get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса |
8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, |
если чтение прервётся раньше) не перекрываются последующими чтениями |
(это будет использовано позднее, в системе кэширования из kordldr.f32). |
Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; |
кончились элементы в папке (первый байт очередного элемента нулевой); |
кончились данные папки в соответствии с цепочкой кластеров из FAT. |
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî |
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè |
 öèêëå ñ÷èòûâàåò êëàñòåðû ïàïêè è èùåò çàïðîøåííûé ýëåìåíò â ïðî÷èòàííûõ |
äàííûõ. Äëÿ ÷òåíèÿ êëàñòåðà èñïîëüçóåò óæå îïèñàííóþ ïðîöåäóðó read_clusters, |
äëÿ ïðîäâèæåíèÿ ïî öåïî÷êå êëàñòåðîâ - îïèñàííóþ äàëåå ïðîöåäóðó |
get_next_clusters. Äàííûå ÷èòàþòñÿ â îáëàñòü ïàìÿòè, íà÷èíàþùóþñÿ ñ àäðåñà |
8000:0000, ïðè ýòîì ïåðâûå 2000h áàéò èç äàííûõ ïàïêè (ìîæåò áûòü, ìåíüøå, |
åñëè ÷òåíèå ïðåðâ¸òñÿ ðàíüøå) íå ïåðåêðûâàþòñÿ ïîñëåäóþùèìè ÷òåíèÿìè |
(ýòî áóäåò èñïîëüçîâàíî ïîçäíåå, â ñèñòåìå êýøèðîâàíèÿ èç kordldr.f32). |
Âûõîä îñóùåñòâëÿåòñÿ â ëþáîì èç ñëåäóþùèõ ñëó÷àåâ: íàéäåí çàïðîøåííûé ýëåìåíò; |
êîí÷èëèñü ýëåìåíòû â ïàïêå (ïåðâûé áàéò î÷åðåäíîãî ýëåìåíòà íóëåâîé); |
êîí÷èëèñü äàííûå ïàïêè â ñîîòâåòñòâèè ñ öåïî÷êîé êëàñòåðîâ èç FAT. |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
===================================================================== |
Работа вспомогательного загрузчика kordldr.f32: |
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. |
В зависимости от этого устанавливает смещения используемых процедур |
бутсектора. Критерий проверки: в CHS-версии по адресу err находится |
байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу |
находится байт 0x14, а адрес процедуры err другой. |
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска |
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с |
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента |
место должно быть, отсюда ограничение в 592 Kb (94000h байт). |
Замечание: этот размер не может превосходить 0A0000h байт и |
на практике оказывается немного (на 1-2 килобайта) меньшим из-за |
наличия дополнительной области данных BIOS "вверху" базовой памяти. |
3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть |
данных корневой папки; копирует загруженные данные в кэш и запоминает, |
что в кэше есть корневая папка. |
4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только |
том случае, когда ему приходится загружать данные корневой папки, |
не поместившиеся в один кластер. В этом случае в памяти присутствует |
один сектор FAT (если было несколько обращений - последний из |
использованных). |
5. Если кластер равен сектору, то бутсектор загрузил только часть файла |
kordldr.f32, и загрузчик подгружает вторую свою часть, используя |
значения регистров на входе в kordldr.f32. |
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не |
найден, или оказался папкой, или оказался слишком большим, то переходит |
на код обработки ошибок из бутсектора с сообщением |
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f32: |
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà. |
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð |
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: â CHS-âåðñèè ïî àäðåñó err íàõîäèòñÿ |
áàéò 0xE8 (ìàøèííàÿ êîìàíäà call), â LBA-âåðñèè ïî òîìó æå àäðåñó |
íàõîäèòñÿ áàéò 0x14, à àäðåñ ïðîöåäóðû err äðóãîé. |
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà |
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ |
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà |
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò). |
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è |
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà |
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè. |
3. Èíèöèàëèçèðóåò êýøèðîâàíèå ïàïîê. Áóòñåêòîð óæå çàãðóçèë êàêóþ-òî ÷àñòü |
äàííûõ êîðíåâîé ïàïêè; êîïèðóåò çàãðóæåííûå äàííûå â êýø è çàïîìèíàåò, |
÷òî â êýøå åñòü êîðíåâàÿ ïàïêà. |
4. Èíèöèàëèçèðóåò êýøèðîâàíèå FAT. Áóòñåêòîð èìååò äåëî ñ FAT â òîì è òîëüêî |
òîì ñëó÷àå, êîãäà åìó ïðèõîäèòñÿ çàãðóæàòü äàííûå êîðíåâîé ïàïêè, |
íå ïîìåñòèâøèåñÿ â îäèí êëàñòåð.  ýòîì ñëó÷àå â ïàìÿòè ïðèñóòñòâóåò |
îäèí ñåêòîð FAT (åñëè áûëî íåñêîëüêî îáðàùåíèé - ïîñëåäíèé èç |
èñïîëüçîâàííûõ). |
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà |
kordldr.f32, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ |
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f32. |
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå |
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò |
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì |
"Fatal error: cannot load the secondary loader". |
Замечание: на этом этапе имя файла уже можно указывать вместе с путём |
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов |
по-прежнему нет. |
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. |
Это нужно, чтобы последующие обращения к коду бутсектора в случае |
ошибок чтения не выводил соответствующее сообщение с последующей |
перезагрузкой, а рапортовал об ошибке чтения, которую могло бы |
как-нибудь обработать ядро. |
8. Если загрузочный диск имеет идентификатор меньше 0x80, |
то устанавливает al='f' ("floppy"), ah=идентификатор диска, |
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). |
(Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но |
уверены ли Вы, что нет загрузочных устройств, подобных дискетам, |
но большего размера, и для которых BIOS-идентификатор меньше 0x80?) |
Устанавливает bx='32' (тип файловой системы - FAT32). |
Устанавливает si=смещение функции обратного вызова. Поскольку в этот |
момент ds=0, то ds:si образуют полный адрес. |
9. Передаёт управление по адресу 1000:0000. |
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì |
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ |
ïî-ïðåæíåìó íåò. |
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err. |
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå |
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé |
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîãëî áû |
êàê-íèáóäü îáðàáîòàòü ÿäðî. |
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80, |
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà, |
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà). |
(Ãîâîðèòå, äèñêåòîê ñ FAT32 íå áûâàåò?  ÷¸ì-òî Âû ïðàâû... íî |
óâåðåíû ëè Âû, ÷òî íåò çàãðóçî÷íûõ óñòðîéñòâ, ïîäîáíûõ äèñêåòàì, |
íî áîëüøåãî ðàçìåðà, è äëÿ êîòîðûõ BIOS-èäåíòèôèêàòîð ìåíüøå 0x80?) |
Óñòàíàâëèâàåò bx='32' (òèï ôàéëîâîé ñèñòåìû - FAT32). |
Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî âûçîâà. Ïîñêîëüêó â ýòîò |
ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ. |
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным |
кодом должна указывать на 0:7C00, а -10 берётся от того, что |
инициализирующий код бутсектора уже поместил в стек 10 байт параметров, |
и они должны сохраняться в неизменности. (Значение [ebp-14], |
"текущий сектор, находящийся в кэше FAT", не используется после |
инициализации кэширования в kordldr.f32.) |
2. Разбирает переданные параметры и вызывает нужную из вспомогательных |
процедур (загрузки файла либо продолжения загрузки файла). |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:(7C00-10), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -10 áåð¸òñÿ îò òîãî, ÷òî |
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 10 áàéò ïàðàìåòðîâ, |
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. (Çíà÷åíèå [ebp-14], |
"òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT", íå èñïîëüçóåòñÿ ïîñëå |
èíèöèàëèçàöèè êýøèðîâàíèÿ â kordldr.f32.) |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò íóæíóþ èç âñïîìîãàòåëüíûõ |
ïðîöåäóð (çàãðóçêè ôàéëà ëèáî ïðîäîëæåíèÿ çàãðóçêè ôàéëà). |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры kordldr.f32. |
Процедура получения следующего кластера в FAT (get_next_cluster): |
1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. |
(В секторе 0x200 байт, каждый вход занимает 4 байта.) |
2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. |
3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, |
выделяет очередной элемент в конце кэша. Если заполнен, удаляет |
самый старый элемент (тот, к которому дольше всего не было обращений); |
для того, чтобы отслеживать порядок элементов по времени последнего |
обращения, все (выделенные) элементы кэша связаны в двусвязный список, |
в котором первым элементом является самый старый, а ссылки вперёд |
указывают на следующий по времени последнего обращения. |
4. Читает соответствующий сектор FAT с диска. |
5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, |
где он находится, и добавляется в конец. (В случае со свежедобавленными |
в кэш элементами удаления не делается, поскольку их в списке ещё нет.) |
6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. |
7. Сравнивает прочитанное значение с пределом: если оно строго меньше |
0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; |
в противном случае цепочка закончилась. |
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f32. |
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster): |
1. Âû÷èñëÿåò íîìåð ñåêòîðà â FAT, â êîòîðîì íàõîäèòñÿ çàïðîøåííûé ýëåìåíò. |
(Â ñåêòîðå 0x200 áàéò, êàæäûé âõîä çàíèìàåò 4 áàéòà.) |
2. Ïðîâåðÿåò, åñòü ëè ñåêòîð â êýøå. Åñëè åñòü, ïðîïóñêàåò øàãè 3 è 4. |
3. Åñëè íåò, òî â êýø íóæíî âñòàâèòü íîâûé ýëåìåíò. Åñëè êýø åù¸ íå çàïîëíåí, |
âûäåëÿåò î÷åðåäíîé ýëåìåíò â êîíöå êýøà. Åñëè çàïîëíåí, óäàëÿåò |
ñàìûé ñòàðûé ýëåìåíò (òîò, ê êîòîðîìó äîëüøå âñåãî íå áûëî îáðàùåíèé); |
äëÿ òîãî, ÷òîáû îòñëåæèâàòü ïîðÿäîê ýëåìåíòîâ ïî âðåìåíè ïîñëåäíåãî |
îáðàùåíèÿ, âñå (âûäåëåííûå) ýëåìåíòû êýøà ñâÿçàíû â äâóñâÿçíûé ñïèñîê, |
â êîòîðîì ïåðâûì ýëåìåíòîì ÿâëÿåòñÿ ñàìûé ñòàðûé, à ññûëêè âïåð¸ä |
óêàçûâàþò íà ñëåäóþùèé ïî âðåìåíè ïîñëåäíåãî îáðàùåíèÿ. |
4. ×èòàåò ñîîòâåòñòâóþùèé ñåêòîð FAT ñ äèñêà. |
5. Êîððåêòèðóåò ñïèñîê: òåêóùèé îáðàáàòûâàåìûé ýëåìåíò óäàëÿåòñÿ ñ òîé ïîçèöèè, |
ãäå îí íàõîäèòñÿ, è äîáàâëÿåòñÿ â êîíåö. ( ñëó÷àå ñî ñâåæåäîáàâëåííûìè |
â êýø ýëåìåíòàìè óäàëåíèÿ íå äåëàåòñÿ, ïîñêîëüêó èõ â ñïèñêå åù¸ íåò.) |
6. Ñ÷èòûâàåò íóæíûé âõîä â FAT, ñáðàñûâàÿ ñòàðøèå 4 áèòà. |
7. Ñðàâíèâàåò ïðî÷èòàííîå çíà÷åíèå ñ ïðåäåëîì: åñëè îíî ñòðîãî ìåíüøå |
0x0FFFFFF7, òî îíî çàäà¸ò íîìåð ñëåäóþùåãî êëàñòåðà â öåïî÷êå; |
â ïðîòèâíîì ñëó÷àå öåïî÷êà çàêîí÷èëàñü. |
Процедура загрузки файла (load_file): |
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. |
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты |
разделяются символом '/') в FAT-формат 8+3. Если это невозможно |
(больше 8 символов в имени, больше 3 символов в расширении или |
больше одной точки), возвращается с ошибкой. |
3. Ищет элемент с таким именем в текущей рассматриваемой папке. |
а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок |
осуществляется по номеру начального кластера.) Если такой папки ещё |
нет, добавляет её в кэш; если тот переполняется, выкидывает папку, |
к которой дольше всего не было обращений. (Для каждого элемента кэша |
хранится метка от 0 до (размер кэша)-1, определяющая его номер при |
сортировке по давности последнего обращения. При обращении к какому-то |
элементу его метка становится нулевой, а те метки, которые меньше |
старого значения, увеличиваются на единицу.) |
б) Просматривает в поисках запрошенного имени все элементы из кэша, |
используя процедуру из бутсектора. Если обнаруживает искомый элемент, |
переходит к шагу 4. Если обнаруживает конец папки, возвращается из |
процедуры с ошибкой. |
в) В цикле считывает папку посекторно. При этом пропускает начальные |
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый |
прочитанный сектор копирует в кэш, если там ещё остаётся место, |
и просматривает в нём все элементы. Работает, пока не случится одно из |
трёх событий: найден искомый элемент; кончились кластеры (судя по |
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце |
(первый байт нулевой). В двух последних случаях возвращается с ошибкой. |
4. Проверяет тип найденного элемента (файл/папка): последний элемент в |
запрошенном имени должен быть файлом, все промежуточные - папками. |
Если текущий компонент имени - промежуточный, продвигает текущую |
рассматриваемую папку и возвращается к пункту 2. |
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный |
при вызове буфер последовательными вызовами функции бутсектора; |
при этом если несколько кластеров файла расположены на диске |
последовательно, то их чтение объединяется в одну операцию. |
Следит за тем, чтобы не превысить указанный при вызове процедуры |
лимит числа секторов для чтения. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4. |
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû |
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî |
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè |
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé. |
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. |
à) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå ïàïîê. (Èäåíòèôèêàöèÿ ïàïîê |
îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) Åñëè òàêîé ïàïêè åù¸ |
íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, âûêèäûâàåò ïàïêó, |
ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ êàæäîãî ýëåìåíòà êýøà |
õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, îïðåäåëÿþùàÿ åãî íîìåð ïðè |
ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. Ïðè îáðàùåíèè ê êàêîìó-òî |
ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, à òå ìåòêè, êîòîðûå ìåíüøå |
ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.) |
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà, |
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò, |
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç |
ïðîöåäóðû ñ îøèáêîé. |
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå |
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé |
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî, |
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç |
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî |
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå |
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé. |
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â |
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè. |
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ |
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2. |
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé |
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà; |
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå |
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ. |
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû |
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ. |
Процедура продолжения загрузки файла (continue_load_file): встроена |
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее |
сохранённые из load_file) и продолжает шаг 5. |
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà |
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå |
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5. |
/kernel/trunk/sec_loader/trunk/boot/PrimaryLoader.txt |
---|
24,68 → 24,68 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Спецификация на первичный загрузчик KordOS. |
Загрузчик должен предоставлять следующие сервисы: |
1. При загрузке компьютера, получив управление от BIOS'а, загружать |
файл loader из папки kord по адресу 1000:0000. |
Размер файла loader не превосходит 30000h = 192 Kb. |
2. При этом устанавливать следующие регистры: |
ax идентифицирует устройство: |
al = тип: |
'f' - флопик |
Ñïåöèôèêàöèÿ íà ïåðâè÷íûé çàãðóç÷èê KordOS. |
Çàãðóç÷èê äîëæåí ïðåäîñòàâëÿòü ñëåäóþùèå ñåðâèñû: |
1. Ïðè çàãðóçêå êîìïüþòåðà, ïîëó÷èâ óïðàâëåíèå îò BIOS'à, çàãðóæàòü |
ôàéë loader èç ïàïêè kord ïî àäðåñó 1000:0000. |
Ðàçìåð ôàéëà loader íå ïðåâîñõîäèò 30000h = 192 Kb. |
2. Ïðè ýòîì óñòàíàâëèâàòü ñëåäóþùèå ðåãèñòðû: |
ax èäåíòèôèöèðóåò óñòðîéñòâî: |
al = òèï: |
'f' - ôëîïèê |
'h' - HDD |
'c' - CD/DVD |
'u' - USB флешка |
'?' - неизвестное устройство |
ah = номер устройства (среди всех устройств фиксированного типа) |
bx = тип файловой системы: |
'u' - USB ôëåøêà |
'?' - íåèçâåñòíîå óñòðîéñòâî |
ah = íîìåð óñòðîéñòâà (ñðåäè âñåõ óñòðîéñòâ ôèêñèðîâàííîãî òèïà) |
bx = òèï ôàéëîâîé ñèñòåìû: |
'12' = FAT12 |
'16' = FAT16 |
'32' = FAT32 |
'nt' = NTFS |
'is' = ISO-9660 |
ds:si = far-указатель на callback-сервис |
3. Предоставлять callback-сервис для вторичного загрузчика - far-процедуру: |
на входе: ax = запрашиваемая функция |
на выходе: CF=1, если функция не поддерживается; CF=0 иначе |
Загрузчик может разрушать все регистры, включая сегментные, |
за исключением ss и sp. |
4. Всегда должна поддерживаться callback-функция 1: |
назначение: прочитать файл, расположенный на загрузочном устройстве |
на входе: ax = 1, ds:di = указатель на информационную структуру: |
dw:dw far-указатель на буфер, |
первое слово - смещение, второе - сегмент |
dw максимальное число 4Kb-блоков для чтения (0x1000 байт) |
должно быть ненулевым и строго меньше 0x100 |
ASCIIZ имя файла в формате "<папка1>/<папка2>/<файл>" |
Если имя файла содержит символы из старшей половины |
ASCIIZ-таблицы или не является 8.3-именем (в смысле, одна из компонент |
имени файла имеет имя длиннее 8 символов или расширение длиннее 3), |
загрузчик может не найти такой файл, даже если он есть |
(а может и найти). |
на выходе: bx = статус: |
0 = успешно |
1 = файл оказался слишком большим, буфер заполнен целиком |
и есть ещё данные файла |
2 = файл не найден |
3 = произошла ошибка чтения |
dx:ax = размер файла или FFFF:FFFF, если файл не найден |
5. Всегда должна поддерживаться callback-функция 2: |
назначение: продолжить чтение файла, частично загруженного функцией 1 |
на входе: ax = 2, ds:di = указатель на информационную структуру: |
dw:dw far-указатель на буфер, |
первое слово - смещение, второе - сегмент |
dw максимальное число 4Kb-блоков для чтения (0x1000 байт) |
должно быть ненулевым и строго меньше 0x100 |
на выходе: bx = статус: |
0 = успешно |
1 = файл оказался слишком большим, буфер заполнен целиком |
и есть ещё данные файла |
3 = произошла ошибка чтения |
dx:ax = размер файла |
Функцию можно вызывать только в случае, когда последний вызов функции |
1 и все последующие вызовы функции 2 вернули bx=1 (иными словами, |
только для продолжения загрузки файла, который уже был частично |
загружен, но ещё не загружен полностью). |
Загрузчик может быть уверен, что данные в областях памяти 0-9000 и |
60000-A0000 не будут модифицированы ядром. |
ds:si = far-óêàçàòåëü íà callback-ñåðâèñ |
3. Ïðåäîñòàâëÿòü callback-ñåðâèñ äëÿ âòîðè÷íîãî çàãðóç÷èêà - far-ïðîöåäóðó: |
íà âõîäå: ax = çàïðàøèâàåìàÿ ôóíêöèÿ |
íà âûõîäå: CF=1, åñëè ôóíêöèÿ íå ïîääåðæèâàåòñÿ; CF=0 èíà÷å |
Çàãðóç÷èê ìîæåò ðàçðóøàòü âñå ðåãèñòðû, âêëþ÷àÿ ñåãìåíòíûå, |
çà èñêëþ÷åíèåì ss è sp. |
4. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 1: |
íàçíà÷åíèå: ïðî÷èòàòü ôàéë, ðàñïîëîæåííûé íà çàãðóçî÷íîì óñòðîéñòâå |
íà âõîäå: ax = 1, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó: |
dw:dw far-óêàçàòåëü íà áóôåð, |
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò |
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò) |
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100 |
ASCIIZ èìÿ ôàéëà â ôîðìàòå "<ïàïêà1>/<ïàïêà2>/<ôàéë>" |
Åñëè èìÿ ôàéëà ñîäåðæèò ñèìâîëû èç ñòàðøåé ïîëîâèíû |
ASCIIZ-òàáëèöû èëè íå ÿâëÿåòñÿ 8.3-èìåíåì (â ñìûñëå, îäíà èç êîìïîíåíò |
èìåíè ôàéëà èìååò èìÿ äëèííåå 8 ñèìâîëîâ èëè ðàñøèðåíèå äëèííåå 3), |
çàãðóç÷èê ìîæåò íå íàéòè òàêîé ôàéë, äàæå åñëè îí åñòü |
(à ìîæåò è íàéòè). |
íà âûõîäå: bx = ñòàòóñ: |
0 = óñïåøíî |
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì |
è åñòü åù¸ äàííûå ôàéëà |
2 = ôàéë íå íàéäåí |
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ |
dx:ax = ðàçìåð ôàéëà èëè FFFF:FFFF, åñëè ôàéë íå íàéäåí |
5. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 2: |
íàçíà÷åíèå: ïðîäîëæèòü ÷òåíèå ôàéëà, ÷àñòè÷íî çàãðóæåííîãî ôóíêöèåé 1 |
íà âõîäå: ax = 2, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó: |
dw:dw far-óêàçàòåëü íà áóôåð, |
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò |
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò) |
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100 |
íà âûõîäå: bx = ñòàòóñ: |
0 = óñïåøíî |
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì |
è åñòü åù¸ äàííûå ôàéëà |
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ |
dx:ax = ðàçìåð ôàéëà |
Ôóíêöèþ ìîæíî âûçûâàòü òîëüêî â ñëó÷àå, êîãäà ïîñëåäíèé âûçîâ ôóíêöèè |
1 è âñå ïîñëåäóþùèå âûçîâû ôóíêöèè 2 âåðíóëè bx=1 (èíûìè ñëîâàìè, |
òîëüêî äëÿ ïðîäîëæåíèÿ çàãðóçêè ôàéëà, êîòîðûé óæå áûë ÷àñòè÷íî |
çàãðóæåí, íî åù¸ íå çàãðóæåí ïîëíîñòüþ). |
Çàãðóç÷èê ìîæåò áûòü óâåðåí, ÷òî äàííûå â îáëàñòÿõ ïàìÿòè 0-9000 è |
60000-A0000 íå áóäóò ìîäèôèöèðîâàíû ÿäðîì. |
/kernel/trunk/sec_loader/trunk/debug_msg.inc |
---|
24,7 → 24,7 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
;Тут определены все сообщения, которые нужны в процессе отладки, и совсем не нужны в рабочей копии программы. |
;Òóò îïðåäåëåíû âñå ñîîáùåíèÿ, êîòîðûå íóæíû â ïðîöåññå îòëàäêè, è ñîâñåì íå íóæíû â ðàáî÷åé êîïèè ïðîãðàììû. |
If DEBUG |
cseg_msg db ' - Adress of code segment',0 |
stack_msg db 'Set stack & segments is have completed',0 |
/kernel/trunk/sec_loader/trunk/loader.asm |
---|
38,7 → 38,7 |
use16 |
org 0x0 |
jmp start |
include 'sl_equ.inc' ; в файле размещены все equ предопределения |
include 'sl_equ.inc' ; â ôàéëå ðàçìåùåíû âñå equ ïðåäîïðåäåëåíèÿ |
include 'boot_st.inc' |
include 'debug_msg.inc' ;here is message from debug |
include 'parse_dat.inc' |
49,8 → 49,8 |
include 'parse_def_sect.inc' |
include 'parse_err.inc' |
file_data dw 0x0,ini_data_ ;формат: смещение: сегмент т.к. используется les |
size_data dw 16 ;16 блоков по 4 кб т.е предел до 64 кб |
file_data dw 0x0,ini_data_ ;ôîðìàò: ñìåùåíèå: ñåãìåíò ò.ê. èñïîëüçóåòñÿ les |
size_data dw 16 ;16 áëîêîâ ïî 4 êá ò.å ïðåäåë äî 64 êá |
name_ini_f db 'kord/startos.ini',0 |
;//////////// |
86,7 → 86,7 |
call printplain |
mov al, '#' |
mov cx, 80 |
;input cx=size al=char будет вывден символ сколько раз указано в cx |
;input cx=size al=char áóäåò âûâäåí ñèìâîë ñêîëüêî ðàç óêàçàíî â cx |
@@: |
call putchar |
loop @b |
94,7 → 94,7 |
if DEBUG |
pushad |
mov ax, cs |
shl eax, 4 ; в десятичной системе адрес сегмента |
shl eax, 4 ; â äåñÿòè÷íîé ñèñòåìå àäðåñ ñåãìåíòà |
mov cx, 0xa |
mov di, cseg_msg |
call decode |
162,7 → 162,7 |
; Load startos.ini |
mov cx, loop_read_startos_file ;кол-во попыток чтения файла конфигурации startos.ini |
mov cx, loop_read_startos_file ;êîë-âî ïîïûòîê ÷òåíèÿ ôàéëà êîíôèãóðàöèè startos.ini |
align 4 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Load startos.ini ; |
254,32 → 254,32 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
fat12_buffer: |
.BS_jmpBoot db 0x90,0x90,0x90 ;3 байта NOP инструкция - ничего не делать |
.BS_OEMName db 'K SyS 64' ;8 байт |
.BPB_BytsPerSec dw 512 ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта |
.BPB_SecPerClus db 0x1 ;кол-во секторов в кластере |
.BPB_RsvdSecCnt dw 0x1 ;для FAt12/16 только 1, для FAT32 обычно 32 |
.BPB_NumFATs db 0x1 ;кол-во фат таблиц, на тот случай если будет сброс на дискету образа рам диска |
.BPB_RootEntCnt dw 512 ;для мак совместимости с fat16 |
.BPB_TotSec16 dw 0x0 ;кл-во секторов |
.BS_jmpBoot db 0x90,0x90,0x90 ;3 áàéòà NOP èíñòðóêöèÿ - íè÷åãî íå äåëàòü |
.BS_OEMName db 'K SyS 64' ;8 áàéò |
.BPB_BytsPerSec dw 512 ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà |
.BPB_SecPerClus db 0x1 ;êîë-âî ñåêòîðîâ â êëàñòåðå |
.BPB_RsvdSecCnt dw 0x1 ;äëÿ FAt12/16 òîëüêî 1, äëÿ FAT32 îáû÷íî 32 |
.BPB_NumFATs db 0x1 ;êîë-âî ôàò òàáëèö, íà òîò ñëó÷àé åñëè áóäåò ñáðîñ íà äèñêåòó îáðàçà ðàì äèñêà |
.BPB_RootEntCnt dw 512 ;äëÿ ìàê ñîâìåñòèìîñòè ñ fat16 |
.BPB_TotSec16 dw 0x0 ;êë-âî ñåêòîðîâ |
.BPB_Media db 0xF0 |
.BPB_FATSz16 dw 0x0 |
.BPB_SecPerTrk dw 0x0 ;содержит геометрию диска для RAMFS на как бы без разницы, пока пустое поле, позже внести реальные значения. |
.BPB_SecPerTrk dw 0x0 ;ñîäåðæèò ãåîìåòðèþ äèñêà äëÿ RAMFS íà êàê áû áåç ðàçíèöû, ïîêà ïóñòîå ïîëå, ïîçæå âíåñòè ðåàëüíûå çíà÷åíèÿ. |
.BPB_NumHeads dw 0x0 |
.BPB_HiddSec dd 0x0 ;кол-во скрытых секторов |
.BPB_HiddSec dd 0x0 ;êîë-âî ñêðûòûõ ñåêòîðîâ |
.BPB_TotSec32 dd 0x0 |
.BS_DrvNum db 'R' ;от слова RAM |
.BS_DrvNum db 'R' ;îò ñëîâà RAM |
.BS_Reserved1 db 0x0 |
.BS_BootSig db 0x29 |
.BS_VolID db 'RFKS' |
.BS_VolLab db 'RAM DISK FS' ;11 символов |
.BS_FilSysType db 'FAT12 ' ;8 символов |
;62 байта структура fat12. |
.BS_VolLab db 'RAM DISK FS' ;11 ñèìâîëîâ |
.BS_FilSysType db 'FAT12 ' ;8 ñèìâîëîâ |
;62 áàéòà ñòðóêòóðà fat12. |
db (512-($-fat12_buffer))dup(0x90) |
;структура для дирректории fat |
;ñòðóêòóðà äëÿ äèððåêòîðèè fat |
struc FAT_32_entry ;Byte Directory Entry Structure |
{ |
.DIR_Name rb 11 |
297,21 → 297,21 |
} |
;Тут будут распологатсья данные, которые затруднительно распологать в стековой области.... |
;Òóò áóäóò ðàñïîëîãàòñüÿ äàííûå, êîòîðûå çàòðóäíèòåëüíî ðàñïîëîãàòü â ñòåêîâîé îáëàñòè.... |
;;; |
;timer |
shot_name_fat rb 11 ;временный буфер для fat12, в нем храняться имена файлов приведенные к правилам FAT /* вдальнейшем перенести в стэк |
shot_name_fat rb 11 ;âðåìåííûé áóôåð äëÿ fat12, â íåì õðàíÿòüñÿ èìåíà ôàéëîâ ïðèâåäåííûå ê ïðàâèëàì FAT /* âäàëüíåéøåì ïåðåíåñòè â ñòýê |
if DEBUG |
rb 1 ;нужен для отладки и вывода имени файла после преобразования |
rb 1 ;íóæåí äëÿ îòëàäêè è âûâîäà èìåíè ôàéëà ïîñëå ïðåîáðàçîâàíèÿ |
dest_name_fat db 24 dup('_');12 |
db 0x0 |
end if |
value_timeout rw 1 ;value to timeout |
old_timer rd 1 ;старое значение вектора таймера |
start_timer rd 1 ;значение таймера |
timer_ rd 1 ;новое значение вектора таймера т.е. SL |
old_timer rd 1 ;ñòàðîå çíà÷åíèå âåêòîðà òàéìåðà |
start_timer rd 1 ;çíà÷åíèå òàéìåðà |
timer_ rd 1 ;íîâîå çíà÷åíèå âåêòîðà òàéìåðà ò.å. SL |
start_stack rw 1 ;save stack |
save_bp_from_timer rw 1 ;save bp from timer |
/kernel/trunk/sec_loader/trunk/parse.inc |
---|
24,31 → 24,31 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
; Модуль парсинга - это стандартный компонент, встраиваемый во вторичный загрузчик. |
; Данный модуль позволяет стандартно произвести разбор ini файла |
; (и с использованием полученных данных ОС будет загружаться дальше). |
; В начале найдем открывающий "[" - это будет указывать на начало |
; секции. Поддерживается 1 секция это [loader], остальные секции могут иметь |
; любые имена, но они должны быть заключены в в скобки [] |
; Ìîäóëü ïàðñèíãà - ýòî ñòàíäàðòíûé êîìïîíåíò, âñòðàèâàåìûé âî âòîðè÷íûé çàãðóç÷èê. |
; Äàííûé ìîäóëü ïîçâîëÿåò ñòàíäàðòíî ïðîèçâåñòè ðàçáîð ini ôàéëà |
; (è ñ èñïîëüçîâàíèåì ïîëó÷åííûõ äàííûõ ÎÑ áóäåò çàãðóæàòüñÿ äàëüøå). |
;  íà÷àëå íàéäåì îòêðûâàþùèé "[" - ýòî áóäåò óêàçûâàòü íà íà÷àëî |
; ñåêöèè. Ïîääåðæèâàåòñÿ 1 ñåêöèÿ ýòî [loader], îñòàëüíûå ñåêöèè ìîãóò èìåòü |
; ëþáûå èìåíà, íî îíè äîëæíû áûòü çàêëþ÷åíû â â ñêîáêè [] |
macro use_parse |
{ |
;input cx=size of ini file |
parse_start: |
;es:di as 2000:0000 new segment |
;установим указатель на загруженный блок |
;óñòàíîâèì óêàçàòåëü íà çàãðóæåííûé áëîê |
enter 256, 0 ;set 16 byte for current task in stack |
;we are is not use bp because bp is pointer on array 16 byte |
mov word [save_bp_from_timer], bp ;save point to own data array |
mov save_cx, cx ;it's placed size of ini file |
les di, dword [file_data] |
;обнулим все переменные выделенные из стека |
;îáíóëèì âñå ïåðåìåííûå âûäåëåííûå èç ñòåêà |
;init flag |
xor ax, ax |
mov status_flag, ax |
;set data size |
mov info_real_mode_size, ini_data_ +0x1000 ;изменим значение занятости памяти |
mov info_real_mode_size, ini_data_ +0x1000 ;èçìåíèì çíà÷åíèå çàíÿòîñòè ïàìÿòè |
;поиск начала блока. |
;ïîèñê íà÷àëà áëîêà. |
;///////////check [loader] |
cld |
63,7 → 63,7 |
.start: |
call get_firs_sym ;get first symbol on new line |
.first_ret: ;первый возврат |
.first_ret: ;ïåðâûé âîçâðàò |
; jcxz .end_file ;.end_loader ;found or not found parametrs in section exit in section |
test cx, cx |
jz error.not_loader |
70,7 → 70,7 |
cmp al, '[' |
jz .parse_loader |
jmp .start |
;////// проверка на наличее секции loader |
;////// ïðîâåðêà íà íàëè÷åå ñåêöèè loader |
use_parse_loader |
;pause |
if DEBUG |
77,9 → 77,9 |
xor ax, ax |
int 16h |
end if |
;////// вывод графического экрана, выбор, секции под дефолту |
;////// âûâîä ãðàôè÷åñêîãî ýêðàíà, âûáîð, ñåêöèè ïîä äåôîëòó |
use_any_sec |
;парсинг выбраной или дефолтной секции т.е. разбор параметров выполнение сценария |
;ïàðñèíã âûáðàíîé èëè äåôîëòíîé ñåêöèè ò.å. ðàçáîð ïàðàìåòðîâ âûïîëíåíèå ñöåíàðèÿ |
use_parse_def_sect |
;////////////////// |
/kernel/trunk/sec_loader/trunk/parse_any.inc |
---|
24,7 → 24,7 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
;тут распологается модуль с помощью которого будут парситься все остальные секции |
;òóò ðàñïîëîãàåòñÿ ìîäóëü ñ ïîìîùüþ êîòîðîãî áóäóò ïàðñèòüñÿ âñå îñòàëüíûå ñåêöèè |
color_sym_black equ 0 |
color_sym_blue equ 1 |
color_sym_green equ 2 |
40,12 → 40,12 |
macro use_any_sec |
{ |
;узнаем работу предыдущего шага т.е. чему = timeout, если он 0, то визуальная часть не будет отображена на дисплее с выбором загрузочных секций. |
;иначе мы ее должны отобразить и ждать заявленое время для выбора и конигурирования пукнктов секции от пользователя. |
;óçíàåì ðàáîòó ïðåäûäóùåãî øàãà ò.å. ÷åìó = timeout, åñëè îí 0, òî âèçóàëüíàÿ ÷àñòü íå áóäåò îòîáðàæåíà íà äèñïëåå ñ âûáîðîì çàãðóçî÷íûõ ñåêöèé. |
;èíà÷å ìû åå äîëæíû îòîáðàçèòü è æäàòü çàÿâëåíîå âðåìÿ äëÿ âûáîðà è êîíèãóðèðîâàíèÿ ïóêíêòîâ ñåêöèè îò ïîëüçîâàòåëÿ. |
if DEBUG |
pusha |
mov ax, word [value_timeout];идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти |
mov ax, word [value_timeout];èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè |
; mov ax,cx |
mov cx, 0x0a |
mov di, show_db1 |
62,7 → 62,7 |
test ax, ax |
jz .parse_run_only |
;отобразим полный список всех найденых секций. |
;îòîáðàçèì ïîëíûé ñïèñîê âñåõ íàéäåíûõ ñåêöèé. |
if DEBUG |
pusha |
mov si, show_all_sect |
70,7 → 70,7 |
popa |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование |
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå |
out 0x60, al |
xor cx, cx |
.wait_loop: ; variant 2 |
102,7 → 102,7 |
mov dword [start_timer], eax |
mov word [timer_], newtimer |
mov word [timer_+2], cs |
;установить свое прерывание на таймер т.е. код будет перрываться ~18 раз в сек и переходить на обработчик |
;óñòàíîâèòü ñâîå ïðåðûâàíèå íà òàéìåð ò.å. êîä áóäåò ïåððûâàòüñÿ ~18 ðàç â ñåê è ïåðåõîäèòü íà îáðàáîò÷èê |
cli |
push 0 |
pop es |
112,7 → 112,7 |
pop dword [es:8*4] |
sti |
;процедура формирования буфера для скролинга секций |
;ïðîöåäóðà ôîðìèðîâàíèÿ áóôåðà äëÿ ñêðîëèíãà ñåêöèé |
;if DEBUG |
; pusha |
; mov ax,point_default |
130,20 → 130,20 |
; int 0x16 |
; popa |
;end if |
;;;;;;;;;;;;;размер предыдущей сеции установим =0 |
;;;;;;;;;;;;;ðàçìåð ïðåäûäóùåé ñåöèè óñòàíîâèì =0 |
mov save_descript_size, 18 |
;отобразить black screen |
;îòîáðàçèòü black screen |
show_bl_sc ;es=0xb800 |
.show_all_scr: |
get_frame_buffer ;es=0x2000 |
;отображение секций |
;îòîáðàæåíèå ñåêöèé |
call show_bl_sc_sect ;es=0xb800 |
;отобразить активный курсор |
;îòîáðàçèòü àêòèâíûé êóðñîð |
.show_active_cursor: |
show_act_cursor |
show_descript ;макрос по отображению описания секции |
show_descript ;ìàêðîñ ïî îòîáðàæåíèþ îïèñàíèÿ ñåêöèè |
;отобразить Press any key .... |
;îòîáðàçèòü Press any key .... |
mov eax, dword [old_timer] |
cmp eax, dword [timer_] |
jz .interrupt_16 |
151,7 → 151,7 |
show_timer_message |
mov word [start_stack], sp |
.interrupt_16: |
xor ax, ax ;получим информацию о том что нажато |
xor ax, ax ;ïîëó÷èì èíôîðìàöèþ î òîì ÷òî íàæàòî |
int 0x16 |
;check on change |
mov ebx, dword [old_timer] |
161,7 → 161,7 |
cli |
push 0 |
pop es |
; mov eax,dword [old_timer] ; восстановим прежднее прерывание |
; mov eax,dword [old_timer] ; âîññòàíîâèì ïðåæäíåå ïðåðûâàíèå |
mov [es:8*4], ebx |
mov dword [timer_], ebx |
sti |
172,7 → 172,7 |
@@: |
call clean_active_cursor ;clean old cursor ;es=0xb800 |
cmp ah, 0x48 ;реакция системы на события |
cmp ah, 0x48 ;ðåàêöèÿ ñèñòåìû íà ñîáûòèÿ |
jz .up |
cmp ah, 0x50 |
jz .down |
188,9 → 188,9 |
cmp al, 0xD |
jnz .show_active_cursor |
jmp .end_show_all ;парсинг секции которая указана в point_default |
jmp .end_show_all ;ïàðñèíã ñåêöèè êîòîðàÿ óêàçàíà â point_default |
.up: |
mov si, point_to_point_def ;значение указателя |
mov si, point_to_point_def ;çíà÷åíèå óêàçàòåëÿ |
add si, 2 |
lea ax, point_to_hframe |
208,8 → 208,8 |
.down: |
mov si, point_to_point_def ;значение указателя |
mov ax, point_to_eframe ;указатель на последний элемент |
mov si, point_to_point_def ;çíà÷åíèå óêàçàòåëÿ |
mov ax, point_to_eframe ;óêàçàòåëü íà ïîñëåäíèé ýëåìåíò |
sub si, 2 |
cmp si, ax |
jb @f |
255,7 → 255,7 |
; тут мы будем парсить только дефолтную секцию и выполнять ее ничего не предлагая пользователю из диалогов. |
; òóò ìû áóäåì ïàðñèòü òîëüêî äåôîëòíóþ ñåêöèþ è âûïîëíÿòü åå íè÷åãî íå ïðåäëàãàÿ ïîëüçîâàòåëþ èç äèàëîãîâ. |
.parse_run_only: |
if DEBUG |
pusha |
286,7 → 286,7 |
macro show_bl_sc |
{ |
;;;;;;;;;;;;;;; |
;очистим экран и выведем меню |
;î÷èñòèì ýêðàí è âûâåäåì ìåíþ |
; draw frames |
xor ax, ax |
if DEBUG |
324,7 → 324,7 |
;;;;;;;;;;;;;;;;;;;;;;; show '__________________________' |
mov di, 480 |
mov ah, color_sym_yellow |
mov al, 'Д' |
mov al, 'Ä' |
mov cx, 61 |
rep stosw |
;;;;;;;;;;;;;;;;;;;;;;; show 'Select section' |
418,7 → 418,7 |
mov si, di ;point frame |
mov bx, cx |
mov dx, size_show_section |
; mov point_to_hframe,di ; внесем значение, так подстраховка не более |
; mov point_to_hframe,di ; âíåñåì çíà÷åíèå, òàê ïîäñòðàõîâêà íå áîëåå |
mov al, byte [es:di] |
push word .first_ret_bl_sc |
443,14 → 443,14 |
.start_bl: |
call get_firs_sym ;get first symbol on new line |
.first_ret_bl_sc: ;первый возврат |
.first_ret_bl_sc: ;ïåðâûé âîçâðàò |
test cx, cx |
jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before |
.analisist_al: |
cmp al, '[' |
jnz .start_bl |
;просматриваем ini файл с начала в поисках секции указаной как default |
;поиск фрейма в котором содержиться значение default |
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default |
;ïîèñê ôðåéìà â êîòîðîì ñîäåðæèòüñÿ çíà÷åíèå default |
.found_sect_bl: |
cmp di, point_loader |
jz .start_bl |
464,12 → 464,12 |
.save_point_def: |
;итак далее мы должны заполнить frame буфер адресов секций, что бы потом по нему быстро перемещаться не вычисляя снова адреса |
mov di, si ;указатель на начало |
;èòàê äàëåå ìû äîëæíû çàïîëíèòü frame áóôåð àäðåñîâ ñåêöèé, ÷òî áû ïîòîì ïî íåìó áûñòðî ïåðåìåùàòüñÿ íå âû÷èñëÿÿ ñíîâà àäðåñà |
mov di, si ;óêàçàòåëü íà íà÷àëî |
mov cx, bx |
lea si, point_to_hframe |
mov dx, size_show_section+1 ;т.к. у нас структура содержит размер между первым и вторым указателем, то нам нужно на 1 адрес больше обсчитать секций. |
;переходим на обработку значения указателя |
mov dx, size_show_section+1 ;ò.ê. ó íàñ ñòðóêòóðà ñîäåðæèò ðàçìåð ìåæäó ïåðâûì è âòîðûì óêàçàòåëåì, òî íàì íóæíî íà 1 àäðåñ áîëüøå îáñ÷èòàòü ñåêöèé. |
;ïåðåõîäèì íà îáðàáîòêó çíà÷åíèÿ óêàçàòåëÿ |
mov al, byte [es:di] |
push word .first_ret_mfb |
cmp al, ' ' |
480,7 → 480,7 |
.start_mfb: |
call get_firs_sym ;get first symbol on new line |
.first_ret_mfb: ;первый возврат |
.first_ret_mfb: ;ïåðâûé âîçâðàò |
jcxz .val_buff_comp ;.end_loader ;found or not found parametrs in section exit in section |
cmp al, '[' |
jnz .start_mfb |
509,7 → 509,7 |
macro show_act_cursor |
{ |
;отображение курсора по умолчанию |
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ |
lea si, point_to_hframe |
mov di, 962-160 |
mov ax, point_default |
554,7 → 554,7 |
} |
macro show_descript |
;Этот макрос показывает краткое описание, если оно есть у секции в пункте |
;Ýòîò ìàêðîñ ïîêàçûâàåò êðàòêîå îïèñàíèå, åñëè îíî åñòü ó ñåêöèè â ïóíêòå |
;Section description |
{ |
local .start_p_sh_d |
568,14 → 568,14 |
mov si, point_to_point_def |
pop es |
sub si, 2 |
mov cx, [si] ;загрузим указатель наследующию секцию |
sub cx, di ;вот теперь имеем истиный размер |
;di - указатель на дефолтную секцию т.е. выбранную cx - размер области. для просмотра |
mov cx, [si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ |
sub cx, di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð |
;di - óêàçàòåëü íà äåôîëòíóþ ñåêöèþ ò.å. âûáðàííóþ cx - ðàçìåð îáëàñòè. äëÿ ïðîñìîòðà |
.start_p_sh_d: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz .exit ;нету? ну ладно - следующее значение тогда ) |
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'd' |
jnz .start_p_sh_d |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
591,7 → 591,7 |
sub bx, parse_descript_e - parse_descript;correct cx |
add bx, cx |
mov cx, bx |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; разбор аля ' = ' |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ðàçáîð àëÿ ' = ' |
mov ax, 0x3d20 ;cut al=' ' ah='=' |
repe scasb |
jcxz .rest_value_loop_sh_d ;not found param timeout |
602,10 → 602,10 |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;di указывает на строчку, которую нам нужно выводить. |
;строчка будет выводиться блоками по 37 символов. |
;настроим куда будем выводить т.е. начало |
;es:di - указывают на строчку из которой мы берем символ, ds:si куда будем выводить |
;;;;;;;;;;;;;;;;;;;;di óêàçûâàåò íà ñòðî÷êó, êîòîðóþ íàì íóæíî âûâîäèòü. |
;ñòðî÷êà áóäåò âûâîäèòüñÿ áëîêàìè ïî 37 ñèìâîëîâ. |
;íàñòðîèì êóäà áóäåì âûâîäèòü ò.å. íà÷àëî |
;es:di - óêàçûâàþò íà ñòðî÷êó èç êîòîðîé ìû áåðåì ñèìâîë, ds:si êóäà áóäåì âûâîäèòü |
push di |
pop si |
/kernel/trunk/sec_loader/trunk/parse_dat.inc |
---|
24,7 → 24,7 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
;Тут представленны теги, для сравнения |
;Òóò ïðåäñòàâëåííû òåãè, äëÿ ñðàâíåíèÿ |
parse_loader db '[loader]' |
parse_loader_e: |
parse_l_timeout db 'timeout' |
/kernel/trunk/sec_loader/trunk/parse_def_sect.inc |
---|
24,10 → 24,10 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
; в этой секции идет разбор параметров указатель на секцию храниться в point_default |
;типы ошибок при обработке макроса |
;Макрос RamdiskFS |
;/определение флагов в записи корневой директории |
; â ýòîé ñåêöèè èäåò ðàçáîð ïàðàìåòðîâ óêàçàòåëü íà ñåêöèþ õðàíèòüñÿ â point_default |
;òèïû îøèáîê ïðè îáðàáîòêå ìàêðîñà |
;Ìàêðîñ RamdiskFS |
;/îïðåäåëåíèå ôëàãîâ â çàïèñè êîðíåâîé äèðåêòîðèè |
ATTR_READ_ONLY equ 0x01 |
ATTR_HIDDEN equ 0x02 |
ATTR_SYSTEM equ 0x04 |
37,9 → 37,9 |
show_error_1 equ 0x1 ;кончились данные - не запланированный конец секции |
show_error_2 equ 0x2 ;нет завершающего символа в размере рам диска. |
show_error_3 equ 0x4 ; рам диск будет иметь размер =64 кб. |
show_error_1 equ 0x1 ;êîí÷èëèñü äàííûå - íå çàïëàíèðîâàííûé êîíåö ñåêöèè |
show_error_2 equ 0x2 ;íåò çàâåðøàþùåãî ñèìâîëà â ðàçìåðå ðàì äèñêà. |
show_error_3 equ 0x4 ; ðàì äèñê áóäåò èìåòü ðàçìåð =64 êá. |
show_error_4 equ 0x8 ; |
macro use_parse_def_sect |
49,41 → 49,41 |
pop es |
mov si, point_to_point_def |
sub si, 2 |
mov cx, [si] ;загрузим указатель наследующию секцию |
mov cx, [si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ |
xor ax, ax ;обнулим аx для очистки флагов |
xor ax, ax ;îáíóëèì àx äëÿ î÷èñòêè ôëàãîâ |
sub cx, di ;вот теперь имеем истиный размер |
mov save_cx_d, cx ;сохраним значение cx своей переменной |
;обнулим переменную флагов, это необходимо, для того, что бы избежать обработку повторяющихся значений |
sub cx, di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð |
mov save_cx_d, cx ;ñîõðàíèì çíà÷åíèå cx ñâîåé ïåðåìåííîé |
;îáíóëèì ïåðåìåííóþ ôëàãîâ, ýòî íåîáõîäèìî, äëÿ òîãî, ÷òî áû èçáåæàòü îáðàáîòêó ïîâòîðÿþùèõñÿ çíà÷åíèé |
mov status_flag, ax |
;;;; |
;ВХод в обработку парсинга значений секций. es:di - указатель на начало секции cx размер секции доступной для парсинга |
;ÂÕîä â îáðàáîòêó ïàðñèíãà çíà÷åíèé ñåêöèé. es:di - óêàçàòåëü íà íà÷àëî ñåêöèè cx ðàçìåð ñåêöèè äîñòóïíîé äëÿ ïàðñèíãà |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;соглашение не разрушаем bp, es, cs, sp |
;use_Loader_Image ;загрузить образ выше 1 мб |
;ñîãëàøåíèå íå ðàçðóøàåì bp, es, cs, sp |
;use_Loader_Image ;çàãðóçèòü îáðàç âûøå 1 ìá |
use_RamdiskFS |
;проверяется самый последний. |
use_LoaderModule ;особенность - передает управление на загруженный модуль. |
;ïðîâåðÿåòñÿ ñàìûé ïîñëåäíèé. |
use_LoaderModule ;îñîáåííîñòü - ïåðåäàåò óïðàâëåíèå íà çàãðóæåííûé ìîäóëü. |
} |
macro use_LoaderModule |
;как вариант сейчас используется модель, при загрузке модуля на него передается управление, решение временое |
;управление будет передаваться только после обработки всей секции |
;êàê âàðèàíò ñåé÷àñ èñïîëüçóåòñÿ ìîäåëü, ïðè çàãðóçêå ìîäóëÿ íà íåãî ïåðåäàåòñÿ óïðàâëåíèå, ðåøåíèå âðåìåíîå |
;óïðàâëåíèå áóäåò ïåðåäàâàòüñÿ òîëüêî ïîñëå îáðàáîòêè âñåé ñåêöèè |
{ |
local .found_end_str |
mov di, point_default ;restore value |
mov cx, save_cx_d |
;обработка конструкции типа LoaderModule=kord/kolibri.ldm |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_p_LM: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz ._afterLoaderModule ;нету? ну ладно - следующее значение тогда ) |
jz ._afterLoaderModule ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'L' |
jnz .start_p_LM |
;проверка на значение LoaderModule |
;ïðîâåðêà íà çíà÷åíèå LoaderModule |
; parse_LoaderModule |
mov bx, cx |
mov ax, di |
97,10 → 97,10 |
add bx, cx |
mov cx, bx |
test status_flag, flag_found_LM ;оценка флагов |
test status_flag, flag_found_LM ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_LM |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
115,26 → 115,26 |
repe scasb ;cut ' ' |
inc cx |
dec di |
;di указывает на начало блока информации, в cx длинна до конца секции. |
;после загрузки заноситься значение занятой памяти. |
;для того что бы загрузить модуль, воспользуемся callback сервисом |
;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 |
;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader |
;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем |
;сохранили певые 2 word |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
push dword [es:di-6] |
lea si, [di-6] |
push word [es:di-2] |
xor ax, ax |
mov word [es:di-6], ax ;вносим нужные значения |
;info_real_mode_size размер и указатель на область в которую можно загрузиться |
mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными |
mov word [es:di-6], ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax, info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4], ax |
mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем |
;;;;;; поиск конца строчки |
mov word [es:di-2], 16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì |
;;;;;; ïîèñê êîíöà ñòðî÷êè |
@@: |
mov al, byte [es:di] |
cmp al, ' ' |
146,7 → 146,7 |
inc di |
dec cx |
jnz @b |
;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè |
.found_end_str: |
push word [es:di] |
189,7 → 189,7 |
} |
macro use_RamdiskFS |
; формирование рам диска, + обработка всего связанного. |
; ôîðìèðîâàíèå ðàì äèñêà, + îáðàáîòêà âñåãî ñâÿçàííîãî. |
{ |
if DEBUG |
local ._not_memory_in_sys |
200,19 → 200,19 |
mov si, ramdiskFS_st |
call printplain |
end if |
; обнулим регистр состояния ошибок |
; îáíóëèì ðåãèñòð ñîñòîÿíèÿ îøèáîê |
xor ax, ax |
mov show_errors_sect, ax |
use_free_memory ; узнаем какого объема у нас доступна память. значение возаращается в ax |
;узнаем сколько у нас есть памяти и сможем ли мы сформировать нужного размера рам диск. |
use_RamdiskSize ;значение возвращается в bx |
cmp free_ad_memory, bx ; размерность в кб. |
use_free_memory ; óçíàåì êàêîãî îáúåìà ó íàñ äîñòóïíà ïàìÿòü. çíà÷åíèå âîçàðàùàåòñÿ â ax |
;óçíàåì ñêîëüêî ó íàñ åñòü ïàìÿòè è ñìîæåì ëè ìû ñôîðìèðîâàòü íóæíîãî ðàçìåðà ðàì äèñê. |
use_RamdiskSize ;çíà÷åíèå âîçâðàùàåòñÿ â bx |
cmp free_ad_memory, bx ; ðàçìåðíîñòü â êá. |
jbe ._not_memory_in_sys |
movzx eax, bx |
shl eax, 10 ;*1024 = get size in byte |
mov save_ramdisksize, eax ; сорханим размер в byte |
mov save_ramdisksize, eax ; ñîðõàíèì ðàçìåð â byte |
get_type_FS ;получим тип файловой системы + создадим ее |
get_type_FS ;ïîëó÷èì òèï ôàéëîâîé ñèñòåìû + ñîçäàäèì åå |
._not_memory_in_sys: |
234,17 → 234,17 |
local .end_get_RS_ERROR_1 |
local .end_get_RS_ERROR_2 |
local ._end_parse_RS |
;обрабатывается размер формируемого рам диска |
;загрузим начало секции, т.к. будем просматривать с начала и всю секцию |
;îáðàáàòûâàåòñÿ ðàçìåð ôîðìèðóåìîãî ðàì äèñêà |
;çàãðóçèì íà÷àëî ñåêöèè, ò.ê. áóäåì ïðîñìàòðèâàòü ñ íà÷àëà è âñþ ñåêöèþ |
mov di, point_default ;restore value |
mov cx, save_cx_d |
.start_p_RS: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz ._end_parse_RS ;нету? ну ладно - следующее значение тогда ) |
jz ._end_parse_RS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'R' |
jnz .start_p_RS |
;проверка на значения RamdiskSize |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx, cx |
mov ax, di |
258,10 → 258,10 |
add bx, cx |
mov cx, bx |
test status_flag, flag_found_RS ;оценка флагов |
test status_flag, flag_found_RS ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RS |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
271,13 → 271,13 |
jcxz .end_get_RS_ERROR_1 ;not found param |
cmp ah, byte [es:di-1] ;find '=' |
jnz .start_p_RS ; перейдем на начало и попробуем найти еще секцию |
jnz .start_p_RS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;Тут нужно преобразовывать строчку в цифровое значение. |
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå. |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
xor bx, bx |
mov cx, 5 |
299,12 → 299,12 |
loop @b |
.correct_size_RS: |
;возможен 1 вариант, когда размер задан в K киллобайтах |
;внутренный формат данных это кол-во запрощеной памяти в кб. |
;âîçìîæåí 1 âàðèàíò, êîãäà ðàçìåð çàäàí â K êèëëîáàéòàõ |
;âíóòðåííûé ôîðìàò äàííûõ ýòî êîë-âî çàïðîùåíîé ïàìÿòè â êá. |
test bx, bx |
jnz @f ;если значение отлично от 0 |
;;;;;сообщение об ошибке, размер "найденого" блока =0 минимально мы должны |
;установить 64 кб размер рам диска. |
jnz @f ;åñëè çíà÷åíèå îòëè÷íî îò 0 |
;;;;;ñîîáùåíèå îá îøèáêå, ðàçìåð "íàéäåíîãî" áëîêà =0 ìèíèìàëüíî ìû äîëæíû |
;óñòàíîâèòü 64 êá ðàçìåð ðàì äèñêà. |
or show_errors_sect, show_error_3 |
mov bx, 64 |
@@: |
319,7 → 319,7 |
.end_get_RS_ERROR_1: |
;сообщение об ошибке - данный участок кода не был корректно обработан :( |
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :( |
or show_errors_sect, show_error_1 |
jmp ._end_parse_RS |
.end_get_RS_ERROR_2: |
346,16 → 346,16 |
macro use_free_memory |
{ |
local _support_function_use_free_memory |
;макрос для получения общего числа доступной памяти в кб, для формирования рам диска за пределами 1 мб. |
;используется 0х88 функция 0х15 прерывания |
; если поддерживается функция, то в ax значение в кб, если нет, то в ax=0 |
;ìàêðîñ äëÿ ïîëó÷åíèÿ îáùåãî ÷èñëà äîñòóïíîé ïàìÿòè â êá, äëÿ ôîðìèðîâàíèÿ ðàì äèñêà çà ïðåäåëàìè 1 ìá. |
;èñïîëüçóåòñÿ 0õ88 ôóíêöèÿ 0õ15 ïðåðûâàíèÿ |
; åñëè ïîääåðæèâàåòñÿ ôóíêöèÿ, òî â ax çíà÷åíèå â êá, åñëè íåò, òî â ax=0 |
mov ah, 0x88 ;ah,0x88 |
int 0x15 |
jnc ._support_function_use_free_memory |
xor ax, ax |
;возвращает в ax число в кб |
;âîçâðàùàåò â ax ÷èñëî â êá |
._support_function_use_free_memory: |
mov free_ad_memory, ax ; если не поддерживается биосом, то в ax=0 |
mov free_ad_memory, ax ; åñëè íå ïîääåðæèâàåòñÿ áèîñîì, òî â ax=0 |
if DEBUG |
pushad |
movzx eax, ax |
380,7 → 380,7 |
} |
macro get_type_FS ;получить и создать образ для заданной RFS. |
macro get_type_FS ;ïîëó÷èòü è ñîçäàòü îáðàç äëÿ çàäàííîé RFS. |
{ |
mov di, point_default ;restore value |
mov cx, save_cx_d |
387,10 → 387,10 |
.start_g_tpe_RFS: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz ._end_parse_FRS ;._end_get_type_RFS ;нету? ну ладно - следующее значение тогда ) |
jz ._end_parse_FRS ;._end_get_type_RFS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'R' |
jnz .start_g_tpe_RFS |
;проверка на значения RamdiskSize |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx, cx |
mov ax, di |
404,10 → 404,10 |
add bx, cx |
mov cx, bx |
test status_flag, flag_found_GTRFMS ;оценка флагов |
test status_flag, flag_found_GTRFMS ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_FRS |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
418,13 → 418,13 |
jz .end_get_FRS_ERROR_1 ;not found param |
cmp ah, byte [es:di-1] ;find '=' |
jnz .start_g_tpe_RFS ; перейдем на начало и попробуем найти еще секцию |
jnz .start_g_tpe_RFS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
dec di |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;Тут нужно преобразовывать строчку в цифровое значение. |
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå. |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov bx, cx |
mov ax, di |
434,7 → 434,7 |
repe cmpsb |
jnz .krfs_cmp ;is not compare |
make_FAT_RamFS ;сделать |
make_FAT_RamFS ;ñäåëàòü |
if DEBUG |
pusha |
464,7 → 464,7 |
.end_get_FRS_ERROR_1: |
;сообщение об ошибке - данный участок кода не был корректно обработан :( |
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :( |
or show_errors_sect, show_error_1 |
jmp ._end_parse_FRS |
.end_get_FRS_ERROR_2: |
486,27 → 486,27 |
local .RS1 |
local .fat12 |
local .fat16 |
; мы должны сформировать в начальный образ Ram FS, а потом записать его за область выше 1 мб.. |
;для случая с FAT12 |
; mov di,fat12_buffer ;ds должен быть = cs |
;es:di - указывают на начало блока для формирования рам фс. |
use_RamdiskSector ;возращаемое значение в ax размер сектора в байтах |
cmp ax, 4096;по спецификации значение должно быть в пределах от 1 до 4096 |
; ìû äîëæíû ñôîðìèðîâàòü â íà÷àëüíûé îáðàç Ram FS, à ïîòîì çàïèñàòü åãî çà îáëàñòü âûøå 1 ìá.. |
;äëÿ ñëó÷àÿ ñ FAT12 |
; mov di,fat12_buffer ;ds äîëæåí áûòü = cs |
;es:di - óêàçûâàþò íà íà÷àëî áëîêà äëÿ ôîðìèðîâàíèÿ ðàì ôñ. |
use_RamdiskSector ;âîçðàùàåìîå çíà÷åíèå â ax ðàçìåð ñåêòîðà â áàéòàõ |
cmp ax, 4096;ïî ñïåöèôèêàöèè çíà÷åíèå äîëæíî áûòü â ïðåäåëàõ îò 1 äî 4096 |
ja .RS1 |
test ax, ax |
jnz @f ;ошибка если сюда прыгнули все таки ... |
jnz @f ;îøèáêà åñëè ñþäà ïðûãíóëè âñå òàêè ... |
.RS1: |
mov word [fat12_buffer.BPB_BytsPerSec], 512 |
;;;;;;;;;;скажем что по дефолту будем юзать значение... |
;;;;;;;;;;ñêàæåì ÷òî ïî äåôîëòó áóäåì þçàòü çíà÷åíèå... |
@@: |
mov word [fat12_buffer.BPB_BytsPerSec], ax;тут все ок |
mov word [fat12_buffer.BPB_BytsPerSec], ax;òóò âñå îê |
;BPB_SecPerClus кол-во секторов в кластере |
use_RamdiskCluster ;возращаемое значение в al |
;BPB_SecPerClus êîë-âî ñåêòîðîâ â êëàñòåðå |
use_RamdiskCluster ;âîçðàùàåìîå çíà÷åíèå â al |
cmp al, 128 |
ja @f |
; test al,0x1 ;проверка на кратность ) |
; test al,0x1 ;ïðîâåðêà íà êðàòíîñòü ) |
; jnz @f |
mov byte [fat12_buffer.BPB_SecPerClus], al |
513,28 → 513,28 |
;incorrect value will be set dafault |
;ниже некорректное значение в т.к. размер кратен 2 и в диапазоне от 1 до 128 включительно |
; мы должны ругнуться на это |
;íèæå íåêîððåêòíîå çíà÷åíèå â ò.ê. ðàçìåð êðàòåí 2 è â äèàïàçîíå îò 1 äî 128 âêëþ÷èòåëüíî |
; ìû äîëæíû ðóãíóòüñÿ íà ýòî |
;@@: ;mov byte [fat12_buffer.BPB_SecPerClus],1 |
;;;;; определеим какая у нас будет использоваться FAT |
;по условию, fat12<4085<=fat16<65525<=fat32 |
; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = кол-во секторов |
;;;;; îïðåäåëåèì êàêàÿ ó íàñ áóäåò èñïîëüçîâàòüñÿ FAT |
;ïî óñëîâèþ, fat12<4085<=fat16<65525<=fat32 |
; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = êîë-âî ñåêòîðîâ |
movzx eax, word [fat12_buffer.BPB_BytsPerSec] |
movzx ebx, byte [fat12_buffer.BPB_SecPerClus] |
imul ebx, eax;тут размерность сектора |
mov eax, save_ramdisksize ;размер запрошенного рам диска в байтах |
imul ebx, eax;òóò ðàçìåðíîñòü ñåêòîðà |
mov eax, save_ramdisksize ;ðàçìåð çàïðîøåííîãî ðàì äèñêà â áàéòàõ |
cdq |
idiv ebx |
;;;;;;;; сейчас частное в eax, а остаток в edx |
;получим кол-во секторов, и можем уже определить тип FAT которую нужно делать. |
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx |
;ïîëó÷èì êîë-âî ñåêòîðîâ, è ìîæåì óæå îïðåäåëèòü òèï FAT êîòîðóþ íóæíî äåëàòü. |
cmp eax, 4085 |
jb .fat12 |
cmp eax, 65525 |
jb .fat16 |
;;;;;;;;;;;;;;;;;;;;;;;; тут fat32 |
mov set_ramfs, 32 ;установим тип файловой системы |
;;;;;;;;;;;;;;;;;;;;;;;; òóò fat32 |
mov set_ramfs, 32 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
mov word [fat12_buffer.BPB_RsvdSecCnt], 32 |
xor eax, eax |
mov word [fat12_buffer.BPB_RootEntCnt], ax |
543,9 → 543,9 |
.fat16: ;fat16 |
;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). |
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000). |
jmp $ |
mov set_ramfs, 16 ;установим тип файловой системы |
mov set_ramfs, 16 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
movzx ebx, byte [fat12_buffer.BPB_SecPerClus] |
imul eax, ebx |
554,17 → 554,17 |
mov word [fat12_buffer.BPB_TotSec16], ax |
mov dword [fat12_buffer.BPB_TotSec32], 0 |
@@: |
;количество секторов занимаемое одной копией фат |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? |
;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число |
;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно |
;быть 0. Пока константа, нужно будет позже доделать. |
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ?? |
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî |
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî |
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü. |
mov eax, root_dir_entry_count |
mov word [fat12_buffer.BPB_RootEntCnt], ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) |
;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб |
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá |
;;;;;;; |
;Для FAT16 это количество секторов одной FAT. Для FAT32 это значение |
;равно 0, а количество секторов одной FAT содержится в BPB_FATSz32. |
;Äëÿ FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. Äëÿ FAT32 ýòî çíà÷åíèå |
;ðàâíî 0, à êîëè÷åñòâî ñåêòîðîâ îäíîé FAT ñîäåðæèòñÿ â BPB_FATSz32. |
;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec; |
;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); |
588,13 → 588,13 |
cdq |
idiv ebx |
;;;;;;;; сейчас частное в eax, а остаток в edx для дискеты 1.44 у нас должно быть значение =14 |
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx äëÿ äèñêåòû 1.44 ó íàñ äîëæíî áûòü çíà÷åíèå =14 |
;BPB_ResvdSecCnt + RootDirSectors |
movzx ebx, word [fat12_buffer.BPB_RsvdSecCnt] |
add ebx, eax |
;DskSize у нас это значение уже получено и доступно |
movzx eax, word [fat12_buffer.BPB_TotSec16] ;должен быть в секторах |
;DskSize ó íàñ ýòî çíà÷åíèå óæå ïîëó÷åíî è äîñòóïíî |
movzx eax, word [fat12_buffer.BPB_TotSec16] ;äîëæåí áûòü â ñåêòîðàõ |
sub eax, ebx |
607,7 → 607,7 |
dec eax |
cdq |
idiv edi |
;FATSz = сейчас частное в eax, а остаток в edx |
;FATSz = ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx |
mov word [fat12_buffer.BPB_FATSz16], ax |
619,7 → 619,7 |
.fat12: ;fat12 |
if DEBUG |
; выведем в отладке, что собираемся делать образ диска c FS=fat12 |
; âûâåäåì â îòëàäêå, ÷òî ñîáèðàåìñÿ äåëàòü îáðàç äèñêà c FS=fat12 |
pushad |
mov si, start_making_FAT12_msg |
call printplain |
628,8 → 628,8 |
;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000). |
mov set_ramfs, 12 ;установим тип файловой системы |
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000). |
mov set_ramfs, 12 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû |
movzx ebx, byte [fat12_buffer.BPB_SecPerClus] |
imul eax, ebx |
638,54 → 638,54 |
mov word [fat12_buffer.BPB_TotSec16], ax |
mov dword [fat12_buffer.BPB_TotSec32], 0 |
@@: |
;количество секторов занимаемое одной копией фат |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Для FAT12/FAT16 это количество секторов одной FAT. ?? |
;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число |
;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно |
;быть 0. Пока константа, нужно будет позже доделать. |
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò |
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ?? |
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî |
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî |
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü. |
mov eax, root_dir_entry_count |
mov word [fat12_buffer.BPB_RootEntCnt], ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb) |
;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб |
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá |
;;;;;;; |
;DskSize(в секторах)*12 (размерность файловой системы, т.е предположим сколько битов потребуется для адресации этого объема) /8 (что получить размер в байтах) |
;полученное число округляем в большую сторону кратное сектору т.е. 512 байт Такой подход не универсален, но пока пойдет |
;вообще у мелкософт это все считается ручками, но мы будем юзать только под коос рам диск с фат12 |
;DskSize(â ñåêòîðàõ)*12 (ðàçìåðíîñòü ôàéëîâîé ñèñòåìû, ò.å ïðåäïîëîæèì ñêîëüêî áèòîâ ïîòðåáóåòñÿ äëÿ àäðåñàöèè ýòîãî îáúåìà) /8 (÷òî ïîëó÷èòü ðàçìåð â áàéòàõ) |
;ïîëó÷åííîå ÷èñëî îêðóãëÿåì â áîëüøóþ ñòîðîíó êðàòíîå ñåêòîðó ò.å. 512 áàéò Òàêîé ïîäõîä íå óíèâåðñàëåí, íî ïîêà ïîéäåò |
;âîîáùå ó ìåëêîñîôò ýòî âñå ñ÷èòàåòñÿ ðó÷êàìè, íî ìû áóäåì þçàòü òîëüêî ïîä êîîñ ðàì äèñê ñ ôàò12 |
movzx eax, word [fat12_buffer.BPB_TotSec16] |
imul eax, 12 |
shr eax, 3 ;делим на 8 но т.е. нам нужно делить еще и на 512 или более в зависимости от размеров кластера |
movzx ebx, word [fat12_buffer.BPB_BytsPerSec] ;размер сектора |
shr eax, 3 ;äåëèì íà 8 íî ò.å. íàì íóæíî äåëèòü åùå è íà 512 èëè áîëåå â çàâèñèìîñòè îò ðàçìåðîâ êëàñòåðà |
movzx ebx, word [fat12_buffer.BPB_BytsPerSec] ;ðàçìåð ñåêòîðà |
cdq |
idiv ebx ;разделим на размер кластера |
;сейчас у нас в eax значение его нужно округлить в большую сторону кратному 512 байтам |
;применим следующее очистим and и добавим 512 байт. таким образом выравним на 512 байт |
;но т.к. все равно делить нижний код нам не нужен |
idiv ebx ;ðàçäåëèì íà ðàçìåð êëàñòåðà |
;ñåé÷àñ ó íàñ â eax çíà÷åíèå åãî íóæíî îêðóãëèòü â áîëüøóþ ñòîðîíó êðàòíîìó 512 áàéòàì |
;ïðèìåíèì ñëåäóþùåå î÷èñòèì and è äîáàâèì 512 áàéò. òàêèì îáðàçîì âûðàâíèì íà 512 áàéò |
;íî ò.ê. âñå ðàâíî äåëèòü íèæíèé êîä íàì íå íóæåí |
; and eax,0xfff200 |
; add eax,0x200 ;добавим 512 байт для 1.44 дискеты идеально подходит )) |
; add eax,0x200 ;äîáàâèì 512 áàéò äëÿ 1.44 äèñêåòû èäåàëüíî ïîäõîäèò )) |
inc ax |
;по идее должно на каждую фат таблицу |
;резервироваться 9 секторов т.е. получается 2*9=18+1 =19 секторов т.е. рут дир находиться на с 20 сетора т.е. с адреса 0х2600 |
;сейчас нужно вычислить сколько будет секторов занимать фат ) нужно разделить на 512 |
;FATSz = сейчас частное в eax |
;ïî èäåå äîëæíî íà êàæäóþ ôàò òàáëèöó |
;ðåçåðâèðîâàòüñÿ 9 ñåêòîðîâ ò.å. ïîëó÷àåòñÿ 2*9=18+1 =19 ñåêòîðîâ ò.å. ðóò äèð íàõîäèòüñÿ íà ñ 20 ñåòîðà ò.å. ñ àäðåñà 0õ2600 |
;ñåé÷àñ íóæíî âû÷èñëèòü ñêîëüêî áóäåò ñåêòîðîâ çàíèìàòü ôàò ) íóæíî ðàçäåëèòü íà 512 |
;FATSz = ñåé÷àñ ÷àñòíîå â eax |
mov word [fat12_buffer.BPB_FATSz16], ax |
;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
get_firstDataSector ;получить смещение до данных |
;создадим певую запись в фат по определенному адресу. |
get_firstDataSector ;ïîëó÷èòü ñìåùåíèå äî äàííûõ |
;ñîçäàäèì ïåâóþ çàïèñü â ôàò ïî îïðåäåëåííîìó àäðåñó. |
first_create_fat_table |
;закиним BPB файловой системы за 1 мб. |
;çàêèíèì BPB ôàéëîâîé ñèñòåìû çà 1 ìá. |
use_BPB_RAM |
; |
;копирование файла. |
;êîïèðîâàíèå ôàéëà. |
use_RamdiskFile |
;;;; вычисляем указатель на корневую дир FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); |
;;;; âû÷èñëÿåì óêàçàòåëü íà êîðíåâóþ äèð FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16); |
; movzx ebx, [fat12_buffer.BPB_NumFATs] |
; movzx eax,ax |
; imul eax,ebx |
;eax=(BPB_NumFATs * BPB_FATSz16) |
; inc eax |
; BPB_ResvdSecCnt значение только 1 для fat12/16 |
;в eax указатель на root dir. для дискеты fat12 должно получиться при кол-во копий fat 1 = 1+ (1*1) =2 или 3 |
; BPB_ResvdSecCnt çíà÷åíèå òîëüêî 1 äëÿ fat12/16 |
;â eax óêàçàòåëü íà root dir. äëÿ äèñêåòû fat12 äîëæíî ïîëó÷èòüñÿ ïðè êîë-âî êîïèé fat 1 = 1+ (1*1) =2 èëè 3 |
if DEBUG |
pusha |
715,7 → 715,7 |
macro use_RamdiskSector |
{ |
;для некоторых FS будет игнорироваться |
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ |
mov di, point_default ;restore value |
mov cx, save_cx_d |
722,11 → 722,11 |
.start_RamdiskSector: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz .end_RamdiskSector ;нету? ну ладно - следующее значение тогда ) |
jz .end_RamdiskSector ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'R' |
jnz .start_RamdiskSector |
;проверка на значения RamdiskSize |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx, cx |
741,10 → 741,10 |
add bx, cx |
mov cx, bx |
test status_flag, flag_found_RamdiskSector ;оценка флагов |
test status_flag, flag_found_RamdiskSector ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RamdiskSector |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
754,7 → 754,7 |
jcxz .end_get_RamS_ERROR_1 ;not found param |
cmp ah, byte [es:di-1] ;find '=' |
jnz .start_RamdiskSector ; перейдем на начало и попробуем найти еще секцию |
jnz .start_RamdiskSector ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
810,7 → 810,7 |
macro use_RamdiskCluster |
{ |
;для некоторых FS будет игнорироваться |
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ |
; push es |
; push di |
mov di, point_default ;restore value |
820,10 → 820,10 |
.start_RamdiskCluster: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz .end_RamdiskCluster ;нету? ну ладно - следующее значение тогда ) |
jz .end_RamdiskCluster ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'R' |
jnz .start_RamdiskCluster |
;проверка на значения RamdiskSize |
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize |
; parse_RamdiskSize |
mov bx, cx |
838,10 → 838,10 |
add bx, cx |
mov cx, bx |
test status_flag, flag_found_RamdiskCluster ;оценка флагов |
test status_flag, flag_found_RamdiskCluster ;îöåíêà ôëàãîâ |
jz .correct_is_not_set_RamdiskCluster |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
851,7 → 851,7 |
jcxz .end_get_RamSC_ERROR_1 ;not found param |
cmp ah, byte [es:di-1] ;find '=' |
jnz .start_RamdiskCluster ; перейдем на начало и попробуем найти еще секцию |
jnz .start_RamdiskCluster ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ |
repe scasb ;cut ' ' |
inc cx |
892,8 → 892,8 |
} |
macro use_Loader_Image |
;предназначен для загрузки образов выше 1 Мб. |
;первоначальная версия загружает образ дискеты 1.44 мб |
;ïðåäíàçíà÷åí äëÿ çàãðóçêè îáðàçîâ âûøå 1 Ìá. |
;ïåðâîíà÷àëüíàÿ âåðñèÿ çàãðóæàåò îáðàç äèñêåòû 1.44 ìá |
{ |
local .start_p_LI |
local .exit |
902,14 → 902,14 |
local .found_end_str |
mov di, point_default ;restore value |
mov cx, save_cx_d |
;обработка конструкции типа LoaderModule=kord/kolibri.ldm |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_p_LI: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz .exit ;нету? ну ладно - следующее значение тогда ) |
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'L' |
jnz .start_p_LI |
;проверка на значение LoaderModule |
;ïðîâåðêà íà çíà÷åíèå LoaderModule |
; parse_LoaderModule |
mov bx, cx |
mov ax, di |
923,10 → 923,10 |
add bx, cx |
mov cx, bx |
; test status_flag,flag_found_LM ;оценка флагов |
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ |
; jz .correct_is_not_set_LI |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
941,26 → 941,26 |
repe scasb ;cut ' ' |
inc cx |
dec di |
;di указывает на начало блока информации, в cx длинна до конца секции. |
;после загрузки заноситься значение занятой памяти. |
;для того что бы загрузить модуль, воспользуемся callback сервисом |
;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 |
;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader |
;мы ее модифицируем до такого состояния dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем |
;сохранили певые 2 word |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
push dword [es:di-6] |
lea si, [di-6] |
push word [es:di-2] |
xor ax, ax |
mov word [es:di-6], ax ;вносим нужные значения |
;info_real_mode_size размер и указатель на область в которую можно загрузиться |
mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными |
mov word [es:di-6], ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax, info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4], ax |
mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем |
;;;;;; поиск конца строчки |
mov word [es:di-2], 16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì |
;;;;;; ïîèñê êîíöà ñòðî÷êè |
@@: |
mov al, byte [es:di] |
cmp al, ' ' |
972,9 → 972,9 |
inc di |
dec cx |
jnz @b |
;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè |
.found_end_str: |
; чтение блока по 64 кб в сегмент и забрасывание его выше 1 мб. |
; ÷òåíèå áëîêà ïî 64 êá â ñåãìåíò è çàáðàñûâàíèå åãî âûøå 1 ìá. |
push word [es:di] |
xor ax, ax |
mov word [es:di], ax |
994,7 → 994,7 |
jnz .error_LM |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; забрасывание блока в 64 кб выше 1 мб. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; çàáðàñûâàíèå áëîêà â 64 êá âûøå 1 ìá. |
mov si, table_15_87 |
push es |
push ds |
1027,7 → 1027,7 |
macro name_in_root_fat |
;макрос, который записывает информацию о загруженном файле в корневую фат таблицу |
;ìàêðîñ, êîòîðûé çàïèñûâàåò èíôîðìàöèþ î çàãðóæåííîì ôàéëå â êîðíåâóþ ôàò òàáëèöó |
{ |
} |
1036,9 → 1036,9 |
macro use_RamdiskFile |
{ |
;загрузка файлов с использование callback сервиса первичного загрузчика |
;используется только для загрузки необходимых и небольших файлов, т.к. достаточно медленно работает |
;для загрузки использует 0х87 функцию int 0x15 прерывания - загрузка блоков данных до 64 кб выше 1 мб |
;çàãðóçêà ôàéëîâ ñ èñïîëüçîâàíèå callback ñåðâèñà ïåðâè÷íîãî çàãðóç÷èêà |
;èñïîëüçóåòñÿ òîëüêî äëÿ çàãðóçêè íåîáõîäèìûõ è íåáîëüøèõ ôàéëîâ, ò.ê. äîñòàòî÷íî ìåäëåííî ðàáîòàåò |
;äëÿ çàãðóçêè èñïîëüçóåò 0õ87 ôóíêöèþ int 0x15 ïðåðûâàíèÿ - çàãðóçêà áëîêîâ äàííûõ äî 64 êá âûøå 1 ìá |
local .start_loop |
local ._end |
local .rest_value_loop |
1046,14 → 1046,14 |
mov di, point_default ;restore value |
mov cx, save_cx_d |
mov data_offset, 0 ;clean offset |
;обработка конструкции типа LoaderModule=kord/kolibri.ldm |
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm |
.start_loop: |
call get_firs_sym ;get first symbol on new line |
test cx, cx |
jz ._end ;нету? ну ладно - следующее значение тогда ) |
jz ._end ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà ) |
cmp al, 'R' |
jnz .start_loop |
;проверка на значение RamdiskFile |
;ïðîâåðêà íà çíà÷åíèå RamdiskFile |
mov bx, cx |
mov ax, di |
1065,10 → 1065,10 |
sub bx, parse_RamdiskFile_e - parse_RamdiskFile;correct cx |
add bx, cx |
mov cx, bx |
; test status_flag,flag_found_LM ;оценка флагов |
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ |
; jz .correct_is_not_set_LM |
; mov si,found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
; call printplain |
; jmp .get_next_str |
1087,26 → 1087,26 |
mov save_di_RAMDISK, di |
mov save_cx_RAMDISK, cx |
;di указывает на начало блока информации, в cx длинна до конца секции. |
;после загрузки заноситься значение занятой памяти. |
;для того что бы загрузить модуль, воспользуемся callback сервисом |
;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0 |
;это выглядит так: в ini файле существует строчка RamdiskFile = @menu,@menu |
;мы ее модифицируем до такого состояния dw,dw,db'@menu',0 конечно сохранив те значения которые мы заменяем |
;сохранили певые 2 word |
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè. |
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè. |
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì |
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0 |
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà RamdiskFile = @menu,@menu |
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'@menu',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì |
;ñîõðàíèëè ïåâûå 2 word |
; |
@@: |
mov al, byte [es:di] |
cmp al, ',' ; т.е. ищем разделитель |
cmp al, ',' ; ò.å. èùåì ðàçäåëèòåëü |
jz .found_end_str |
inc di |
dec cx |
jnz @b |
;;;not found допустим,что это конец файла и он не имеет привычного завершения строки |
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðøåíèÿ ñòðîêè |
.found_end_str: |
; mov al,byte [es:di] |
; cmp al,' ' ; убираем пробелы, если они есть |
; cmp al,' ' ; óáèðàåì ïðîáåëû, åñëè îíè åñòü |
; jnz @f |
; inc di |
; dec cx |
1115,7 → 1115,7 |
;@@: |
mov point_to_dest_file_name, di |
inc di |
;проверка индивидуальности имени файла |
;ïðîâåðêà èíäèâèäóàëüíîñòè èìåíè ôàéëà |
check_name_file |
;/restore di - point and cx -size section |
mov di, save_di_RAMDISK |
1122,7 → 1122,7 |
mov cx, save_cx_RAMDISK |
test al, al |
jnz .start_loop ;если в al значение не =0, то такое имя уже существует в системе. |
jnz .start_loop ;åñëè â al çíà÷åíèå íå =0, òî òàêîå èìÿ óæå ñóùåñòâóåò â ñèñòåìå. |
1132,13 → 1132,13 |
push word [es:di-2] |
push di |
xor ax, ax |
mov word [es:di-6], ax ;вносим нужные значения |
;info_real_mode_size размер и указатель на область в которую можно загрузиться |
mov ax, info_real_mode_size ;0x3000 ;следующий сегмент за данными |
mov word [es:di-6], ax ;âíîñèì íóæíûå çíà÷åíèÿ |
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ |
mov ax, info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè |
mov word [es:di-4], ax |
mov word [es:di-2], 16 ;кол-во блоков по 4 кб =64 кб т.е. больше не читаем |
mov word [es:di-2], 16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ÷èòàåì |
mov di, point_to_dest_file_name |
1186,19 → 1186,19 |
cmp bx, 2 |
ja .error |
; сейчас у нас в dx:ax размер файла, который мы загрузили. |
; возможна ситуация, когда в bx=1 т.е. есть еще данные на диске |
; ñåé÷àñ ó íàñ â dx:ax ðàçìåð ôàéëà, êîòîðûé ìû çàãðóçèëè. |
; âîçìîæíà ñèòóàöèÿ, êîãäà â bx=1 ò.å. åñòü åùå äàííûå íà äèñêå |
mov status_flag_loader_f, bx |
shl edx, 16 |
mov dx, ax |
; shr edx,10 ;размер файла в кб. |
;;в edx размер в байтах. |
; shr edx,10 ;ðàçìåð ôàéëà â êá. |
;;â edx ðàçìåð â áàéòàõ. |
mov save_file_size, edx |
mov eax, edx |
;восстановим полностью файл сценария |
;âîññòàíîâèì ïîëíîñòüþ ôàéë ñöåíàðèÿ |
pop di |
pop cx ;длинна остатка с 2-ой частью имени т.е. с именем назначением. |
pop cx ;äëèííà îñòàòêà ñ 2-îé ÷àñòüþ èìåíè ò.å. ñ èìåíåì íàçíà÷åíèåì. |
pop word [es:di] |
pop di |
pop word [es:di-2] |
1227,24 → 1227,24 |
; загрузим чему у нас равен кластер |
; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта |
; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;кол-во секторов в кластере |
; çàãðóçèì ÷åìó ó íàñ ðàâåí êëàñòåð |
; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà |
; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;êîë-âî ñåêòîðîâ â êëàñòåðå |
; imul ax,bx |
;сейчас в eax размер кластера (512) байт |
;в edx длина файла в байтах до 64 кб |
;закиним файл за 1 мб |
;1 нам нужно составить фат таблицу т.е. произвести разметку рамдиска, затем перенесем по адресу файл |
;ñåé÷àñ â eax ðàçìåð êëàñòåðà (512) áàéò |
;â edx äëèíà ôàéëà â áàéòàõ äî 64 êá |
;çàêèíèì ôàéë çà 1 ìá |
;1 íàì íóæíî ñîñòàâèòü ôàò òàáëèöó ò.å. ïðîèçâåñòè ðàçìåòêó ðàìäèñêà, çàòåì ïåðåíåñåì ïî àäðåñó ôàéë |
;записать инфорамацию о файле в корневую директорию |
;çàïèñàòü èíôîðàìàöèþ î ôàéëå â êîðíåâóþ äèðåêòîðèþ |
register_file_in_fat |
;перенести за 1 мб содержимое файла |
;ïåðåíåñòè çà 1 ìá ñîäåðæèìîå ôàéëà |
move_file_up |
;проверим, загружен ли до конца файл? т.е. если размер файла больше чем 64 кб, то будет подгружать оставшиеся блоки |
;ïðîâåðèì, çàãðóæåí ëè äî êîíöà ôàéë? ò.å. åñëè ðàçìåð ôàéëà áîëüøå ÷åì 64 êá, òî áóäåò ïîäãðóæàòü îñòàâøèåñÿ áëîêè |
cmp status_flag_loader_f, 0x1 |
jnz @f |
;нужно дозагузить данные файла и перенести их за 1-ый мб согласно фат структуре |
;íóæíî äîçàãóçèòü äàííûå ôàéëà è ïåðåíåñòè èõ çà 1-ûé ìá ñîãëàñíî ôàò ñòðóêòóðå |
1255,7 → 1255,7 |
@@: |
;тут организован цикл по загрузке файлов в корневую директорию |
;òóò îðãàíèçîâàí öèêë ïî çàãðóçêå ôàéëîâ â êîðíåâóþ äèðåêòîðèþ |
mov di, save_di_RAMDISK |
mov cx, save_cx_RAMDISK |
if DEBUG |
1278,7 → 1278,7 |
jmp .start_loop |
._end: |
;перенесем за 1-ый мб фат и рут дир |
;ïåðåíåñåì çà 1-ûé ìá ôàò è ðóò äèð |
move_up_fat_and_root_d |
1286,7 → 1286,7 |
;загрузка блока |
;çàãðóçêà áëîêà |
; mov ah,0x87 |
; mov cx, ;size in byte |
1296,8 → 1296,8 |
} |
macro use_BPB_RAM ;закинуть самые первые 512 байт за 1-й мб |
;данный макрос закидывает BPB структуру т.е. первые 512 байт, пока только фат12 за 1 мб |
macro use_BPB_RAM ;çàêèíóòü ñàìûå ïåðâûå 512 áàéò çà 1-é ìá |
;äàííûé ìàêðîñ çàêèäûâàåò BPB ñòðóêòóðó ò.å. ïåðâûå 512 áàéò, ïîêà òîëüêî ôàò12 çà 1 ìá |
{ |
mov ax, fat12_buffer |
mov si, table_15_87 |
1305,7 → 1305,7 |
push es |
push ds |
pop es |
mov cx, 256 ;бут сектор укладывается в 512 байт 512/2=256 |
mov cx, 256 ;áóò ñåêòîð óêëàäûâàåòñÿ â 512 áàéò 512/2=256 |
mov ah, 0x87 |
int 0x15 |
pop es |
1326,8 → 1326,8 |
end if |
} |
macro first_create_fat_table |
;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение |
;для смещения в корневой таблице. |
;äàííûé ìàêðîñ ñîçäàåò îôîðìëÿåò 3 ïåðâûõ áàéòà fat òàáëèöû, è óñòàíàâëèâàåò óêàçàòåëü íà ñëåäóþùèé áëîê, è âíîñèò 0 çíà÷åíèå |
;äëÿ ñìåùåíèÿ â êîðíåâîé òàáëèöå. |
{ |
mov al, byte [fat12_buffer.BPB_Media] |
1361,12 → 1361,12 |
end if |
push di ; push word info_real_mode_size+0x1000 ;cледующий сегмент за загруженным участком |
push di ; push word info_real_mode_size+0x1000 ;cëåäóþùèé ñåãìåíò çà çàãðóæåííûì ó÷àñòêîì |
xor di, di |
mov point_to_free_root, di ;значение смещения =0 в корневой фат таблице описания |
mov point_to_free_root, di ;çíà÷åíèå ñìåùåíèÿ =0 â êîðíåâîé ôàò òàáëèöå îïèñàíèÿ |
pop ds ; загружен следующий сегмент т.е. пустой сегмент |
pop ds ; çàãðóæåí ñëåäóþùèé ñåãìåíò ò.å. ïóñòîé ñåãìåíò |
mov byte [di], al |
or ax, -1 |
1390,9 → 1390,9 |
} |
macro register_file_in_fat |
;макрос регистрации файла в файловой структуре Fat |
;пока поддерживается только фат12, пока )) |
;вычисление смежных кластеров и занесение инфы в fat/ |
;ìàêðîñ ðåãèñòðàöèè ôàéëà â ôàéëîâîé ñòðóêòóðå Fat |
;ïîêà ïîääåðæèâàåòñÿ òîëüêî ôàò12, ïîêà )) |
;âû÷èñëåíèå ñìåæíûõ êëàñòåðîâ è çàíåñåíèå èíôû â fat/ |
{ |
local .step2 |
local .step3 |
1399,21 → 1399,21 |
local .end |
local .eof_file |
;di point on root dir на фри секцию. |
;di point on root dir íà ôðè ñåêöèþ. |
push es |
mov ax, info_real_mode_size |
add ax, 0x1000 |
mov es, ax ; push word info_real_mode_size+0x1000 ;сегмент следующий за загруженным блоком в 64 кб |
mov es, ax ; push word info_real_mode_size+0x1000 ;ñåãìåíò ñëåäóþùèé çà çàãðóæåííûì áëîêîì â 64 êá |
; определяем тип фат пока не определяем, пока только фат 12 |
; 12 бит, для вычесления соседних каластеров. |
mov di, firstDataSect ;в секторах |
; îïðåäåëÿåì òèï ôàò ïîêà íå îïðåäåëÿåì, ïîêà òîëüêî ôàò 12 |
; 12 áèò, äëÿ âû÷åñëåíèÿ ñîñåäíèõ êàëàñòåðîâ. |
mov di, firstDataSect ;â ñåêòîðàõ |
sub di, size_root_dir |
;теперь в ax размер в секторах начала рут дир |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di, 9;imul 512 |
add di, point_to_free_root ;смещение в уже записанных 32-х структурах. |
;необходимо внести значение в рут дир т.е. 32 байта |
add di, point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ. |
;íåîáõîäèìî âíåñòè çíà÷åíèå â ðóò äèð ò.å. 32 áàéòà |
if DEBUG |
pushad |
; mov ax,point_default |
1434,16 → 1434,16 |
;gs:di - указатель для внесения инфорации в рут область фат таблицы инормации о файле. |
;gs:di - óêàçàòåëü äëÿ âíåñåíèÿ èíôîðàöèè â ðóò îáëàñòü ôàò òàáëèöû èíîðìàöèè î ôàéëå. |
mov si, shot_name_fat |
mov cx, 11 |
;запишем в структуру имя |
;çàïèøåì â ñòðóêòóðó èìÿ |
@@: |
lodsb |
stosb |
loop @b |
;запишем атрибуты файла и DIR_NTRes - зарезеврированный байт =0 |
;çàïèøåì àòðèáóòû ôàéëà è DIR_NTRes - çàðåçåâðèðîâàííûé áàéò =0 |
xor ax, ax |
mov ah, ATTR_VOLUME_ID |
mov word [es:di], ax |
1452,19 → 1452,19 |
mov byte [es:di], 100 |
inc di |
;DIR_CrtTime |
mov word [es:di], 0x032b ;дата |
mov word [es:di], 0x032b ;äàòà |
add di, 2 |
;DIR_CrtDate |
mov word [es:di], 0x0 ;время >< |
mov word [es:di], 0x0 ;âðåìÿ >< |
add di, 2 |
;DIR_LstAccDate |
mov word [es:di], 0x032b ;дата моего |
mov word [es:di], 0x032b ;äàòà ìîåãî |
add di, 2 |
;DIR_FstClusHI |
mov word [es:di], 0x0 ;время для фат12 /16 всегда 0 |
mov word [es:di], 0x0 ;âðåìÿ äëÿ ôàò12 /16 âñåãäà 0 |
add di, 2 |
;DIR_WrtTime |
mov word [es:di], 0x0 ;время >< |
mov word [es:di], 0x0 ;âðåìÿ >< |
add di, 2 |
;DIR_WrtDate |
mov word [es:di], 0x032b |
1475,28 → 1475,28 |
add di, 2 |
push di |
;DIR_FstClusLO Младшее слово номера первого кластера. |
; mov ax,point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи |
;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат |
;DIR_FstClusLO Ìëàäøåå ñëîâî íîìåðà ïåðâîãî êëàñòåðà. |
; mov ax,point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè |
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò |
mov bx, ax |
shr bx, 1 |
add ax, bx |
;в ах сейчас FATOffset |
;â àõ ñåé÷àñ FATOffset |
;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec); |
mov bx, word [fat12_buffer.BPB_BytsPerSec] |
cwd |
idiv bx |
;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) четный или нечетный указатель. |
;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) ÷åòíûé èëè íå÷åòíûé óêàçàòåëü. |
mov si, ax |
;нам нужно в цикле записать все кластеры которые будут использованы для размещения файла. |
;узнаем размер кластера. |
;íàì íóæíî â öèêëå çàïèñàòü âñå êëàñòåðû êîòîðûå áóäóò èñïîëüçîâàíû äëÿ ðàçìåùåíèÿ ôàéëà. |
;óçíàåì ðàçìåð êëàñòåðà. |
movzx eax, word [fat12_buffer.BPB_BytsPerSec] |
movzx ebx, byte [fat12_buffer.BPB_SecPerClus] |
imul eax, ebx |
;ax - размер кластера. |
;сейчас будем записывать во временный буфер фат таблицу для выбранного файла. Поскольку мы его загрузили возможно не полностью |
;мы обработаем запись для фат полностью, в не зависимости от предела буфера где возможна часть файла. |
mov ebx, save_file_size ;размер файла в байтах |
;ax - ðàçìåð êëàñòåðà. |
;ñåé÷àñ áóäåì çàïèñûâàòü âî âðåìåííûé áóôåð ôàò òàáëèöó äëÿ âûáðàííîãî ôàéëà. Ïîñêîëüêó ìû åãî çàãðóçèëè âîçìîæíî íå ïîëíîñòüþ |
;ìû îáðàáîòàåì çàïèñü äëÿ ôàò ïîëíîñòüþ, â íå çàâèñèìîñòè îò ïðåäåëà áóôåðà ãäå âîçìîæíà ÷àñòü ôàéëà. |
mov ebx, save_file_size ;ðàçìåð ôàéëà â áàéòàõ |
@@: |
sub ebx, eax |
1504,8 → 1504,8 |
jbe .eof_file |
inc point_next_fat_str |
mov cx, point_next_fat_str ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи |
;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат |
mov cx, point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè |
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò |
mov dx, ax |
shr dx, 1 |
add cx, dx |
1543,7 → 1543,7 |
inc point_next_fat_str |
pop di |
;DIR_FileSize 32-битный DWORD содержит размер файла в байтах. |
;DIR_FileSize 32-áèòíûé DWORD ñîäåðæèò ðàçìåð ôàéëà â áàéòàõ. |
mov eax, save_file_size |
mov dword [es:di], eax |
1550,11 → 1550,11 |
if DEBUG |
pushad |
mov di, firstDataSect ;в секторах |
mov di, firstDataSect ;â ñåêòîðàõ |
sub di, size_root_dir |
;теперь в ax размер в секторах начала рут дир |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di, 9;imul 512 |
add di, point_to_free_root ;смещение в уже записанных 32-х структурах. |
add di, point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ. |
push di |
1561,7 → 1561,7 |
mov si, dest_name_fat |
mov cx, 11 |
;запишем в структуру имя |
;çàïèøåì â ñòðóêòóðó èìÿ |
@@: |
mov al, byte [es:di] |
inc di |
1585,7 → 1585,7 |
add point_to_free_root, 32 ;увелицим смещение до следующего значения. |
add point_to_free_root, 32 ;óâåëèöèì ñìåùåíèå äî ñëåäóþùåãî çíà÷åíèÿ. |
pop es |
} |
1595,8 → 1595,8 |
macro get_firstDataSector |
;макрос для вычисления певого сектора данных т.е. данных файлов в фате |
;вычислим FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; |
;ìàêðîñ äëÿ âû÷èñëåíèÿ ïåâîãî ñåêòîðà äàííûõ ò.å. äàííûõ ôàéëîâ â ôàòå |
;âû÷èñëèì FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors; |
{ |
mov ax, word [fat12_buffer.BPB_FATSz16] |
movzx bx, byte [fat12_buffer.BPB_NumFATs] |
1608,9 → 1608,9 |
mov size_root_dir, bx |
movzx bx, byte [fat12_buffer.BPB_RsvdSecCnt] ;add 1 for fat 16/12 |
add ax, bx |
;ax=firstDataSector - где начинается первый секторо от 0 сектора в секторах. - фактически = 24 сектор |
mov firstDataSect, ax ;сохраним для вычисления |
; получимзначение кластеров, это объем в который мы можем записать данные |
;ax=firstDataSector - ãäå íà÷èíàåòñÿ ïåðâûé ñåêòîðî îò 0 ñåêòîðà â ñåêòîðàõ. - ôàêòè÷åñêè = 24 ñåêòîð |
mov firstDataSect, ax ;ñîõðàíèì äëÿ âû÷èñëåíèÿ |
; ïîëó÷èìçíà÷åíèå êëàñòåðîâ, ýòî îáúåì â êîòîðûé ìû ìîæåì çàïèñàòü äàííûå |
mov bx, word [fat12_buffer.BPB_TotSec16] |
sub bx, ax |
mov ax, bx |
1621,7 → 1621,7 |
if DEBUG |
pushad |
mov ax, firstDataSect ;первый сектор данных |
mov ax, firstDataSect ;ïåðâûé ñåêòîð äàííûõ |
mov cx, 0x0a |
mov di, firstDataSect_msg |
call decode |
1629,7 → 1629,7 |
mov si, firstDataSect_msg |
call printplain |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov ax, size_root_dir ;размер рут дир в сетокторах |
mov ax, size_root_dir ;ðàçìåð ðóò äèð â ñåòîêòîðàõ |
mov cx, 0x0a |
mov di, size_root_dir_msg |
call decode |
1637,7 → 1637,7 |
mov si, size_root_dir_msg |
call printplain |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
mov ax, DataClasters;кластеры |
mov ax, DataClasters;êëàñòåðû |
mov cx, 0x0a |
mov di, DataClasters_msg |
call decode |
1651,40 → 1651,40 |
} |
macro use_RamdiskPATHS |
;парсинг пути источника файлов. |
;ïàðñèíã ïóòè èñòî÷íèêà ôàéëîâ. |
{ |
} |
macro use_RamdiskPATHD |
;парсинг пути назначения файлов. |
;ïàðñèíã ïóòè íàçíà÷åíèÿ ôàéëîâ. |
{ |
} |
macro check_name_file |
;макрос проверки имени на повтор, имя должно быть уникальным. |
;входные данные: es- сегмент где лежит файл для парсинга т.е. startos.ini |
;di - указатель на имя файла т.е. es:di указывает на имя файла назначения |
;выходные данные eax =-1 имя совпало, eax=0 имя не совпало. |
;ìàêðîñ ïðîâåðêè èìåíè íà ïîâòîð, èìÿ äîëæíî áûòü óíèêàëüíûì. |
;âõîäíûå äàííûå: es- ñåãìåíò ãäå ëåæèò ôàéë äëÿ ïàðñèíãà ò.å. startos.ini |
;di - óêàçàòåëü íà èìÿ ôàéëà ò.å. es:di óêàçûâàåò íà èìÿ ôàéëà íàçíà÷åíèÿ |
;âûõîäíûå äàííûå eax =-1 èìÿ ñîâïàëî, eax=0 èìÿ íå ñîâïàëî. |
{ |
local .no_equal |
local .exit |
local .loop_size_root_dir |
;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. |
;преобразуем в аналог фат записи сточку с именем назначения |
convertion_file_name ; преобразовали имя по нужным правилам |
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè. |
;ïðåîáðàçóåì â àíàëîã ôàò çàïèñè ñòî÷êó ñ èìåíåì íàçíà÷åíèÿ |
convertion_file_name ; ïðåîáðàçîâàëè èìÿ ïî íóæíûì ïðàâèëàì |
test ax, ax |
jnz .exit |
lea si, [shot_name_fat] ; desination name of file |
;вычислим указатель на корневую директорию |
;âû÷èñëèì óêàçàòåëü íà êîðíåâóþ äèðåêòîðèþ |
mov di, firstDataSect |
sub di, size_root_dir |
;теперь в ax размер в секторах начала рут дир |
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð |
shl di, 9;imul 512 |
;di= Это смещение от начала буфера до рут директории. в пределах 64 кб. |
;загрузим значение - т.е. кол-во элементов, которые мы можем просматривать. |
;di= Ýòî ñìåùåíèå îò íà÷àëà áóôåðà äî ðóò äèðåêòîðèè. â ïðåäåëàõ 64 êá. |
;çàãðóçèì çíà÷åíèå - ò.å. êîë-âî ýëåìåíòîâ, êîòîðûå ìû ìîæåì ïðîñìàòðèâàòü. |
mov dx, root_dir_entry_count |
mov ax, info_real_mode_size |
1766,7 → 1766,7 |
loop @b |
;.succesfuly: |
;печально, такое имя уже имеется :( |
;ïå÷àëüíî, òàêîå èìÿ óæå èìååòñÿ :( |
or ax, -1 |
jmp .exit |
1799,9 → 1799,9 |
macro convertion_file_name |
;макрос конвертации имени, это нужно поскольку формат представленный не соответсвует фат и напрямую редко можно когда использовать |
;преобразование имени типа hello.asm в 'HELLO ASM', в соответствии с правилами fat. |
;входные параметры es:di указатель на имя файла которое нужно преобразовать, конечный буфер shot_name_fat |
;ìàêðîñ êîíâåðòàöèè èìåíè, ýòî íóæíî ïîñêîëüêó ôîðìàò ïðåäñòàâëåííûé íå ñîîòâåòñâóåò ôàò è íàïðÿìóþ ðåäêî ìîæíî êîãäà èñïîëüçîâàòü |
;ïðåîáðàçîâàíèå èìåíè òèïà hello.asm â 'HELLO ASM', â ñîîòâåòñòâèè ñ ïðàâèëàìè fat. |
;âõîäíûå ïàðàìåòðû es:di óêàçàòåëü íà èìÿ ôàéëà êîòîðîå íóæíî ïðåîáðàçîâàòü, êîíå÷íûé áóôåð shot_name_fat |
{ |
local .next_step |
local .error |
1813,11 → 1813,11 |
local .st4 |
local .st5 |
;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными. |
; mov di,point_to_dest_file_name входной параметр |
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè. |
; mov di,point_to_dest_file_name âõîäíîé ïàðàìåòð |
mov si, shot_name_fat |
or first_input, -1 ;при первом входе устанавливаем флаг |
mov cx, 11 ;длинна имени в стуктуре фат таблицы |
or first_input, -1 ;ïðè ïåðâîì âõîäå óñòàíàâëèâàåì ôëàã |
mov cx, 11 ;äëèííà èìåíè â ñòóêòóðå ôàò òàáëèöû |
@@: |
mov al, byte [es:di] |
1867,19 → 1867,19 |
cmp first_input, -1 |
jnz .next_step |
and first_input, 0 ;сборосим флаг. |
and first_input, 0 ;ñáîðîñèì ôëàã. |
cmp al, '.' |
jz .error ;обработка точки, файл не может начинаться с точки |
jz .error ;îáðàáîòêà òî÷êè, ôàéë íå ìîæåò íà÷èíàòüñÿ ñ òî÷êè |
.next_step: |
cmp al, 0x2e |
jnz .st2 ;обработка точки, в середине файла |
;тут у нас установлен разделитель |
;все остальнео место займут пробелы |
jnz .st2 ;îáðàáîòêà òî÷êè, â ñåðåäèíå ôàéëà |
;òóò ó íàñ óñòàíîâëåí ðàçäåëèòåëü |
;âñå îñòàëüíåî ìåñòî çàéìóò ïðîáåëû |
mov al, ' ' |
;!fixme обработаны не все исключения :( |
cmp cl, 3 ;формат файла такой GIDGIDIIASM т.е. gidgidii.asm |
;!fixme îáðàáîòàíû íå âñå èñêëþ÷åíèÿ :( |
cmp cl, 3 ;ôîðìàò ôàéëà òàêîé GIDGIDIIASM ò.å. gidgidii.asm |
jbe .st2 |
1897,7 → 1897,7 |
cmp al, 0x60 |
jbe .st2_l |
xor al, 0x20;сделаем заглавные буквы |
xor al, 0x20;ñäåëàåì çàãëàâíûå áóêâû |
.st2_l: |
mov byte [si], al |
inc di |
1909,7 → 1909,7 |
xor ax, ax |
jmp @f |
;;;;;;;;файл закончился, и нужно внести в конец пробелы |
;;;;;;;;ôàéë çàêîí÷èëñÿ, è íóæíî âíåñòè â êîíåö ïðîáåëû |
.st4_s: |
mov al, ' ' |
.st4: |
1941,18 → 1941,18 |
} |
macro move_file_up |
;макрос который перемещает за 1 мб с правилами фат данные файла. |
;ìàêðîñ êîòîðûé ïåðåìåùàåò çà 1 ìá ñ ïðàâèëàìè ôàò äàííûå ôàéëà. |
{ |
local .st1 |
local .correct_on_byte |
;сейчас имеет быть ситуация, когда BPB уже перемещен за 1 мб, фат, и рут дир будут позже перемещены, |
;а нам нужно вычислить место, и перенести туда содержимое файла |
;полученое значение указывает в байтах на начало данных |
;ñåé÷àñ èìååò áûòü ñèòóàöèÿ, êîãäà BPB óæå ïåðåìåùåí çà 1 ìá, ôàò, è ðóò äèð áóäóò ïîçæå ïåðåìåùåíû, |
;à íàì íóæíî âû÷èñëèòü ìåñòî, è ïåðåíåñòè òóäà ñîäåðæèìîå ôàéëà |
;ïîëó÷åíîå çíà÷åíèå óêàçûâàåò â áàéòàõ íà íà÷àëî äàííûõ |
mov ax, info_real_mode_size ; сегмент где расположены данные |
mov ax, info_real_mode_size ; ñåãìåíò ãäå ðàñïîëîæåíû äàííûå |
mov si, table_15_87 |
mov word [si+8*2+2], ax |
;смещение до данных уже за 1-м мб |
;ñìåùåíèå äî äàííûõ óæå çà 1-ì ìá |
movzx eax, firstDataSect |
movzx edx, data_offset |
add eax, edx |
1959,7 → 1959,7 |
movzx ebx, word [fat12_buffer.BPB_BytsPerSec] |
movzx edx, byte [fat12_buffer.BPB_SecPerClus] |
imul bx, dx ;получим размер кластера |
imul bx, dx ;ïîëó÷èì ðàçìåð êëàñòåðà |
1966,7 → 1966,7 |
push ebx ;save bx |
imul eax, ebx |
; shl eax,9 ;умножим на 512 |
; shl eax,9 ;óìíîæèì íà 512 |
if DEBUG |
pushad |
2002,25 → 2002,25 |
@@: |
mov byte [si+8*3+3], dl ;куда писать |
mov byte [si+8*3+3], dl ;êóäà ïèñàòü |
mov word [si+8*3+2], ax |
mov ecx, save_file_size ;размер файла в байтах. |
cmp ecx, 0x0000ffff ;размер блока т.е. 64 кб |
jbe .correct_on_byte ;корректировка на байт значения |
mov ecx, save_file_size ;ðàçìåð ôàéëà â áàéòàõ. |
cmp ecx, 0x0000ffff ;ðàçìåð áëîêà ò.å. 64 êá |
jbe .correct_on_byte ;êîððåêòèðîâêà íà áàéò çíà÷åíèÿ |
mov ecx, 0x00010000 ;65536 |
sub save_file_size, ecx ;отнимим |
; jmp .st1 ;получим 0х8000 |
sub save_file_size, ecx ;îòíèìèì |
; jmp .st1 ;ïîëó÷èì 0õ8000 |
;корректировка значения должна быть выполенена на размер кластера |
;êîððåêòèðîâêà çíà÷åíèÿ äîëæíà áûòü âûïîëåíåíà íà ðàçìåð êëàñòåðà |
.correct_on_byte: |
;/узнаем размер кластера |
;/óçíàåì ðàçìåð êëàñòåðà |
pop eax ;restore size of claster |
push ecx |
@@: |
2040,9 → 2040,9 |
jz .st1 |
inc ecx |
.st1: |
shr ecx, 1 ; преобразовать значение для 0x87 function |
shr ecx, 1 ; ïðåîáðàçîâàòü çíà÷åíèå äëÿ 0x87 function |
;перенесем блок за 1 мб |
;ïåðåíåñåì áëîê çà 1 ìá |
push es |
push ds |
pop es |
2068,7 → 2068,7 |
macro move_up_fat_and_root_d |
;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию |
;ìàêðîñ, êîòîðûé ïîçâîëÿåò ïåðåíåñòè âûøå 1 ìá â ñòðóêòóðó îáðàçà ôàò òàáëèöó è ðóò äèðåêòîðèþ |
{ |
local .st1 |
2077,20 → 2077,20 |
mov si, table_15_87 |
mov word [si+8*2+2], ax |
;смещение до данных |
;ñìåùåíèå äî äàííûõ |
mov ax, 512 |
mov word [si+8*3+2], ax |
;fixme! тут необходимо сделать подержку т.е. формировать смещение файла в уже записанных данных. |
;fixme! òóò íåîáõîäèìî ñäåëàòü ïîäåðæêó ò.å. ôîðìèðîâàòü ñìåùåíèå ôàéëà â óæå çàïèñàííûõ äàííûõ. |
movzx ecx, word [fat12_buffer.BPB_FATSz16] |
movzx bx, byte [fat12_buffer.BPB_NumFATs] |
imul cx, bx ;9x1=9 |
add cx, size_root_dir ;размер корневой дирректории |
add cx, size_root_dir ;ðàçìåð êîðíåâîé äèððåêòîðèè |
shl ecx, 9 ;imul 512 |
;корректировка значения |
;êîððåêòèðîâêà çíà÷åíèÿ |
test ecx, 0x1 |
jz .st1 |
inc ecx |
/kernel/trunk/sec_loader/trunk/parse_err.inc |
---|
30,7 → 30,7 |
mov cx, bx |
jmp ret_on_ch ;return |
;///// ошибка при находжении длинны секции в параметре default |
;///// îøèáêà ïðè íàõîäæåíèè äëèííû ñåêöèè â ïàðàìåòðå default |
.error_get_size_d_sect: |
leave ;clear array in stack |
mov si, not_found_def_sect |
42,7 → 42,7 |
mov si, not_found_sec_loader |
jmp err_show_ini |
.default_eq_loader: ;критическая ошибка default секция = loader |
.default_eq_loader: ;êðèòè÷åñêàÿ îøèáêà default ñåêöèÿ = loader |
leave |
mov si, default_eq_loader |
jmp err_show_ini |
/kernel/trunk/sec_loader/trunk/parse_loader.inc |
---|
24,10 → 24,10 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
;блок макросов по обработке секции [loader] |
;входные данные: |
;es:di - указатель на секцию начинающиюся с '[' встечающиюся после 0хa |
;cx - счетчик кол-во байт для проверке в кадре |
;áëîê ìàêðîñîâ ïî îáðàáîòêå ñåêöèè [loader] |
;âõîäíûå äàííûå: |
;es:di - óêàçàòåëü íà ñåêöèþ íà÷èíàþùèþñÿ ñ '[' âñòå÷àþùèþñÿ ïîñëå 0õa |
;cx - ñ÷åò÷èê êîë-âî áàéò äëÿ ïðîâåðêå â êàäðå |
; |
macro use_parse_loader |
{ |
35,7 → 35,7 |
;////////////////// |
;/ parse [loader] |
;////////////////// |
mov bx, cx ;cохраним в регистры значения счетчика и указателя |
mov bx, cx ;cîõðàíèì â ðåãèñòðû çíà÷åíèÿ ñ÷åò÷èêà è óêàçàòåëÿ |
mov ax, di |
; mov word [bp-4],.start ;is alredy set, see up |
42,9 → 42,9 |
mov si, parse_loader |
mov cx, parse_loader_e - parse_loader |
repe cmpsb |
jnz error.rest_value ;цепочка не совпала :( перейдем далее т.е. будем снова искать)) |
jnz error.rest_value ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå ò.å. áóäåì ñíîâà èñêàòü)) |
;сохраним указательна loader, что бы потом больше его не искать |
;ñîõðàíèì óêàçàòåëüíà loader, ÷òî áû ïîòîì áîëüøå åãî íå èñêàòü |
mov point_loader, ax |
sub bx, parse_loader_e - parse_loader;correct cx |
add bx, cx |
63,7 → 63,7 |
mov dx, di |
@@: |
call get_firs_sym |
jcxz .loader_f_end ;.end_loader ; end даже если мы не нашли секцию предположим что секция [loader] стоит в конце |
jcxz .loader_f_end ;.end_loader ; end äàæå åñëè ìû íå íàøëè ñåêöèþ ïðåäïîëîæèì ÷òî ñåêöèÿ [loader] ñòîèò â êîíöå |
cmp al, '[' |
jnz @b |
74,7 → 74,7 |
;//timeout=5 |
;//default=main |
; mov di,dx ;set pointer on section [loader] i think it's not need |
mov cx, bx ;set counter for parsing section [loader] cx= кол-ву символов в секции [loader] |
mov cx, bx ;set counter for parsing section [loader] cx= êîë-âó ñèìâîëîâ â ñåêöèè [loader] |
mov ret_on_ch, .get_next_str; return point |
;;;;;;; parse timeout & default |
.get_next_str: |
82,7 → 82,7 |
test cx, cx |
jz .end_loader |
; jcxz .end_loader ;завершение парсинга значений timeout & default |
; jcxz .end_loader ;çàâåðøåíèå ïàðñèíãà çíà÷åíèé timeout & default |
cmp al, 't' |
jz .loader_timeout |
cmp al, 'd' |
96,7 → 96,7 |
mov cx, parse_l_default_e - parse_l_default |
repe cmpsb |
jnz error.rest_value ;is not compare цепочка не совпала |
jnz error.rest_value ;is not compare öåïî÷êà íå ñîâïàëà |
sub bx, parse_l_default_e - parse_l_default;correct cx |
add bx, cx |
105,7 → 105,7 |
test status_flag, flag_found_default |
jz .correct_is_not_set |
mov si, found_equal_default ;мы нашли что флаг уже установлен, информируем |
mov si, found_equal_default ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
call printplain |
jmp .get_next_str |
121,12 → 121,12 |
repe scasb ;cut ' ' |
inc cx |
dec di |
;сейчас es:di указывают на название секции, имя секции по дефолту не должно быть loader т.е. иначе возможно зацикливание |
;установим указатель si на это значение и сначала проверим |
;ñåé÷àñ es:di óêàçûâàþò íà íàçâàíèå ñåêöèè, èìÿ ñåêöèè ïî äåôîëòó íå äîëæíî áûòü loader ò.å. èíà÷å âîçìîæíî çàöèêëèâàíèå |
;óñòàíîâèì óêàçàòåëü si íà ýòî çíà÷åíèå è ñíà÷àëà ïðîâåðèì |
;получение длинны секции |
; cx=bx содержит длинну остатка секции |
; di=ax указатель на текущию секцию |
;ïîëó÷åíèå äëèííû ñåêöèè |
; cx=bx ñîäåðæèò äëèííó îñòàòêà ñåêöèè |
; di=ax óêàçàòåëü íà òåêóùèþ ñåêöèþ |
mov bx, cx |
mov dx, di |
135,7 → 135,7 |
inc di |
dec cx |
test cx, cx |
jz error.error_get_size_d_sect ;переход на обработку ошибки по нахождению длины дефолтной секции |
jz error.error_get_size_d_sect ;ïåðåõîä íà îáðàáîòêó îøèáêè ïî íàõîæäåíèþ äëèíû äåôîëòíîé ñåêöèè |
cmp al, ' ' |
jz @b |
cmp al, 0xd |
146,13 → 146,13 |
; |
inc cx ;correct cx |
mov ax, bx |
sub bx, cx ; в bx длина секции которая определена по дефолту |
sub bx, cx ; â bx äëèíà ñåêöèè êîòîðàÿ îïðåäåëåíà ïî äåôîëòó |
mov save_cx_d, bx |
mov di, dx |
mov cx, bx ;set size default section |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;проверка на =loader |
;save in reg point and счетчик |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ïðîâåðêà íà =loader |
;save in reg point and ñ÷åò÷èê |
;check on loader |
mov bx, ax |
mov ax, dx |
160,22 → 160,22 |
mov si, parse_loader |
inc si ;set only loader and 6 char in counter |
repe cmpsb |
jnz .check_section ;цепочка не совпала :( перейдем далее )) значит не исключение |
jnz .check_section ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå |
jmp error.default_eq_loader ;error критическая ошибка т.е. в дефолте присутствует имя [loader] |
jmp error.default_eq_loader ;error êðèòè÷åñêàÿ îøèáêà ò.å. â äåôîëòå ïðèñóòñòâóåò èìÿ [loader] |
.check_section: ;поиск соответствующей секции нам нужно будет узнать адрес этой секции |
.check_section: ;ïîèñê ñîîòâåòñòâóþùåé ñåêöèè íàì íóæíî áóäåò óçíàòü àäðåñ ýòîé ñåêöèè |
mov cx, bx |
mov di, ax |
;///////////////////////////// |
; mov ret_on_ch,.start_d ;set return |
mov si, di ;установим указатель на нашу секцию, которая по дефолту |
mov si, di ;óñòàíîâèì óêàçàòåëü íà íàøó ñåêöèþ, êîòîðàÿ ïî äåôîëòó |
push di ;save point di |
push cx ;save cx |
;установим указатель es:di на начало ini файла |
;óñòàíîâèì óêàçàòåëü es:di íà íà÷àëî ini ôàéëà |
mov cx, save_cx ;it's placed size of ini file |
les di, dword [file_data] |
190,13 → 190,13 |
.start_d: |
call get_firs_sym ;get first symbol on new line |
.first_ret_d: ;первый возврат |
.first_ret_d: ;ïåðâûé âîçâðàò |
jcxz .correct_exit ;.end_loader ;found or not found parametrs in section exit in section |
cmp al, '[' |
jz .found_sect_d |
jmp .start_d |
;просматриваем ini файл с начала в поисках секции указаной как default |
;идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти |
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default |
;èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè |
.found_sect_d: |
;check on name section |
215,9 → 215,9 |
pop ds |
pop si |
jnz .not_compare_d_s ;цепочка не совпала :( перейдем далее )) значит не исключение |
jnz .not_compare_d_s ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå |
cmp byte[es:di], ']' |
jnz .not_compare_d_s ;нет в конце нашей секции завершающего символа :( |
jnz .not_compare_d_s ;íåò â êîíöå íàøåé ñåêöèè çàâåðøàþùåãî ñèìâîëà :( |
243,7 → 243,7 |
jmp .start_d |
.correct_exit: |
pop cx ;восстановим значение счетчика |
pop cx ;âîññòàíîâèì çíà÷åíèå ñ÷åò÷èêà |
pop di |
272,7 → 272,7 |
test status_flag, flag_found_timeout |
jz .correct_is_not_set_t |
mov si, found_equal_timeout ;мы нашли что флаг уже установлен, информируем |
mov si, found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì |
call printplain |
jmp .get_next_str |
288,7 → 288,7 |
inc cx |
dec di |
;get timeout value |
;2 знакa может быть обработано т.е. значение от 0 до 99 секунд |
;2 çíàêa ìîæåò áûòü îáðàáîòàíî ò.å. çíà÷åíèå îò 0 äî 99 ñåêóíä |
push cx |
xor bx, bx |
mov cx, 2 |
/kernel/trunk/sec_loader/trunk/sl_equ.inc |
---|
23,12 → 23,12 |
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
; Предопределения |
DEBUG equ 1 ;компиляция с отладочной информацией =1 без отладочной инфорации =0 |
loop_read_startos_file equ 3 ;кол-во попыток считать через callback сервис файл конфигурации блок2 |
root_dir_entry_count equ 224 ;кол-во элементов в корневой дирректории |
;point_to_fat_struc equ 0xA000 ;временный буфер, куда будет размещена Fat таблица, и затем перенесена за 1 мб |
ini_data_ equ 0x2000 ;файл где размещен файл сценария загрузки, там происходит синтаксический разбор |
; Ïðåäîïðåäåëåíèÿ |
DEBUG equ 1 ;êîìïèëÿöèÿ ñ îòëàäî÷íîé èíôîðìàöèåé =1 áåç îòëàäî÷íîé èíôîðàöèè =0 |
loop_read_startos_file equ 3 ;êîë-âî ïîïûòîê ñ÷èòàòü ÷åðåç callback ñåðâèñ ôàéë êîíôèãóðàöèè áëîê2 |
root_dir_entry_count equ 224 ;êîë-âî ýëåìåíòîâ â êîðíåâîé äèððåêòîðèè |
;point_to_fat_struc equ 0xA000 ;âðåìåííûé áóôåð, êóäà áóäåò ðàçìåùåíà Fat òàáëèöà, è çàòåì ïåðåíåñåíà çà 1 ìá |
ini_data_ equ 0x2000 ;ôàéë ãäå ðàçìåùåí ôàéë ñöåíàðèÿ çàãðóçêè, òàì ïðîèñõîäèò ñèíòàêñè÷åñêèé ðàçáîð |
size_show_section equ 18 |
default_timeout_value equ 5 ;default value to timeout is will was some errors |
flag_found_default equ 0x1 ;default value is found |
38,15 → 38,15 |
flag_found_GTRFMS equ 0x4 ;found type RamFS |
flag_found_RamdiskSector equ 0x8 ;found RamdiskSector |
flag_found_RamdiskCluster equ 0x16 ;found RamdiskCluster |
;statick data эти данные не предопределяются в течении выполнения всей программы. |
;statick data ýòè äàííûå íå ïðåäîïðåäåëÿþòñÿ â òå÷åíèè âûïîëíåíèÿ âñåé ïðîãðàììû. |
save_cx equ word [bp-2] ;save cx size ini file |
ret_on_ch equ word [bp-4] ;point to return разрушаемое значение |
ret_on_ch equ word [bp-4] ;point to return ðàçðóøàåìîå çíà÷åíèå |
save_cx_d equ word [bp-6] ;save cx - size default section and working section |
status_flag equ word [bp-8] ;status flag |
point_loader equ word [bp-10] |
point_default equ word [bp-12] ;point to default |
;данные которые зависимы от ветки выполнения и которые могут быть переопределены в процессе выполнения программы. |
;äàííûå êîòîðûå çàâèñèìû îò âåòêè âûïîëíåíèÿ è êîòîðûå ìîãóò áûòü ïåðåîïðåäåëåíû â ïðîöåññå âûïîëíåíèÿ ïðîãðàììû. |
point_to_hframe equ word [bp-14] ;point on start frame (for change section) |
point_to_1 equ word [bp-16] |
point_to_2 equ word [bp-18] |
73,26 → 73,26 |
; тут расположено временное хранилище для cx и di при переходе на следующий буфер при поиске секций |
find_sec_di equ word [bp-58] ;тут будет храниться di |
info_real_mode_size equ word [bp-60];тут храниться информация о занятой области т.е. размер, можно узнать сколько осталось места вычислив |
free_ad_memory equ word [bp-62] ;сколько у нас расширенной памяти для формирования рам диска и загрузки модулей |
show_errors_sect equ word [bp-64] ;переменая которая хранит биты ошибок для каждой логической секции. |
save_descript_size equ word [bp-66] ;save descript size previos section сохраним размер предыдущей секции которую выводили |
; òóò ðàñïîëîæåíî âðåìåííîå õðàíèëèùå äëÿ cx è di ïðè ïåðåõîäå íà ñëåäóþùèé áóôåð ïðè ïîèñêå ñåêöèé |
find_sec_di equ word [bp-58] ;òóò áóäåò õðàíèòüñÿ di |
info_real_mode_size equ word [bp-60];òóò õðàíèòüñÿ èíôîðìàöèÿ î çàíÿòîé îáëàñòè ò.å. ðàçìåð, ìîæíî óçíàòü ñêîëüêî îñòàëîñü ìåñòà âû÷èñëèâ |
free_ad_memory equ word [bp-62] ;ñêîëüêî ó íàñ ðàñøèðåííîé ïàìÿòè äëÿ ôîðìèðîâàíèÿ ðàì äèñêà è çàãðóçêè ìîäóëåé |
show_errors_sect equ word [bp-64] ;ïåðåìåíàÿ êîòîðàÿ õðàíèò áèòû îøèáîê äëÿ êàæäîé ëîãè÷åñêîé ñåêöèè. |
save_descript_size equ word [bp-66] ;save descript size previos section ñîõðàíèì ðàçìåð ïðåäûäóùåé ñåêöèè êîòîðóþ âûâîäèëè |
save_ramdisksize equ dword [bp-70] ;save size of ramdisk in byte |
save_file_size equ dword [bp-74] ;save size of reading file |
set_ramfs equ word [bp-76] ;определенный тип файловой системы,нужно для формирования рам диска |
point_next_fat_str equ word [bp-78] ;указатель на следующий элемент fat таблицы |
size_root_dir equ word [bp-80] ;кол-во элементов в секторах по 512 байт корневой директории |
firstDataSect equ word [bp-82] ;первый сектор данных в сеторах от 0 |
DataClasters equ word [bp-84] ;размер массива доступной для записи данных в кластерах. |
point_to_free_root equ word [bp-86] ;указатель на следующий пустую запись в рут дир |
point_to_dest_file_name equ word [bp-88] ;указывает на начало имени файла назначения. в формате es:point_to_dest_file_name, где es =0x2000 |
data_offset equ word [bp-90] ;смещение в кластерах для записанных данных т.е перекинутых за 1-й мб |
first_input equ word [bp-92] ;поле для флагов в преобразовании имени. |
save_di_RAMDISK equ word [bp-94] ;сохраним di -указателя при обработке секции |
save_cx_RAMDISK equ word [bp-96] ;сохраним размер остатка секции |
status_flag_loader_f equ word [bp-98] ;сохраним результат выполенения загрузки файла |
set_ramfs equ word [bp-76] ;îïðåäåëåííûé òèï ôàéëîâîé ñèñòåìû,íóæíî äëÿ ôîðìèðîâàíèÿ ðàì äèñêà |
point_next_fat_str equ word [bp-78] ;óêàçàòåëü íà ñëåäóþùèé ýëåìåíò fat òàáëèöû |
size_root_dir equ word [bp-80] ;êîë-âî ýëåìåíòîâ â ñåêòîðàõ ïî 512 áàéò êîðíåâîé äèðåêòîðèè |
firstDataSect equ word [bp-82] ;ïåðâûé ñåêòîð äàííûõ â ñåòîðàõ îò 0 |
DataClasters equ word [bp-84] ;ðàçìåð ìàññèâà äîñòóïíîé äëÿ çàïèñè äàííûõ â êëàñòåðàõ. |
point_to_free_root equ word [bp-86] ;óêàçàòåëü íà ñëåäóþùèé ïóñòóþ çàïèñü â ðóò äèð |
point_to_dest_file_name equ word [bp-88] ;óêàçûâàåò íà íà÷àëî èìåíè ôàéëà íàçíà÷åíèÿ. â ôîðìàòå es:point_to_dest_file_name, ãäå es =0x2000 |
data_offset equ word [bp-90] ;ñìåùåíèå â êëàñòåðàõ äëÿ çàïèñàííûõ äàííûõ ò.å ïåðåêèíóòûõ çà 1-é ìá |
first_input equ word [bp-92] ;ïîëå äëÿ ôëàãîâ â ïðåîáðàçîâàíèè èìåíè. |
save_di_RAMDISK equ word [bp-94] ;ñîõðàíèì di -óêàçàòåëÿ ïðè îáðàáîòêå ñåêöèè |
save_cx_RAMDISK equ word [bp-96] ;ñîõðàíèì ðàçìåð îñòàòêà ñåêöèè |
status_flag_loader_f equ word [bp-98] ;ñîõðàíèì ðåçóëüòàò âûïîëåíåíèÿ çàãðóçêè ôàéëà |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;данные которые используются при обработке секции, т.е. после нажатия Enter, уже не возможно вернуться в первоначальный экран |
;для возврата, необходимо перезапустить полностью код т.е. стартовать с 0х1000:0000 |
;äàííûå êîòîðûå èñïîëüçóþòñÿ ïðè îáðàáîòêå ñåêöèè, ò.å. ïîñëå íàæàòèÿ Enter, óæå íå âîçìîæíî âåðíóòüñÿ â ïåðâîíà÷àëüíûé ýêðàí |
;äëÿ âîçâðàòà, íåîáõîäèìî ïåðåçàïóñòèòü ïîëíîñòüþ êîä ò.å. ñòàðòîâàòü ñ 0õ1000:0000 |
/kernel/trunk/sec_loader/trunk/sl_proc.inc |
---|
24,7 → 24,7 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
; тут описываются процедуры которые используются в secondary loader |
; òóò îïèñûâàþòñÿ ïðîöåäóðû êîòîðûå èñïîëüçóþòñÿ â secondary loader |
color_sym_black equ 0 |
color_sym_blue equ 1 |
color_sym_green equ 2 |
40,7 → 40,7 |
color_sym_white equ 15 |
if DEBUG |
decode: |
;input eax - число, es:di куда писать, cx=10 |
;input eax - ÷èñëî, es:di êóäà ïèñàòü, cx=10 |
cmp eax, ecx |
jb @f |
xor edx, edx |
198,7 → 198,7 |
dec di |
;все вырезали и все готово для вывода имени секции )) |
;âñå âûðåçàëè è âñå ãîòîâî äëÿ âûâîäà èìåíè ñåêöèè )) |
push es |
pop ds |
249,7 → 249,7 |
pop si |
ret |
.not_name_sec_fb: ;нет имени в названии секции - значит так и скажем об этом |
.not_name_sec_fb: ;íåò èìåíè â íàçâàíèè ñåêöèè - çíà÷èò òàê è ñêàæåì îá ýòîì |
push cs |
pop ds |
mov di, default_section_name |
256,45 → 256,45 |
jmp .def_sect_name |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;процедура поиска вверх следующей секции |
;в point_default содержиться указатель на дефаулт секцию, и в пределах врейма мы бегаем по заранее пропарсеными значениям указателей |
;для того что бы отобразить и пропарсить следующий фрейм, нам нужно получить за пердыдущий или следующий указатель |
;ïðîöåäóðà ïîèñêà ââåðõ ñëåäóþùåé ñåêöèè |
;â point_default ñîäåðæèòüñÿ óêàçàòåëü íà äåôàóëò ñåêöèþ, è â ïðåäåëàõ âðåéìà ìû áåãàåì ïî çàðàíåå ïðîïàðñåíûìè çíà÷åíèÿì óêàçàòåëåé |
;äëÿ òîãî ÷òî áû îòîáðàçèòü è ïðîïàðñèòü ñëåäóþùèé ôðåéì, íàì íóæíî ïîëó÷èòü çà ïåðäûäóùèé èëè ñëåäóþùèé óêàçàòåëü |
find_before_sect: |
mov di, point_default |
.e: |
push ini_data_ |
pop es |
mov cx, di ;предположим будем просматривать к началу, текущая позиция di = сколько символов от начала документа имеется |
mov bx, cx ;копия |
mov cx, di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê íà÷àëó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ |
mov bx, cx ;êîïèÿ |
;настроили указатель на дефаулт секцию |
;будем искать вверх |
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ |
;áóäåì èñêàòü ââåðõ |
.find_start_section: |
std ;установка флага направления - будем просматирвать к началу нашего ини файла |
;будем искать начало секции т.е. '[' этот символ |
std ;óñòàíîâêà ôëàãà íàïðàâëåíèÿ - áóäåì ïðîñìàòèðâàòü ê íà÷àëó íàøåãî èíè ôàéëà |
;áóäåì èñêàòü íà÷àëî ñåêöèè ò.å. '[' ýòîò ñèìâîë |
mov al, 0xa |
repnz scasb ;просканируем на наличее символа начала секции |
jcxz .go_ ;мы просмотрели до начала файла, но так и ничего не нашли ;(( по тихому выйдем ) |
repnz scasb ;ïðîñêàíèðóåì íà íàëè÷åå ñèìâîëà íà÷àëà ñåêöèè |
jcxz .go_ ;ìû ïðîñìîòðåëè äî íà÷àëà ôàéëà, íî òàê è íè÷åãî íå íàøëè ;(( ïî òèõîìó âûéäåì ) |
mov find_sec_di, di ;сохраним данные |
mov find_sec_di, di ;ñîõðàíèì äàííûå |
mov cx, di ; |
sub bx, cx |
mov cx, bx ;в сx значение - кол-во символов |
mov cx, bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ |
cld |
call get_firs_sym |
.ret_go: |
jcxz ._not_section ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее |
jcxz ._not_section ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå |
cmp di, point_loader; секцию loader мы не заносим иначе крах |
cmp di, point_loader; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ |
jz ._not_section |
;все удачно мы нашли вхождение секции предыдущей |
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé |
cmp al, '[' |
jnz ._not_section |
mov point_default, di |
.exit_scan_sect: |
ret |
;;;;;;;; восстановим значения и продолжим поиски начала секции которая нас устроит )) |
;;;;;;;; âîññòàíîâèì çíà÷åíèÿ è ïðîäîëæèì ïîèñêè íà÷àëà ñåêöèè êîòîðàÿ íàñ óñòðîèò )) |
._not_section: |
mov di, find_sec_di |
mov cx, di |
302,7 → 302,7 |
jmp .find_start_section |
.go_: |
cld |
mov cx, bx ;в сx значение - кол-во символов |
mov cx, bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ |
mov al, byte [es:di] |
push word .f_go |
313,11 → 313,11 |
jmp get_firs_sym.first_sp |
.f_go: |
jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее |
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå |
cmp di, point_loader; секцию loader мы не заносим иначе крах |
cmp di, point_loader; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ |
jz .exit_scan_sect |
;все удачно мы нашли вхождение секции предыдущей |
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé |
cmp al, '[' |
jnz .exit_scan_sect |
mov point_default, di |
336,14 → 336,14 |
mov di, point_default |
push ini_data_ |
pop es |
mov cx, save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется |
sub cx, di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало |
mov cx, save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ |
sub cx, di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî |
jmp .let_s_go |
.h: |
push ini_data_ |
pop es |
mov cx, save_cx;di ;предположим будем просматривать к концу, текущая позиция di = сколько символов от начала документа имеется |
; sub cx,di ;сейчас в cx остаток т.е. сколько можно крутить до конца и не вылазить на начало |
mov cx, save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ |
; sub cx,di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî |
mov al, byte [es:di] |
push word .let_s_go_ret |
356,17 → 356,17 |
;настроили указатель на дефаулт секцию |
;будем искать вниз |
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ |
;áóäåì èñêàòü âíèç |
.let_s_go: |
call get_firs_sym |
.let_s_go_ret: |
jcxz .exit_scan_sect ; в данном случае имеем конструкцию 0xa ... ; hello [секция] обломс ищем далее |
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå |
cmp al, '[' |
jnz .let_s_go |
cmp di, point_loader |
jz .let_s_go |
;все удачно мы нашли вхождение секции предыдущей |
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé |
mov point_default, di |
.exit_scan_sect: |
ret |
374,8 → 374,8 |
;;;;;;;;;;;;;;;;;;;;;;;;;; |
;clean old cursor |
clean_active_cursor: |
;не изменяет значение ax |
;отображение курсора по умолчанию |
;íå èçìåíÿåò çíà÷åíèå ax |
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ |
lea si, point_to_hframe |
mov di, 962-160 |
mov dx, point_default |
405,7 → 405,7 |
pop ax |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;установка таймера и отображение счетчика времени |
;óñòàíîâêà òàéìåðà è îòîáðàæåíèå ñ÷åò÷èêà âðåìåíè |
gettime: |
mov ah, 0 |
int 1Ah |
462,13 → 462,13 |
mov dword [timer_], eax |
mov sp, word [start_stack] |
mov bp, word [save_bp_from_timer] |
;;не восстановленый стек :( |
;;íå âîññòàíîâëåíûé ñòåê :( |
sti |
jmp parse_start.parse_run_only |
.decode: |
;input ax - число, es:di куда писать, bx=10 |
;input ax - ÷èñëî, es:di êóäà ïèñàòü, bx=10 |
cmp ax, bx |
jb @f |
xor dx, dx |
485,9 → 485,9 |
ret |
show_bl_sc_sect: |
;1) отображение списка секций. Если секция не имет имя - ошибка - вывод Section unname |
;проверка на наличее имени. |
;входные данные es:di -указатель на секцию - cx размер секции |
;1) îòîáðàæåíèå ñïèñêà ñåêöèé. Åñëè ñåêöèÿ íå èìåò èìÿ - îøèáêà - âûâîä Section unname |
;ïðîâåðêà íà íàëè÷åå èìåíè. |
;âõîäíûå äàííûå es:di -óêàçàòåëü íà ñåêöèþ - cx ðàçìåð ñåêöèè |
; push bp |
mov bx, point_to_eframe |
lea si, point_to_hframe |
/kernel/trunk/sec_loader/trunk/loader.lst |
---|
905,7 → 905,7 |
0E58: E2 FC loop @b |
0E5A: BF E0 01 mov di, 480 |
0E5D: B4 0E mov ah, color_sym_yellow |
0E5F: B0 C4 mov al, 'Д' |
0E5F: B0 C4 mov al, 'Ä' |
0E61: B9 3D 00 mov cx, 61 |
0E64: F3 rep |
0E65: AB stosw |
/kernel/trunk/sec_loader/trunk/startos.ini |
---|
24,15 → 24,15 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
; это комментарий |
; ýòî êîììåíòàðèé |
[loader] |
; секция [loader] содержит параметры загрузчика |
; в течение timeout секунд загрузчик будет ждать реакции пользователя, |
; если её не последует, будет загружена конфигурация, указанная в default |
; ñåêöèÿ [loader] ñîäåðæèò ïàðàìåòðû çàãðóç÷èêà |
; â òå÷åíèå timeout ñåêóíä çàãðóç÷èê áóäåò æäàòü ðåàêöèè ïîëüçîâàòåëÿ, |
; åñëè å¸ íå ïîñëåäóåò, áóäåò çàãðóæåíà êîíôèãóðàöèÿ, óêàçàííàÿ â default |
timeout=5 |
default=kolibri_EE |
; прочие секции - по одной на каждую конфигурацию |
; и по одной на каждый вторичный модуль |
; ïðî÷èå ñåêöèè - ïî îäíîé íà êàæäóþ êîíôèãóðàöèþ |
; è ïî îäíîé íà êàæäûé âòîðè÷íûé ìîäóëü |
[main] |
name="Kord OS v 0.00001" |
descript="This is x64 OS microkernel" |
/kernel/trunk/const.inc |
---|
330,7 → 330,7 |
twdw equ 0x2000 ;(CURRENT_TASK-window_data) |
std_application_base_address equ new_app_base |
RING0_STACK_SIZE equ (0x2000 - 512) ;512 байт для контекста FPU |
RING0_STACK_SIZE equ (0x2000 - 512) ;512 áàéò äëÿ êîíòåêñòà FPU |
REG_SS equ (RING0_STACK_SIZE-4) |
REG_APP_ESP equ (RING0_STACK_SIZE-8) |
/kernel/trunk/kernel.asm |
---|
84,7 → 84,6 |
include "proc32.inc" |
include "kglobals.inc" |
include "lang.inc" |
include "encoding.inc" |
include "const.inc" |
max_processes equ 255 |
495,9 → 494,9 |
; !!!! It`s dirty hack, fix it !!! |
; Bits of EDX : |
; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register |
; Bit 3116 During the SYSRET instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register |
; Bit 150 During the SYSCALL instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; mov edx, (os_code + 16) * 65536 + os_code |
3338,8 → 3337,8 |
;now counter in ecx |
;(edx:eax) esi:edi => edx:esi |
; Fast Call MSR can't be destroy |
; Но MSR_AMD_EFER можно изменять, т.к. в этом регистре лиш |
; включаются/выключаются расширенные возможности |
; ® MSR_AMD_EFER ¬®¦® ¨§¬¥ïâì, â.ª. ¢ í⮬ ॣ¨áâॠ«¨è |
; ¢ª«îç îâáï/¢ëª«îç îâáï à áè¨à¥ë¥ ¢®§¬®¦®á⨠|
cmp edx, MSR_SYSENTER_CS |
je @f |
cmp edx, MSR_SYSENTER_ESP |
/kernel/trunk/video/vga.inc |
---|
403,7 → 403,7 |
align 4 |
.no_mouseunder: |
shl ebx, 9 |
lea ebx, [ebx+ebx*4] ; умножение на 5 |
lea ebx, [ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov edi, edx |
add edi, [LFBAddress] ; + LFB address |
501,7 → 501,7 |
add eax, [temp.cx] |
and eax, 0xfff8 |
shl ebx, 9 |
lea ebx, [ebx+ebx*4]; умножение на 5 |
lea ebx, [ebx+ebx*4]; óìíîæåíèå íà 5 |
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov esi, ebx |
add esi, [LFBAddress] ; + LFB address |
/kernel/trunk/gui/event.inc |
---|
21,8 → 21,8 |
event_uid dd 0 |
endg |
EV_SPACE = 512 |
FreeEvents = event_start-EVENT.fd ; "виртуальный" event, используются только поля: |
; FreeEvents.fd=event_start и FreeEvents.bk=event_end |
FreeEvents = event_start-EVENT.fd ; "âèðòóàëüíûé" event, èñïîëüçóþòñÿ òîëüêî ïîëÿ: |
; FreeEvents.fd=event_start è FreeEvents.bk=event_end |
;----------------------------------------------------------------------------- |
align 4 |
init_events: ;; used from kernel.asm |
31,8 → 31,8 |
jz .fail |
; eax - current event, ebx - previos event below |
mov ecx, EV_SPACE ; current - in allocated space |
mov ebx, FreeEvents ; previos - начало списка |
push ebx ; оно же и конец потом будет |
mov ebx, FreeEvents ; previos - íà÷àëî ñïèñêà |
push ebx ; îíî æå è êîíåö ïîòîì áóäåò |
;-------------------------------------- |
align 4 |
@@: |
41,7 → 41,7 |
mov ebx, eax ; previos <- current |
add eax, sizeof.EVENT ; new current |
loop @b |
pop eax ; вот оно концом и стало |
pop eax ; âîò îíî êîíöîì è ñòàëî |
mov [ebx+EVENT.fd], eax |
mov [eax+EVENT.bk], ebx |
;-------------------------------------- |
49,16 → 49,16 |
.fail: |
ret |
;----------------------------------------------------------------------------- |
EVENT_WATCHED equ 0x10000000 ;бит 28 |
EVENT_SIGNALED equ 0x20000000 ;бит 29 |
MANUAL_RESET equ 0x40000000 ;бит 30 |
MANUAL_DESTROY equ 0x80000000 ;бит 31 |
EVENT_WATCHED equ 0x10000000 ;áèò 28 |
EVENT_SIGNALED equ 0x20000000 ;áèò 29 |
MANUAL_RESET equ 0x40000000 ;áèò 30 |
MANUAL_DESTROY equ 0x80000000 ;áèò 31 |
;----------------------------------------------------------------------------- |
align 4 |
create_event: ;; EXPORT use |
;info: |
; Переносим EVENT из списка FreeEvents в список ObjList текущего слота |
; EVENT.state устанавливаем из ecx, EVENT.code косвенно из esi (если esi<>0) |
; Ïåðåíîñèì EVENT èç ñïèñêà FreeEvents â ñïèñîê ObjList òåêóùåãî ñëîòà |
; EVENT.state óñòàíàâëèâàåì èç ecx, EVENT.code êîñâåííî èç esi (åñëè esi<>0) |
;param: |
; esi - event data |
; ecx - flags |
76,9 → 76,9 |
align 4 |
set_event: ;; INTERNAL use !!! don't use for Call |
;info: |
; Берем новый event из FreeEvents, заполняем его поля, как указано в ecx,edx,esi |
; и устанавливаем в список, указанный в ebx. |
; Возвращаем сам event (в eax), и его uid (в edx) |
; Áåðåì íîâûé event èç FreeEvents, çàïîëíÿåì åãî ïîëÿ, êàê óêàçàíî â ecx,edx,esi |
; è óñòàíàâëèâàåì â ñïèñîê, óêàçàííûé â ebx. |
; Âîçâðàùàåì ñàì event (â eax), è åãî uid (â edx) |
;param: |
; ebx - start-chain "virtual" event for entry new event Right of him |
; ecx - flags (copied to EVENT.state) |
115,13 → 115,13 |
align 4 |
RemoveEventTo: ;; INTERNAL use !!! don't use for Call |
;param: |
; eax - указатель на event, КОТОРЫЙ вставляем |
; ebx - указатель на event, ПОСЛЕ которого вставляем |
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì |
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì |
;scratched: ebx,ecx |
mov ecx, eax ; ecx=eax=Self, ebx=NewLeft |
xchg ecx, [ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight |
cmp eax, ecx ; стоп, себе думаю... |
je .break ; - а не дурак ли я? |
cmp eax, ecx ; ñòîï, ñåáå äóìàþ... |
je .break ; - à íå äóðàê ëè ÿ? |
mov [ecx+EVENT.bk], eax ; NewRight.bk=Self |
xchg ebx, [eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft |
xchg ecx, [eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight |
142,7 → 142,7 |
push edi |
;-------------------------------------- |
align 4 |
.small: ; криво как-то... |
.small: ; êðèâî êàê-òî... |
pop edi |
pushfd |
cli |
149,15 → 149,15 |
call pid_to_slot ; saved all registers (eax - retval) |
shl eax, 8 |
jz RemoveEventTo.break ; POPF+RET |
jmp edi ; штатный возврат |
jmp edi ; øòàòíûé âîçâðàò |
;----------------------------------------------------------------------------- |
align 4 |
raise_event: ;; EXPORT use |
;info: |
; Устанавливаем данные EVENT.code |
; Если там флаг EVENT_SIGNALED уже активен - больше ничего |
; Иначе: этот флаг взводится, за исключением случая наличия флага EVENT_WATCHED в edx |
; В этом случае EVENT_SIGNALED взводится лишь при наличие EVENT_WATCHED в самом событии |
; Óñòàíàâëèâàåì äàííûå EVENT.code |
; Åñëè òàì ôëàã EVENT_SIGNALED óæå àêòèâåí - áîëüøå íè÷åãî |
; Èíà÷å: ýòîò ôëàã âçâîäèòñÿ, çà èñêëþ÷åíèåì ñëó÷àÿ íàëè÷èÿ ôëàãà EVENT_WATCHED â edx |
;  ýòîì ñëó÷àå EVENT_SIGNALED âçâîäèòñÿ ëèøü ïðè íàëè÷èå EVENT_WATCHED â ñàìîì ñîáûòèè |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
205,8 → 205,8 |
align 4 |
send_event: ;; EXPORT use |
;info: |
; Создает новый EVENT (вытаскивает из списка FreeEvents) в списке EventList |
; целевого слота (eax=pid), с данными из esi косвенно, и state=EVENT_SIGNALED |
; Ñîçäàåò íîâûé EVENT (âûòàñêèâàåò èç ñïèñêà FreeEvents) â ñïèñêå EventList |
; öåëåâîãî ñëîòà (eax=pid), ñ äàííûìè èç esi êîñâåííî, è state=EVENT_SIGNALED |
;param: |
; eax - slots pid, to sending new event |
; esi - pointer to sending data (in code field of new event) |
251,24 → 251,24 |
align 4 |
Wait_events_ex: |
;info: |
; Ожидание "абстрактного" события через перевод слота в 5-ю позицию. |
; Абстрактность заключена в том, что факт события определяется функцией APPDATA.wait_test, |
; которая задается клиентом и может быть фактически любой. |
; Это позволяет shed-у надежно определить факт события, и не совершать "холостых" переключений, |
; предназначенных для разборок типа "свой/чужой" внутри задачи. |
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ. |
; Àáñòðàêòíîñòü çàêëþ÷åíà â òîì, ÷òî ôàêò ñîáûòèÿ îïðåäåëÿåòñÿ ôóíêöèåé APPDATA.wait_test, |
; êîòîðàÿ çàäàåòñÿ êëèåíòîì è ìîæåò áûòü ôàêòè÷åñêè ëþáîé. |
; Ýòî ïîçâîëÿåò shed-ó íàäåæíî îïðåäåëèòü ôàêò ñîáûòèÿ, è íå ñîâåðøàòü "õîëîñòûõ" ïåðåêëþ÷åíèé, |
; ïðåäíàçíà÷åííûõ äëÿ ðàçáîðîê òèïà "ñâîé/÷óæîé" âíóòðè çàäà÷è. |
;param: |
; edx - wait_test, клиентская ф-я тестирования (адрес кода) |
; ecx - wait_param, дополнительный параметр, возможно необходимый для [wait_test] |
; edx - wait_test, êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ (àäðåñ êîäà) |
; ecx - wait_param, äîïîëíèòåëüíûé ïàðàìåòð, âîçìîæíî íåîáõîäèìûé äëÿ [wait_test] |
; ebx - wait_timeout |
;retval: |
; eax - результат вызова [wait_test] (=0 => timeout) |
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout) |
;scratched: esi |
mov esi, [current_slot] |
mov [esi+APPDATA.wait_param], ecx |
pushad |
mov ebx, esi;пока это вопрос, чего куды сувать.......... |
pushfd ; это следствие общей концепции: пусть ф-я тестирования имеет |
cli ; право рассчитывать на закрытые прерывания, как при вызове из shed |
mov ebx, esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call edx |
popfd |
mov [esp+28], eax |
290,12 → 290,12 |
align 4 |
wait_event: ;; EXPORT use |
;info: |
; Ожидание флага EVENT_SIGNALED в совершенно конкретном Event |
; (устанавливаемого, надо полагать, через raise_event) |
; При активном флаге MANUAL_RESET - больше ничего |
; Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются, |
; и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота, |
; а при не активном - уничтожается штатно (destroy_event.internal) |
; Îæèäàíèå ôëàãà EVENT_SIGNALED â ñîâåðøåííî êîíêðåòíîì Event |
; (óñòàíàâëèâàåìîãî, íàäî ïîëàãàòü, ÷åðåç raise_event) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
326,16 → 326,16 |
align 4 |
get_event_ex: ;; f68:14 |
;info: |
; Ожидание любого события в очереди EventList текущего слота |
; Данные события code - копируются в память приложения (косвенно по edi) |
; При активном флаге MANUAL_RESET - больше ничего |
; Иначе: флаги EVENT_SIGNALED и EVENT_WATCHED у полученного события сбрасываются, |
; и, при активном MANUAL_DESTROY - перемещается в список ObjList текущего слота, |
; а при не активном - уничтожается штатно (destroy_event.internal) |
; Îæèäàíèå ëþáîãî ñîáûòèÿ â î÷åðåäè EventList òåêóùåãî ñëîòà |
; Äàííûå ñîáûòèÿ code - êîïèðóþòñÿ â ïàìÿòü ïðèëîæåíèÿ (êîñâåííî ïî edi) |
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî |
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ, |
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà, |
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal) |
;param: |
; edi - адрес в коде приложения для копирования данных из EVENT.code |
; edi - àäðåñ â êîäå ïðèëîæåíèÿ äëÿ êîïèðîâàíèÿ äàííûõ èç EVENT.code |
;retval: |
; eax - собственно EVENT (будем называть это его хэндлом) |
; eax - ñîáñòâåííî EVENT (áóäåì íàçûâàòü ýòî åãî õýíäëîì) |
;scratched: ebx,ecx,edx,esi,edi |
mov edx, get_event_queue ; wait_test |
call Wait_events ; timeout ignored |
361,12 → 361,12 |
align 4 |
destroy_event: ;; EXPORT use |
;info: |
; Переносим EVENT в список FreeEvents, чистим поля magic,destroy,pid,id |
; Ïåðåíîñèì EVENT â ñïèñîê FreeEvents, ÷èñòèì ïîëÿ magic,destroy,pid,id |
;param: |
; eax - event |
; ebx - uid (for Dummy testing) |
;retval: |
; eax - адрес объекта EVENT (=0 => fail) |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
;scratched: ebx,ecx |
call DummyTest ; not returned for fail !!! |
;-------------------------------------- |
385,17 → 385,17 |
align 4 |
get_event_queue: |
;info: |
; клиентская ф-я тестирования для get_event_ex |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ get_event_ex |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - адрес APPDATA слота тестирования |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - адрес объекта EVENT (=0 => fail) |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
add ebx, APP_EV_OFFSET |
mov eax, [ebx+APPOBJ.bk] ; выбираем с конца, по принципу FIFO |
mov eax, [ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO |
cmp eax, ebx ; empty ??? |
je get_event_alone.ret0 |
;-------------------------------------- |
406,15 → 406,15 |
align 4 |
get_event_alone: |
;info: |
; клиентская ф-я тестирования для wait_event |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ wait_event |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - адрес APPDATA слота тестирования |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - адрес объекта EVENT (=0 => fail) |
; eax - àäðåñ îáúåêòà EVENT (=0 => fail) |
mov eax, [ebx+APPDATA.wait_param] |
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24 |
jnz .ret |
458,7 → 458,7 |
;-------------------------------------- |
align 4 |
.result: |
setae byte[esp+32+4] ;считаем, что исходно: dword[esp+32+4]==72 |
setae byte[esp+32+4] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32+4]==72 |
;-------------------------------------- |
align 4 |
.retf: |
470,9 → 470,9 |
;----------------------------------------------------------------------------- |
align 4 |
sys_getevent: ;; f11 |
mov ebx, [current_slot];пока это вопрос, чего куды сувать.......... |
pushfd ; это следствие общей концепции: пусть ф-я тестирования имеет |
cli ; право рассчитывать на закрытые прерывания, как при вызове из shed |
mov ebx, [current_slot];ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü.......... |
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò |
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed |
call get_event_for_app |
popfd |
mov [esp+32], eax |
494,15 → 494,15 |
align 4 |
get_event_for_app: ;; used from f10,f11,f23 |
;info: |
; клиентская ф-я тестирования для приложений (f10,f23) |
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ ïðèëîæåíèé (f10,f23) |
;warning: |
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot |
; -may be assumed, that interrupt are disabled |
; -it is not restriction for scratched registers |
;param: |
; ebx - адрес APPDATA слота тестирования |
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ |
;retval: |
; eax - номер события (=0 => no events) |
; eax - íîìåð ñîáûòèÿ (=0 => no events) |
movzx edi, bh ; bh is assumed as [CURRENT_TASK] |
shl edi, 5 |
add edi, CURRENT_TASK ; edi is assumed as [TASK_BASE] |
510,11 → 510,11 |
and ecx, 0x7FFFFFFF |
;-------------------------------------- |
align 4 |
.loop: ; пока не исчерпаем все биты маски |
bsr eax, ecx ; находим ненулевой бит маски (31 -> 0) |
jz .no_events ; исчерпали все биты маски, но ничего не нашли ??? |
btr ecx, eax ; сбрасываем проверяемый бит маски |
; переходим на обработчик этого (eax) бита |
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè |
bsr eax, ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0) |
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ??? |
btr ecx, eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè |
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà |
cmp eax, 9 |
jae .loop ; eax=[9..31], ignored (event 10...32) |
/kernel/trunk/blkdev/cd_drv.inc |
---|
9,21 → 9,21 |
;********************************************************** |
; Непосредственная работа с устройством СD (ATAPI) |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI) |
;********************************************************** |
; Автор части исходного текста Кулаков Владимир Геннадьевич |
; Адаптация, доработка и разработка Mario79,<Lrz> |
; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷ |
; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz> |
; Максимальное количество повторений операции чтения |
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ |
MaxRetr equ 10 |
; Предельное время ожидания готовности к приему команды |
; (в тиках) |
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû |
; (â òèêàõ) |
BSYWaitTime equ 1000 ;2 |
NoTickWaitTime equ 0xfffff |
CDBlockSize equ 2048 |
;******************************************** |
;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * |
;* Многократное повторение чтения при сбоях * |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ * |
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ * |
;******************************************** |
ReadCDWRetr: |
;----------------------------------------------------------- |
85,34 → 85,34 |
ReadCDWRetr_1: |
pushad |
; Цикл, пока команда не выполнена успешно или не |
; исчерпано количество попыток |
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå |
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê |
mov ECX, MaxRetr |
@@NextRetr: |
; Подать команду |
; Ïîäàòü êîìàíäó |
;************************************************* |
;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * |
;* Считываются данные пользователя, информация * |
;* субканала и контрольная информация * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале; * |
;* CDSectorAddress - адрес считываемого сектора. * |
;* Данные считывается в массив CDDataBuf. * |
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ * |
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ * |
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. * |
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. * |
;************************************************* |
;ReadCD: |
push ecx |
; pusha |
; Задать размер сектора |
; Çàäàòü ðàçìåð ñåêòîðà |
; mov [CDBlockSize],2048 ;2352 |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Сформировать пакетную команду для считывания |
; сектора данных |
; Задать код команды Read CD |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
; Çàäàòü êîä êîìàíäû Read CD |
mov [PacketCommand], byte 0x28;0xBE |
; Задать адрес сектора |
; Çàäàòü àäðåñ ñåêòîðà |
mov AX, word [CDSectorAddress+2] |
xchg AL, AH |
mov word [PacketCommand+2], AX |
121,11 → 121,11 |
mov word [PacketCommand+4], AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
; Задать количество считываемых секторов |
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ |
mov [PacketCommand+8], byte 1 |
; Задать считывание данных в полном объеме |
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå |
; mov [PacketCommand+9],byte 0xF8 |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
pop ecx |
; ret |
147,7 → 147,7 |
jz @@NextRetr |
jmp .wait |
@@: |
; Задержка на 2,5 секунды |
; Çàäåðæêà íà 2,5 ñåêóíäû |
; mov EAX,[timer_ticks] |
; add EAX,50 ;250 |
;@@Wait: |
161,53 → 161,53 |
ret |
; Универсальные процедуры, обеспечивающие выполнение |
; пакетных команд в режиме PIO |
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå |
; ïàêåòíûõ êîìàíä â ðåæèìå PIO |
; Максимально допустимое время ожидания реакции |
; устройства на пакетную команду (в тиках) |
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè |
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ) |
MaxCDWaitTime equ 1000 ;200 ;10 секунд |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
uglobal |
; Область памяти для формирования пакетной команды |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: |
rb 12 ;DB 12 DUP (?) |
; Область памяти для приема данных от дисковода |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Размер принимаемого блока данных в байтах |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
;CDBlockSize DW ? |
; Адрес считываемого сектора данных |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: |
DD ? |
; Время начала очередной операции с диском |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Время начала ожидания готовности устройства |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
WURStartTime DD 0 |
; указатель буфера для считывания |
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ |
CDDataBuf_pointer dd 0 |
endg |
;**************************************************** |
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * |
;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале; * |
;* PacketCommand - 12-байтный командный пакет; * |
;* CDBlockSize - размер принимаемого блока данных. * |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; * |
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. * |
; return eax DevErrorCode |
;**************************************************** |
SendPacketDatCommand: |
xor eax, eax |
; mov byte [DevErrorCode],al |
; Задать режим CHS |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode], al |
; Послать ATA-команду передачи пакетной команды |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures], al |
mov byte [ATASectorCount], al |
mov byte [ATASectorNumber], al |
; Загрузить размер передаваемого блока |
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà |
mov [ATAHead], al |
; mov AX,[CDBlockSize] |
mov [ATACylinder], CDBlockSize |
214,13 → 214,13 |
mov [ATACommand], 0A0h |
call SendCommandToHDD_1 |
test eax, eax |
; cmp [DevErrorCode],0 ;проверить код ошибки |
jnz @@End_8 ;закончить, сохранив код ошибки |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Ожидание готовности дисковода к приему |
; пакетной команды |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
add DX, 7 ;ïîðò 1õ7h |
mov ecx, NoTickWaitTime |
@@WaitDevice0: |
cmp [timer_ticks_enable], 0 |
231,21 → 231,21 |
jmp .test |
@@: |
call change_task |
; Проверить время выполнения команды |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, BSYWaitTime |
ja @@Err1_1 ;ошибка тайм-аута |
; Проверить готовность |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test: |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0 |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6 |
test AL, 08h ;состояние сигнала DRQ |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0 |
; Послать пакетную команду |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
cli |
mov DX, [ATABasePortAddr] |
mov AX, [PacketCommand] |
261,9 → 261,9 |
mov AX, [PacketCommand+10] |
out DX, AX |
sti |
; Ожидание готовности данных |
; Îæèäàíèå ãîòîâíîñòè äàííûõ |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
add DX, 7 ;ïîðò 1õ7h |
mov ecx, NoTickWaitTime |
@@WaitDevice1: |
cmp [timer_ticks_enable], 0 |
274,40 → 274,40 |
jmp .test_1 |
@@: |
call change_task |
; Проверить время выполнения команды |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, MaxCDWaitTime |
ja @@Err1_1 ;ошибка тайм-аута |
; Проверить готовность |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
.test_1: |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1 |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_temp |
test AL, 08h ;состояние сигнала DRQ |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice1 |
; Принять блок данных от контроллера |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf |
; Загрузить адрес регистра данных контроллера |
mov DX, [ATABasePortAddr];порт 1x0h |
; Загрузить в счетчик размер блока в байтах |
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà |
mov DX, [ATABasePortAddr];ïîðò 1x0h |
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ |
xor ecx, ecx |
mov CX, CDBlockSize |
; Вычислить размер блока в 16-разрядных словах |
shr CX, 1;разделить размер блока на 2 |
; Принять блок данных |
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ |
shr CX, 1;ðàçäåëèòü ðàçìåð áëîêà íà 2 |
; Ïðèíÿòü áëîê äàííûõ |
cli |
cld |
rep insw |
sti |
; Успешное завершение приема данных |
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ |
@@End_8: |
xor eax, eax |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Err1_1: |
xor eax, eax |
inc eax |
329,21 → 329,21 |
;*********************************************** |
;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * |
;* Входные параметры передаются через * |
;* глобальные перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале; * |
;* PacketCommand - 12-байтный командный пакет. * |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç * |
;* ãëîáàëüíûå ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. * |
;*********************************************** |
SendPacketNoDatCommand: |
pushad |
xor eax, eax |
; mov byte [DevErrorCode],al |
; Задать режим CHS |
; Çàäàòü ðåæèì CHS |
mov byte [ATAAddressMode], al |
; Послать ATA-команду передачи пакетной команды |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov byte [ATAFeatures], al |
mov byte [ATASectorCount], al |
mov byte [ATASectorNumber], al |
351,29 → 351,29 |
mov byte [ATAHead], al |
mov [ATACommand], 0A0h |
call SendCommandToHDD_1 |
; cmp [DevErrorCode],0 ;проверить код ошибки |
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
test eax, eax |
jnz @@End_9 ;закончить, сохранив код ошибки |
; Ожидание готовности дисковода к приему |
; пакетной команды |
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
add DX, 7 ;ïîðò 1õ7h |
@@WaitDevice0_1: |
call change_task |
; Проверить время ожидания |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, BSYWaitTime |
ja @@Err1_3 ;ошибка тайм-аута |
; Проверить готовность |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0_1 |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL, 08h ;состояние сигнала DRQ |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0_1 |
; Послать пакетную команду |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
; cli |
mov DX, [ATABasePortAddr] |
mov AX, word [PacketCommand] |
391,29 → 391,29 |
; sti |
cmp [ignore_CD_eject_wait], 1 |
je @@clear_DEC |
; Ожидание подтверждения приема команды |
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
add DX, 7 ;ïîðò 1õ7h |
@@WaitDevice1_1: |
call change_task |
; Проверить время выполнения команды |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX, [timer_ticks] |
sub EAX, [TickCounter_1] |
cmp EAX, MaxCDWaitTime |
ja @@Err1_3 ;ошибка тайм-аута |
; Ожидать освобождения устройства |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1_1 |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL, 40h ;состояние сигнала DRDY |
test AL, 40h ;ñîñòîÿíèå ñèãíàëà DRDY |
jz @@WaitDevice1_1 |
@@clear_DEC: |
and [DevErrorCode], 0 |
popad |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Err1_3: |
xor eax, eax |
inc eax |
426,53 → 426,53 |
ret |
;**************************************************** |
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1); * |
;* ATAFeatures - "особенности"; * |
;* ATASectorCount - количество секторов; * |
;* ATASectorNumber - номер начального сектора; * |
;* ATACylinder - номер начального цилиндра; * |
;* ATAHead - номер начальной головки; * |
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
;* ATACommand - код команды. * |
;* После успешного выполнения функции: * |
;* в ATABasePortAddr - базовый адрес HDD; * |
;* в DevErrorCode - ноль. * |
;* При возникновении ошибки в DevErrorCode будет * |
;* возвращен код ошибки в eax * |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè â eax * |
;**************************************************** |
SendCommandToHDD_1: |
; pushad |
; mov [DevErrorCode],0 not need |
; Проверить значение кода режима |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode], 1 |
ja @@Err2_4 |
; Проверить корректность номера канала |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3_4 |
cmp BX, 2 |
ja @@Err3_4 |
; Установить базовый адрес |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov AX, [ebx+StandardATABases] |
mov [ATABasePortAddr], AX |
; Ожидание готовности HDD к приему команды |
; Выбрать нужный диск |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX, [ATABasePortAddr] |
add DX, 6 ;адрес регистра головок |
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_4 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Ожидать, пока диск не будет готов |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov eax, [timer_ticks] |
mov [TickCounter_1], eax |
486,43 → 486,43 |
jmp .test |
@@: |
call change_task |
; Проверить время ожидания |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov eax, [timer_ticks] |
sub eax, [TickCounter_1] |
cmp eax, BSYWaitTime;300 ;ожидать 3 сек. |
ja @@Err1_4 ;ошибка тайм-аута |
; Прочитать регистр состояния |
cmp eax, BSYWaitTime;300 ;îæèäàòü 3 ñåê. |
ja @@Err1_4 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
.test: |
in AL, DX |
; Проверить состояние сигнала BSY |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL, 80h |
jnz @@WaitHDReady_2 |
; Проверить состояние сигнала DRQ |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL, 08h |
jnz @@WaitHDReady_2 |
; Загрузить команду в регистры контроллера |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX, [ATABasePortAddr] |
inc DX ;регистр "особенностей" |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL, [ATAFeatures] |
out DX, AL |
inc DX ;счетчик секторов |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL, [ATASectorCount] |
out DX, AL |
inc DX ;регистр номера сектора |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL, [ATASectorNumber] |
out DX, AL |
inc DX ;номер цилиндра (младший байт) |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX, [ATACylinder] |
out DX, AL |
inc DX ;номер цилиндра (старший байт) |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL, AH |
out DX, AL |
inc DX ;номер головки/номер диска |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL, [DiskNumber] |
shl AL, 4 |
cmp [ATAHead], 0Fh;проверить номер головки |
cmp [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5_4 |
or AL, [ATAHead] |
or AL, 10100000b |
530,17 → 530,17 |
shl AH, 6 |
or AL, AH |
out DX, AL |
; Послать команду |
; Ïîñëàòü êîìàíäó |
mov AL, [ATACommand] |
inc DX ;регистр команд |
inc DX ;ðåãèñòð êîìàíä |
out DX, AL |
sti |
; Сбросить признак ошибки |
; Ñáðîñèòü ïðèçíàê îøèáêè |
; mov [DevErrorCode],0 |
@@End_10: |
xor eax, eax |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Err1_4: |
xor eax, eax |
inc eax |
561,31 → 561,31 |
@@Err5_4: |
mov eax, 5 |
; mov [DevErrorCode],5 |
; Завершение работы программы |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
; sti |
; popad |
;************************************************* |
;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
WaitUnitReady: |
pusha |
; Запомнить время начала операции |
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè |
mov EAX, [timer_ticks] |
mov [WURStartTime], EAX |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Сформировать команду TEST UNIT READY |
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY |
mov [PacketCommand], word 00h |
; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА |
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ |
mov ecx, NoTickWaitTime |
@@SendCommand: |
; Подать команду проверки готовности |
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè |
call SendPacketNoDatCommand |
cmp [timer_ticks_enable], 0 |
jne @f |
597,16 → 597,16 |
jmp @@SendCommand |
@@: |
call change_task |
; Проверить код ошибки |
; Ïðîâåðèòü êîä îøèáêè |
cmp [DevErrorCode], 0 |
je @@End_11 |
; Проверить время ожидания готовности |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè |
mov EAX, [timer_ticks] |
sub EAX, [WURStartTime] |
cmp EAX, MaxCDWaitTime |
jb @@SendCommand |
.Error: |
; Ошибка тайм-аута |
; Îøèáêà òàéì-àóòà |
mov [DevErrorCode], 1 |
@@End_11: |
popa |
613,21 → 613,21 |
ret |
;************************************************* |
;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
prevent_medium_removal: |
pusha |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Задать код команды |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand], byte 0x1E |
; Задать код запрета |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4], byte 11b |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax, ATAPI_IDE0_lock |
add eax, [cdpos] |
637,21 → 637,21 |
ret |
;************************************************* |
;* РАЗРЕШИТЬ СМЕНУ ДИСКА * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
allow_medium_removal: |
pusha |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Задать код команды |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand], byte 0x1E |
; Задать код запрета |
; Çàäàòü êîä çàïðåòà |
mov [PacketCommand+4], byte 00b |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
mov eax, ATAPI_IDE0_lock |
add eax, [cdpos] |
661,54 → 661,54 |
ret |
;************************************************* |
;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
LoadMedium: |
pusha |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Сформировать команду START/STOP UNIT |
; Задать код команды |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand], word 1Bh |
; Задать операцию загрузки носителя |
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ |
mov [PacketCommand+4], word 00000011b |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
EjectMedium: |
pusha |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Сформировать команду START/STOP UNIT |
; Задать код команды |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand], word 1Bh |
; Задать операцию извлечения носителя |
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ |
mov [PacketCommand+4], word 00000010b |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* Проверить событие нажатия кнопки извлечения * |
;* диска * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ * |
;* äèñêà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
proc check_ATAPI_device_event_has_work? |
mov eax, [timer_ticks] |
867,78 → 867,78 |
ignore_CD_eject_wait db 0 |
endg |
;************************************************* |
;* Получить сообщение о событии или состоянии * |
;* устройства * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè * |
;* óñòðîéñòâà * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
GetEvent_StatusNotification: |
pusha |
mov [CDDataBuf_pointer], CDDataBuf |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Задать код команды |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand], byte 4Ah |
mov [PacketCommand+1], byte 00000001b |
; Задать запрос класса сообщений |
; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé |
mov [PacketCommand+4], byte 00010000b |
; Размер выделенной области |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7], byte 8h |
mov [PacketCommand+8], byte 0h |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
; прочитать информацию из TOC |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
; ïðî÷èòàòü èíôîðìàöèþ èç TOC |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
Read_TOC: |
pusha |
mov [CDDataBuf_pointer], CDDataBuf |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Сформировать пакетную команду для считывания |
; сектора данных |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
mov [PacketCommand], byte 0x43 |
; Задать формат |
; Çàäàòü ôîðìàò |
mov [PacketCommand+2], byte 1 |
; Размер выделенной области |
; Ðàçìåð âûäåëåííîé îáëàñòè |
mov [PacketCommand+7], byte 0xFF |
mov [PacketCommand+8], byte 0h |
; Подать команду |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
;************************************************* |
;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
;ReadCapacity: |
; pusha |
;; Очистить буфер пакетной команды |
;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
; call clear_packet_buffer |
;; Задать размер буфера в байтах |
;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ |
; mov [CDBlockSize],8 |
;; Сформировать команду READ CAPACITY |
;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY |
; mov [PacketCommand],word 25h |
;; Подать команду |
;; Ïîäàòü êîìàíäó |
; call SendPacketDatCommand |
; popa |
; ret |
clear_packet_buffer: |
; Очистить буфер пакетной команды |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
and [PacketCommand], dword 0 |
and [PacketCommand+4], dword 0 |
and [PacketCommand+8], dword 0 |
/kernel/trunk/blkdev/flp_drv.inc |
---|
9,12 → 9,12 |
;********************************************************** |
; Непосредственная работа с контроллером гибкого диска |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Автор исходного текста Кулаков Владимир Геннадьевич. |
; Адаптация и доработка Mario79 |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
;give_back_application_data: ; переслать приложению |
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
; mov edi,[TASK_BASE] |
; mov edi,[edi+TASKDATA.mem_start] |
; add edi,ecx |
26,7 → 26,7 |
rep movsd |
ret |
;take_data_from_application: ; взять из приложени |
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
; mov esi,[TASK_BASE] |
; mov esi,[esi+TASKDATA.mem_start] |
; add esi,ecx |
38,37 → 38,37 |
rep movsd |
ret |
; Коды завершения операции с контроллером (FDC_Status) |
FDC_Normal equ 0 ;нормальное завершение |
FDC_TimeOut equ 1 ;ошибка тайм-аута |
FDC_DiskNotFound equ 2 ;в дисководе нет диска |
FDC_TrackNotFound equ 3 ;дорожка не найдена |
FDC_SectorNotFound equ 4 ;сектор не найден |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Максимальные значения координат сектора (заданные |
; значения соответствуют параметрам стандартного |
; трехдюймового гибкого диска объемом 1,44 Мб) |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Счетчик тиков таймера |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Код завершения операции с контроллером НГМД |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Флаг прерывания от НГМД |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Момент начала последней операции с НГМД |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Номер дисковода |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Координаты сектора |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Блок результата операции |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
76,18 → 76,18 |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Счетчик повторения операции чтени |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
ReadRepCounter DB ? |
; Счетчик повторения операции рекалибровки |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Область памяти для хранения прочитанного сектора |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД * |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
117,29 → 117,29 |
ret |
;*********************************** |
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC * |
;* Параметры: * |
;* AL - выводимый байт. * |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH, AL ;запомнить байт в AH |
; Сбросить переменную состояния контроллера |
mov AH, AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status], FDC_Normal |
; Проверить готовность контроллера к приему данных |
mov DX, 3F4h ;(порт состояния FDC) |
mov ecx, 0x10000 ;установить счетчик тайм-аута |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL, DX ;прочитать регистр RS |
and AL, 0C0h ;выделить разряды 6 и 7 |
cmp AL, 80h ;проверить разряды 6 и 7 |
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL, 0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL, 80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Ошибка тайм-аута |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status], FDC_TimeOut |
jmp @@End_5 |
; Вывести байт в порт данных |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL, AH |
150,29 → 150,29 |
ret |
;****************************************** |
;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC * |
;* Процедура не имеет входных параметров. * |
;* Выходные данные: * |
;* AL - считанный байт. * |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Сбросить переменную состояния контроллера |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status], FDC_Normal |
; Проверить готовность контроллера к передаче данных |
mov DX, 3F4h ;(порт состояния FDC) |
xor CX, CX ;установить счетчик тайм-аута |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX, CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL, DX ;прочитать регистр RS |
and AL, 0C0h ;выдлить разряды 6 и 7 |
cmp AL, 0C0h ;проверить разряды 6 и 7 |
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL, 0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL, 0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Ошибка тайм-аута |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status], FDC_TimeOut |
jmp @@End_6 |
; Ввести байт из порта данных |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL, DX |
182,17 → 182,17 |
ret |
;********************************************* |
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Установить флаг прерывани |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag], 1 |
ret |
;****************************************** |
;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ * |
;* НГМД * |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func], FDCInterrupt |
199,28 → 199,28 |
ret |
;******************************************* |
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Сбросить байт состояния операции |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status], FDC_Normal |
; Сбросить флаг прерывани |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag], 0 |
; Обнулить счетчик тиков |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax, [timer_ticks] |
mov [TickCounter], eax |
; Ожидать установки флага прерывания НГМД |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag], 0 |
jnz @@End_7 ;прерывание произошло |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax, [timer_ticks] |
sub eax, [TickCounter] |
cmp eax, 50 ;25 ;5 ;ожидать 5 тиков |
cmp eax, 50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Ошибка тайм-аута |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status], FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: |
228,7 → 228,7 |
ret |
;********************************* |
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
237,11 → 237,11 |
mov al, [flp_number] |
cmp [fdd_motor_status], al |
je fdd_motor_on |
; Произвести сброс контроллера НГМД |
mov DX, 3F2h;порт управления двигателями |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL, 0 |
out DX, AL |
; Выбрать и включить мотор дисковода |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number], 1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
252,10 → 252,10 |
mov AL, 2Dh ; Floppy B |
FDDMotorON_1: |
out DX, AL |
; Обнулить счетчик тиков |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax, [timer_ticks] |
mov [TickCounter], eax |
; Ожидать 0,5 с |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax, [timer_ticks] |
274,7 → 274,7 |
ret |
;***************************************** |
;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax, [timer_ticks] |
282,7 → 282,7 |
ret |
;***************************************** |
;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
proc check_fdd_motor_status_has_work? |
cmp [flp_status], 0 |
318,7 → 318,7 |
ret |
;********************************** |
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
332,35 → 332,35 |
FDDMotorOFF_2: |
pop DX |
pop AX |
; сброс флагов кеширования в связи с устареванием информации |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read], 0 |
mov [flp_fat], 0 |
ret |
FDDMotorOFF_A: |
mov DX, 3F2h;порт управления двигателями |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL, 0Ch ; Floppy A |
out DX, AL |
ret |
FDDMotorOFF_B: |
mov DX, 3F2h;порт управления двигателями |
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL, 5h ; Floppy B |
out DX, AL |
ret |
;******************************* |
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" * |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Подать команду "Рекалибровка" |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL, 07h |
call FDCDataOutput |
mov AL, 00h |
call FDCDataOutput |
; Ожидать завершения операции |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
371,30 → 371,30 |
ret |
;***************************************************** |
;* ПОИСК ДОРОЖКИ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1). * |
;* Результат операции заносится в FDC_Status. * |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Подать команду "Поиск" |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL, 0Fh |
call FDCDataOutput |
; Передать байт номера головки/накопител |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
mov AL, [FDD_Head] |
shl AL, 2 |
call FDCDataOutput |
; Передать байт номера дорожки |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL, [FDD_Track] |
call FDCDataOutput |
; Ожидать завершения операции |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit |
; Сохранить результат поиска |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL, 08h |
call FDCDataOutput |
call FDCDataInput |
401,24 → 401,24 |
mov [FDC_ST0], AL |
call FDCDataInput |
mov [FDC_C], AL |
; Проверить результат поиска |
; Поиск завершен? |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0], 100000b |
je @@Err |
; Заданный трек найден? |
; Çàäàííûé òðåê íàéäåí? |
mov AL, [FDC_C] |
cmp AL, [FDD_Track] |
jne @@Err |
; Номер головки совпадает с заданным? |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL, [FDC_ST0] |
and AL, 100b |
shr AL, 2 |
cmp AL, [FDD_Head] |
jne @@Err |
; Операция завершена успешно |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status], FDC_Normal |
jmp @@Exit |
@@Err: ; Трек не найден |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status], FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
427,27 → 427,27 |
ret |
;******************************************************* |
;* ЧТЕНИЕ СЕКТОРА ДАННЫХ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции чтения * |
;* содержимое сектора будет занесено в FDD_DataBuffer. * |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Установить скорость передачи 500 Кбайт/с |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX, 0 |
mov DX, 03F7h |
out DX, AL |
; Инициализировать канал прямого доступа к памяти |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode], 0x46 |
call Init_FDC_DMA |
; Подать команду "Чтение данных" |
mov AL, 0E6h ;чтение в мультитрековом режиме |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL, 0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL, [FDD_Head] |
shl AL, 2 |
458,19 → 458,19 |
call FDCDataOutput |
mov AL, [FDD_Sector] |
call FDCDataOutput |
mov AL, 2 ;код размера сектора (512 байт) |
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL, 18 ;+1; 3Fh ;число секторов на дорожке |
mov AL, 18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL, 1Bh ;значение GPL |
mov AL, 1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL, 0FFh;значение DTL |
mov AL, 0FFh;çíà÷åíèå DTL |
call FDCDataOutput |
; Ожидаем прерывание по завершении операции |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit_1 |
; Считываем статус завершения операции |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0], 11011000b |
jnz @@Err_1 |
485,21 → 485,21 |
ret |
;******************************************************* |
;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции чтения * |
;* содержимое сектора будет занесено в FDD_DataBuffer. * |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Обнулить счетчик повторения операции рекалибровки |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter], 0 |
@@TryAgain: |
; Обнулить счетчик повторения операции чтени |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter], 0 |
@@ReadSector_1: |
call ReadSector |
507,11 → 507,11 |
je @@Exit_2 |
cmp [FDC_Status], 1 |
je @@Err_3 |
; Троекратное повторение чтени |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter], 3 |
jb @@ReadSector_1 |
; Троекратное повторение рекалибровки |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
527,27 → 527,27 |
ret |
;******************************************************* |
;* ЗАПИСЬ СЕКТОРА ДАННЫХ * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции записи * |
;* содержимое FDD_DataBuffer будет занесено в сектор. * |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Установить скорость передачи 500 Кбайт/с |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX, 0 |
mov DX, 03F7h |
out DX, AL |
; Инициализировать канал прямого доступа к памяти |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode], 0x4A |
call Init_FDC_DMA |
; Подать команду "Запись данных" |
mov AL, 0xC5 ;0x45 ;запись в мультитрековом режиме |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL, 0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL, [FDD_Head] |
shl AL, 2 |
558,19 → 558,19 |
call FDCDataOutput |
mov AL, [FDD_Sector] |
call FDCDataOutput |
mov AL, 2 ;код размера сектора (512 байт) |
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL, 18; 3Fh ;число секторов на дорожке |
mov AL, 18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL, 1Bh ;значение GPL |
mov AL, 1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL, 0FFh;значение DTL |
mov AL, 0FFh;çíà÷åíèå DTL |
call FDCDataOutput |
; Ожидаем прерывание по завершении операции |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status], FDC_Normal |
jne @@Exit_3 |
; Считываем статус завершения операции |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0], 11000000b ;11011000b |
jnz @@Err_2 |
584,21 → 584,21 |
ret |
;******************************************************* |
;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
;* Параметры передаются через глобальные переменные: * |
;* FDD_Track - номер дорожки (0-79); * |
;* FDD_Head - номер головки (0-1); * |
;* FDD_Sector - номер сектора (1-18). * |
;* Результат операции заносится в FDC_Status. * |
;* В случае успешного выполнения операции записи * |
;* содержимое FDD_DataBuffer будет занесено в сектор. * |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Обнулить счетчик повторения операции рекалибровки |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter], 0 |
@@TryAgain_1: |
; Обнулить счетчик повторения операции чтени |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter], 0 |
@@WriteSector_1: |
call WriteSector |
606,11 → 606,11 |
je @@Exit_4 |
cmp [FDC_Status], 1 |
je @@Err_4 |
; Троекратное повторение чтени |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter], 3 |
jb @@WriteSector_1 |
; Троекратное повторение рекалибровки |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
625,7 → 625,7 |
ret |
;********************************************* |
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
/kernel/trunk/blkdev/rd.inc |
---|
346,10 → 346,10 |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 0xF0 ; 'Ё' |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 0xF1 ; 'ё' |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
389,9 → 389,9 |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 0xF0 ; 'Ё' |
cmp al, 'ð' |
jz .yo1 |
cmp al, 0xF1 ; 'ё' |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
411,16 → 411,16 |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, 0xF1 ; 'ё' |
cmp al, 'ñ' |
jz .yo1 |
cmp al, 0xA0 ; 'а' |
cmp al, ' ' |
jb .ret |
cmp al, 0xE0 ; 'р' |
cmp al, 'à' |
jb .rus1 |
cmp al, 0xEF ; 'я' |
cmp al, 'ï' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 0xE0-0x90 |
sub al, 'à'-'' |
.ret: |
ret |
.rus1: |
/kernel/trunk/blkdev/hd_drv.inc |
---|
109,28 → 109,28 |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al; ATAFeatures регистр "особенностей" |
out dx, al; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx, al; ATASectorCount счётчик секторов |
out dx, al; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
inc edx |
mov eax, [esp+4] |
out dx, al; ATASectorNumber регистр номера сектора |
out dx, al; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax, 8 |
inc edx |
out dx, al; ATACylinder номер цилиндра (младший байт) |
out dx, al; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax, 8 |
inc edx |
out dx, al; номер цилиндра (старший байт) |
out dx, al; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax, 8 |
inc edx |
and al, 1+2+4+8 |
add al, byte [hdid] |
add al, 128+64+32 |
out dx, al; номер головки/номер диска |
out dx, al; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al, 20h |
out dx, al; ATACommand регистр команд |
out dx, al; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
/kernel/trunk/blkdev/disk_cache.inc |
---|
397,7 → 397,7 |
mov dword [esi+8], 1 ; same as in hd |
mov eax, [esi] |
mov edx, [esi+4] ; edx:eax = sector to write |
; Объединяем запись цепочки последовательных секторов в одно обращение к диску |
; Îáúåäèíÿåì çàïèñü öåïî÷êè ïîñëåäîâàòåëüíûõ ñåêòîðîâ â îäíî îáðàùåíèå ê äèñêó |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+12+8], 2 |
/kernel/trunk/blkdev/ide_cache.inc |
---|
52,7 → 52,7 |
cmp [dma_hdd], 1 |
jnz .nodma |
@@: |
; Объединяем запись цепочки последовательных секторов в одно обращение к диску |
; ¡ê¥¤¨ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+8+4], 2 |
/kernel/trunk/blkdev/fdc.inc |
---|
37,9 → 37,9 |
call check_label |
cmp [FDC_Status], 0 |
jne unnecessary_save_image |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 0; Сторона |
mov [FDD_Sector], 1; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 0; Ñòîðîíà |
mov [FDD_Sector], 1; Ñåêòîð |
mov esi, RAMDISK |
call SeekTrack |
save_image_1: |
/kernel/trunk/core/memory.inc |
---|
631,21 → 631,21 |
mov eax, [pf_err_code] |
cmp ebx, OS_BASE ;ebx == .err_addr |
jb .user_space ;страница в памяти приложения ; |
jb .user_space ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ; |
cmp ebx, page_tabs |
jb .kernel_space ;страница в памяти ядра |
jb .kernel_space ;ñòðàíèöà â ïàìÿòè ÿäðà |
cmp ebx, kernel_tabs |
jb .alloc;.app_tabs ;таблицы страниц приложения ; |
;просто создадим одну |
if 0 ;пока это просто лишнее |
jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ; |
;ïðîñòî ñîçäàäèì îäíó |
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå |
cmp ebx, LFB_BASE |
jb .core_tabs ;таблицы страниц ядра |
;Ошибка |
jb .core_tabs ;òàáëèöû ñòðàíèö ÿäðà |
;Îøèáêà |
.lfb: |
;область LFB |
;Ошибка |
;îáëàñòü LFB |
;Îøèáêà |
jmp .fail |
end if |
.core_tabs: |
661,8 → 661,8 |
.user_space: |
test eax, PG_MAP |
jnz .err_access ;Страница присутствует |
;Ошибка доступа ? |
jnz .err_access ;Ñòðàíèöà ïðèñóòñòâóåò |
;Îøèáêà äîñòóïà ? |
shr ebx, 12 |
mov ecx, ebx |
669,13 → 669,13 |
shr ecx, 10 |
mov edx, [master_tab+ecx*4] |
test edx, PG_MAP |
jz .fail ;таблица страниц не создана |
;неверный адрес в программе |
jz .fail ;òàáëèöà ñòðàíèö íå ñîçäàíà |
;íåâåðíûé àäðåñ â ïðîãðàììå |
mov eax, [page_tabs+ebx*4] |
test eax, 2 |
jz .fail ;адрес не зарезервирован для ; |
;использования. Ошибка |
jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ; |
;èñïîëüçîâàíèÿ. Îøèáêà |
.alloc: |
call alloc_page |
test eax, eax |
731,16 → 731,16 |
.kernel_space: |
test eax, PG_MAP |
jz .fail ;страница не присутствует |
jz .fail ;ñòðàíèöà íå ïðèñóòñòâóåò |
test eax, 12 ;U/S (+below) |
jnz .fail ;приложение обратилось к памяти |
;ядра |
jnz .fail ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè |
;ÿäðà |
;test eax, 8 |
;jnz .fail ;установлен зарезервированный бит |
;в таблицах страниц. добавлено в P4/Xeon |
;jnz .fail ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò |
;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon |
;попытка записи в защищённую страницу ядра |
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà |
cmp ebx, tss._io_map_0 |
jb .fail |
/kernel/trunk/core/sched.inc |
---|
99,8 → 99,8 |
loop .newupdate |
ret |
;TODO: Надо бы убрать использование do_change_task из V86... |
; и после этого перенести обработку TASKDATA.counter_add/sum в do_change_task |
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86... |
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task |
align 4 |
do_change_task: |
/kernel/trunk/core/sys32.inc |
---|
61,7 → 61,7 |
idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data) |
dw 2*($-sys_int-4)-1 |
dd idts ;0x8000B100 |
dw 0 ;просто выравнивание |
dw 0 ;ïðîñòî âûðàâíèâàíèå |
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b |
dd msg_exc_c,msg_exc_d,msg_exc_e |
109,19 → 109,19 |
pf_err_code dd ? |
endg |
page_fault_exc: ; дуракоусточивость: селекторы испорчены... |
pop [ss:pf_err_code]; действительно до следующего #PF |
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû... |
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF |
save_ring3_context |
mov bl, 14 |
exc_c: ; исключения (все, кроме 7-го - #NM) |
; Фрэйм стека при исключении/прерывании из 3-го кольца + pushad (т.е., именно здесь) |
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM) |
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü) |
reg_ss equ esp+0x30 |
reg_esp3 equ esp+0x2C |
reg_eflags equ esp+0x28 |
reg_cs3 equ esp+0x24 |
reg_eip equ esp+0x20 |
; это фрэйм от pushad |
; ýòî ôðýéì îò pushad |
reg_eax equ esp+0x1C |
reg_ecx equ esp+0x18 |
reg_edx equ esp+0x14 |
131,10 → 131,10 |
reg_esi equ esp+0x04 |
reg_edi equ esp+0x00 |
mov ax, app_data ;исключение |
mov ds, ax ;загрузим правильные значения |
mov es, ax ;в регистры |
cld ; и приводим DF к стандарту |
mov ax, app_data ;èñêëþ÷åíèå |
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ |
mov es, ax ;â ðåãèñòðû |
cld ; è ïðèâîäèì DF ê ñòàíäàðòó |
movzx ebx, bl |
; redirect to V86 manager? (EFLAGS & 0x20000) != 0? |
test byte[reg_eflags+2], 2 |
290,12 → 290,12 |
ret |
; * eax = 64 - номер функции |
; * ebx = 1 - единственная подфункция |
; * ecx = новый размер памяти |
;Возвращаемое значение: |
; * eax = 0 - успешно |
; * eax = 1 - недостаточно памяти |
; * eax = 64 - íîìåð ôóíêöèè |
; * ebx = 1 - åäèíñòâåííàÿ ïîäôóíêöèÿ |
; * ecx = íîâûé ðàçìåð ïàìÿòè |
;Âîçâðàùàåìîå çíà÷åíèå: |
; * eax = 0 - óñïåøíî |
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè |
align 4 |
sys_resize_app_memory: |
685,6 → 685,17 |
ret |
restore .slot |
;iglobal |
;if lang eq ru |
; boot_sched_1 db '®§¤ ¨¥ GDT TSS 㪠§ ⥫ï',0 |
; boot_sched_2 db '®§¤ ¨¥ IDT â ¡«¨æë',0 |
;else |
; boot_sched_1 db 'Building gdt tss pointer',0 |
; boot_sched_2 db 'Building IDT table',0 |
;end if |
;endg |
;build_scheduler: |
; mov esi, boot_sched_1 |
; call boot_log |
/kernel/trunk/core/v86.inc |
---|
178,7 → 178,7 |
; esi=handle |
; out: eax=V86 address, para-aligned (0x10 multiple) |
; destroys: nothing |
; недописана!!! |
; ¥¤®¯¨á !!! |
;v86_alloc: |
; push ebx ecx edx edi |
; lea ebx, [esi+V86_machine.mutex] |
377,8 → 377,8 |
jnz .nogp |
; Otherwise we can safely access byte at CS:IP |
; (because it is #GP, not #PF handler) |
; Если бы мы могли схлопотать исключение только из-за чтения байтов кода, |
; мы бы его уже схлопотали и это было бы не #GP |
; ᫨ ¡ë ¬ë ¬®£«¨ áå«®¯®â âì ¨áª«î票¥ ⮫쪮 ¨§-§ çâ¥¨ï ¡ ©â®¢ ª®¤ , |
; ¬ë ¡ë ¥£® 㦥 áå«®¯®â «¨ ¨ íâ® ¡ë«® ¡ë ¥ #GP |
movzx esi, word [esp+v86_regs.cs] |
shl esi, 4 |
add esi, [esp+v86_regs.eip] |
/kernel/trunk/core/conf_lib.inc |
---|
164,7 → 164,7 |
proc strtoint_dec stdcall,strs |
pushad |
xor edx, edx |
; поиск конца |
; ¯®¨áª ª®æ |
mov esi, [strs] |
@@: |
lodsb |
180,7 → 180,7 |
dec ebx |
or ebx, ebx |
jz @f |
imul ecx, ecx, 10; порядок |
imul ecx, ecx, 10; ¯®à冷ª |
jmp @b |
@@: |
/kernel/trunk/core/conf_lib-sp.inc |
---|
1,11 → 1,11 |
; Éste archivo debe ser editado con codificación CP866 |
; ste archivo debe ser editado con codificaci¢n CP866 |
ugui_mouse_speed:cp850 'velocidad del ratón',0 |
ugui_mouse_delay:cp850 'demora del ratón',0 |
ugui_mouse_speed db 'velocidad del rat¢n',0 |
ugui_mouse_delay db 'demora del rat¢n',0 |
udev:cp850 'disp',0 |
unet:cp850 'red',0 |
unet_active:cp850 'activa',0 |
unet_addr:cp850 'direc',0 |
unet_mask:cp850 'másc',0 |
unet_gate:cp850 'puer',0 |
udev db 'disp',0 |
unet db 'red',0 |
unet_active db 'activa',0 |
unet_addr db 'direc',0 |
unet_mask db 'm sc',0 |
unet_gate db 'puer',0 |
/kernel/trunk/core/sys32-sp.inc |
---|
1,4 → 1,4 |
; Éste archivo debe ser editado con codificación CP866 |
; ste archivo debe ser editado con codificaci¢n CP866 |
msg_sel_ker: cp850 "núcleo", 0 |
msg_sel_app: cp850 "aplicación", 0 |
msg_sel_ker db "n£cleo", 0 |
msg_sel_app db "aplicaci¢n", 0 |
/kernel/trunk/core/syscall.inc |
---|
29,7 → 29,7 |
align 32 |
sysenter_entry: |
; Настраиваем стек |
; Íàñòðàèâàåì ñòåê |
mov esp, [ss:tss._esp0] |
sti |
push ebp ; save app esp + 4 |
47,7 → 47,7 |
call unprotect_from_terminate |
popad |
;------------------ |
xchg ecx, [ss:esp] ; в вершин стека - app ecx, ecx - app esp + 4 |
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4 |
sub ecx, 4 |
xchg edx, [ecx] ; edx - return point, & save original edx |
push edx |
/kernel/trunk/data32.inc |
---|
49,43 → 49,43 |
if lang eq ru |
boot_initirq: cp866 'Инициализация IRQ',0 |
boot_picinit: cp866 'Инициализация PIC',0 |
boot_v86machine: cp866 'Инициализация системы V86 машины',0 |
boot_inittimer: cp866 'Инициализация системного таймера (IRQ0)',0 |
boot_initapic: cp866 'Попытка инициализации APIC',0 |
boot_enableirq: cp866 'Включить прерывания 2, 6, 13, 14, 15',0 |
boot_enablint_ide:cp866 'Разрешение прерываний в контроллере IDE',0 |
boot_detectfloppy:cp866 'Поиск floppy дисководов',0 |
boot_detecthdcd: cp866 'Поиск жестких дисков и ATAPI приводов',0 |
boot_getcache: cp866 'Получение памяти для кэша',0 |
boot_detectpart: cp866 'Поиск разделов на дисковых устройствах',0 |
boot_init_sys: cp866 'Инициализация системного каталога /sys',0 |
boot_loadlibs: cp866 'Загрузка библиотек (.obj)',0 |
boot_memdetect: cp866 'Количество оперативной памяти',' ',' Мб',0 |
boot_tss: cp866 'Установка TSSs',0 |
boot_cpuid: cp866 'Чтение CPUIDs',0 |
; boot_devices: cp866 'Поиск устройств',0 |
boot_timer: cp866 'Установка таймера',0 |
boot_irqs: cp866 'Переопределение IRQ',0 |
boot_setmouse: cp866 'Установка мыши',0 |
boot_windefs: cp866 'Установка настроек окон по умолчанию',0 |
boot_bgr: cp866 'Установка фона',0 |
boot_resirqports: cp866 'Резервирование IRQ и портов',0 |
boot_setrports: cp866 'Установка адресов IRQ',0 |
boot_setostask: cp866 'Создание процесса ядра',0 |
boot_allirqs: cp866 'Открытие всех IRQ',0 |
boot_tsc: cp866 'Чтение TSC',0 |
boot_cpufreq: cp866 'Частота процессора ',' ',' МГц',0 |
boot_pal_ega: cp866 'Установка EGA/CGA 320x200 палитры',0 |
boot_pal_vga: cp866 'Установка VGA 640x480 палитры',0 |
boot_failed: cp866 'Загрузка первого приложения не удалась',0 |
boot_mtrr: cp866 'Установка MTRR',0 |
boot_initirq db '¨æ¨ «¨§ æ¨ï IRQ',0 |
boot_picinit db '¨æ¨ «¨§ æ¨ï PIC',0 |
boot_v86machine db '¨æ¨ «¨§ æ¨ï á¨á⥬ë V86 ¬ è¨ë',0 |
boot_inittimer db '¨æ¨ «¨§ æ¨ï á¨á⥬®£® â ©¬¥à (IRQ0)',0 |
boot_initapic db '®¯ë⪠¨¨æ¨ «¨§ 樨 APIC',0 |
boot_enableirq db 'ª«îç¨âì ¯à¥àë¢ ¨ï 2, 6, 13, 14, 15',0 |
boot_enablint_ide db ' §à¥è¥¨¥ ¯à¥àë¢ ¨© ¢ ª®â஫«¥à¥ IDE',0 |
boot_detectfloppy db '®¨áª floppy ¤¨áª®¢®¤®¢',0 |
boot_detecthdcd db '®¨áª ¦¥áâª¨å ¤¨áª®¢ ¨ ATAPI ¯à¨¢®¤®¢',0 |
boot_getcache db '®«ã票¥ ¯ ¬ï⨠¤«ï ªíè ',0 |
boot_detectpart db '®¨áª à §¤¥«®¢ ¤¨áª®¢ëå ãáâனá⢠å',0 |
boot_init_sys db '¨æ¨ «¨§ æ¨ï á¨á⥬®£® ª â «®£ /sys',0 |
boot_loadlibs db ' £à㧪 ¡¨¡«¨®â¥ª (.obj)',0 |
boot_memdetect db '®«¨ç¥á⢮ ®¯¥à ⨢®© ¯ ¬ïâ¨',' ',' ¡',0 |
boot_tss db 'áâ ®¢ª TSSs',0 |
boot_cpuid db '⥨¥ CPUIDs',0 |
; boot_devices db '®¨áª ãáâனáâ¢',0 |
boot_timer db 'áâ ®¢ª â ©¬¥à ',0 |
boot_irqs db '¥à¥®¯à¥¤¥«¥¨¥ IRQ',0 |
boot_setmouse db 'áâ ®¢ª ¬ëè¨',0 |
boot_windefs db 'áâ ®¢ª áâ஥ª ®ª® ¯® 㬮«ç ¨î',0 |
boot_bgr db 'áâ ®¢ª ä® ',0 |
boot_resirqports db '¥§¥à¢¨à®¢ ¨¥ IRQ ¨ ¯®à⮢',0 |
boot_setrports db 'áâ ®¢ª ¤à¥á®¢ IRQ',0 |
boot_setostask db '®§¤ ¨¥ ¯à®æ¥áá ï¤à ',0 |
boot_allirqs db 'âªàë⨥ ¢á¥å IRQ',0 |
boot_tsc db '⥨¥ TSC',0 |
boot_cpufreq db ' áâ®â ¯à®æ¥áá®à ',' ',' æ',0 |
boot_pal_ega db 'áâ ®¢ª EGA/CGA 320x200 ¯ «¨âàë',0 |
boot_pal_vga db 'áâ ®¢ª VGA 640x480 ¯ «¨âàë',0 |
boot_failed db ' £à㧪 ¯¥à¢®£® ¯à¨«®¦¥¨ï ¥ 㤠« áì',0 |
boot_mtrr db 'áâ ®¢ª MTRR',0 |
boot_APIC_found: cp866 'APIC включен', 0 |
boot_APIC_nfound: cp866 'APIC не найден', 0 |
boot_APIC_found db 'APIC ¢ª«îç¥', 0 |
boot_APIC_nfound db 'APIC ¥ ©¤¥', 0 |
if preboot_blogesc |
boot_tasking: cp866 'Все готово для запуска, нажмитре ESC для старта',0 |
boot_tasking db 'ᥠ£®â®¢® ¤«ï § ¯ã᪠, ¦¬¨âॠESC ¤«ï áâ àâ ',0 |
end if |
else if lang eq sp |
include 'data32sp.inc' |
159,7 → 159,7 |
firstapp db 'LAUNCHER',0 |
notifyapp db '@notify',0 |
if lang eq ru |
ud_user_message: cp866 'Ошибка: неподдерживаемая инструкция процессора',0 |
ud_user_message db '訡ª : ¥¯®¤¤¥à¦¨¢ ¥¬ ï ¨áâàãªæ¨ï ¯à®æ¥áá®à ',0 |
else if ~ lang eq sp |
ud_user_message db 'Error: unsupported processor instruction',0 |
end if |
/kernel/trunk/detect/sear_par.inc |
---|
9,9 → 9,9 |
;**************************************************** |
; поиск логических дисков на обнаруженных HDD |
; и занесение данных в область таблицы |
; автор Mario79 |
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD |
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû |
; àâòîð Mario79 |
;**************************************************** |
mov [transfer_adress], DRIVE_DATA+0xa |
search_partitions_ide0: |
/kernel/trunk/detect/dev_fd.inc |
---|
9,9 → 9,9 |
;*************************************************** |
; предварительная очистка области таблицы |
; поиск и занесение в таблицу приводов FDD |
; автор Mario79 |
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû |
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD |
; àâòîð Mario79 |
;*************************************************** |
xor eax, eax |
mov edi, DRIVE_DATA |
/kernel/trunk/detect/dev_hdcd.inc |
---|
9,13 → 9,13 |
;****************************************************** |
; поиск приводов HDD и CD |
; автор исходного текста Кулаков Владимир Геннадьевич. |
; адаптация и доработка Mario79 |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
;****************************************************** |
;**************************************************** |
;* ПОИСК HDD и CD * |
;* ÏÎÈÑÊ HDD è CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber], 1 |
71,54 → 71,54 |
ret |
; Адрес считываемого сектора в режиме LBA |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
uglobal |
SectorAddress DD ? |
endg |
;************************************************* |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска на канале (0 или 1). * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Задать режим CHS |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode], 0 |
; Послать команду идентификации устройства |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures], 0 |
mov [ATAHead], 0 |
mov [ATACommand], 0ECh |
call SendCommandToHDD |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End ;закончить, сохранив код ошибки |
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè |
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
mov DX, [ATABasePortAddr] |
add DX, 7 ;адрес регистра состояни |
add DX, 7 ;àäðåñ ðåãèñòðà ñîñòîÿíè |
mov ecx, 0xffff |
@@WaitCompleet: |
; Проверить время выполнения команды |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
dec ecx |
; cmp ecx,0 |
jz @@Error1 ;ошибка тайм-аута |
; Проверить готовность |
jz @@Error1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6 |
test AL, 08h ;состояние сигнала DRQ |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet |
; Принять блок данных от контроллера |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];регистр данных |
mov CX, 256 ;число считываемых слов |
rep insw ;принять блок данных |
mov DX, [ATABasePortAddr];ðåãèñòð äàííûõ |
mov CX, 256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw ;ïðèíÿòü áëîê äàííûõ |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Error1: |
mov [DevErrorCode], 1 |
ret |
129,120 → 129,120 |
iglobal |
; Стандартные базовые адреса каналов 1 и 2 |
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2 |
StandardATABases DW 1F0h, 170h |
endg |
uglobal |
; Номер канала |
; Íîìåð êàíàëà |
ChannelNumber DW ? |
; Номер диска |
; Íîìåð äèñêà |
DiskNumber DB ? |
; Базовый адрес группы портов контроллера ATA |
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA |
ATABasePortAddr DW ? |
; Параметры ATA-команды |
ATAFeatures DB ? ;особенности |
ATASectorCount DB ? ;количество обрабатываемых секторов |
ATASectorNumber DB ? ;номер начального сектора |
ATACylinder DW ? ;номер начального цилиндра |
ATAHead DB ? ;номер начальной головки |
ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) |
ATACommand DB ? ;код команды, подлежащей выполнению |
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый |
; интервал ожидания, 2 - неверный код режима адресации, |
; 3 - неверный номер канала, 4 - неверный номер диска, |
; 5 - неверный номер головки, 6 - ошибка при выполнении |
; команды) |
; Ïàðàìåòðû ATA-êîìàíäû |
ATAFeatures DB ? ;îñîáåííîñòè |
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ |
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà |
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà |
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè |
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA) |
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ |
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé |
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè, |
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà, |
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè |
; êîìàíäû) |
DevErrorCode dd ? |
endg |
;**************************************************** |
;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1); * |
;* ATAFeatures - "особенности"; * |
;* ATASectorCount - количество секторов; * |
;* ATASectorNumber - номер начального сектора; * |
;* ATACylinder - номер начального цилиндра; * |
;* ATAHead - номер начальной головки; * |
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
;* ATACommand - код команды. * |
;* После успешного выполнения функции: * |
;* в ATABasePortAddr - базовый адрес HDD; * |
;* в DevErrorCode - ноль. * |
;* При возникновении ошибки в DevErrorCode будет * |
;* возвращен код ошибки. * |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD: |
; Проверить значение кода режима |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode], 1 |
ja @@Err2 |
; Проверить корректность номера канала |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3 |
cmp BX, 2 |
ja @@Err3 |
; Установить базовый адрес |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov AX, [ebx+StandardATABases] |
mov [ATABasePortAddr], AX |
; Ожидание готовности HDD к приему команды |
; Выбрать нужный диск |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX, [ATABasePortAddr] |
add DX, 6 ;адрес регистра головок |
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Ожидать, пока диск не будет готов |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov ecx, 0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Проверить время ожидани |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
; cmp ecx,0 |
jz @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;ожидать 300 тиков |
; ja @@Err1 ;ошибка тайм-аута |
; Прочитать регистр состояни |
; cmp eax,300 ;îæèäàòü 300 òèêîâ |
; ja @@Err1 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL, DX |
; Проверить состояние сигнала BSY |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL, 80h |
jnz @@WaitHDReady |
; Проверить состояние сигнала DRQ |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL, 08h |
jnz @@WaitHDReady |
; Загрузить команду в регистры контроллера |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX, [ATABasePortAddr] |
inc DX ;регистр "особенностей" |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL, [ATAFeatures] |
out DX, AL |
inc DX ;счетчик секторов |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL, [ATASectorCount] |
out DX, AL |
inc DX ;регистр номера сектора |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL, [ATASectorNumber] |
out DX, AL |
inc DX ;номер цилиндра (младший байт) |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX, [ATACylinder] |
out DX, AL |
inc DX ;номер цилиндра (старший байт) |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL, AH |
out DX, AL |
inc DX ;номер головки/номер диска |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL, [DiskNumber] |
shl AL, 4 |
cmp [ATAHead], 0Fh;проверить номер головки |
cmp [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5 |
or AL, [ATAHead] |
or AL, 10100000b |
250,15 → 250,15 |
shl AH, 6 |
or AL, AH |
out DX, AL |
; Послать команду |
; Ïîñëàòü êîìàíäó |
mov AL, [ATACommand] |
inc DX ;регистр команд |
inc DX ;ðåãèñòð êîìàíä |
out DX, AL |
sti |
; Сбросить признак ошибки |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode], 0 |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Err1: |
mov [DevErrorCode], 1 |
ret |
273,22 → 273,22 |
ret |
@@Err5: |
mov [DevErrorCode], 5 |
; Завершение работы программы |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
ret |
;************************************************* |
;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * |
;* Входные параметры передаются через глобальные * |
;* перменные: * |
;* ChannelNumber - номер канала; * |
;* DiskNumber - номер диска на канале. * |
;* Идентификационный блок данных считывается * |
;* в массив Sector512. * |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadCD_ID: |
; Задать режим CHS |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode], 0 |
; Послать команду идентификации устройства |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures], 0 |
mov [ATASectorCount], 0 |
mov [ATASectorNumber], 0 |
296,34 → 296,34 |
mov [ATAHead], 0 |
mov [ATACommand], 0A1h |
call SendCommandToHDD |
cmp [DevErrorCode], 0;проверить код ошибки |
jne @@End_1 ;закончить, сохранив код ошибки |
; Ожидать готовность данных HDD |
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè |
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD |
mov DX, [ATABasePortAddr] |
add DX, 7 ;порт 1х7h |
add DX, 7 ;ïîðò 1õ7h |
mov ecx, 0xffff |
@@WaitCompleet_1: |
; Проверить врем |
; Ïðîâåðèòü âðåì |
dec ecx |
; cmp ecx,0 |
jz @@Error1_1 ;ошибка тайм-аута |
; Проверить готовность |
jz @@Error1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL, DX |
test AL, 80h ;состояние сигнала BSY |
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet_1 |
test AL, 1 ;состояние сигнала ERR |
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6_1 |
test AL, 08h ;состояние сигнала DRQ |
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet_1 |
; Принять блок данных от контроллера |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI, Sector512 ;offset Sector512 |
mov DX, [ATABasePortAddr];порт 1x0h |
mov CX, 256;число считываемых слов |
mov DX, [ATABasePortAddr];ïîðò 1x0h |
mov CX, 256;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw |
ret |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
@@Error1_1: |
mov [DevErrorCode], 1 |
ret |
333,52 → 333,52 |
ret |
;************************************************* |
;* СБРОС УСТРОЙСТВА * |
;* Входные параметры передаются через глобальные * |
;* переменные: * |
;* ChannelNumber - номер канала (1 или 2); * |
;* DiskNumber - номер диска (0 или 1). * |
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1). * |
;************************************************* |
DeviceReset: |
; Проверить корректность номера канала |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX, [ChannelNumber] |
cmp BX, 1 |
jb @@Err3_2 |
cmp BX, 2 |
ja @@Err3_2 |
; Установить базовый адрес |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX, 1 |
movzx ebx, bx |
mov DX, [ebx+StandardATABases] |
mov [ATABasePortAddr], DX |
; Выбрать нужный диск |
add DX, 6 ;адрес регистра головок |
; Âûáðàòü íóæíûé äèñê |
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL, [DiskNumber] |
cmp AL, 1 ;проверить номера диска |
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_2 |
shl AL, 4 |
or AL, 10100000b |
out DX, AL |
; Послать команду "Сброс" |
; Ïîñëàòü êîìàíäó "Ñáðîñ" |
mov AL, 08h |
inc DX ;регистр команд |
inc DX ;ðåãèñòð êîìàíä |
out DX, AL |
mov ecx, 0x80000 |
@@WaitHDReady_1: |
; Проверить время ожидани |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
; cmp ecx,0 |
je @@Err1_2 ;ошибка тайм-аута |
; Прочитать регистр состояни |
je @@Err1_2 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL, DX |
; Проверить состояние сигнала BSY |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL, 80h |
jnz @@WaitHDReady_1 |
; Сбросить признак ошибки |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode], 0 |
ret |
; Обработка ошибок |
; Îáðàáîòêà îøèáîê |
@@Err1_2: |
mov [DevErrorCode], 1 |
ret |
387,7 → 387,7 |
ret |
@@Err4_2: |
mov [DevErrorCode], 4 |
; Записать код ошибки |
; Çàïèñàòü êîä îøèáêè |
ret |
EndFindHDD: |
/kernel/trunk/docs/sysfuncr.txt |
---|
5,2667 → 5,2667 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
СИСТЕМНЫЕ ФУНКЦИИ ОПЕРАЦИОННОЙ СИСТЕМЫ Kolibri 0.7.7.0 |
Kolibri 0.7.7.0 |
Номер функции помещается в регистр eax. |
Вызов системной функции осуществляется командой "int 0x40". |
Все регистры, кроме явно указанных в возвращаемом значении, |
включая регистр флагов eflags, сохраняются. |
®¬¥à äãªæ¨¨ ¯®¬¥é ¥âáï ¢ ॣ¨áâà eax. |
맮¢ á¨á⥬®© äãªæ¨¨ ®áãé¥á⢫ï¥âáï ª®¬ ¤®© "int 0x40". |
ᥠॣ¨áâàë, ªà®¬¥  㪠§ ëå ¢ ¢®§¢à é ¥¬®¬ § 票¨, |
¢ª«îç ï ॣ¨áâà ä« £®¢ eflags, á®åà ïîâáï. |
====================================================================== |
============== Функция 0 - определить и нарисовать окно. ============= |
============== ãªæ¨ï 0 - ®¯à¥¤¥«¨âì ¨ à¨á®¢ âì ®ª®. ============= |
====================================================================== |
Определяет окно приложения. Рисует рамку окна, заголовок и рабочую |
область. Для окон со скином определяет стандартные кнопки закрытия и |
минимизации. |
Параметры: |
* eax = 0 - номер функции |
* ebx = [координата по оси x]*65536 + [размер по оси x] |
* ecx = [координата по оси y]*65536 + [размер по оси y] |
* edx = 0xXYRRGGBB, где: |
* Y = стиль окна: |
* Y=0 - тип I - окно фиксированных размеров |
* Y=1 - только определить область окна, ничего не рисовать |
* Y=2 - тип II - окно изменяемых размеров |
* Y=3 - окно со скином |
* Y=4 - окно со скином фиксированных размеров |
* остальные возможные значения (от 5 до 15) зарезервированы, |
вызов функции с такими Y игнорируется |
* RR, GG, BB = соответственно красная, зеленая, синяя |
составляющие цвета рабочей области окна |
(игнорируется для стиля Y=2) |
* X = DCBA (биты) |
* A = 1 - у окна есть заголовок; для стилей Y=3,4 адрес строки |
заголовка задаётся в edi, для прочих стилей |
используется подфункция 1 функции 71 |
* B = 1 - координаты всех графических примитивов задаются |
относительно клиентской области окна |
* C = 1 - не закрашивать рабочую область при отрисовке окна |
* D = 0 - нормальная заливка рабочей области, 1 - градиентная |
Следующие параметры предназначены для окон типа I и II и |
игнорируются для стилей Y=1,3: |
* esi = 0xXYRRGGBB - цвет заголовка |
* RR, GG, BB определяют сам цвет |
* Y=0 - обычное окно, Y=1 - неперемещаемое окно |
* X определяет градиент заголовка: X=0 - нет градиента, |
X=8 - обычный градиент, |
для окон типа II X=4 - негативный градиент |
* прочие значения X и Y зарезервированы |
* edi = 0x00RRGGBB - цвет рамки |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Положение и размеры окна устанавливаются при первом вызове |
этой функции и игнорируются при последующих; для изменения |
положения и/или размеров уже созданного окна используйте |
67-ю функцию. |
* Для окон стилей Y=3,4 с заголовком (A=1) строка заголовка |
устанавливается при первом вызове этой функции и игнорируется при |
последующих (точнее говоря, игнорируется после вызова |
подфункции 2 функции 12 - конца перерисовки); |
для изменения строки заголовка уже созданного окна используйте |
подфункцию 1 функции 71. |
* Если использовать окна соответствующих стилей, то положение |
и/или размеры окна могут меняться пользователем. |
Текущие положение и размеры могут быть получены вызовом функции 9. |
* Окно должно умещаться на экране. Если переданные координаты |
и размеры не удовлетворяют этому условию, то соответствующая |
координата (или, возможно, обе) считается нулем, а если и это |
не помогает, то соответствующий размер (или, возможно, оба) |
устанавливается в размер экрана. |
¯à¥¤¥«ï¥â ®ª® ¯à¨«®¦¥¨ï. ¨áã¥â à ¬ªã ®ª , § £®«®¢®ª ¨ à ¡®çãî |
®¡« áâì. «ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥â áâ ¤ àâë¥ ª®¯ª¨ § ªàëâ¨ï ¨ |
¬¨¨¬¨§ 樨. |
à ¬¥âàë: |
* eax = 0 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYRRGGBB, £¤¥: |
* Y = áâ¨«ì ®ª : |
* Y=0 - ⨯ I - ®ª® 䨪á¨à®¢ ëå à §¬¥à®¢ |
* Y=1 - ⮫쪮 ®¯à¥¤¥«¨âì ®¡« áâì ®ª , ¨ç¥£® ¥ à¨á®¢ âì |
* Y=2 - ⨯ II - ®ª® ¨§¬¥ï¥¬ëå à §¬¥à®¢ |
* Y=3 - ®ª® ᮠ᪨®¬ |
* Y=4 - ®ª® ᮠ᪨®¬ 䨪á¨à®¢ ëå à §¬¥à®¢ |
* ®áâ «ìë¥ ¢®§¬®¦ë¥ § 票ï (®â 5 ¤® 15) § १¥à¢¨à®¢ ë, |
¢ë§®¢ äãªæ¨¨ á â ª¨¬¨ Y ¨£®à¨àã¥âáï |
* RR, GG, BB = ᮮ⢥âá⢥® ªà á ï, §¥«¥ ï, á¨ïï |
á®áâ ¢«ïî騥 梥â à ¡®ç¥© ®¡« á⨠®ª |
(¨£®à¨àã¥âáï ¤«ï á⨫ï Y=2) |
* X = DCBA (¡¨âë) |
* A = 1 - ã ®ª ¥áâì § £®«®¢®ª; ¤«ï á⨫¥© Y=3,4 ¤à¥á áâப¨ |
§ £®«®¢ª § ¤ ñâáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥© |
¨á¯®«ì§ã¥âáï ¯®¤äãªæ¨ï 1 äãªæ¨¨ 71 |
* B = 1 - ª®®à¤¨ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï |
®â®á¨â¥«ì® ª«¨¥â᪮© ®¡« á⨠®ª |
* C = 1 - ¥ § ªà 訢 âì à ¡®çãî ®¡« áâì ¯à¨ ®âà¨á®¢ª¥ ®ª |
* D = 0 - ®à¬ «ì ï § «¨¢ª à ¡®ç¥© ®¡« áâ¨, 1 - £à ¤¨¥â ï |
«¥¤ãî騥 ¯ à ¬¥âàë ¯à¥¤ § ç¥ë ¤«ï ®ª® ⨯ I ¨ II ¨ |
¨£®à¨àãîâáï ¤«ï á⨫¥© Y=1,3: |
* esi = 0xXYRRGGBB - 梥⠧ £®«®¢ª |
* RR, GG, BB ®¯à¥¤¥«ïîâ á ¬ 梥â |
* Y=0 - ®¡ë箥 ®ª®, Y=1 - ¥¯¥à¥¬¥é ¥¬®¥ ®ª® |
* X ®¯à¥¤¥«ï¥â £à ¤¨¥â § £®«®¢ª : X=0 - ¥â £à ¤¨¥â , |
X=8 - ®¡ëçë© £à ¤¨¥â, |
¤«ï ®ª® ⨯ II X=4 - ¥£ â¨¢ë© £à ¤¨¥â |
* ¯à®ç¨¥ § 票ï X ¨ Y § १¥à¢¨à®¢ ë |
* edi = 0x00RRGGBB - 梥â à ¬ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®«®¦¥¨¥ ¨ à §¬¥àë ®ª ãáâ ¢«¨¢ îâáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ |
í⮩ äãªæ¨¨ ¨ ¨£®à¨àãîâáï ¯à¨ ¯®á«¥¤ãîé¨å; ¤«ï ¨§¬¥¥¨ï |
¯®«®¦¥¨ï ¨/¨«¨ à §¬¥à®¢ 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
67-î äãªæ¨î. |
* «ï ®ª® á⨫¥© Y=3,4 á § £®«®¢ª®¬ (A=1) áâப § £®«®¢ª |
ãáâ ¢«¨¢ ¥âáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ í⮩ äãªæ¨¨ ¨ ¨£®à¨àã¥âáï ¯à¨ |
¯®á«¥¤ãîé¨å (â®ç¥¥ £®¢®àï, ¨£®à¨àã¥âáï ¯®á«¥ ¢ë§®¢ |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 12 - ª®æ ¯¥à¥à¨á®¢ª¨); |
¤«ï ¨§¬¥¥¨ï áâப¨ § £®«®¢ª 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 1 äãªæ¨¨ 71. |
* ᫨ ¨á¯®«ì§®¢ âì ®ª ᮮ⢥âáâ¢ãîé¨å á⨫¥©, â® ¯®«®¦¥¨¥ |
¨/¨«¨ à §¬¥àë ®ª ¬®£ãâ ¬¥ïâìáï ¯®«ì§®¢ ⥫¥¬. |
¥ªã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì ¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ª® ¤®«¦® 㬥é âìáï íªà ¥. ᫨ ¯¥à¥¤ ë¥ ª®®à¤¨ âë |
¨ à §¬¥àë ¥ 㤮¢«¥â¢®àïîâ í⮬ã ãá«®¢¨î, ⮠ᮮ⢥âáâ¢ãîé ï |
ª®®à¤¨ â (¨«¨, ¢®§¬®¦®, ®¡¥) áç¨â ¥âáï ã«¥¬, ¥á«¨ ¨ íâ® |
¥ ¯®¬®£ ¥â, ⮠ᮮ⢥âáâ¢ãî騩 à §¬¥à (¨«¨, ¢®§¬®¦®, ®¡ ) |
ãáâ ¢«¨¢ ¥âáï ¢ à §¬¥à íªà . |
Далее обозначим xpos,ypos,xsize,ysize - значения, передаваемые |
в ebx,ecx. Координаты приводятся относительно левого верхнего |
угла окна, который, таким образом, задается как (0,0), координаты |
правого нижнего угла суть (xsize,ysize). |
* Размеры окна понимаются в смысле координат правого нижнего угла. |
Это же относится и ко всем остальным функциям. |
Это означает, что реальные размеры на 1 пиксель больше. |
* Вид окна типа I: |
* рисуется внешняя рамка цвета, указанного в edi, |
шириной 1 пиксель |
* рисуется заголовок - прямоугольник с левым верхним углом (1,1) |
и правым нижним (xsize-1,min(25,ysize)) цвета, указанного в esi |
(с учетом градиента) |
* если ysize>=26, то закрашивается рабочая область окна - |
прямоугольник с левым верхним углом (1,21) и правым нижним |
(xsize-1,ysize-1) (размерами (xsize-1)*(ysize-21)) - цветом, |
указанным в edx (с учетом градиента) |
* если A=1 и строка заголовка установлена подфункцией 1 |
функции 71, то она выводится в соответствующем месте заголовка |
* Вид окна стиля Y=1: |
* полностью определяется приложением |
* Вид окна типа II: |
* рисуется внешняя рамка шириной 1 пиксель "затенённого" цвета |
edi (все составляющие цвета уменьшаются в два раза) |
* рисуется промежуточная рамка шириной 3 пикселя цвета edi |
* рисуется внутренняя рамка шириной 1 пиксель |
"затенённого" цвета edi |
* рисуется заголовок - прямоугольник с левым верхним углом (4,4) |
и правым нижним (xsize-4,min(20,ysize)) цвета, указанного в esi |
(с учетом градиента) |
* если ysize>=26, то закрашивается рабочая область окна - |
прямоугольник с левым верхним углом (5,20) и правым нижним |
(xsize-5,ysize-5) - цветом, указанным в edx (с учетом градиента) |
* если A=1 и строка заголовка установлена подфункцией 1 |
функции 71, то она выводится в соответствующем месте заголовка |
* Вид окна со скином: |
* рисуется внешняя рамка шириной 1 пиксель |
цвета 'outer' из скина |
* рисуется промежуточная рамка шириной 3 пикселя |
цвета 'frame' из скина |
* рисуется внутренняя рамка шириной 1 пиксель |
цвета 'inner' из скина |
* рисуется заголовок (по картинкам из скина) в прямоугольнике |
«¥¥ ®¡®§ 稬 xpos,ypos,xsize,ysize - § 票ï, ¯¥à¥¤ ¢ ¥¬ë¥ |
¢ ebx,ecx. ®®à¤¨ âë ¯à¨¢®¤ïâáï ®â®á¨â¥«ì® «¥¢®£® ¢¥à奣® |
㣫 ®ª , ª®â®àë©, â ª¨¬ ®¡à §®¬, § ¤ ¥âáï ª ª (0,0), ª®®à¤¨ âë |
¯à ¢®£® ¨¦¥£® 㣫 áãâì (xsize,ysize). |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 . |
â® ¦¥ ®â®á¨âáï ¨ ª® ¢á¥¬ ®áâ «ìë¬ äãªæ¨ï¬. |
â® ®§ ç ¥â, ç⮠ॠ«ìë¥ à §¬¥àë 1 ¯¨ªá¥«ì ¡®«ìè¥. |
* ¨¤ ®ª ⨯ I: |
* à¨áã¥âáï ¢¥èïï à ¬ª 梥â , 㪠§ ®£® ¢ edi, |
è¨à¨®© 1 ¯¨ªá¥«ì |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,1) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-1,min(25,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (1,21) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-1,ysize-1) (à §¬¥à ¬¨ (xsize-1)*(ysize-21)) - 梥⮬, |
㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª á⨫ï Y=1: |
* ¯®«®áâìî ®¯à¥¤¥«ï¥âáï ¯à¨«®¦¥¨¥¬ |
* ¨¤ ®ª ⨯ II: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì "§ â¥ñ®£®" 梥â |
edi (¢á¥ á®áâ ¢«ïî騥 梥â 㬥ìè îâáï ¢ ¤¢ à § ) |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï 梥â edi |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
"§ â¥ñ®£®" 梥â edi |
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (4,4) |
¨ ¯à ¢ë¬ ¨¦¨¬ (xsize-4,min(20,ysize)) 梥â , 㪠§ ®£® ¢ esi |
(á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,20) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ¥á«¨ A=1 ¨ áâப § £®«®¢ª ãáâ ®¢«¥ ¯®¤äãªæ¨¥© 1 |
äãªæ¨¨ 71, â® ® ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª |
* ¨¤ ®ª ᮠ᪨®¬: |
* à¨áã¥âáï ¢¥èïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'outer' ¨§ ᪨ |
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç ï à ¬ª è¨à¨®© 3 ¯¨ªá¥«ï |
梥â 'frame' ¨§ ᪨ |
* à¨áã¥âáï ¢ãâà¥ïï à ¬ª è¨à¨®© 1 ¯¨ªá¥«ì |
梥â 'inner' ¨§ ᪨ |
* à¨áã¥âáï § £®«®¢®ª (¯® ª à⨪ ¬ ¨§ ᪨ ) ¢ ¯àאַ㣮«ì¨ª¥ |
(0,0) - (xsize,_skinh-1) |
* если ysize>=26, то закрашивается рабочая область окна - |
прямоугольник с левым верхним углом (5,_skinh) и правым нижним |
(xsize-5,ysize-5) - цветом, указанным в edx (с учетом градиента) |
* определяются две стандартные кнопки: закрытия и минимизации |
(смотри функцию 8) |
* если A=1 и в edi (ненулевой) указатель на строку заголовка, |
то она выводится в заголовке в месте, определяемом скином |
* Значение переменной _skinh доступно как результат вызова |
подфункции 4 функции 48 |
* ¥á«¨ ysize>=26, â® § ªà 訢 ¥âáï à ¡®ç ï ®¡« áâì ®ª - |
¯àאַ㣮«ì¨ª á «¥¢ë¬ ¢¥à娬 㣫®¬ (5,_skinh) ¨ ¯à ¢ë¬ ¨¦¨¬ |
(xsize-5,ysize-5) - 梥⮬, 㪠§ ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥â ) |
* ®¯à¥¤¥«ïîâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨: § ªàëâ¨ï ¨ ¬¨¨¬¨§ 樨 |
(ᬮâਠäãªæ¨î 8) |
* ¥á«¨ A=1 ¨ ¢ edi (¥ã«¥¢®©) 㪠§ ⥫ì áâப㠧 £®«®¢ª , |
â® ® ¢ë¢®¤¨âáï ¢ § £®«®¢ª¥ ¢ ¬¥áâ¥, ®¯à¥¤¥«ï¥¬®¬ ᪨®¬ |
* 票¥ ¯¥à¥¬¥®© _skinh ¤®áâ㯮 ª ª १ã«ìâ ⠢맮¢ |
¯®¤äãªæ¨¨ 4 äãªæ¨¨ 48 |
====================================================================== |
================= Функция 1 - поставить точку в окне. ================ |
================= ãªæ¨ï 1 - ¯®áâ ¢¨âì â®çªã ¢ ®ª¥. ================ |
====================================================================== |
Параметры: |
* eax = 1 - номер функции |
* ebx = x-координата (относительно окна) |
* ecx = y-координата (относительно окна) |
* edx = 0x00RRGGBB - цвет точки |
edx = 0x01xxxxxx - инвертировать цвет точки |
(младшие 24 бита игнорируются) |
Возвращаемое значение: |
* функция не возвращает значения |
à ¬¥âàë: |
* eax = 1 - ®¬¥à äãªæ¨¨ |
* ebx = x-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* ecx = y-ª®®à¤¨ â (®â®á¨â¥«ì® ®ª ) |
* edx = 0x00RRGGBB - 梥â â®çª¨ |
edx = 0x01xxxxxx - ¨¢¥àâ¨à®¢ âì 梥â â®çª¨ |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
============== Функция 2 - получить код нажатой клавиши. ============= |
============== ãªæ¨ï 2 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª« ¢¨è¨. ============= |
====================================================================== |
Забирает код нажатой клавиши из буфера. |
Параметры: |
* eax = 2 - номер функции |
Возвращаемое значение: |
* если буфер пуст, возвращается eax=1 |
* если буфер непуст, то возвращается al=0, ah=код нажатой клавиши, |
старшее слово регистра eax обнулено |
* если есть "горячая клавиша", то возвращается |
al=2, ah=сканкод нажатой клавиши (0 для управляющих клавиш), |
старшее слово регистра eax содержит состояние управляющих клавиш |
в момент нажатия горячей клавиши |
Замечания: |
* Существует общесистемный буфер нажатых клавиш размером 120 байт, |
организованный как очередь. |
* Существует ещё один общесистемный буфер на 120 "горячих клавиш". |
* При вызове этой функции приложением с неактивным окном |
считается, что буфер нажатых клавиш пуст. |
* По умолчанию эта функция возвращает ASCII-коды; переключиться на |
режим сканкодов (и назад) можно с использованием функции 66. |
Однако, горячие клавиши всегда возвращаются как сканкоды. |
* Узнать, какие комбинации клавиш соответствуют каким кодам, можно, |
запустив приложения keyascii и scancode. |
* Сканкоды возвращаются непосредственно клавиатурой и фиксированы; |
ASCII-коды получаются с использованием таблиц преобразования, |
которые можно установить подфункцией 2 функции 21 и прочитать |
подфункцией 2 функции 26. |
* Как следствие, ASCII-коды учитывают текущую раскладку клавиатуры |
(rus/en) в отличие от сканкодов. |
* Поступает информация только о тех горячих клавишах, которые были |
определены этим потоком подфункцией 4 функции 66. |
¡¨à ¥â ª®¤ ¦ ⮩ ª« ¢¨è¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 2 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, ah=ª®¤ ¦ ⮩ ª« ¢¨è¨, |
áâ à襥 á«®¢® ॣ¨áâà eax ®¡ã«¥® |
* ¥á«¨ ¥áâì "£®àïç ï ª« ¢¨è ", â® ¢®§¢à é ¥âáï |
al=2, ah=᪠ª®¤ ¦ ⮩ ª« ¢¨è¨ (0 ¤«ï ã¯à ¢«ïîé¨å ª« ¢¨è), |
áâ à襥 á«®¢® ॣ¨áâà eax ᮤ¥à¦¨â á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è |
¢ ¬®¬¥â ¦ â¨ï £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ãé¥áâ¢ã¥â ®¡é¥á¨áâ¥¬ë© ¡ãä¥à ¦ âëå ª« ¢¨è à §¬¥à®¬ 120 ¡ ©â, |
®à£ ¨§®¢ ë© ª ª ®ç¥à¥¤ì. |
* ãé¥áâ¢ã¥â ¥éñ ®¤¨ ®¡é¥á¨áâ¥¬ë© ¡ãä¥à 120 "£®àïç¨å ª« ¢¨è". |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
áç¨â ¥âáï, çâ® ¡ãä¥à ¦ âëå ª« ¢¨è ¯ãáâ. |
* ® 㬮«ç ¨î íâ äãªæ¨ï ¢®§¢à é ¥â ASCII-ª®¤ë; ¯¥à¥ª«îç¨âìáï |
०¨¬ ᪠ª®¤®¢ (¨ § ¤) ¬®¦® á ¨á¯®«ì§®¢ ¨¥¬ äãªæ¨¨ 66. |
¤ ª®, £®àï稥 ª« ¢¨è¨ ¢á¥£¤ ¢®§¢à é îâáï ª ª ᪠ª®¤ë. |
* § âì, ª ª¨¥ ª®¬¡¨ 樨 ª« ¢¨è ᮮ⢥âáâ¢ãîâ ª ª¨¬ ª®¤ ¬, ¬®¦®, |
§ ¯ãá⨢ ¯à¨«®¦¥¨ï keyascii ¨ scancode. |
* ª ª®¤ë ¢®§¢à é îâáï ¥¯®á।á⢥® ª« ¢¨ âãன ¨ 䨪á¨à®¢ ë; |
ASCII-ª®¤ë ¯®«ãç îâáï á ¨á¯®«ì§®¢ ¨¥¬ â ¡«¨æ ¯à¥®¡à §®¢ ¨ï, |
ª®â®àë¥ ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2 äãªæ¨¨ 21 ¨ ¯à®ç¨â âì |
¯®¤äãªæ¨¥© 2 äãªæ¨¨ 26. |
* ª á«¥¤á⢨¥, ASCII-ª®¤ë ãç¨âë¢ îâ ⥪ãéãî à ᪫ ¤ªã ª« ¢¨ âãàë |
(rus/en) ¢ ®â«¨ç¨¥ ®â ᪠ª®¤®¢. |
* ®áâ㯠¥â ¨ä®à¬ æ¨ï ⮫쪮 ® â¥å £®àïç¨å ª« ¢¨è å, ª®â®àë¥ ¡ë«¨ |
®¯à¥¤¥«¥ë í⨬ ¯®â®ª®¬ ¯®¤äãªæ¨¥© 4 äãªæ¨¨ 66. |
====================================================================== |
================ Функция 3 - получить системное время. =============== |
================ ãªæ¨ï 3 - ¯®«ãç¨âì á¨á⥬®¥ ¢à¥¬ï. =============== |
====================================================================== |
Параметры: |
* eax = 3 - номер функции |
Возвращаемое значение: |
* eax = 0x00SSMMHH, где HH:MM:SS = часы:минуты:секунды |
* каждый элемент возвращается как BCD-число, например, |
для времени 23:59:59 результат будет 0x00595923 |
Замечания: |
* Смотри также подфункцию 9 функции 26 - получение времени |
с момента запуска системы; она во многих случаях удобнее, |
поскольку возвращает просто DWORD-значение счетчика времени. |
* Системное время можно установить функцией 22. |
à ¬¥âàë: |
* eax = 3 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00SSMMHH, £¤¥ HH:MM:SS = ç áë:¬¨ãâë:ᥪã¤ë |
* ª ¦¤ë© í«¥¬¥â ¢®§¢à é ¥âáï ª ª BCD-ç¨á«®, ¯à¨¬¥à, |
¤«ï ¢à¥¬¥¨ 23:59:59 १ã«ìâ ⠡㤥â 0x00595923 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 9 äãªæ¨¨ 26 - ¯®«ã票¥ ¢à¥¬¥¨ |
á ¬®¬¥â § ¯ã᪠á¨á⥬ë; ® ¢® ¬®£¨å á«ãç ïå 㤮¡¥¥, |
¯®áª®«ìªã ¢®§¢à é ¥â ¯à®áâ® DWORD-§ 票¥ áç¥â稪 ¢à¥¬¥¨. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
============== Функция 4 - вывести строку текста в окно. ============= |
============== ãªæ¨ï 4 - ¢ë¢¥á⨠áâபã ⥪áâ ¢ ®ª®. ============= |
====================================================================== |
Параметры: |
* eax = 4 - номер функции |
* ebx = [координата по оси x]*65536 + [координата по оси y] |
* ecx = 0xXYRRGGBB, где |
* RR, GG, BB задают цвет текста |
* X=ABnn (биты): |
* nn задает используемый шрифт: 0=системный моноширинный, |
1=системный шрифт переменной ширины |
* A=0 - выводить esi символов, A=1 - выводить ASCIIZ-строку |
* B=1 - закрашивать фон цветом edi |
* Y=Cnnn (биты): |
* C=1 перенаправить вывод в область пользователя, задано в edi |
* nnn - не используется в текущем виде, должно быть 0 (zero) |
* edx = указатель на начало строки |
* esi = для A=0 длина строки, должна быть не больше 255; |
для A=1 игнорируется |
* edi = цвет для закраски фона, если B=1 |
* edi = указатель на область пользователя, если C=1 |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Первый системный шрифт считывается при загрузке из файла char.mt, |
второй - из char2.mt. |
* Оба шрифта имеют высоту 9 пикселей, ширина моноширинного шрифта |
равна 6 пикселей. |
* C=1, глубина точки = 32 бита, область пользователя выглядит так: |
à ¬¥âàë: |
* eax = 4 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* ecx = 0xXYRRGGBB, £¤¥ |
* RR, GG, BB § ¤ îâ 梥â ⥪áâ |
* X=ABnn (¡¨âë): |
* nn § ¤ ¥â ¨á¯®«ì§ã¥¬ë© èà¨äâ: 0=á¨áâ¥¬ë© ¬®®è¨à¨ë©, |
1=á¨áâ¥¬ë© èà¨äâ ¯¥à¥¬¥®© è¨à¨ë |
* A=0 - ¢ë¢®¤¨âì esi ᨬ¢®«®¢, A=1 - ¢ë¢®¤¨âì ASCIIZ-áâபã |
* B=1 - § ªà 訢 âì ä® æ¢¥â®¬ edi |
* Y=Cnnn (¡¨âë): |
* C=1 ¯¥à¥ ¯à ¢¨âì ¢ë¢®¤ ¢ ®¡« áâì ¯®«ì§®¢ ⥫ï, § ¤ ® ¢ edi |
* nnn - ¥ ¨á¯®«ì§ã¥âáï ¢ ⥪ã饬 ¢¨¤¥, ¤®«¦® ¡ëâì 0 (zero) |
* edx = 㪠§ ⥫ì ç «® áâப¨ |
* esi = ¤«ï A=0 ¤«¨ áâப¨, ¤®«¦ ¡ëâì ¥ ¡®«ìè¥ 255; |
¤«ï A=1 ¨£®à¨àã¥âáï |
* edi = 梥⠤«ï § ªà ᪨ ä® , ¥á«¨ B=1 |
* edi = 㪠§ â¥«ì ®¡« áâì ¯®«ì§®¢ ⥫ï, ¥á«¨ C=1 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥à¢ë© á¨áâ¥¬ë© èà¨äâ áç¨âë¢ ¥âáï ¯à¨ § £à㧪¥ ¨§ ä ©« char.mt, |
¢â®à®© - ¨§ char2.mt. |
* ¡ èà¨äâ ¨¬¥îâ ¢ëá®âã 9 ¯¨ªá¥«¥©, è¨à¨ ¬®®è¨à¨®£® èà¨äâ |
à ¢ 6 ¯¨ªá¥«¥©. |
* C=1, £«ã¡¨ â®çª¨ = 32 ¡¨â , ®¡« áâì ¯®«ì§®¢ â¥«ï ¢ë£«ï¤¨â â ª: |
dword Xsize |
dword Ysize |
остаток области = Xsize * Y size * 4 |
* Нельзя одновременно использовать B=1 и C=1, поскольку в обоих |
случаях использован регистр edi для разных целей. |
®áâ ⮪ ®¡« á⨠= Xsize * Y size * 4 |
* ¥«ì§ï ®¤®¢à¥¬¥® ¨á¯®«ì§®¢ âì B=1 ¨ C=1, ¯®áª®«ìªã ¢ ®¡®¨å |
á«ãç ïå ¨á¯®«ì§®¢ ॣ¨áâà edi ¤«ï à §ëå 楫¥©. |
====================================================================== |
========================= Функция 5 - пауза. ========================= |
========================= ãªæ¨ï 5 - ¯ 㧠. ========================= |
====================================================================== |
Задерживает выполнение программы на заданное время. |
Параметры: |
* eax = 5 - номер функции |
* ebx = время в сотых долях секунды |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Передача ebx=0 не передает управление следующему процессу и |
вообще не производит никаких действий. Если действительно |
требуется передать управление следующему процессу |
(закончить текущий квант времени), используйте подфункцию 1 |
функции 68. |
¤¥à¦¨¢ ¥â ¢ë¯®«¥¨¥ ¯à®£à ¬¬ë § ¤ ®¥ ¢à¥¬ï. |
à ¬¥âàë: |
* eax = 5 - ®¬¥à äãªæ¨¨ |
* ebx = ¢à¥¬ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥à¥¤ ç ebx=0 ¥ ¯¥à¥¤ ¥â ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã ¨ |
¢®®¡é¥ ¥ ¯à®¨§¢®¤¨â ¨ª ª¨å ¤¥©á⢨©. ᫨ ¤¥©áâ¢¨â¥«ì® |
âॡã¥âáï ¯¥à¥¤ âì ã¯à ¢«¥¨¥ á«¥¤ãî饬㠯à®æ¥ááã |
(§ ª®ç¨âì ⥪ã騩 ª¢ ⠢६¥¨), ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 1 |
äãªæ¨¨ 68. |
====================================================================== |
=============== Функция 6 - прочитать файл с рамдиска. =============== |
=============== ãªæ¨ï 6 - ¯à®ç¨â âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
Параметры: |
* eax = 6 - номер функции |
* ebx = указатель на имя файла |
* ecx = номер стартового блока, считая с 1; |
ecx=0 - читать с начала файла (то же самое, что и ecx=1) |
* edx = число блоков для чтения; |
edx=0 - читать один блок (то же самое, что и edx=1) |
* esi = указатель на область памяти, куда будут записаны данные |
Возвращаемое значение: |
* eax = длина файла в байтах, если файл успешно прочитан |
* eax = -1, если файл не найден |
Замечания: |
* Данная функция является устаревшей; функция 70 |
позволяет выполнять те же действия с расширенными возможностями. |
* Блок = 512 байт. |
* Для чтения всего файла можно указать заведомо большое значение |
в edx, например, edx = -1; но в этом случае будьте готовы к тому, |
что программа "упадет", если файл окажется слишком большим |
и "не влезет" в память программы. |
* Имя файла должно быть либо в формате 8+3 символов |
(первые 8 символов - собственно имя, последние 3 - расширение, |
короткие имена и расширения дополняются пробелами), |
либо в формате 8.3 символов "FILE.EXT"/"FILE.EX " |
(имя не более 8 символов, точка, расширение 3 символа, |
дополненное при необходимости пробелами). |
Имя файла должно быть записано заглавными буквами. |
Завершающий символ с кодом 0 не нужен (не ASCIIZ-строка). |
* Эта функция не поддерживает папки на рамдиске. |
à ¬¥âàë: |
* eax = 6 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = ®¬¥à áâ à⮢®£® ¡«®ª , áç¨â ï á 1; |
ecx=0 - ç¨â âì á ç « ä ©« (â® ¦¥ á ¬®¥, çâ® ¨ ecx=1) |
* edx = ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï; |
edx=0 - ç¨â âì ®¤¨ ¡«®ª (â® ¦¥ á ¬®¥, çâ® ¨ edx=1) |
* esi = 㪠§ â¥«ì ®¡« áâì ¯ ¬ïâ¨, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤«¨ ä ©« ¢ ¡ ©â å, ¥á«¨ ä ©« ãá¯¥è® ¯à®ç¨â |
* eax = -1, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ï äãªæ¨ï ï¥âáï ãáâ ॢ襩; äãªæ¨ï 70 |
¯®§¢®«ï¥â ¢ë¯®«ïâì ⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* «®ª = 512 ¡ ©â. |
* «ï çâ¥¨ï ¢á¥£® ä ©« ¬®¦® 㪠§ âì § ¢¥¤®¬® ¡®«ì讥 § 票¥ |
¢ edx, ¯à¨¬¥à, edx = -1; ® ¢ í⮬ á«ãç ¥ ¡ã¤ì⥠£®â®¢ë ª ⮬ã, |
çâ® ¯à®£à ¬¬ "㯠¤¥â", ¥á«¨ ä ©« ®ª ¦¥âáï ᫨誮¬ ¡®«ì訬 |
¨ "¥ ¢«¥§¥â" ¢ ¯ ¬ïâì ¯à®£à ¬¬ë. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯ª¨ à ¬¤¨áª¥. |
====================================================================== |
=============== Функция 7 - вывести изображение в окно. ============== |
=============== ãªæ¨ï 7 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ ¢ ®ª®. ============== |
====================================================================== |
Параметры: |
* eax = 7 - номер функции |
* ebx = указатель на изображение в формате BBGGRRBBGGRR... |
* ecx = [размер по оси x]*65536 + [размер по оси y] |
* edx = [координата по оси x]*65536 + [координата по оси y] |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Координаты изображения - это координаты верхнего левого угла |
изображения относительно окна. |
* Размер изображения в байтах есть 3*xsize*ysize. |
à ¬¥âàë: |
* eax = 7 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize. |
====================================================================== |
=============== Функция 8 - определить/удалить кнопку. =============== |
=============== ãªæ¨ï 8 - ®¯à¥¤¥«¨âì/㤠«¨âì ª®¯ªã. =============== |
====================================================================== |
Параметры для определения кнопки: |
* eax = 8 - номер функции |
* ebx = [координата по оси x]*65536 + [размер по оси x] |
* ecx = [координата по оси y]*65536 + [размер по оси y] |
* edx = 0xXYnnnnnn, где: |
* nnnnnn = идентификатор кнопки |
* старший (31-й) бит edx сброшен |
* если 30-й бит edx установлен - не прорисовывать кнопку |
* если 29-й бит edx установлен - не рисовать рамку |
при нажатии на кнопку |
* esi = 0x00RRGGBB - цвет кнопки |
Параметры для удаления кнопки: |
* eax = 8 - номер функции |
* edx = 0x80nnnnnn, где nnnnnn - идентификатор кнопки |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Размеры кнопки должны быть больше 0 и меньше 0x8000. |
* Для окон со скином при определении окна (вызове 0-й функции) |
создаются две стандартные кнопки - закрытия окна |
с идентификатором 1 и минимизации окна с идентификатором 0xffff. |
* Создание двух кнопок с одинаковыми идентификаторами |
вполне допустимо. |
* Кнопка с идентификатором 0xffff при нажатии интерпретируется |
системой как кнопка минимизации, система обрабатывает такое |
нажатие самостоятельно, не обращаясь к приложению. |
В остальном это обычная кнопка. |
* Общее количество кнопок для всех приложений ограничено |
числом 4095. |
à ¬¥âàë ¤«ï ®¯à¥¤¥«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYnnnnnn, £¤¥: |
* nnnnnn = ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
* áâ à訩 (31-©) ¡¨â edx á¡à®è¥ |
* ¥á«¨ 30-© ¡¨â edx ãáâ ®¢«¥ - ¥ ¯à®à¨á®¢ë¢ âì ª®¯ªã |
* ¥á«¨ 29-© ¡¨â edx ãáâ ®¢«¥ - ¥ à¨á®¢ âì à ¬ªã |
¯à¨ ¦ ⨨ ª®¯ªã |
* esi = 0x00RRGGBB - 梥⠪®¯ª¨ |
à ¬¥âàë ¤«ï 㤠«¥¨ï ª®¯ª¨: |
* eax = 8 - ®¬¥à äãªæ¨¨ |
* edx = 0x80nnnnnn, £¤¥ nnnnnn - ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* §¬¥àë ª®¯ª¨ ¤®«¦ë ¡ëâì ¡®«ìè¥ 0 ¨ ¬¥ìè¥ 0x8000. |
* «ï ®ª® ᮠ᪨®¬ ¯à¨ ®¯à¥¤¥«¥¨¨ ®ª (¢ë§®¢¥ 0-© äãªæ¨¨) |
ᮧ¤ îâáï ¤¢¥ áâ ¤ àâë¥ ª®¯ª¨ - § ªàëâ¨ï ®ª |
á ¨¤¥â¨ä¨ª â®à®¬ 1 ¨ ¬¨¨¬¨§ 樨 ®ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff. |
* ®§¤ ¨¥ ¤¢ãå ª®¯®ª á ®¤¨ ª®¢ë¬¨ ¨¤¥â¨ä¨ª â®à ¬¨ |
¢¯®«¥ ¤®¯ãá⨬®. |
* ®¯ª á ¨¤¥â¨ä¨ª â®à®¬ 0xffff ¯à¨ ¦ ⨨ ¨â¥à¯à¥â¨àã¥âáï |
á¨á⥬®© ª ª ª®¯ª ¬¨¨¬¨§ 樨, á¨á⥬ ®¡à ¡ âë¢ ¥â â ª®¥ |
¦ ⨥ á ¬®áâ®ï⥫ì®, ¥ ®¡à é ïáì ª ¯à¨«®¦¥¨î. |
®á⠫쮬 íâ® ®¡ëç ï ª®¯ª . |
* ¡é¥¥ ª®«¨ç¥á⢮ ª®¯®ª ¤«ï ¢á¥å ¯à¨«®¦¥¨© ®£à ¨ç¥® |
ç¨á«®¬ 4095. |
====================================================================== |
============= Функция 9 - информация о потоке выполнения. ============ |
============= ãªæ¨ï 9 - ¨ä®à¬ æ¨ï ® ¯®â®ª¥ ¢ë¯®«¥¨ï. ============ |
====================================================================== |
Параметры: |
* eax = 9 - номер функции |
* ebx = указатель на буфер размера 1 Кб |
* ecx = номер слота потока |
ecx = -1 - получить информацию о текущем потоке |
Возвращаемое значение: |
* eax = максимальный номер слота потока |
* буфер, на который указывает ebx, содержит следующую информацию: |
* +0: dword: использование процессора (сколько тактов в секунду |
уходит на исполнение именно этого потока) |
* +4: word: позиция окна потока в оконном стэке |
* +6: word: (не имеет отношения к запрошенному потоку) |
номер слота потока, окно которого находится в оконном стэке |
в позиции ecx |
* +8: word: зарезервировано |
* +10 = +0xA: 11 байт: имя процесса |
(имя запущенного файла - исполняемый файл без расширения) |
* +21 = +0x15: byte: зарезервировано, этот байт не изменяется |
* +22 = +0x16: dword: адрес процесса в памяти |
* +26 = +0x1A: dword: размер используемой памяти - 1 |
* +30 = +0x1E: dword: идентификатор (PID/TID) |
* +34 = +0x22: dword: координата окна потока по оси x |
* +38 = +0x26: dword: координата окна потока по оси y |
* +42 = +0x2A: dword: размер окна потока по оси x |
* +46 = +0x2E: dword: размер окна потока по оси y |
* +50 = +0x32: word: состояние слота потока: |
* 0 = поток выполняется |
* 1 = поток приостановлен |
* 2 = поток приостановлен в момент ожидания события |
* 3 = поток завершается в результате вызова функции -1 или |
насильственно как следствие вызова подфункции 2 функции 18 |
или завершения работы системы |
* 4 = поток завершается в результате исключения |
* 5 = поток ожидает события |
* 9 = запрошенный слот свободен, вся остальная информация о |
слоте не имеет смысла |
* +52 = +0x34: word: зарезервировано, это слово не изменяется |
* +54 = +0x36: dword: координата начала клиентской области |
по оси x |
* +58 = +0x3A: dword: координата начала клиентской области |
по оси y |
* +62 = +0x3E: dword: ширина клиентской области |
* +66 = +0x42: dword: высота клиентской области |
* +70 = +0x46: byte: состояние окна - битовое поле |
* бит 0 (маска 1): окно максимизировано |
* бит 1 (маска 2): окно минимизировано в панель задач |
* бит 2 (маска 4): окно свёрнуто в заголовок |
* +71 = +0x47: dword: маска событий |
Замечания: |
* Слоты нумеруются с 1. |
* Возвращаемое значение не есть общее число потоков, поскольку |
бывают свободные слоты. |
* При создании процесса автоматически создается поток выполнения. |
* Функция выдает информацию о потоке. Каждый процесс имеет |
хотя бы один поток. Один процесс может создать несколько потоков, |
в этом случае каждый поток получает свой слот, причем поля |
+10, +22, +26 в этих слотах совпадают. |
Для приложений не существует общего способа определить, |
принадлежат ли два потока одному процессу. |
* Активное окно - окно, находящееся на вершине оконного стэка, |
оно получает сообщения о вводе с клавиатуры. Для него позиция в |
оконном стэке совпадает с возвращаемым значением. |
* Слот 1 соответствует специальному потоку операционной системы, |
для которого: |
* окно находится внизу оконного стэка, поля +4 и +6 содержат |
значение 1 |
* имя процесса - "OS/IDLE" (дополненное пробелами) |
* адрес процесса в памяти равен 0, размер используемой памяти |
à ¬¥âàë: |
* eax = 9 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 1 ¡ |
* ecx = ®¬¥à ᫮⠯®â®ª |
ecx = -1 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¯®â®ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ªá¨¬ «ìë© ®¬¥à ᫮⠯®â®ª |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ebx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ¨á¯®«ì§®¢ ¨¥ ¯à®æ¥áá®à (᪮«ìª® ⠪⮢ ¢ ᥪã¤ã |
ã室¨â ¨á¯®«¥¨¥ ¨¬¥® í⮣® ¯®â®ª ) |
* +4: word: ¯®§¨æ¨ï ®ª ¯®â®ª ¢ ®ª®®¬ áâíª¥ |
* +6: word: (¥ ¨¬¥¥â ®â®è¥¨ï ª § ¯à®è¥®¬ã ¯®â®ªã) |
®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® 室¨âáï ¢ ®ª®®¬ áâíª¥ |
¢ ¯®§¨æ¨¨ ecx |
* +8: word: § १¥à¢¨à®¢ ® |
* +10 = +0xA: 11 ¡ ©â: ¨¬ï ¯à®æ¥áá |
(¨¬ï § ¯ã饮£® ä ©« - ¨á¯®«ï¥¬ë© ä ©« ¡¥§ à áè¨à¥¨ï) |
* +21 = +0x15: byte: § १¥à¢¨à®¢ ®, íâ®â ¡ ©â ¥ ¨§¬¥ï¥âáï |
* +22 = +0x16: dword: ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ï⨠|
* +26 = +0x1A: dword: à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠- 1 |
* +30 = +0x1E: dword: ¨¤¥â¨ä¨ª â®à (PID/TID) |
* +34 = +0x22: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ x |
* +38 = +0x26: dword: ª®®à¤¨ â ®ª ¯®â®ª ¯® ®á¨ y |
* +42 = +0x2A: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ x |
* +46 = +0x2E: dword: à §¬¥à ®ª ¯®â®ª ¯® ®á¨ y |
* +50 = +0x32: word: á®áâ®ï¨¥ ᫮⠯®â®ª : |
* 0 = ¯®â®ª ¢ë¯®«ï¥âáï |
* 1 = ¯®â®ª ¯à¨®áâ ®¢«¥ |
* 2 = ¯®â®ª ¯à¨®áâ ®¢«¥ ¢ ¬®¬¥â ®¦¨¤ ¨ï ᮡëâ¨ï |
* 3 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¢ë§®¢ äãªæ¨¨ -1 ¨«¨ |
ᨫìá⢥® ª ª á«¥¤á⢨¥ ¢ë§®¢ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 |
¨«¨ § ¢¥à襨ï à ¡®âë á¨á⥬ë |
* 4 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ ⥠¨áª«î票ï |
* 5 = ¯®â®ª ®¦¨¤ ¥â ᮡëâ¨ï |
* 9 = § ¯à®è¥ë© á«®â ᢮¡®¤¥, ¢áï ®áâ «ì ï ¨ä®à¬ æ¨ï ® |
᫮⥠¥ ¨¬¥¥â á¬ëá« |
* +52 = +0x34: word: § १¥à¢¨à®¢ ®, íâ® á«®¢® ¥ ¨§¬¥ï¥âáï |
* +54 = +0x36: dword: ª®®à¤¨ â ç « ª«¨¥â᪮© ®¡« á⨠|
¯® ®á¨ x |
* +58 = +0x3A: dword: ª®®à¤¨ â ç « ª«¨¥â᪮© ®¡« á⨠|
¯® ®á¨ y |
* +62 = +0x3E: dword: è¨à¨ ª«¨¥â᪮© ®¡« á⨠|
* +66 = +0x42: dword: ¢ëá®â ª«¨¥â᪮© ®¡« á⨠|
* +70 = +0x46: byte: á®áâ®ï¨¥ ®ª - ¡¨â®¢®¥ ¯®«¥ |
* ¡¨â 0 (¬ ᪠1): ®ª® ¬ ªá¨¬¨§¨à®¢ ® |
* ¡¨â 1 (¬ ᪠2): ®ª® ¬¨¨¬¨§¨à®¢ ® ¢ ¯ ¥«ì § ¤ ç |
* ¡¨â 2 (¬ ᪠4): ®ª® á¢ñàãâ® ¢ § £®«®¢®ª |
* +71 = +0x47: dword: ¬ ᪠ᮡë⨩ |
¬¥ç ¨ï: |
* «®âë 㬥àãîâáï á 1. |
* ®§¢à é ¥¬®¥ § 票¥ ¥ ¥áâì ®¡é¥¥ ç¨á«® ¯®â®ª®¢, ¯®áª®«ìªã |
¡ë¢ îâ ᢮¡®¤ë¥ á«®âë. |
* ਠᮧ¤ ¨¨ ¯à®æ¥áá ¢â®¬ â¨ç¥áª¨ ᮧ¤ ¥âáï ¯®â®ª ¢ë¯®«¥¨ï. |
* ãªæ¨ï ¢ë¤ ¥â ¨ä®à¬ æ¨î ® ¯®â®ª¥. ¦¤ë© ¯à®æ¥áá ¨¬¥¥â |
å®âï ¡ë ®¤¨ ¯®â®ª. ¤¨ ¯à®æ¥áá ¬®¦¥â ᮧ¤ âì ¥áª®«ìª® ¯®â®ª®¢, |
¢ í⮬ á«ãç ¥ ª ¦¤ë© ¯®â®ª ¯®«ãç ¥â ᢮© á«®â, ¯à¨ç¥¬ ¯®«ï |
+10, +22, +26 ¢ íâ¨å á«®â å ᮢ¯ ¤ îâ. |
«ï ¯à¨«®¦¥¨© ¥ áãé¥áâ¢ã¥â ®¡é¥£® ᯮᮡ ®¯à¥¤¥«¨âì, |
¯à¨ ¤«¥¦ â «¨ ¤¢ ¯®â®ª ®¤®¬ã ¯à®æ¥ááã. |
* ªâ¨¢®¥ ®ª® - ®ª®, 室ï饥áï ¢¥à訥 ®ª®®£® áâíª , |
®® ¯®«ãç ¥â á®®¡é¥¨ï ® ¢¢®¤¥ á ª« ¢¨ âãàë. «ï ¥£® ¯®§¨æ¨ï ¢ |
®ª®®¬ áâíª¥ ᮢ¯ ¤ ¥â á ¢®§¢à é ¥¬ë¬ § 票¥¬. |
* «®â 1 ᮮ⢥âáâ¢ã¥â á¯¥æ¨ «ì®¬ã ¯®â®ªã ®¯¥à 樮®© á¨á⥬ë, |
¤«ï ª®â®à®£®: |
* ®ª® 室¨âáï ¢¨§ã ®ª®®£® áâíª , ¯®«ï +4 ¨ +6 ᮤ¥à¦ â |
§ 票¥ 1 |
* ¨¬ï ¯à®æ¥áá - "OS/IDLE" (¤®¯®«¥®¥ ¯à®¡¥« ¬¨) |
* ¤à¥á ¯à®æ¥áá ¢ ¯ ¬ïâ¨ à ¢¥ 0, à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠|
16 Mb (0x1000000) |
* PID=1 |
* координаты и размеры окна, равно как и клиентской области, |
условно полагаются равными 0 |
* состояние слота - всегда 0 (выполняется) |
* время выполнения складывается из времени, уходящего на |
собственно работу, и времени простоя в ожидании прерывания |
(которое можно получить вызовом подфункции 4 функции 18). |
* Начиная со слота 2, размещаются обычные приложения. |
* Обычные приложения размещаются в памяти по адресу 0 |
(константа ядра std_application_base_address). |
Наложения не происходит, поскольку у каждого процесса своя |
таблица страниц. |
* При создании потока ему назначаются слот в системной таблице и |
идентификатор (Process/Thread IDentifier = PID/TID), которые для |
заданного потока не изменяются со временем. |
После завершения потока его слот может быть заново использован |
для другого потока. Идентификатор потока не может быть назначен |
другому потоку даже после завершения первого. |
Назначаемые новым потокам идентификаторы монотонно растут. |
* Если поток еще не определил свое окно вызовом функции 0, то |
положение и размеры этого окна полагаются нулями. |
* Координаты клиентской области окна берутся относительно окна. |
* В данный момент используется только часть буфера размером |
71 = 0x47 байта. Тем не менее рекомендуется использовать буфер |
размером 1 Кб для будущей совместимости, в будущем могут быть |
добавлены некоторые поля. |
* ª®®à¤¨ âë ¨ à §¬¥àë ®ª , à ¢® ª ª ¨ ª«¨¥â᪮© ®¡« áâ¨, |
ãá«®¢® ¯®« £ îâáï à ¢ë¬¨ 0 |
* á®áâ®ï¨¥ á«®â - ¢á¥£¤ 0 (¢ë¯®«ï¥âáï) |
* ¢à¥¬ï ¢ë¯®«¥¨ï ᪫ ¤ë¢ ¥âáï ¨§ ¢à¥¬¥¨, ã室ï饣® |
ᮡá⢥® à ¡®âã, ¨ ¢à¥¬¥¨ ¯à®áâ®ï ¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï |
(ª®â®à®¥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 18). |
* ç¨ ï á® á«®â 2, à §¬¥é îâáï ®¡ëçë¥ ¯à¨«®¦¥¨ï. |
* ¡ëçë¥ ¯à¨«®¦¥¨ï à §¬¥é îâáï ¢ ¯ ¬ï⨠¯® ¤à¥áã 0 |
(ª®áâ â ï¤à std_application_base_address). |
«®¦¥¨ï ¥ ¯à®¨á室¨â, ¯®áª®«ìªã ã ª ¦¤®£® ¯à®æ¥áá ᢮ï |
â ¡«¨æ áâà ¨æ. |
* ਠᮧ¤ ¨¨ ¯®â®ª ¥¬ã § ç îâáï ᫮⠢ á¨á⥬®© â ¡«¨æ¥ ¨ |
¨¤¥â¨ä¨ª â®à (Process/Thread IDentifier = PID/TID), ª®â®àë¥ ¤«ï |
§ ¤ ®£® ¯®â®ª ¥ ¨§¬¥ïîâáï á® ¢à¥¬¥¥¬. |
®á«¥ § ¢¥àè¥¨ï ¯®â®ª ¥£® ᫮⠬®¦¥â ¡ëâì § ®¢® ¨á¯®«ì§®¢ |
¤«ï ¤à㣮£® ¯®â®ª . ¤¥â¨ä¨ª â®à ¯®â®ª ¥ ¬®¦¥â ¡ëâì § ç¥ |
¤à㣮¬ã ¯®â®ªã ¤ ¦¥ ¯®á«¥ § ¢¥àè¥¨ï ¯¥à¢®£®. |
§ ç ¥¬ë¥ ®¢ë¬ ¯®â®ª ¬ ¨¤¥â¨ä¨ª â®àë ¬®®â®® à áâãâ. |
* ᫨ ¯®â®ª ¥é¥ ¥ ®¯à¥¤¥«¨« ᢮¥ ®ª® ¢ë§®¢®¬ äãªæ¨¨ 0, â® |
¯®«®¦¥¨¥ ¨ à §¬¥àë í⮣® ®ª ¯®« £ îâáï ã«ï¬¨. |
* ®®à¤¨ âë ª«¨¥â᪮© ®¡« á⨠®ª ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ¤ ë© ¬®¬¥â ¨á¯®«ì§ã¥âáï ⮫쪮 ç áâì ¡ãä¥à à §¬¥à®¬ |
71 = 0x47 ¡ ©â . ¥¬ ¥ ¬¥¥¥ ४®¬¥¤ã¥âáï ¨á¯®«ì§®¢ âì ¡ãä¥à |
à §¬¥à®¬ 1 ¡ ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨, ¢ ¡ã¤ã饬 ¬®£ãâ ¡ëâì |
¤®¡ ¢«¥ë ¥ª®â®àë¥ ¯®«ï. |
====================================================================== |
==================== Функция 10 - ожидать события. =================== |
==================== ãªæ¨ï 10 - ®¦¨¤ âì ᮡëâ¨ï. =================== |
====================================================================== |
Если очередь сообщений пуста, то ждет появления сообщения в очереди. |
В таком состоянии поток не получает процессорного времени. |
Затем считывает сообщение из очереди. |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , â® ¦¤¥â ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨. |
â ª®¬ á®áâ®ï¨¨ ¯®â®ª ¥ ¯®«ãç ¥â ¯à®æ¥áá®à®£® ¢à¥¬¥¨. |
⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
Параметры: |
* eax = 10 - номер функции |
Возвращаемое значение: |
* eax = событие (смотри список событий) |
Замечания: |
* Учитываются только те события, которые входят в маску, |
устанавливаемую функцией 40. По умолчанию это события |
перерисовки, нажатия на клавиши и на кнопки. |
* Для проверки, есть ли сообщение в очереди, используйте функцию 11. |
Чтобы ждать не более определенного времени, используйте |
функцию 23. |
à ¬¥âàë: |
* eax = 10 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
======= Функция 11 - проверить, есть ли событие, без ожидания. ======= |
======= ãªæ¨ï 11 - ¯à®¢¥à¨âì, ¥áâì «¨ ᮡë⨥, ¡¥§ ®¦¨¤ ¨ï. ======= |
====================================================================== |
Если в очереди сообщений есть какое-то событие, то считывает и |
возвращает его. Если очередь пуста, возвращает нуль. |
Параметры: |
* eax = 11 - номер функции |
Возвращаемое значение: |
* eax = 0 - очередь сообщений пуста |
* иначе eax = событие (смотри список событий) |
Замечания: |
* Учитываются только те события, которые входят в маску, |
устанавливаемую функцией 40. По умолчанию это события |
перерисовки, нажатия на клавиши и на кнопки. |
* Для ожидания появления события в очереди, используйте функцию 10. |
Чтобы ждать не более определенного времени, используйте |
функцию 23. |
᫨ ¢ ®ç¥à¥¤¨ á®®¡é¥¨© ¥áâì ª ª®¥-⮠ᮡë⨥, â® áç¨âë¢ ¥â ¨ |
¢®§¢à é ¥â ¥£®. ᫨ ®ç¥à¥¤ì ¯ãáâ , ¢®§¢à é ¥â ã«ì. |
à ¬¥âàë: |
* eax = 11 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ®¦¨¤ ¨ï ¯®ï¢«¥¨ï ᮡëâ¨ï ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
â®¡ë ¦¤ âì ¥ ¡®«¥¥ ®¯à¥¤¥«¥®£® ¢à¥¬¥¨, ¨á¯®«ì§ã©â¥ |
äãªæ¨î 23. |
====================================================================== |
=========== Функция 12 - начать/закончить перерисовку окна. ========== |
=========== ãªæ¨ï 12 - ç âì/§ ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ========== |
====================================================================== |
-------------- Подфункция 1 - начать перерисовку окна. --------------- |
Параметры: |
* eax = 12 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
-------------- ®¤äãªæ¨ï 1 - ç âì ¯¥à¥à¨á®¢ªã ®ª . --------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------- Подфункция 2 - закончить перерисовку окна. ------------- |
Параметры: |
* eax = 12 - номер функции |
* ebx = 2 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Функция начала перерисовки удаляет все определённые |
функцией 8 кнопки, их следует определить повторно. |
------------- ®¤äãªæ¨ï 2 - § ª®ç¨âì ¯¥à¥à¨á®¢ªã ®ª . ------------- |
à ¬¥âàë: |
* eax = 12 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ç « ¯¥à¥à¨á®¢ª¨ 㤠«ï¥â ¢á¥ ®¯à¥¤¥«ñë¥ |
äãªæ¨¥© 8 ª®¯ª¨, ¨å á«¥¤ã¥â ®¯à¥¤¥«¨âì ¯®¢â®à®. |
====================================================================== |
============ Функция 13 - нарисовать прямоугольник в окне. =========== |
============ ãªæ¨ï 13 - à¨á®¢ âì ¯àאַ㣮«ì¨ª ¢ ®ª¥. =========== |
====================================================================== |
Параметры: |
* eax = 13 - номер функции |
* ebx = [координата по оси x]*65536 + [размер по оси x] |
* ecx = [координата по оси y]*65536 + [размер по оси y] |
* edx = цвет 0xRRGGBB или 0x80RRGGBB для градиентной заливки |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Под координатами понимаются координаты левого верхнего угла |
прямоугольника относительно окна. |
à ¬¥âàë: |
* eax = 13 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 梥â 0xRRGGBB ¨«¨ 0x80RRGGBB ¤«ï £à ¤¨¥â®© § «¨¢ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®¤ ª®®à¤¨ â ¬¨ ¯®¨¬ îâáï ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 |
¯àאַ㣮«ì¨ª ®â®á¨â¥«ì® ®ª . |
====================================================================== |
================ Функция 14 - получить размеры экрана. =============== |
================ ãªæ¨ï 14 - ¯®«ãç¨âì à §¬¥àë íªà . =============== |
====================================================================== |
Параметры: |
* eax = 14 - номер функции |
Возвращаемое значение: |
* eax = [xsize]*65536 + [ysize], где |
* xsize = x-координата правого нижнего угла экрана = |
размер по горизонтали - 1 |
* ysize = y-координата правого нижнего угла экрана = |
размер по вертикали - 1 |
Замечания: |
* Смотри также подфункцию 5 функции 48 - получить размеры рабочей |
области экрана. |
à ¬¥âàë: |
* eax = 14 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [xsize]*65536 + [ysize], £¤¥ |
* xsize = x-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® £®à¨§®â «¨ - 1 |
* ysize = y-ª®®à¤¨ â ¯à ¢®£® ¨¦¥£® 㣫 íªà = |
à §¬¥à ¯® ¢¥à⨪ «¨ - 1 |
¬¥ç ¨ï: |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 5 äãªæ¨¨ 48 - ¯®«ãç¨âì à §¬¥àë à ¡®ç¥© |
®¡« á⨠íªà . |
====================================================================== |
= Функция 15, подфункция 1 - установить размер фонового изображения. = |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = ширина изображения |
* edx = высота изображения |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Вызов функции обязателен перед вызовом подфункций 2 и 5. |
* Для обновления экрана (после завершения серии команд, работающих с |
фоном) вызывайте подфункцию 3 перерисовки фона. |
* Есть парная функция получения размеров фонового изображения - |
подфункция 1 функции 39. |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = è¨à¨ ¨§®¡à ¦¥¨ï |
* edx = ¢ëá®â ¨§®¡à ¦¥¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ®¡ï§ ⥫¥ ¯¥à¥¤ ¢ë§®¢®¬ ¯®¤äãªæ¨© 2 ¨ 5. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 39. |
====================================================================== |
= Функция 15, подфункция 2 - поставить точку на фоновом изображении. = |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ä®®¢®¬ ¨§®¡à ¦¥¨¨. = |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = смещение |
* edx = цвет точки 0xRRGGBB |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Смещение для точки с координатами (x,y) вычисляется как |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
* edx = 梥â â®çª¨ 0xRRGGBB |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¬¥é¥¨¥ ¤«ï â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª |
(x+y*xsize)*3. |
* Если указанное смещение превышает установленный подфункцией 1 |
размер, вызов игнорируется. |
* Для обновления экрана (после завершения серии команд, работающих с |
фоном) вызывайте подфункцию 3 перерисовки фона. |
* Есть парная функция получения точки с фонового изображения - |
подфункция 2 функции 39. |
* ᫨ 㪠§ ®¥ ᬥ饨¥ ¯à¥¢ëè ¥â ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 1 |
à §¬¥à, ¢ë§®¢ ¨£®à¨àã¥âáï. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï â®çª¨ á ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 39. |
====================================================================== |
============ Функция 15, подфункция 3 - перерисовать фон. ============ |
============ ãªæ¨ï 15, ¯®¤äãªæ¨ï 3 - ¯¥à¥à¨á®¢ âì ä®. ============ |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 3 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
===== Функция 15, подфункция 4 - установить режим отрисовки фона. ==== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ==== |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 4 - номер подфункции |
* ecx = режим отрисовки: |
* 1 = замостить |
* 2 = растянуть |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Для обновления экрана (после завершения серии команд, работающих с |
фоном) вызывайте подфункцию 3 перерисовки фона. |
* Есть парная команда получения режима отрисовки фона - |
подфункция 4 функции 39. |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬ ®âà¨á®¢ª¨: |
* 1 = § ¬®áâ¨âì |
* 2 = à áâïãâì |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï ª®¬ ¤ ¯®«ã票ï ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 39. |
====================================================================== |
===== Функция 15, подфункция 5 - поместить блок пикселей на фон. ===== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 5 - ¯®¬¥áâ¨âì ¡«®ª ¯¨ªá¥«¥© ä®. ===== |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = указатель на данные в формате BBGGRRBBGGRR... |
* edx = смещение в данных фонового изображения |
* esi = размер данных в байтах = 3 * число пикселей |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Проверки корректности смещения и размера не производится. |
* Цвет каждого пикселя хранится как 3-байтная величина BBGGRR. |
* Пиксели фонового изображения записываются последовательно |
слева направо, сверху вниз. |
* Смещение пикселя с координатами (x,y) есть (x+y*xsize)*3. |
* Для обновления экрана (после завершения серии команд, работающих с |
фоном) вызывайте подфункцию 3 перерисовки фона. |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* edx = ᬥ饨¥ ¢ ¤ ëå ä®®¢®£® ¨§®¡à ¦¥¨ï |
* esi = à §¬¥à ¤ ëå ¢ ¡ ©â å = 3 * ç¨á«® ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ஢¥àª¨ ª®à४â®áâ¨ á¬¥é¥¨ï ¨ à §¬¥à ¥ ¯à®¨§¢®¤¨âáï. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
* ¬¥é¥¨¥ ¯¨ªá¥«ï á ª®®à¤¨ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
====================================================================== |
====================== Функция 15, подфункция 6 ====================== |
==== Спроецировать данные фона на адресное пространство процесса. ==== |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 6 ====================== |
==== ¯à®¥æ¨à®¢ âì ¤ ë¥ ä® ¤à¥á®¥ ¯à®áâà á⢮ ¯à®æ¥áá . ==== |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 6 - номер подфункции |
Возвращаемое значение: |
* eax = указатель на данные фона, 0 при ошибке |
Замечания: |
* Спроецированные данные доступны на чтение и запись. |
* Размер данных фона равен 3*xsize*ysize. Изменение размеров фона |
блокируется на время работы с спроецированными данными. |
* Цвет каждого пикселя хранится как 3-байтовая величина BBGGRR. |
* Пиксели фонового изображения записываются последовательно |
слева направо, сверху вниз. |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¤ ë¥ ä® , 0 ¯à¨ ®è¨¡ª¥ |
¬¥ç ¨ï: |
* ¯à®¥æ¨à®¢ ë¥ ¤ ë¥ ¤®áâã¯ë ç⥨¥ ¨ § ¯¨áì. |
* §¬¥à ¤ ëå ä® à ¢¥ 3*xsize*ysize. §¬¥¥¨¥ à §¬¥à®¢ ä® |
¡«®ª¨àã¥âáï ¢à¥¬ï à ¡®âë á á¯à®¥æ¨à®¢ 묨 ¤ 묨. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â®¢ ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
====================================================================== |
====================== Функция 15, подфункция 7 ====================== |
=== Закрыть проекцию данных фона на адресное пространство процесса. == |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 7 ====================== |
=== ªàëâì ¯à®¥ªæ¨î ¤ ëå ä® ¤à¥á®¥ ¯à®áâà á⢮ ¯à®æ¥áá . == |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 7 - номер подфункции |
* ecx = указатель на данные фона |
Возвращаемое значение: |
* eax = 1 при успехе, 0 при ошибке |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä® |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 ¯à¨ ãᯥå¥, 0 ¯à¨ ®è¨¡ª¥ |
====================================================================== |
====================== Функция 15, подфункция 8 ====================== |
=========== Получить координаты последней отрисовки фона. ============ |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 8 ====================== |
=========== ®«ãç¨âì ª®®à¤¨ âë ¯®á«¥¤¥© ®âà¨á®¢ª¨ ä® . ============ |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 8 - номер подфункции |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Замечания: |
* (left,top) - координаты левого верхнего угла, |
(right,bottom) - координаты правого нижнего. |
* Для получения более достоверных сведений, необходимо вызвать |
функцию сразу после получения события: |
5 = завершилась перерисовка фона рабочего стола |
¬¥ç ¨ï: |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
* «ï ¯®«ãç¥¨ï ¡®«¥¥ ¤®á⮢¥àëå ᢥ¤¥¨©, ¥®¡å®¤¨¬® ¢ë§¢ âì |
äãªæ¨î áà §ã ¯®á«¥ ¯®«ã票ï ᮡëâ¨ï: |
5 = § ¢¥à訫 áì ¯¥à¥à¨á®¢ª ä® à ¡®ç¥£® á⮫ |
====================================================================== |
====================== Функция 15, подфункция 9 ====================== |
=============== Перерисовать прямоугольную часть фона. =============== |
====================== ãªæ¨ï 15, ¯®¤äãªæ¨ï 9 ====================== |
=============== ¥à¥à¨á®¢ âì ¯àאַ㣮«ìãî ç áâì ä® . =============== |
====================================================================== |
Параметры: |
* eax = 15 - номер функции |
* ebx = 9 - номер подфункции |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* (left,top) - координаты левого верхнего угла, |
(right,bottom) - координаты правого нижнего. |
* Если параметры установлены некорректно - фон не перерисовывается. |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
* ᫨ ¯ à ¬¥âàë ãáâ ®¢«¥ë ¥ª®à४⮠- ä® ¥ ¯¥à¥à¨á®¢ë¢ ¥âáï. |
====================================================================== |
============= Функция 16 - сохранить рамдиск на дискету. ============= |
============= ãªæ¨ï 16 - á®åà ¨âì à ¬¤¨áª ¤¨áª¥âã. ============= |
====================================================================== |
Параметры: |
* eax = 16 - номер функции |
* ebx = 1 или ebx = 2 - на какую дискету сохранять |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - ошибка |
à ¬¥âàë: |
* eax = 16 - ®¬¥à äãªæ¨¨ |
* ebx = 1 ¨«¨ ebx = 2 - ª ªãî ¤¨áª¥âã á®åà ïâì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
====================================================================== |
============== Функция 17 - получить код нажатой кнопки. ============= |
============== ãªæ¨ï 17 - ¯®«ãç¨âì ª®¤ ¦ ⮩ ª®¯ª¨. ============= |
====================================================================== |
Забирает код нажатой кнопки из буфера. |
Параметры: |
* eax = 17 - номер функции |
Возвращаемое значение: |
* если буфер пуст, возвращается eax=1 |
* если буфер непуст: |
* старшие 24 бита eax содержат идентификатор кнопки |
(в частности, в ah оказывается младший байт идентификатора; |
если все кнопки имеют идентификатор, меньший 256, |
то для различения достаточно ah) |
* al = 0 - кнопка была нажата левой кнопкой мыши |
* al = бит, соответствующий нажавшей кнопке мыши, если не левой |
Замечания: |
* "Буфер" хранит только одну кнопку, при нажатии новой кнопки |
информация о старой теряется. |
* При вызове этой функции приложением с неактивным окном |
возвращается ответ "буфер пуст". |
* Возвращаемое значение al соответствует состоянию кнопок мыши |
в формате подфункции 2 функции 37 в момент начала нажатия |
на кнопку, за исключением младшего бита (соответствующего левой |
кнопке мыши), который сбрасывается. |
¡¨à ¥â ª®¤ ¦ ⮩ ª®¯ª¨ ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 17 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1 |
* ¥á«¨ ¡ãä¥à ¥¯ãáâ: |
* áâ à訥 24 ¡¨â eax ᮤ¥à¦ â ¨¤¥â¨ä¨ª â®à ª®¯ª¨ |
(¢ ç áâ®áâ¨, ¢ ah ®ª §ë¢ ¥âáï ¬« ¤è¨© ¡ ©â ¨¤¥â¨ä¨ª â®à ; |
¥á«¨ ¢á¥ ª®¯ª¨ ¨¬¥îâ ¨¤¥â¨ä¨ª â®à, ¬¥ì訩 256, |
â® ¤«ï à §«¨ç¥¨ï ¤®áâ â®ç® ah) |
* al = 0 - ª®¯ª ¡ë« ¦ â «¥¢®© ª®¯ª®© ¬ëè¨ |
* al = ¡¨â, ᮮ⢥âáâ¢ãî騩 ¦ ¢è¥© ª®¯ª¥ ¬ëè¨, ¥á«¨ ¥ «¥¢®© |
¬¥ç ¨ï: |
* "ãä¥à" åà ¨â ⮫쪮 ®¤ã ª®¯ªã, ¯à¨ ¦ ⨨ ®¢®© ª®¯ª¨ |
¨ä®à¬ æ¨ï ® áâ ன â¥àï¥âáï. |
* ਠ¢ë§®¢¥ í⮩ äãªæ¨¨ ¯à¨«®¦¥¨¥¬ á ¥ ªâ¨¢ë¬ ®ª®¬ |
¢®§¢à é ¥âáï ®â¢¥â "¡ãä¥à ¯ãáâ". |
* ®§¢à é ¥¬®¥ § 票¥ al ᮮ⢥âáâ¢ã¥â á®áâ®ï¨î ª®¯®ª ¬ëè¨ |
¢ ä®à¬ ⥠¯®¤äãªæ¨¨ 2 äãªæ¨¨ 37 ¢ ¬®¬¥â ç « ¦ â¨ï |
ª®¯ªã, § ¨áª«î票¥¬ ¬« ¤è¥£® ¡¨â (ᮮ⢥âáâ¢ãî饣® «¥¢®© |
ª®¯ª¥ ¬ëè¨), ª®â®àë© á¡à áë¢ ¥âáï. |
====================================================================== |
= Функция 18, подфункция 1 - сделать самым нижним окно потока. ======= |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 1 - ᤥ« âì á ¬ë¬ ¨¦¨¬ ®ª® ¯®â®ª . ======= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = номер слота потока |
Возвращаемое значение: |
* функция не возвращает значения |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
==== Функция 18, подфункция 2 - завершить процесс/поток по слоту. ==== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 2 - § ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® á«®âã. ==== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = номер слота процесса/потока |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Нельзя завершить поток операционной системы OS/IDLE (номер слота |
1), можно завершить любой обычный поток/процесс. |
* Смотри также подфункцию 18 - завершение |
процесса/потока с заданным идентификатором. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯à®æ¥áá /¯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 18 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª á § ¤ ë¬ ¨¤¥â¨ä¨ª â®à®¬. |
====================================================================== |
= Функция 18, подфункция 3 - сделать активным окно заданного потока. = |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 3 - ᤥ« âì ªâ¨¢ë¬ ®ª® § ¤ ®£® ¯®â®ª . = |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = номер слота потока |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* При указании корректного, но несуществующего слота активизируется |
какое-то окно. |
* Узнать, какое окно является активным, можно вызовом подфункции 7. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᫮⠯®â®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ਠ㪠§ ¨¨ ª®à४⮣®, ® ¥áãé¥áâ¢ãî饣® ᫮⠪⨢¨§¨àã¥âáï |
ª ª®¥-â® ®ª®. |
* § âì, ª ª®¥ ®ª® ï¥âáï ªâ¨¢ë¬, ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7. |
====================================================================== |
Функция 18, подфункция 4 - получить счётчик пустых тактов в секунду. |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì áçñâ稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã. |
====================================================================== |
Под пустыми тактами понимается время, в которое процессор простаивает |
в ожидании прерывания (в инструкции hlt). |
®¤ ¯ãáâ묨 ⠪⠬¨ ¯®¨¬ ¥âáï ¢à¥¬ï, ¢ ª®â®à®¥ ¯à®æ¥áá®à ¯à®áâ ¨¢ ¥â |
¢ ®¦¨¤ ¨¨ ¯à¥àë¢ ¨ï (¢ ¨áâàãªæ¨¨ hlt). |
Параметры: |
* eax = 18 - номер функции |
* ebx = 4 - номер подфункции |
Возвращаемое значение: |
* eax = значение счётчика пустых тактов в секунду |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § 票¥ áçñâ稪 ¯ãáâëå ⠪⮢ ¢ ᥪã¤ã |
====================================================================== |
======== Функция 18, подфункция 5 - получить тактовую частоту. ======= |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ⠪⮢ãî ç áâ®âã. ======= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 5 - номер подфункции |
Возвращаемое значение: |
* eax = тактовая частота (по модулю 2^32 тактов = 4ГГц) |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⠪⮢ ï ç áâ®â (¯® ¬®¤ã«î 2^32 ⠪⮢ = 4æ) |
====================================================================== |
Функция 18, подфункция 6 - сохранить рамдиск в файл на жёстком диске. |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 6 - á®åà ¨âì à ¬¤¨áª ¢ ä ©« ¦ñá⪮¬ ¤¨áª¥. |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 6 - номер подфункции |
* ecx = указатель на строку с полным именем файла |
(например, "/hd0/1/kolibri/kolibri.img") |
Возвращаемое значение: |
* eax = 0 - успешно |
* иначе eax = код ошибки файловой системы |
Замечания: |
* Все папки в указанном пути должны существовать, иначе вернётся |
значение 5, "файл не найден". |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì áâபã á ¯®«ë¬ ¨¬¥¥¬ ä ©« |
( ¯à¨¬¥à, "/hd0/1/kolibri/kolibri.img") |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* ¨ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* ᥠ¯ ¯ª¨ ¢ 㪠§ ®¬ ¯ã⨠¤®«¦ë áãé¥á⢮¢ âì, ¨ ç¥ ¢¥àñâáï |
§ 票¥ 5, "ä ©« ¥ ©¤¥". |
====================================================================== |
====== Функция 18, подфункция 7 - получить номер активного окна. ===== |
====== ãªæ¨ï 18, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ®¬¥à ªâ¨¢®£® ®ª . ===== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 7 - номер подфункции |
Возвращаемое значение: |
* eax = номер активного окна (номер слота потока, окно которого |
активно) |
Замечания: |
* Активное окно находится вверху оконного стэка и получает |
сообщения обо всём вводе с клавиатуры. |
* Сделать окно активным можно вызовом подфункции 3. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ªâ¨¢®£® ®ª (®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® |
ªâ¨¢®) |
¬¥ç ¨ï: |
* ªâ¨¢®¥ ®ª® 室¨âáï ¢¢¥àåã ®ª®®£® áâíª ¨ ¯®«ãç ¥â |
á®®¡é¥¨ï ®¡® ¢áñ¬ ¢¢®¤¥ á ª« ¢¨ âãàë. |
* ¤¥« âì ®ª® ªâ¨¢ë¬ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3. |
====================================================================== |
==== Функция 18, подфункция 8 - отключить/разрешить звук спикера. ==== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 8 - ®âª«îç¨âì/à §à¥è¨âì §¢ãª ᯨª¥à . ==== |
====================================================================== |
При отключённом звуке вызовы подфункции 55 функции 55 игнорируются. |
При включённом - направляются на встроенный спикер. |
ਠ®âª«îçñ®¬ §¢ãª¥ ¢ë§®¢ë ¯®¤äãªæ¨¨ 55 äãªæ¨¨ 55 ¨£®à¨àãîâáï. |
ਠ¢ª«îçñ®¬ - ¯à ¢«ïîâáï ¢áâà®¥ë© á¯¨ª¥à. |
--------------- Подподфункция 1 - получить состояние. ---------------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = 1 - номер подподфункции |
Возвращаемое значение: |
* eax = 0 - звук спикера разрешён; 1 - запрещён |
--------------- ®¤¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥. ---------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - §¢ãª ᯨª¥à à §à¥èñ; 1 - § ¯à¥éñ |
-------------- Подподфункция 2 - переключить состояние. -------------- |
Переключает состояния разрешения/запрещения. |
Параметры: |
* eax = 18 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = 2 - номер подподфункции |
Возвращаемое значение: |
* функция не возвращает значения |
-------------- ®¤¯®¤äãªæ¨ï 2 - ¯¥à¥ª«îç¨âì á®áâ®ï¨¥. -------------- |
¥à¥ª«îç ¥â á®áâ®ï¨ï à §à¥è¥¨ï/§ ¯à¥é¥¨ï. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
= Функция 18, подфункция 9 - завершение работы системы с параметром. = |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 9 - § ¢¥à襨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬. = |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 9 - номер подфункции |
* ecx = параметр: |
* 2 = выключить компьютер |
* 3 = перезагрузить компьютер |
* 4 = перезапустить ядро из файла kernel.mnt на рамдиске |
Возвращаемое значение: |
* при неверном ecx регистры не меняются (т.е. eax=18) |
* при правильном вызове всегда возвращается признак успеха eax=0 |
Замечания: |
* Не следует полагаться на возвращаемое значение при неверном |
вызове, оно может измениться в последующих версиях ядра. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¯ à ¬¥âà: |
* 2 = ¢ëª«îç¨âì ª®¬¯ìîâ¥à |
* 3 = ¯¥à¥§ £à㧨âì ª®¬¯ìîâ¥à |
* 4 = ¯¥à¥§ ¯ãáâ¨âì ï¤à® ¨§ ä ©« kernel.mnt à ¬¤¨áª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* ¯à¨ ¥¢¥à®¬ ecx ॣ¨áâàë ¥ ¬¥ïîâáï (â.¥. eax=18) |
* ¯à¨ ¯à ¢¨«ì®¬ ¢ë§®¢¥ ¢á¥£¤ ¢®§¢à é ¥âáï ¯à¨§ ª ãᯥå eax=0 |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¯à¨ ¥¢¥à®¬ |
¢ë§®¢¥, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¯®á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
====================================================================== |
======== Функция 18, подфункция 10 - свернуть окно приложения. ======= |
======== ãªæ¨ï 18, ¯®¤äãªæ¨ï 10 - ᢥàãâì ®ª® ¯à¨«®¦¥¨ï. ======= |
====================================================================== |
Сворачивает собственное окно. |
Параметры: |
* eax = 18 - номер функции |
* ebx = 10 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Минимизированное окно с точки зрения функции 9 сохраняет положение |
и размеры. |
* Восстановление окна приложения происходит при активизировании |
подфункцией 3. |
* Обычно нет необходимости явно сворачивать/разворачивать своё окно: |
сворачивание окна осуществляется системой при нажатии на кнопку |
минимизации (которая для окон со скином определяется автоматически |
функцией 0, для окон без скина её можно определить функцией 8), |
восстановление - приложением @panel. |
¢®à 稢 ¥â ᮡá⢥®¥ ®ª®. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¨¨¬¨§¨à®¢ ®¥ ®ª® á â®çª¨ §à¥¨ï äãªæ¨¨ 9 á®åà ï¥â ¯®«®¦¥¨¥ |
¨ à §¬¥àë. |
* ®ááâ ®¢«¥¨¥ ®ª ¯à¨«®¦¥¨ï ¯à®¨á室¨â ¯à¨ ªâ¨¢¨§¨à®¢ ¨¨ |
¯®¤äãªæ¨¥© 3. |
* ¡ëç® ¥â ¥®¡å®¤¨¬®á⨠ ᢮à 稢 âì/à §¢®à 稢 âì ᢮ñ ®ª®: |
᢮à 稢 ¨¥ ®ª ®áãé¥á⢫ï¥âáï á¨á⥬®© ¯à¨ ¦ ⨨ ª®¯ªã |
¬¨¨¬¨§ 樨 (ª®â®à ï ¤«ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥âáï ¢â®¬ â¨ç¥áª¨ |
äãªæ¨¥© 0, ¤«ï ®ª® ¡¥§ ᪨ ¥ñ ¬®¦® ®¯à¥¤¥«¨âì äãªæ¨¥© 8), |
¢®ááâ ®¢«¥¨¥ - ¯à¨«®¦¥¨¥¬ @panel. |
====================================================================== |
====================== Функция 18, подфункция 11 ===================== |
============= Получить информацию о дисковой подсистеме. ============= |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 11 ===================== |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ¤¨áª®¢®© ¯®¤á¨á⥬¥. ============= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 11 - номер подфункции |
* ecx = тип таблицы: |
* 1 = короткая версия, 10 байт |
* 2 = полная версия, 65536 байт |
* edx = указатель на буфер (в приложении) для таблицы |
Возвращаемое значение: |
* функция не возвращает значения |
Формат таблицы: короткая версия: |
* +0: byte: информация о НГМД (дисководах для дискет), AAAABBBB, |
где AAAA задаёт тип первого дисковода, BBBB - второго согласно |
следующему списку: |
* 0 = нет дисковода |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ â ¡«¨æë: |
* 1 = ª®à®âª ï ¢¥àá¨ï, 10 ¡ ©â |
* 2 = ¯®« ï ¢¥àá¨ï, 65536 ¡ ©â |
* edx = 㪠§ â¥«ì ¡ãä¥à (¢ ¯à¨«®¦¥¨¨) ¤«ï â ¡«¨æë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë: ª®à®âª ï ¢¥àá¨ï: |
* +0: byte: ¨ä®à¬ æ¨ï ® (¤¨áª®¢®¤ å ¤«ï ¤¨áª¥â), AAAABBBB, |
£¤¥ AAAA § ¤ ñâ ⨯ ¯¥à¢®£® ¤¨áª®¢®¤ , BBBB - ¢â®à®£® ᮣ« á® |
á«¥¤ãî饬ã ᯨáªã: |
* 0 = ¥â ¤¨áª®¢®¤ |
* 1 = 360Kb, 5.25'' |
* 2 = 1.2Mb, 5.25'' |
* 3 = 720Kb, 3.5'' |
* 4 = 1.44Mb, 3.5'' |
* 5 = 2.88Mb, 3.5'' (такие дискеты сейчас уже не используются) |
Например, для стандартной конфигурации из одного 1.44-дисковода |
здесь будет 40h, а для случая 1.2Mb на A: и 1.44Mb на B: |
значение оказывается 24h. |
* +1: byte: информация о жёстких дисках и CD-приводах, AABBCCDD, |
где AA соответствует контроллеру IDE0, ..., DD - IDE3: |
* 0 = устройство отсутствует |
* 1 = жёсткий диск |
* 2 = CD-привод |
Например, в случае HD на IDE0 и CD на IDE2 здесь будет 48h. |
* +2: 4 db: число найденных разделов на жёстких дисках с |
соответственно IDE0,...,IDE3. |
При отсутствии жёсткого диска на IDEx соответствующий байт |
нулевой, при наличии показывает число распознанных разделов, |
которых может и не быть (если носитель не отформатирован или |
если файловая система не поддерживается). В текущей версии ядра |
для жёстких дисков поддерживаются только FAT16, FAT32 и NTFS. |
* +6: 4 db: зарезервировано |
Формат таблицы: полная версия: |
* +0: 10 db: такие же, как и в короткой версии |
* +10: 100 db: данные для первого раздела |
* +110: 100 db: данные для второго раздела |
* 5 = 2.88Mb, 3.5'' (â ª¨¥ ¤¨áª¥âë ᥩç á 㦥 ¥ ¨á¯®«ì§ãîâáï) |
¯à¨¬¥à, ¤«ï áâ ¤ à⮩ ª®ä¨£ãà 樨 ¨§ ®¤®£® 1.44-¤¨áª®¢®¤ |
§¤¥áì ¡ã¤¥â 40h, ¤«ï á«ãç ï 1.2Mb A: ¨ 1.44Mb B: |
§ 票¥ ®ª §ë¢ ¥âáï 24h. |
* +1: byte: ¨ä®à¬ æ¨ï ® ¦ñáâª¨å ¤¨áª å ¨ CD-¯à¨¢®¤ å, AABBCCDD, |
£¤¥ AA ᮮ⢥âáâ¢ã¥â ª®â஫«¥àã IDE0, ..., DD - IDE3: |
* 0 = ãáâனá⢮ ®âáãâáâ¢ã¥â |
* 1 = ¦ñá⪨© ¤¨áª |
* 2 = CD-¯à¨¢®¤ |
¯à¨¬¥à, ¢ á«ãç ¥ HD IDE0 ¨ CD IDE2 §¤¥áì ¡ã¤¥â 48h. |
* +2: 4 db: ç¨á«® ©¤¥ëå à §¤¥«®¢ ¦ñáâª¨å ¤¨áª å á |
ᮮ⢥âá⢥® IDE0,...,IDE3. |
ਠ®âáãâá⢨¨ ¦ñá⪮£® ¤¨áª IDEx ᮮ⢥âáâ¢ãî騩 ¡ ©â |
ã«¥¢®©, ¯à¨ «¨ç¨¨ ¯®ª §ë¢ ¥â ç¨á«® à ᯮ§ ëå à §¤¥«®¢, |
ª®â®àëå ¬®¦¥â ¨ ¥ ¡ëâì (¥á«¨ ®á¨â¥«ì ¥ ®âä®à¬ â¨à®¢ ¨«¨ |
¥á«¨ ä ©«®¢ ï á¨á⥬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï). ⥪ã饩 ¢¥àᨨ ï¤à |
¤«ï ¦ñáâª¨å ¤¨áª®¢ ¯®¤¤¥à¦¨¢ îâáï ⮫쪮 FAT16, FAT32 ¨ NTFS. |
* +6: 4 db: § १¥à¢¨à®¢ ® |
®à¬ â â ¡«¨æë: ¯®« ï ¢¥àá¨ï: |
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ |
* +10: 100 db: ¤ ë¥ ¤«ï ¯¥à¢®£® à §¤¥« |
* +110: 100 db: ¤ ë¥ ¤«ï ¢â®à®£® à §¤¥« |
* ... |
* +10+100*(n-1): 100 db: данные для последнего раздела |
Разделы расположены в следующем порядке: сначала последовательно все |
распознанные разделы на HD на IDE0 (если есть), |
затем на HD на IDE1 (если есть) и т.д. до IDE3. |
Формат информации о разделе: |
* +0: dword: начальный физический сектор раздела |
* +4: dword: последний физический сектор раздела |
(принадлежит разделу) |
* +8: byte: тип файловой системы: |
* +10+100*(n-1): 100 db: ¤ ë¥ ¤«ï ¯®á«¥¤¥£® à §¤¥« |
§¤¥«ë à ᯮ«®¦¥ë ¢ á«¥¤ãî饬 ¯®à浪¥: á ç « ¯®á«¥¤®¢ â¥«ì® ¢á¥ |
à ᯮ§ ë¥ à §¤¥«ë HD IDE0 (¥á«¨ ¥áâì), |
§ ⥬ HD IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3. |
®à¬ â ¨ä®à¬ 樨 ® à §¤¥«¥: |
* +0: dword: ç «ìë© ä¨§¨ç¥áª¨© ᥪâ®à à §¤¥« |
* +4: dword: ¯®á«¥¤¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« |
(¯à¨ ¤«¥¦¨â à §¤¥«ã) |
* +8: byte: ⨯ ä ©«®¢®© á¨á⥬ë: |
16=FAT16, 32=FAT32, 1=NTFS |
* формат дальнейших данных зависит от файловой системы, |
может меняться с изменениями в ядре и поэтому не описывается |
Замечания: |
* Короткая таблица может быть использована для получения информации |
об имеющихся устройствах. |
* ä®à¬ â ¤ «ì¥©è¨å ¤ ëå § ¢¨á¨â ®â ä ©«®¢®© á¨á⥬ë, |
¬®¦¥â ¬¥ïâìáï á ¨§¬¥¥¨ï¬¨ ¢ ï¤à¥ ¨ ¯®í⮬㠥 ®¯¨áë¢ ¥âáï |
¬¥ç ¨ï: |
* ®à®âª ï â ¡«¨æ ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ¤«ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 |
®¡ ¨¬¥îé¨åáï ãáâனá⢠å. |
====================================================================== |
========== Функция 18, подфункция 13 - получить версию ядра. ========= |
========== ãªæ¨ï 18, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì ¢¥àá¨î ï¤à . ========= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = указатель на буфер (не менее 16 байт), куда будет помещена |
информация |
Возвращаемое значение: |
* функция не возвращает значения |
Структура буфера: |
db a,b,c,d для версии a.b.c.d |
db 0: зарезервировано |
dd REV - номер svn-ревизии ядра |
Для ядра Kolibri 0.7.7.0+: |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à (¥ ¬¥¥¥ 16 ¡ ©â), ªã¤ ¡ã¤¥â ¯®¬¥é¥ |
¨ä®à¬ æ¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
âàãªâãà ¡ãä¥à : |
db a,b,c,d ¤«ï ¢¥àᨨ a.b.c.d |
db 0: § १¥à¢¨à®¢ ® |
dd REV - ®¬¥à svn-ॢ¨§¨¨ ï¤à |
«ï ï¤à Kolibri 0.7.7.0+: |
db 0,7,7,0 |
db 0 |
dd 1675 |
====================================================================== |
====================== Функция 18, подфункция 14 ===================== |
======= Ожидать начала обратного хода луча развёртки монитора. ======= |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 14 ===================== |
======= ¦¨¤ âì ç « ®¡à ⮣® 室 «ãç à §¢ñà⪨ ¬®¨â®à . ======= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 14 - номер подфункции |
Возвращаемое значение: |
* eax = 0 как признак успеха |
Замечания: |
* Функция предназначена исключительно для активных |
высокопроизводительных графических приложений; используется для |
плавного вывода графики. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
¬¥ç ¨ï: |
* ãªæ¨ï ¯à¥¤ § ç¥ ¨áª«îç¨â¥«ì® ¤«ï ªâ¨¢ëå |
¢ë᮪®¯à®¨§¢®¤¨â¥«ìëå £à ä¨ç¥áª¨å ¯à¨«®¦¥¨©; ¨á¯®«ì§ã¥âáï ¤«ï |
¯« ¢®£® ¢ë¢®¤ £à 䨪¨. |
====================================================================== |
== Функция 18, подфункция 15 - поместить курсор мыши в центр экрана. = |
== ãªæ¨ï 18, ¯®¤äãªæ¨ï 15 - ¯®¬¥áâ¨âì ªãàá®à ¬ëè¨ ¢ æ¥âà íªà . = |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 15 - номер подфункции |
Возвращаемое значение: |
* eax = 0 как признак успеха |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ª ª ¯à¨§ ª ãᯥå |
====================================================================== |
====================== Функция 18, подфункция 16 ===================== |
============ Получить размер свободной оперативной памяти. =========== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 16 ===================== |
============ ®«ãç¨âì à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 16 - номер подфункции |
Возвращаемое значение: |
* eax = размер свободной памяти в килобайтах |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 16 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¬¥à ᢮¡®¤®© ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== Функция 18, подфункция 17 ===================== |
============ Получить размер имеющейся оперативной памяти. =========== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 17 ===================== |
============ ®«ãç¨âì à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ïâ¨. =========== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 17 - номер подфункции |
Возвращаемое значение: |
* eax = общий размер имеющейся памяти в килобайтах |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ¯ ¬ï⨠¢ ª¨«®¡ ©â å |
====================================================================== |
====================== Функция 18, подфункция 18 ===================== |
============= Завершить процесс/поток по идентификатору. ============= |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 18 ===================== |
============= ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® ¨¤¥â¨ä¨ª â®àã. ============= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 18 - номер подфункции |
* ecx = идентификатор процесса/потока (PID/TID) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = -1 - ошибка (процесс не найден или является системным) |
Замечания: |
* Нельзя завершить поток операционной системы OS/IDLE (номер слота |
1), можно завершить любой обычный поток/процесс. |
* Смотри также подфункцию 2 - завершение |
процесса/потока по заданному слоту. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 18 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª (PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡ª (¯à®æ¥áá ¥ ©¤¥ ¨«¨ ï¥âáï á¨á⥬ë¬) |
¬¥ç ¨ï: |
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à 樮®© á¨á⥬ë OS/IDLE (®¬¥à á«®â |
1), ¬®¦® § ¢¥àè¨âì «î¡®© ®¡ëçë© ¯®â®ª/¯à®æ¥áá. |
* ¬®âਠ⠪¦¥ ¯®¤äãªæ¨î 2 - § ¢¥à襨¥ |
¯à®æ¥áá /¯®â®ª ¯® § ¤ ®¬ã á«®âã. |
====================================================================== |
=== Функция 18, подфункция 19 - получить/установить настройки мыши. == |
=== ãªæ¨ï 18, ¯®¤äãªæ¨ï 19 - ¯®«ãç¨âì/ãáâ ®¢¨âì áâனª¨ ¬ëè¨. == |
====================================================================== |
------------- Подподфункция 0 - получить скорость мыши. -------------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 0 - номер подподфункции |
Возвращаемое значение: |
* eax = текущая скорость мыши |
------------- ®¤¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ᪮à®áâì ¬ëè¨. -------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï ᪮à®áâì ¬ëè¨ |
------------ Подподфункция 1 - установить скорость мыши. ------------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 1 - номер подподфункции |
* edx = новое значение скорости |
Возвращаемое значение: |
* функция не возвращает значения |
------------ ®¤¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ᪮à®áâì ¬ëè¨. ------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ®¢®¥ § 票¥ ᪮à®á⨠|
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------- Подподфункция 2 - получить задержку мыши. -------------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 2 - номер подподфункции |
Возвращаемое значение: |
* eax = текущая задержка мыши |
------------- ®¤¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì § ¤¥à¦ªã ¬ëè¨. -------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ãé ï § ¤¥à¦ª ¬ëè¨ |
------------ Подподфункция 3 - установить задержку мыши. ------------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 3 - номер подподфункции |
* edx = новое значение задержки мыши |
Возвращаемое значение: |
* функция не возвращает значения |
------------ ®¤¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì § ¤¥à¦ªã ¬ëè¨. ------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 3 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ®¢®¥ § 票¥ § ¤¥à¦ª¨ ¬ëè¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
-------- Подподфункция 4 - установить положение курсора мыши. -------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 4 - номер подподфункции |
* edx = [координата по оси x]*65536 + [координата по оси y] |
Возвращаемое значение: |
* функция не возвращает значения |
-------- ®¤¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ¯®«®¦¥¨¥ ªãàá®à ¬ëè¨. -------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 4 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------- Подподфункция 5 - симулировать состояние клавиш мыши. -------- |
Параметры: |
* eax = 18 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = 5 - номер подподфункции |
* edx = информация о эмулируемом состоянии кнопок мыши: |
(соответствует возвращаемому значению подфункции 2 функции 37) |
* бит 0 установлен = левая кнопка нажата |
* бит 1 установлен = правая кнопка нажата |
* бит 2 установлен = средняя кнопка нажата |
* бит 3 установлен = 4-я кнопка нажата |
* бит 4 установлен = 5-я кнопка нажата |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Рекомендуемая скорость мыши (в подподфункции 1) от 1 до 9. |
Устанавливаемая величина не проверяется кодом ядра, поэтому |
используйте осторожно, при некорректном значении курсор может |
"замёрзнуть". Скорость мыши можно регулировать в приложении SETUP. |
* Рекомендуемая величина задержки (в подподфункции 3) = 10. |
Меньшие значения не обрабатываются COM-мышами. При очень больших |
значениях невозможно передвижение мыши на 1 пиксель и курсор будет |
прыгать на величину установленной скорости (подподфункция 1). |
Устанавливаемая величина не проверяется кодом ядра. |
Величину задержки можно менять в приложении SETUP. |
* Подподфункция 4 не проверяет переданное значение. Перед вызовом |
необходимо узнать текущее разрешение экрана (подфункцией 14) |
и проверить, что устанавливаемое положение не выходит за пределы |
экрана. |
------- ®¤¯®¤äãªæ¨ï 5 - ᨬ㫨஢ âì á®áâ®ï¨¥ ª« ¢¨è ¬ëè¨. -------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 5 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
* edx = ¨ä®à¬ æ¨ï ® í¬ã«¨à㥬®¬ á®áâ®ï¨¨ ª®¯®ª ¬ëè¨: |
(ᮮ⢥âáâ¢ã¥â ¢®§¢à é ¥¬®¬ã § ç¥¨î ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 37) |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â |
* ¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â |
* ¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¥ª®¬¥¤ã¥¬ ï ᪮à®áâì ¬ëè¨ (¢ ¯®¤¯®¤äãªæ¨¨ 1) ®â 1 ¤® 9. |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à , ¯®í⮬ã |
¨á¯®«ì§ã©â¥ ®áâ®à®¦®, ¯à¨ ¥ª®à४⮬ § 票¨ ªãàá®à ¬®¦¥â |
"§ ¬ñà§ãâì". ª®à®áâì ¬ëè¨ ¬®¦® ॣ㫨஢ âì ¢ ¯à¨«®¦¥¨¨ SETUP. |
* ¥ª®¬¥¤ã¥¬ ï ¢¥«¨ç¨ § ¤¥à¦ª¨ (¢ ¯®¤¯®¤äãªæ¨¨ 3) = 10. |
¥ì訥 § ç¥¨ï ¥ ®¡à ¡ âë¢ îâáï COM-¬ëè ¬¨. ਠ®ç¥ì ¡®«ìè¨å |
§ 票ïå ¥¢®§¬®¦® ¯¥à¥¤¢¨¦¥¨¥ ¬ëè¨ 1 ¯¨ªá¥«ì ¨ ªãàá®à ¡ã¤¥â |
¯àë£ âì ¢¥«¨ç¨ã ãáâ ®¢«¥®© ᪮à®á⨠(¯®¤¯®¤äãªæ¨ï 1). |
áâ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨ ¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à . |
¥«¨ç¨ã § ¤¥à¦ª¨ ¬®¦® ¬¥ïâì ¢ ¯à¨«®¦¥¨¨ SETUP. |
* ®¤¯®¤äãªæ¨ï 4 ¥ ¯à®¢¥àï¥â ¯¥à¥¤ ®¥ § 票¥. ¥à¥¤ ¢ë§®¢®¬ |
¥®¡å®¤¨¬® 㧠âì ⥪ã饥 à §à¥è¥¨¥ íªà (¯®¤äãªæ¨¥© 14) |
¨ ¯à®¢¥à¨âì, çâ® ãáâ ¢«¨¢ ¥¬®¥ ¯®«®¦¥¨¥ ¥ ¢ë室¨â § ¯à¥¤¥«ë |
íªà . |
====================================================================== |
====================== Функция 18, подфункция 20 ===================== |
============= Получить информацию об оперативной памяти. ============= |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 20 ===================== |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ®¡ ®¯¥à ⨢®© ¯ ¬ïâ¨. ============= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 20 - номер подфункции |
* ecx = указатель на буфер для информации (36 байт) |
Возвращаемое значение: |
* eax = общий размер имеющейся оперативной памяти в байтах |
или -1 в случае ошибки |
* буфер, на который указывает ecx, содержит следующую информацию: |
* +0: dword: общий размер имеющейся оперативной памяти в страницах |
* +4: dword: размер свободной оперативной памяти в страницах |
* +8: dword: число страничных ошибок (исключений #PF) |
в приложениях |
* +12: dword: размер кучи ядра в байтах |
* +16: dword: размер свободной памяти в куче ядра в байтах |
* +20: dword: общее количество блоков памяти в куче ядра |
* +24: dword: количество свободных блоков памяти в куче ядра |
* +28: dword: размер наибольшего свободного блока в куче ядра |
(зарезервировано) |
* +32: dword: размер наибольшего выделенного блока в куче ядра |
(зарезервировано) |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 20 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¨ä®à¬ 樨 (36 ¡ ©â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ï⨠¢ ¡ ©â å |
¨«¨ -1 ¢ á«ãç ¥ ®è¨¡ª¨ |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à ⨢®© ¯ ¬ï⨠¢ áâà ¨æ å |
* +4: dword: à §¬¥à ᢮¡®¤®© ®¯¥à ⨢®© ¯ ¬ï⨠¢ áâà ¨æ å |
* +8: dword: ç¨á«® áâà ¨çëå ®è¨¡®ª (¨áª«î票© #PF) |
¢ ¯à¨«®¦¥¨ïå |
* +12: dword: à §¬¥à ªãç¨ ï¤à ¢ ¡ ©â å |
* +16: dword: à §¬¥à ᢮¡®¤®© ¯ ¬ï⨠¢ ªãç¥ ï¤à ¢ ¡ ©â å |
* +20: dword: ®¡é¥¥ ª®«¨ç¥á⢮ ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à |
* +24: dword: ª®«¨ç¥á⢮ ᢮¡®¤ëå ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à |
* +28: dword: à §¬¥à ¨¡®«ì襣® ᢮¡®¤®£® ¡«®ª ¢ ªãç¥ ï¤à |
(§ १¥à¢¨à®¢ ®) |
* +32: dword: à §¬¥à ¨¡®«ì襣® ¢ë¤¥«¥®£® ¡«®ª ¢ ªãç¥ ï¤à |
(§ १¥à¢¨à®¢ ®) |
====================================================================== |
====================== Функция 18, подфункция 21 ===================== |
======= Получить номер слота процесса/потока по идентификатору. ====== |
====================== ãªæ¨ï 18, ¯®¤äãªæ¨ï 21 ===================== |
======= ®«ãç¨âì ®¬¥à ᫮⠯à®æ¥áá /¯®â®ª ¯® ¨¤¥â¨ä¨ª â®àã. ====== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 21 - номер подфункции |
* ecx = идентификатор процесса/потока (PID/TID) |
Возвращаемое значение: |
* eax = 0 - ошибка (неверный идентификатор) |
* иначе eax = номер слота |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 21 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª (PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®è¨¡ª (¥¢¥àë© ¨¤¥â¨ä¨ª â®à) |
* ¨ ç¥ eax = ®¬¥à á«®â |
====================================================================== |
Функция 18, подфункция 22 - операции с окном другого процесса/потока. |
ãªæ¨ï 18, ¯®¤äãªæ¨ï 22 - ®¯¥à 樨 á ®ª®¬ ¤à㣮£® ¯à®æ¥áá /¯®â®ª . |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 22 - номер подфункции |
* ecx = тип операции: |
* 0 = минимизация окна, поток задан номером слота |
* 1 = минимизация окна, поток задан идентификатором |
* 2 = восстановление окна, поток задан номером слота |
* 3 = восстановление окна, поток задан идентификатором |
* edx = параметр операции (номер слота или PID/TID) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = -1 - ошибка (неправильный параметр) |
Замечания: |
* Поток может свернуть своё окно вызовом подфункции 10. |
* Восстановление окна с одновременной активизацией осуществляется |
подфункции 3 (принимающей номер слота). |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 22 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ ®¯¥à 樨: |
* 0 = ¬¨¨¬¨§ æ¨ï ®ª , ¯®â®ª § ¤ ®¬¥à®¬ á«®â |
* 1 = ¬¨¨¬¨§ æ¨ï ®ª , ¯®â®ª § ¤ ¨¤¥â¨ä¨ª â®à®¬ |
* 2 = ¢®ááâ ®¢«¥¨¥ ®ª , ¯®â®ª § ¤ ®¬¥à®¬ á«®â |
* 3 = ¢®ááâ ®¢«¥¨¥ ®ª , ¯®â®ª § ¤ ¨¤¥â¨ä¨ª â®à®¬ |
* edx = ¯ à ¬¥âà ®¯¥à 樨 (®¬¥à ᫮⠨«¨ PID/TID) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡ª (¥¯à ¢¨«ìë© ¯ à ¬¥âà) |
¬¥ç ¨ï: |
* ®â®ª ¬®¦¥â ᢥàãâì ᢮ñ ®ª® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 10. |
* ®ááâ ®¢«¥¨¥ ®ª á ®¤®¢à¥¬¥®© ªâ¨¢¨§ 樥© ®áãé¥á⢫ï¥âáï |
¯®¤äãªæ¨¨ 3 (¯à¨¨¬ î饩 ®¬¥à á«®â ). |
====================================================================== |
======= Функция 18, подфункция 23 - минимизировать все окна. ========= |
======= ãªæ¨ï 18, ¯®¤äãªæ¨ï 23 - ¬¨¨¬¨§¨à®¢ âì ¢á¥ ®ª . ========= |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 23 - номер подфункции |
Возвращаемое значение: |
* eax = 0 - все окна были минимизированы до вызова функции |
* eax = N - количество окон свернутых функцией |
Замечания: |
* Окна спец. потоков (имя начинается с символа @) не сворачиваются. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 23 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¢á¥ ®ª ¡ë«¨ ¬¨¨¬¨§¨à®¢ ë ¤® ¢ë§®¢ äãªæ¨¨ |
* eax = N - ª®«¨ç¥á⢮ ®ª® ᢥàãâëå äãªæ¨¥© |
¬¥ç ¨ï: |
* ª ᯥæ. ¯®â®ª®¢ (¨¬ï ç¨ ¥âáï á ᨬ¢®« @) ¥ ᢮à 稢 îâáï. |
====================================================================== |
===== Функция 18, подфункция 24 - установить пределы отрисовки. ====== |
===== ãªæ¨ï 18, ¯®¤äãªæ¨ï 24 - ãáâ ®¢¨âì ¯à¥¤¥«ë ®âà¨á®¢ª¨. ====== |
====================================================================== |
Параметры: |
* eax = 18 - номер функции |
* ebx = 24 - номер подфункции |
* ecx = новый размер по X |
* edx = новый размер по Y |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Функция не меняет физический размер видеорежима. Она предназначена |
для нестандартных дисплеев, отображающих изображение частично. |
* Размеры указываемые в функции не должны превышать размеры текущего |
видеорежима, иначе функция ничего не изменит. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 24 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¢ë© à §¬¥à ¯® X |
* edx = ®¢ë© à §¬¥à ¯® Y |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¬¥ï¥â 䨧¨ç¥áª¨© à §¬¥à ¢¨¤¥®à¥¦¨¬ . ¯à¥¤ § ç¥ |
¤«ï ¥áâ ¤ àâëå ¤¨á¯«¥¥¢, ®â®¡à ¦ îé¨å ¨§®¡à ¦¥¨¥ ç áâ¨ç®. |
* §¬¥àë 㪠§ë¢ ¥¬ë¥ ¢ äãªæ¨¨ ¥ ¤®«¦ë ¯à¥¢ëè âì à §¬¥àë ⥪ã饣® |
¢¨¤¥®à¥¦¨¬ , ¨ ç¥ äãªæ¨ï ¨ç¥£® ¥ ¨§¬¥¨â. |
====================================================================== |
==================== Функция 20 - интерфейс MIDI. ==================== |
==================== ãªæ¨ï 20 - ¨â¥à䥩á MIDI. ==================== |
====================================================================== |
------------------------ Подфункция 1 - сброс ------------------------ |
Параметры: |
* eax = 20 - номер функции |
* ebx = 1 - номер подфункции |
------------------------ ®¤äãªæ¨ï 1 - á¡à®á ------------------------ |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
-------------------- Подфункция 2 - вывести байт --------------------- |
Параметры: |
* eax = 20 - номер функции |
* ebx = 2 - номер подфункции |
* cl = байт для вывода |
Возвращаемое значение (одинаково для обеих подфункций): |
* eax = 0 - успешно |
* eax = 1 - не определён базовый порт |
Замечания: |
* Предварительно должен быть определён базовый порт вызовом |
подфункции 1 функции 21. |
-------------------- ®¤äãªæ¨ï 2 - ¢ë¢¥á⨠¡ ©â --------------------- |
à ¬¥âàë: |
* eax = 20 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤«ï ¢ë¢®¤ |
®§¢à é ¥¬®¥ § 票¥ (®¤¨ ª®¢® ¤«ï ®¡¥¨å ¯®¤äãªæ¨©): |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«ñ ¡ §®¢ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ®¯à¥¤¥«ñ ¡ §®¢ë© ¯®à⠢맮¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
==== Функция 21, подфункция 1 - установить базовый порт MPU MIDI. ==== |
==== ãªæ¨ï 21, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ==== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = номер базового порта |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = -1 - ошибочный номер порта |
Замечания: |
* Номер порта должен удовлетворять условиям 0x100<=ecx<=0xFFFF. |
* Установка базы нужна для работы функции 20. |
* Получить установленный базовый порт можно вызовом |
подфункции 1 функции 26. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ¡ §®¢®£® ¯®àâ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = -1 - ®è¨¡®çë© ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* ®¬¥à ¯®àâ ¤®«¦¥ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF. |
* áâ ®¢ª ¡ §ë 㦠¤«ï à ¡®âë äãªæ¨¨ 20. |
* ®«ãç¨âì ãáâ ®¢«¥ë© ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 26. |
====================================================================== |
===== Функция 21, подфункция 2 - установить раскладку клавиатуры. ==== |
===== ãªæ¨ï 21, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ==== |
====================================================================== |
Раскладка клавиатуры используется для преобразования сканкодов, |
поступающих от клавиатуры, в ASCII-коды, считываемые функцией 2. |
Параметры: |
* eax = 21 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = какую раскладку устанавливать: |
* 1 = нормальную |
* 2 = раскладку при нажатом Shift |
* 3 = раскладку при нажатом Alt |
* edx = указатель на раскладку - таблицу длиной 128 байт |
Или: |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ãáâ ¢«¨¢ âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ ⥫ì à ᪫ ¤ªã - â ¡«¨æã ¤«¨®© 128 ¡ ©â |
Ǭ: |
* ecx = 9 |
* dx = идентификатор страны (1=eng, 2=fi, 3=ger, 4=rus) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - параметр задан неверно |
Замечания: |
* Если нажат Alt, то используется раскладка с Alt; |
если не нажат Alt, но нажат Shift, то |
используется раскладка с Shift; |
если не нажаты Alt и Shift, но нажат Ctrl, то используется |
нормальная раскладка, после чего из кода вычитается 0x60; |
если не нажата ни одна из управляющих клавиш, то используется |
нормальная раскладка. |
* Получить раскладки и идентификатор страны можно с помощью |
подфункции 2 функции 26. |
* Идентификатор страны - глобальная системная переменная, которая |
самим ядром не используется; однако приложение @panel отображает |
соответствующую текущей стране иконку. |
* Приложение @panel переключает раскладки по запросу пользователя. |
* dx = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® |
¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* ®«ãç¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 26. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã. |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
=========== Функция 21, подфункция 3 - установить базу CD. =========== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¡ §ã CD. =========== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* База CD используется функцией 24. |
* Получить установленную базу CD можно вызовом |
подфункции 3 функции 26. |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã CD ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 26. |
====================================================================== |
========= Функция 21, подфункция 5 - установить язык системы. ======== |
========= ãªæ¨ï 21, ¯®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ï§ëª á¨á⥬ë. ======== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = язык системы (1=eng, 2=fi, 3=ger, 4=rus) |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* Язык системы - глобальная системная переменная, никак |
не используемая самим ядром, однако приложение @panel рисует |
соответствующую иконку. |
* Проверок на корректность не делается, поскольку ядро эту |
переменную не использует. |
* Получить язык системы можно вызовом подфункции 5 функции 26. |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï, ¯®áª®«ìªã ï¤à® íâã |
¯¥à¥¬¥ãî ¥ ¨á¯®«ì§ã¥â. |
* ®«ãç¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 26. |
====================================================================== |
=========== Функция 21, подфункция 7 - установить базу HD. =========== |
=========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 7 - ãáâ ®¢¨âì ¡ §ã HD. =========== |
====================================================================== |
База HD нужна для определения, на какой жёсткий диск писать, при |
использовании устаревшего синтаксиса /HD в устаревшей функции 58; |
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3 |
база устанавливается автоматически. |
Параметры: |
* eax = 21 - номер функции |
* ebx = 7 - номер подфункции |
* ecx = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Возвращаемое значение: |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* Любое приложение в любой момент времени может изменить базу. |
* Не следует изменять базу, когда какое-нибудь приложение работает |
с жёстким диском. Если не хотите глюков системы. |
* Получить установленную базу можно вызовом подфункции 7 функции 26. |
* Следует также определить используемый раздел жёсткого диска |
подфункцией 8. |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì ¡ §ã, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 26. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 8. |
====================================================================== |
========== Функция 21, подфункция 8 - установить раздел HD. ========== |
========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì à §¤¥« HD. ========== |
====================================================================== |
Раздел HD нужен для определения, на какой раздел жёсткого диска |
писать, при использовании устаревшего синтаксиса /HD в устаревшей |
функции 58; при использовании современного синтаксиса |
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически. |
Параметры: |
* eax = 21 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = раздел HD (считая с 1) |
Возвращаемое значение: |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = à §¤¥« HD (áç¨â ï á 1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* Любое приложение в любой момент времени может изменить раздел. |
* Не следует изменять раздел, когда какое-нибудь приложение работает |
с жёстким диском. Если не хотите глюков системы. |
* Получить установленный раздел можно вызовом подфункции 8 |
функции 26. |
* Проверок на корректность не делается. |
* Узнать число разделов на жёстком диске можно вызовом |
подфункции 11 функции 18. |
* Следует также определить используемую базу жёсткого диска |
подфункцией 7. |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì à §¤¥«, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ë© à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 |
äãªæ¨¨ 26. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 7. |
====================================================================== |
====================== Функция 21, подфункция 11 ===================== |
=========== Разрешить/запретить низкоуровневый доступ к HD. ========== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 11 ===================== |
=========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 11 - номер подфункции |
* ecx = 0/1 - запретить/разрешить |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* Используется при LBA-чтении (подфункция 8 функции 58). |
* Текущая реализация использует только младший бит ecx. |
* Получить текущее состояние можно вызовом подфункции 11 функции 26. |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 11 äãªæ¨¨ 26. |
====================================================================== |
====================== Функция 21, подфункция 12 ===================== |
========== Разрешить/запретить низкоуровневый доступ к PCI. ========== |
====================== ãªæ¨ï 21, ¯®¤äãªæ¨ï 12 ===================== |
========== §à¥è¨âì/§ ¯à¥â¨âì ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 12 - номер подфункции |
* ecx = 0/1 - запретить/разрешить |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
Замечания: |
* Используется при работе с шиной PCI (функция 62). |
* Текущая реализация использует только младший бит ecx. |
* Получить текущее состояние можно вызовом подфункции 12 функции 26. |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* ®«ãç¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 12 äãªæ¨¨ 26. |
====================================================================== |
============= Функция 21, подфункция 13, подподфункция 1 ============= |
==== Инициализировать + получить информацию о драйвере vmode.mdr. ==== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 1 ============= |
==== ¨æ¨ «¨§¨à®¢ âì + ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤à ©¢¥à¥ vmode.mdr. ==== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = 1 - номер функции драйвера |
* edx = указатель на буфер размера 512 байт |
Возвращаемое значение: |
* если драйвер не загружен (никогда не бывает в текущей реализации): |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à 512 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¤à ©¢¥à ¥ § £à㦥 (¨ª®£¤ ¥ ¡ë¢ ¥â ¢ ⥪ã饩 ॠ«¨§ 樨): |
* eax = -1 |
* ebx, ecx разрушаются |
* если драйвер загружен: |
* eax = 'MDAZ' (в стиле fasm'а, т.е. 'M' - младший байт, |
'Z' - старший) - сигнатура |
* ebx = текущая частота развёртки (в Гц) |
* ecx разрушается |
* буфер, на который указывает edx, заполнен |
Формат буфера: |
* +0: 32*byte: имя драйвера, "Trans VideoDriver" (без кавычек, |
дополнено пробелами) |
* +32 = +0x20: dword: версия драйвера (версия x.y кодируется как |
y*65536+x), для текущей реализации 1 (1.0) |
* +36 = +0x24: 7*dword: зарезервировано (0 в текущей реализации) |
* +64 = +0x40: 32*word: список поддерживаемых видеорежимов (каждое |
слово - номер видеорежима, после собственно списка идут нули) |
* +128 = +0x80: 32*(5*word): список поддерживаемых частот развёрток |
для видеорежимов: для каждого видеорежима, указанного в предыдущем |
поле, указано до 5 поддерживаемых частот |
(в неиспользуемых позициях записаны нули) |
Замечания: |
* Функция инициализирует драйвер (если он ещё не инициализирован) |
и должна вызываться первой, перед остальными (иначе они будут |
возвращать -1, ничего не делая). |
* В текущей реализации поддерживается только одна частота развёртки |
на видеорежим. |
* ebx, ecx à §àãè îâáï |
* ¥á«¨ ¤à ©¢¥à § £à㦥: |
* eax = 'MDAZ' (¢ á⨫¥ fasm' , â.¥. 'M' - ¬« ¤è¨© ¡ ©â, |
'Z' - áâ à訩) - ᨣ âãà |
* ebx = ⥪ãé ï ç áâ®â à §¢ñà⪨ (¢ æ) |
* ecx à §àãè ¥âáï |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â edx, § ¯®«¥ |
®à¬ â ¡ãä¥à : |
* +0: 32*byte: ¨¬ï ¤à ©¢¥à , "Trans VideoDriver" (¡¥§ ª ¢ë祪, |
¤®¯®«¥® ¯à®¡¥« ¬¨) |
* +32 = +0x20: dword: ¢¥àá¨ï ¤à ©¢¥à (¢¥àá¨ï x.y ª®¤¨àã¥âáï ª ª |
y*65536+x), ¤«ï ⥪ã饩 ॠ«¨§ 樨 1 (1.0) |
* +36 = +0x24: 7*dword: § १¥à¢¨à®¢ ® (0 ¢ ⥪ã饩 ॠ«¨§ 樨) |
* +64 = +0x40: 32*word: ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ¢¨¤¥®à¥¦¨¬®¢ (ª ¦¤®¥ |
á«®¢® - ®¬¥à ¢¨¤¥®à¥¦¨¬ , ¯®á«¥ ᮡá⢥® ᯨ᪠¨¤ãâ 㫨) |
* +128 = +0x80: 32*(5*word): ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â à §¢ñà⮪ |
¤«ï ¢¨¤¥®à¥¦¨¬®¢: ¤«ï ª ¦¤®£® ¢¨¤¥®à¥¦¨¬ , 㪠§ ®£® ¢ ¯à¥¤ë¤ã饬 |
¯®«¥, 㪠§ ® ¤® 5 ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â |
(¢ ¥¨á¯®«ì§ã¥¬ëå ¯®§¨æ¨ïå § ¯¨á ë 㫨) |
¬¥ç ¨ï: |
* ãªæ¨ï ¨¨æ¨ «¨§¨àã¥â ¤à ©¢¥à (¥á«¨ ® ¥éñ ¥ ¨¨æ¨ «¨§¨à®¢ ) |
¨ ¤®«¦ ¢ë§ë¢ âìáï ¯¥à¢®©, ¯¥à¥¤ ®áâ «ì묨 (¨ ç¥ ®¨ ¡ã¤ãâ |
¢®§¢à é âì -1, ¨ç¥£® ¥ ¤¥« ï). |
* ⥪ã饩 ॠ«¨§ 樨 ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ®¤ ç áâ®â à §¢ñà⪨ |
¢¨¤¥®à¥¦¨¬. |
====================================================================== |
============= Функция 21, подфункция 13, подподфункция 2 ============= |
============= Получить информацию о текущем видеорежиме. ============= |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 2 ============= |
============= ®«ãç¨âì ¨ä®à¬ æ¨î ® ⥪ã饬 ¢¨¤¥®à¥¦¨¬¥. ============= |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = 2 - номер функции драйвера |
Возвращаемое значение: |
* eax = -1 - драйвер не загружен или не инициализирован; |
ebx,ecx разрушаются |
* eax = [ширина]*65536 + [высота] |
* ebx = частота вертикальной развёртки (в Гц) |
* ecx = номер текущего видеорежима |
Замечания: |
* Драйвер предварительно должен быть инициализирован вызовом |
функции драйвера 1. |
* Если нужны только размеры экрана, целесообразней использовать |
функцию 14 с учётом того, что она возвращает размеры на 1 меньше. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ ; |
ebx,ecx à §àãè îâáï |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
* ebx = ç áâ®â ¢¥à⨪ «ì®© à §¢ñà⪨ (¢ æ) |
* ecx = ®¬¥à ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ᫨ ã¦ë ⮫쪮 à §¬¥àë íªà , 楫¥á®®¡à §¥© ¨á¯®«ì§®¢ âì |
äãªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ® ¢®§¢à é ¥â à §¬¥àë 1 ¬¥ìè¥. |
====================================================================== |
= Функция 21, подфункция 13, подподфункция 3 - установить видеорежим. |
= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì ¢¨¤¥®à¥¦¨¬. |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = 3 - номер функции драйвера |
* edx = [частота развёртки]*65536 + [номер видеорежима] |
Возвращаемое значение: |
* eax = -1 - драйвер не загружен, не инициализирован или |
произошла ошибка |
* eax = 0 - успешно |
* ebx, ecx разрушаются |
Замечания: |
* Драйвер предварительно должен быть инициализирован вызовом |
функции драйвера 1. |
* Номер видеорежима и частота должны быть в таблице, возвращаемой |
функцией драйвера 1. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 3 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = [ç áâ®â à §¢ñà⪨]*65536 + [®¬¥à ¢¨¤¥®à¥¦¨¬ ] |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥, ¥ ¨¨æ¨ «¨§¨à®¢ ¨«¨ |
¯à®¨§®è« ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ®¬¥à ¢¨¤¥®à¥¦¨¬ ¨ ç áâ®â ¤®«¦ë ¡ëâì ¢ â ¡«¨æ¥, ¢®§¢à é ¥¬®© |
äãªæ¨¥© ¤à ©¢¥à 1. |
====================================================================== |
============= Функция 21, подфункция 13, подподфункция 4 ============= |
================= Вернуться к начальному видеорежиму. ================ |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 4 ============= |
================= ¥àãâìáï ª ç «ì®¬ã ¢¨¤¥®à¥¦¨¬ã. ================ |
====================================================================== |
Возвращает экран в видеорежим, установленный при загрузке системы. |
Параметры: |
* eax = 21 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = 4 - номер функции драйвера |
Возвращаемое значение: |
* eax = -1 - драйвер не загружен или не инициализирован |
* eax = 0 - успешно |
* ebx, ecx разрушаются |
Замечания: |
* Драйвер предварительно должен быть инициализирован вызовом |
функции драйвера 1. |
®§¢à é ¥â íªà ¢ ¢¨¤¥®à¥¦¨¬, ãáâ ®¢«¥ë© ¯à¨ § £à㧪¥ á¨á⥬ë. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 4 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
====================================================================== |
============= Функция 21, подфункция 13, подподфункция 5 ============= |
======== Увеличить/уменьшить размер видимой области монитора. ======== |
============= ãªæ¨ï 21, ¯®¤äãªæ¨ï 13, ¯®¤¯®¤äãªæ¨ï 5 ============= |
======== ¢¥«¨ç¨âì/㬥ìè¨âì à §¬¥à ¢¨¤¨¬®© ®¡« á⨠¬®¨â®à . ======== |
====================================================================== |
Параметры: |
* eax = 21 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = 5 - номер функции драйвера |
* edx = 0/1 - уменьшить/увеличить размер по горизонтали |
на одну позицию |
* edx = 2/3 - в текущей реализации не поддерживается; планируется |
как уменьшение/увеличение размера по вертикали на одну позицию |
Возвращаемое значение: |
* eax = -1 - драйвер не загружен или не инициализирован |
* eax = 0 - успешно |
* ebx, ecx разрушаются |
Замечания: |
* Драйвер предварительно должен быть инициализирован вызовом |
функции драйвера 1. |
* Функция влияет только на физический размер изображения |
на мониторе; логический размер (число пикселей) не меняется. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 5 - ®¬¥à äãªæ¨¨ ¤à ©¢¥à |
* edx = 0/1 - 㬥ìè¨âì/㢥«¨ç¨âì à §¬¥à ¯® £®à¨§®â «¨ |
®¤ã ¯®§¨æ¨î |
* edx = 2/3 - ¢ ⥪ã饩 ॠ«¨§ 樨 ¥ ¯®¤¤¥à¦¨¢ ¥âáï; ¯« ¨àã¥âáï |
ª ª 㬥ì襨¥/㢥«¨ç¥¨¥ à §¬¥à ¯® ¢¥à⨪ «¨ ®¤ã ¯®§¨æ¨î |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤à ©¢¥à ¥ § £à㦥 ¨«¨ ¥ ¨¨æ¨ «¨§¨à®¢ |
* eax = 0 - ãá¯¥è® |
* ebx, ecx à §àãè îâáï |
¬¥ç ¨ï: |
* à ©¢¥à ¯à¥¤¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¨¨æ¨ «¨§¨à®¢ ¢ë§®¢®¬ |
äãªæ¨¨ ¤à ©¢¥à 1. |
* ãªæ¨ï ¢«¨ï¥â ⮫쪮 䨧¨ç¥áª¨© à §¬¥à ¨§®¡à ¦¥¨ï |
¬®¨â®à¥; «®£¨ç¥áª¨© à §¬¥à (ç¨á«® ¯¨ªá¥«¥©) ¥ ¬¥ï¥âáï. |
====================================================================== |
============ Функция 22 - установить системную дату/время. =========== |
============ ãªæ¨ï 22 - ãáâ ®¢¨âì á¨á⥬ãî ¤ âã/¢à¥¬ï. =========== |
====================================================================== |
Параметры: |
* eax = 22 - номер функции |
* ebx = 0 - установить время |
* ecx = 0x00SSMMHH - время в двоично-десятичном коде (BCD): |
* HH=час 00..23 |
* MM=минута 00..59 |
* SS=секунда 00..59 |
* ebx = 1 - установить дату |
* ecx = 0x00DDMMYY - дата в двоично-десятичном коде (BCD): |
* DD=день 01..31 |
* MM=месяц 01..12 |
* YY=год 00..99 |
* ebx = 2 - установить день недели |
* ecx = 1 для воскресенья, ..., 7 для субботы |
* ebx = 3 - установить будильник |
à ¬¥âàë: |
* eax = 22 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ãáâ ®¢¨âì ¢à¥¬ï |
* ecx = 0x00SSMMHH - ¢à¥¬ï ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* HH=ç á 00..23 |
* MM=¬¨ãâ 00..59 |
* SS=ᥪ㤠00..59 |
* ebx = 1 - ãáâ ®¢¨âì ¤ âã |
* ecx = 0x00DDMMYY - ¤ â ¢ ¤¢®¨ç®-¤¥áïâ¨ç®¬ ª®¤¥ (BCD): |
* DD=¤¥ì 01..31 |
* MM=¬¥áïæ 01..12 |
* YY=£®¤ 00..99 |
* ebx = 2 - ãáâ ®¢¨âì ¤¥ì ¥¤¥«¨ |
* ecx = 1 ¤«ï ¢®áªà¥á¥ìï, ..., 7 ¤«ï áã¡¡®âë |
* ebx = 3 - ãáâ ®¢¨âì ¡ã¤¨«ì¨ª |
* ecx = 0x00SSMMHH |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - параметр задан неверно |
* eax = 2 - CMOS-батарейки разрядились |
Замечания: |
* Ценность установки дня недели представляется сомнительной, |
поскольку он мало где используется |
(день недели можно рассчитать по дате). |
* Будильник можно установить на срабатывание в заданное время |
каждые сутки. При этом отключить его существующими системными |
функциями нельзя. |
* Срабатывание будильника заключается в генерации IRQ8. |
* Вообще-то CMOS поддерживает для будильника установку значения |
0xFF в качестве одного из параметров и означает это, что |
соответствующий параметр игнорируется. Но в текущей реализации |
это не пройдёт (вернётся значение 1). |
* Будильник - глобальный системный ресурс; установка будильника |
автоматически отменяет предыдущую установку. Впрочем, на данный |
момент ни одна программа его не использует. |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯ à ¬¥âà § ¤ ¥¢¥à® |
* eax = 2 - CMOS-¡ â ३ª¨ à §à廊«¨áì |
¬¥ç ¨ï: |
* ¥®áâì ãáâ ®¢ª¨ ¤ï ¥¤¥«¨ ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©, |
¯®áª®«ìªã ® ¬ «® £¤¥ ¨á¯®«ì§ã¥âáï |
(¤¥ì ¥¤¥«¨ ¬®¦® à ááç¨â âì ¯® ¤ â¥). |
* 㤨«ì¨ª ¬®¦® ãáâ ®¢¨âì áà ¡ âë¢ ¨¥ ¢ § ¤ ®¥ ¢à¥¬ï |
ª ¦¤ë¥ áã⪨. ਠí⮬ ®âª«îç¨âì ¥£® áãé¥áâ¢ãî騬¨ á¨á⥬묨 |
äãªæ¨ï¬¨ ¥«ì§ï. |
* à ¡ âë¢ ¨¥ ¡ã¤¨«ì¨ª § ª«îç ¥âáï ¢ £¥¥à 樨 IRQ8. |
* ®®¡é¥-â® CMOS ¯®¤¤¥à¦¨¢ ¥â ¤«ï ¡ã¤¨«ì¨ª ãáâ ®¢ªã § 票ï |
0xFF ¢ ª ç¥á⢥ ®¤®£® ¨§ ¯ à ¬¥â஢ ¨ ®§ ç ¥â íâ®, çâ® |
ᮮ⢥âáâ¢ãî騩 ¯ à ¬¥âà ¨£®à¨àã¥âáï. ® ¢ ⥪ã饩 ॠ«¨§ 樨 |
íâ® ¥ ¯à®©¤ñâ (¢¥àñâáï § 票¥ 1). |
* 㤨«ì¨ª - £«®¡ «ìë© á¨áâ¥¬ë© à¥áãàá; ãáâ ®¢ª ¡ã¤¨«ì¨ª |
¢â®¬ â¨ç¥áª¨ ®â¬¥ï¥â ¯à¥¤ë¤ãéãî ãáâ ®¢ªã. ¯à®ç¥¬, ¤ ë© |
¬®¬¥â ¨ ®¤ ¯à®£à ¬¬ ¥£® ¥ ¨á¯®«ì§ã¥â. |
====================================================================== |
============== Функция 23 - ожидать события с таймаутом. ============= |
============== ãªæ¨ï 23 - ®¦¨¤ âì ᮡëâ¨ï á â ©¬ ã⮬. ============= |
====================================================================== |
Если очередь сообщений пуста, ждёт появления сообщения в очереди, |
но не более указанного времени. Затем считывает сообщение из очереди. |
᫨ ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ , ¦¤ñâ ¯®ï¢«¥¨ï á®®¡é¥¨ï ¢ ®ç¥à¥¤¨, |
® ¥ ¡®«¥¥ 㪠§ ®£® ¢à¥¬¥¨. ⥬ áç¨âë¢ ¥â á®®¡é¥¨¥ ¨§ ®ç¥à¥¤¨. |
Параметры: |
* eax = 23 - номер функции |
* ebx = таймаут (в сотых долях секунды) |
Возвращаемое значение: |
* eax = 0 - очередь сообщений пуста |
* иначе eax = событие (смотри список событий) |
Замечания: |
* Учитываются только те события, которые входят в маску, |
устанавливаемую функцией 40. По умолчанию это события |
перерисовки, нажатия на клавиши и на кнопки. |
* Для проверки, есть ли сообщение в очереди, используйте функцию 11. |
Чтобы ждать сколь угодно долго, используйте функцию 10. |
* Передача ebx=0 приводит к моментальному возвращению eax=0. |
* При текущей реализации произойдёт немедленный возврат из функции |
с eax=0, если сложение ebx с текущим значением счётчика времени |
вызовет 32-битное переполнение. |
à ¬¥âàë: |
* eax = 23 - ®¬¥à äãªæ¨¨ |
* ebx = â ©¬ ãâ (¢ á®âëå ¤®«ïå ᥪã¤ë) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥¨© ¯ãáâ |
* ¨ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩) |
¬¥ç ¨ï: |
* ç¨âë¢ îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î í⮠ᮡëâ¨ï |
¯¥à¥à¨á®¢ª¨, ¦ â¨ï ª« ¢¨è¨ ¨ ª®¯ª¨. |
* «ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äãªæ¨î 11. |
â®¡ë ¦¤ âì ᪮«ì 㣮¤® ¤®«£®, ¨á¯®«ì§ã©â¥ äãªæ¨î 10. |
* ¥à¥¤ ç ebx=0 ¯à¨¢®¤¨â ª ¬®¬¥â «ì®¬ã ¢®§¢à 饨î eax=0. |
* ਠ⥪ã饩 ॠ«¨§ 樨 ¯à®¨§®©¤ñâ ¥¬¥¤«¥ë© ¢®§¢à â ¨§ äãªæ¨¨ |
á eax=0, ¥á«¨ á«®¦¥¨¥ ebx á ⥪ã騬 § 票¥¬ áçñâ稪 ¢à¥¬¥¨ |
¢ë§®¢¥â 32-¡¨â®¥ ¯¥à¥¯®«¥¨¥. |
====================================================================== |
======= Функция 24, подфункция 1 - начать проигрывать CD-audio. ====== |
======= ãªæ¨ï 24, ¯®¤äãªæ¨ï 1 - ç âì ¯à®¨£àë¢ âì CD-audio. ====== |
====================================================================== |
Параметры: |
* eax = 24 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = 0x00FRSSMM, где |
* MM = начальная минута |
* SS = начальная секунда |
* FR = начальный фрейм |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - не определена база CD |
Замечания: |
* Предварительно нужно определить базовый порт CD вызовом |
подфункции 3 функции 21. |
* В секунде 75 фреймов, в минуте 60 секунд. |
* Функция асинхронна (возвращает управление, когда началось |
проигрывание). |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0x00FRSSMM, £¤¥ |
* MM = ç «ì ï ¬¨ãâ |
* SS = ç «ì ï ᥪ㤠|
* FR = ç «ìë© ä३¬ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ᥪ㤥 75 ä३¬®¢, ¢ ¬¨ã⥠60 ᥪã¤. |
* ãªæ¨ï á¨åà® (¢®§¢à é ¥â ã¯à ¢«¥¨¥, ª®£¤ ç «®áì |
¯à®¨£àë¢ ¨¥). |
====================================================================== |
===== Функция 24, подфункция 2 - получить информацию о дорожках. ===== |
===== ãªæ¨ï 24, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ¤®à®¦ª å. ===== |
====================================================================== |
Параметры: |
* eax = 24 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = указатель на буфер для таблицы |
(максимум 8*64h+4 байт=100 дорожек) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - не определена база CD |
Замечания: |
* Формат таблицы с информацией о дорожках такой же, как и для |
ATAPI-CD команды 43h (READ TOC), обычной таблицы (подкоманда 00h). |
Адреса возвращаются в формате MSF. |
* Предварительно нужно определить базовый порт CD вызовом |
подфункции 3 функции 21. |
* Функция возвращает информацию только о не более чем 100 |
первых дорожках. В большинстве случаев этого достаточно. |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï â ¡«¨æë |
(¬ ªá¨¬ã¬ 8*64h+4 ¡ ©â=100 ¤®à®¦¥ª) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ®à¬ â â ¡«¨æë á ¨ä®à¬ 樥© ® ¤®à®¦ª å â ª®© ¦¥, ª ª ¨ ¤«ï |
ATAPI-CD ª®¬ ¤ë 43h (READ TOC), ®¡ë箩 â ¡«¨æë (¯®¤ª®¬ ¤ 00h). |
¤à¥á ¢®§¢à é îâáï ¢ ä®à¬ ⥠MSF. |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
* ãªæ¨ï ¢®§¢à é ¥â ¨ä®à¬ æ¨î ⮫쪮 ® ¥ ¡®«¥¥ 祬 100 |
¯¥à¢ëå ¤®à®¦ª å. ¡®«ìè¨á⢥ á«ãç ¥¢ í⮣® ¤®áâ â®ç®. |
====================================================================== |
==== Функция 24, подфункция 3 - остановить проигрываемое CD-audio. === |
==== ãªæ¨ï 24, ¯®¤äãªæ¨ï 3 - ®áâ ®¢¨âì ¯à®¨£àë¢ ¥¬®¥ CD-audio. === |
====================================================================== |
Параметры: |
* eax = 24 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - не определена база CD |
Замечания: |
* Предварительно нужно определить базовый порт CD вызовом |
подфункции 3 функции 21. |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ ®¯à¥¤¥«¥ ¡ § CD |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® 㦮 ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
======= Функция 24, подфункция 4 - извлечь лоток привода диска. ====== |
======= ãªæ¨ï 24, ¯®¤äãªæ¨ï 4 - ¨§¢«¥çì «®â®ª ¯à¨¢®¤ ¤¨áª . ====== |
====================================================================== |
Параметры: |
* eax = 24 - номер функции |
* ebx = 4 - номер подфункции |
* ecx = номер CD/DVD-диска |
(от 0=Primary Master до 3=Secondary Slave) |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Функция поддерживается только для ATAPI-устройств (CD и DVD). |
* При извлечении лотка производится разблокировка ручного управления |
механизмом лотка. |
* При извлечении лотка код производит очистку кэша соответствующего |
устройства. |
* Примером использования функции является приложение CD_tray. |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à CD/DVD-¤¨áª |
(®â 0=Primary Master ¤® 3=Secondary Slave) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD). |
* ਠ¨§¢«¥ç¥¨¨ «®âª ¯à®¨§¢®¤¨âáï à §¡«®ª¨à®¢ª àã箣® ã¯à ¢«¥¨ï |
¬¥å ¨§¬®¬ «®âª . |
* ਠ¨§¢«¥ç¥¨¨ «®âª ª®¤ ¯à®¨§¢®¤¨â ®ç¨áâªã ªíè ᮮ⢥âáâ¢ãî饣® |
ãáâனá⢠. |
* ਬ¥à®¬ ¨á¯®«ì§®¢ ¨ï äãªæ¨¨ ï¥âáï ¯à¨«®¦¥¨¥ CD_tray. |
====================================================================== |
====== Функция 24, подфункция 5 - загрузить лоток привода диска. ===== |
====== ãªæ¨ï 24, ¯®¤äãªæ¨ï 5 - § £à㧨âì «®â®ª ¯à¨¢®¤ ¤¨áª . ===== |
====================================================================== |
Параметры: |
* eax = 24 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = номер CD/DVD-диска |
(от 0=Primary Master до 3=Secondary Slave) |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Функция поддерживается только для ATAPI-устройств (CD и DVD). |
* Примером использования функции является приложение CD_tray. |
à ¬¥âàë: |
* eax = 24 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à CD/DVD-¤¨áª |
(®â 0=Primary Master ¤® 3=Secondary Slave) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD). |
* ਬ¥à®¬ ¨á¯®«ì§®¢ ¨ï äãªæ¨¨ ï¥âáï ¯à¨«®¦¥¨¥ CD_tray. |
====================================================================== |
========== Функция 25 - записать область на слой фона. =============== |
========== ãªæ¨ï 25 - § ¯¨á âì ®¡« áâì á«®© ä® . =============== |
====================================================================== |
Параметры: |
* eax = 25 - номер функции |
* ebx = указатель на предварительно выделенную область памяти, |
где размещено исходное изображение в формате BBGGRRTTBBGGRRTT... |
* ecx = [размер по оси x]*65536 + [размер по оси y] |
* edx = [координата по оси x]*65536 + [координата по оси y] |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Координаты области - это координаты верхнего левого угла |
области относительно экрана. |
* Размер изображения в байтах есть 4*xsize*ysize. |
* TT - байт указатель прозрачности, в настоящее время: |
от 1 до FF - непрозрачно, от 0 - прозрачно. |
* Функция размещает изображение не на фоновое изображение (ф.15), |
а напрямую в LFB. Опции ф.15 для ф. 25 не имеют смысла. |
à ¬¥âàë: |
* eax = 25 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¯à¥¤¢ à¨â¥«ì® ¢ë¤¥«¥ãî ®¡« áâì ¯ ¬ïâ¨, |
£¤¥ à §¬¥é¥® ¨á室®¥ ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRTTBBGGRRTT... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ®¡« á⨠- íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
®¡« á⨠®â®á¨â¥«ì® íªà . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 4*xsize*ysize. |
* TT - ¡ ©â 㪠§ â¥«ì ¯à®§à ç®áâ¨, ¢ áâ®ï饥 ¢à¥¬ï: |
®â 1 ¤® FF - ¥¯à®§à ç®, ®â 0 - ¯à®§à ç®. |
* ãªæ¨ï à §¬¥é ¥â ¨§®¡à ¦¥¨¥ ¥ ä®®¢®¥ ¨§®¡à ¦¥¨¥ (ä.15), |
¯àï¬ãî ¢ LFB. ¯æ¨¨ ä.15 ¤«ï ä. 25 ¥ ¨¬¥îâ á¬ëá« . |
====================================================================== |
===== Функция 26, подфункция 1 - получить базовый порт MPU MIDI. ===== |
===== ãªæ¨ï 26, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ===== |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = номер порта |
Замечания: |
* Установить базовый порт можно вызовом |
подфункции 1 функции 21. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ¯®àâ |
¬¥ç ¨ï: |
* áâ ®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 1 äãªæ¨¨ 21. |
====================================================================== |
====== Функция 26, подфункция 2 - получить раскладку клавиатуры. ===== |
====== ãªæ¨ï 26, ¯®¤äãªæ¨ï 2 - ¯®«ãç¨âì à ᪫ ¤ªã ª« ¢¨ âãàë. ===== |
====================================================================== |
Раскладка клавиатуры используется для преобразования сканкодов, |
поступающих от клавиатуры, в ASCII-коды, считываемые функцией 2. |
Параметры: |
* eax = 26 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = какую раскладку получать: |
* 1 = нормальную |
* 2 = раскладку при нажатом Shift |
* 3 = раскладку при нажатом Alt |
* edx = указатель на буфер длиной 128 байт, куда будет скопирована |
раскладка |
Возвращаемое значение: |
* функция не возвращает значения |
Или: |
* eax = 26 - номер функции |
* ebx = 2 - номер подфункции |
᪫ ¤ª ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ¨ï ᪠ª®¤®¢, |
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨âë¢ ¥¬ë¥ äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª ªãî à ᪫ ¤ªã ¯®«ãç âì: |
* 1 = ®à¬ «ìãî |
* 2 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Shift |
* 3 = à ᪫ ¤ªã ¯à¨ ¦ ⮬ Alt |
* edx = 㪠§ â¥«ì ¡ãä¥à ¤«¨®© 128 ¡ ©â, ªã¤ ¡ã¤¥â ᪮¯¨à®¢ |
à ᪫ ¤ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
Ǭ: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 9 |
Возвращаемое значение: |
* eax = идентификатор страны (1=eng, 2=fi, 3=ger, 4=rus) |
Замечания: |
* Если нажат Alt, то используется раскладка с Alt; |
если не нажат Alt, но нажат Shift, то используется |
раскладка с Shift; |
если не нажаты Alt и Shift, но нажат Ctrl, то используется |
нормальная раскладка, после чего из кода вычитается 0x60; |
если не нажата ни одна из управляющих клавиш, то используется |
нормальная раскладка. |
* Установить раскладки и идентификатор страны можно с помощью |
подфункции 2 функции 21. |
* Идентификатор страны - глобальная системная переменная, которая |
самим ядром не используется; однако приложение @panel отображает |
соответствующую текущей стране иконку |
(используя описываемую функцию). |
* Приложение @panel переключает раскладки по запросу пользователя. |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¨¤¥â¨ä¨ª â®à áâà ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* ᫨ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à ᪫ ¤ª á Alt; |
¥á«¨ ¥ ¦ â Alt, ® ¦ â Shift, â® ¨á¯®«ì§ã¥âáï |
à ᪫ ¤ª á Shift; |
¥á«¨ ¥ ¦ âë Alt ¨ Shift, ® ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª , ¯®á«¥ 祣® ¨§ ª®¤ ¢ëç¨â ¥âáï 0x60; |
¥á«¨ ¥ ¦ â ¨ ®¤ ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï |
®à¬ «ì ï à ᪫ ¤ª . |
* áâ ®¢¨âì à ᪫ ¤ª¨ ¨ ¨¤¥â¨ä¨ª â®à áâà ë ¬®¦® á ¯®¬®éìî |
¯®¤äãªæ¨¨ 2 äãªæ¨¨ 21. |
* ¤¥â¨ä¨ª â®à áâà ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ª®â®à ï |
á ¬¨¬ ï¤à®¬ ¥ ¨á¯®«ì§ã¥âáï; ®¤ ª® ¯à¨«®¦¥¨¥ @panel ®â®¡à ¦ ¥â |
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ¥ ¨ª®ªã |
(¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* ਫ®¦¥¨¥ @panel ¯¥à¥ª«îç ¥â à ᪫ ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ ⥫ï. |
====================================================================== |
============ Функция 26, подфункция 3 - получить базу CD. ============ |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì ¡ §ã CD. ============ |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 3 - номер подфункции |
Возвращаемое значение: |
* eax = база CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Замечания: |
* База CD используется функцией 24. |
* Установить базу CD можно вызовом подфункции 3 функции 21. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* § CD ¨á¯®«ì§ã¥âáï äãªæ¨¥© 24. |
* áâ ®¢¨âì ¡ §ã CD ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3 äãªæ¨¨ 21. |
====================================================================== |
========== Функция 26, подфункция 5 - получить язык системы. ========= |
========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì ï§ëª á¨á⥬ë. ========= |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 5 - номер подфункции |
Возвращаемое значение: |
* eax = язык системы (1=eng, 2=fi, 3=ger, 4=rus) |
Замечания: |
* Язык системы - глобальная системная переменная, никак |
не используемая самим ядром, однако приложение @panel рисует |
соответствующую иконку (используя описываемую функцию). |
* Установить язык системы можно вызовом подфункции 5 функции 21. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus) |
¬¥ç ¨ï: |
* §ëª á¨á⥬ë - £«®¡ «ì ï á¨á⥬ ï ¯¥à¥¬¥ ï, ¨ª ª |
¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤ ª® ¯à¨«®¦¥¨¥ @panel à¨áã¥â |
ᮮ⢥âáâ¢ãîéãî ¨ª®ªã (¨á¯®«ì§ãï ®¯¨áë¢ ¥¬ãî äãªæ¨î). |
* áâ ®¢¨âì ï§ëª á¨áâ¥¬ë ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 5 äãªæ¨¨ 21. |
====================================================================== |
============ Функция 26, подфункция 7 - получить базу HD. ============ |
============ ãªæ¨ï 26, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============ |
====================================================================== |
База HD нужна для определения, на какой жёсткий диск писать, при |
использовании устаревшего синтаксиса /HD в устаревшей функции 58; |
при использовании современного синтаксиса /HD0,/HD1,/HD2,/HD3 |
база устанавливается автоматически. |
Параметры: |
* eax = 26 - номер функции |
* ebx = 7 - номер подфункции |
Возвращаемое значение: |
* eax = база HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Замечания: |
* Любое приложение в любой момент времени может изменить базу. |
* Установить базу можно вызовом подфункции 7 функции 21. |
* Получить используемый раздел жёсткого диска можно подфункцией 8. |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* áâ ®¢¨âì ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 21. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 8. |
====================================================================== |
=========== Функция 26, подфункция 8 - получить раздел HD. =========== |
=========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 8 - ¯®«ãç¨âì à §¤¥« HD. =========== |
====================================================================== |
Раздел HD нужен для определения, на какой раздел жёсткого диска |
писать, при использовании устаревшего синтаксиса /HD в устаревшей |
функции 58; при использовании современного синтаксиса |
/HD0,/HD1,/HD2,/HD3 база и раздел устанавливаются автоматически. |
Параметры: |
* eax = 26 - номер функции |
* ebx = 8 - номер подфункции |
Возвращаемое значение: |
* eax = раздел HD (считая с 1) |
Замечания: |
* Любое приложение в любой момент времени может изменить раздел. |
* Установить раздел можно вызовом подфункции 8 функции 21. |
* Узнать число разделов на жёстком диске можно вызовом |
подфункции 11 функции 18. |
* Получить используемую базу жёсткого диска можно подфункцией 7. |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¤¥« HD (áç¨â ï á 1) |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* áâ ®¢¨âì à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 äãªæ¨¨ 21. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 7. |
====================================================================== |
=== Функция 26, подфункция 9 - получить значение счётчика времени. === |
=== ãªæ¨ï 26, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì § 票¥ áçñâ稪 ¢à¥¬¥¨. === |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 9 - номер подфункции |
Возвращаемое значение: |
* eax = число сотых долей секунды, прошедших с момента |
запуска системы |
Замечания: |
* Счётчик берётся по модулю 2^32, что соответствует немногим более |
497 суток. |
* Системное время можно получить функцией 3. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® á®âëå ¤®«¥© ᥪã¤ë, ¯à®è¥¤è¨å á ¬®¬¥â |
§ ¯ã᪠á¨á⥬ë |
¬¥ç ¨ï: |
* çñâ稪 ¡¥àñâáï ¯® ¬®¤ã«î 2^32, ç⮠ᮮ⢥âáâ¢ã¥â ¥¬®£¨¬ ¡®«¥¥ |
497 áã⮪. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ¯®«ãç¨âì äãªæ¨¥© 3. |
====================================================================== |
====================== Функция 26, подфункция 11 ===================== |
=========== Узнать, разрешён ли низкоуровневый доступ к HD. ========== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 11 ===================== |
=========== § âì, à §à¥èñ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª HD. ========== |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 11 - номер подфункции |
Возвращаемое значение: |
* eax = 0/1 - запрещён/разрешён |
Замечания: |
* Используется при LBA-чтении (подфункция 8 функции 58). |
* Установить текущее состояние можно вызовом |
подфункции 11 функции 21. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥éñ/à §à¥èñ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ LBA-ç⥨¨ (¯®¤äãªæ¨ï 8 äãªæ¨¨ 58). |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 21. |
====================================================================== |
====================== Функция 26, подфункция 12 ===================== |
========== Узнать, разрешён ли низкоуровневый доступ к PCI. ========== |
====================== ãªæ¨ï 26, ¯®¤äãªæ¨ï 12 ===================== |
========== § âì, à §à¥èñ «¨ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI. ========== |
====================================================================== |
Параметры: |
* eax = 26 - номер функции |
* ebx = 12 - номер подфункции |
Возвращаемое значение: |
* eax = 0/1 - запрещён/разрешён |
Замечания: |
* Используется при работе с шиной PCI (функция 62). |
* Текущая реализация использует только младший бит ecx. |
* Установить текущее состояние можно вызовом |
подфункции 12 функции 21. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0/1 - § ¯à¥éñ/à §à¥èñ |
¬¥ç ¨ï: |
* ᯮ«ì§ã¥âáï ¯à¨ à ¡®â¥ á 訮© PCI (äãªæ¨ï 62). |
* ¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx. |
* áâ ®¢¨âì ⥪ã饥 á®áâ®ï¨¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 12 äãªæ¨¨ 21. |
====================================================================== |
================ Функция 29 - получить системную дату. =============== |
================ ãªæ¨ï 29 - ¯®«ãç¨âì á¨á⥬ãî ¤ âã. =============== |
====================================================================== |
Параметры: |
* eax = 29 - номер функции |
Возвращаемое значение: |
* eax = 0x00DDMMYY, где |
(используется двоично-десятичное кодирование, BCD) |
* YY = две младшие цифры года (00..99) |
* MM = месяц (01..12) |
* DD = день (01..31) |
Замечания: |
* Системную дату можно установить функцией 22. |
à ¬¥âàë: |
* eax = 29 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00DDMMYY, £¤¥ |
(¨á¯®«ì§ã¥âáï ¤¢®¨ç®-¤¥áïâ¨ç®¥ ª®¤¨à®¢ ¨¥, BCD) |
* YY = ¤¢¥ ¬« ¤è¨¥ æ¨äàë £®¤ (00..99) |
* MM = ¬¥áïæ (01..12) |
* DD = ¤¥ì (01..31) |
¬¥ç ¨ï: |
* ¨á⥬ãî ¤ âã ¬®¦® ãáâ ®¢¨âì äãªæ¨¥© 22. |
====================================================================== |
================ Функция 30 - работа с текущей папкой. =============== |
================ ãªæ¨ï 30 - à ¡®â á ⥪ã饩 ¯ ¯ª®©. =============== |
====================================================================== |
-------- Подфункция 1 - установить текущую папку для потока. --------- |
Параметры: |
* eax = 30 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = указатель на ASCIIZ-строку с путём к новой текущей папке |
Возвращаемое значение: |
* функция не возвращает значения |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . --------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯ãâñ¬ ª ®¢®© ⥪ã饩 ¯ ¯ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- Подфункция 2 - получить текущую папку для потока. ---------- |
Параметры: |
* eax = 30 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = указатель на буфер |
* edx = размер буфера |
Возвращаемое значение: |
* eax = длина имени текущей папки (включая завершающий 0) |
Замечания: |
* Если размера буфера недостаточно для копирования всего имени, |
копируются только первые (edx-1) байт и в конце ставится |
завершающий 0. |
* По умолчанию, текущая папка для потока - "/rd/1". |
* При создании процесса/потока текущая папка наследуется от |
родителя. |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . ---------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤«¨ ¨¬¥¨ ⥪ã饩 ¯ ¯ª¨ (¢ª«îç ï § ¢¥àè î騩 0) |
¬¥ç ¨ï: |
* ᫨ à §¬¥à ¡ãä¥à ¥¤®áâ â®ç® ¤«ï ª®¯¨à®¢ ¨ï ¢á¥£® ¨¬¥¨, |
ª®¯¨àãîâáï ⮫쪮 ¯¥à¢ë¥ (edx-1) ¡ ©â ¨ ¢ ª®æ¥ áâ ¢¨âáï |
§ ¢¥àè î騩 0. |
* ® 㬮«ç ¨î, ⥪ãé ï ¯ ¯ª ¤«ï ¯®â®ª - "/rd/1". |
* ਠᮧ¤ ¨¨ ¯à®æ¥áá /¯®â®ª ⥪ãé ï ¯ ¯ª á«¥¤ã¥âáï ®â |
த¨â¥«ï. |
====================================================================== |
========= Функция 34 - узнать кому принадлежит точка экрана. ========= |
========= ãªæ¨ï 34 - 㧠âì ª®¬ã ¯à¨ ¤«¥¦¨â â®çª íªà . ========= |
====================================================================== |
Параметры: |
* eax = 34 - номер функции |
* ebx = x-координата (относительно экрана) |
* ecx = y-координата (относительно экрана) |
à ¬¥âàë: |
* eax = 34 - ®¬¥à äãªæ¨¨ |
* ebx = x-ª®®à¤¨ â (®â®á¨â¥«ì® íªà ) |
* ecx = y-ª®®à¤¨ â (®â®á¨â¥«ì® íªà ) |
Возвращаемое значение: |
* eax = 0x000000XX - точка принадлежит слоту окна N |
При некорректных значениях ebx и ecx функция возвращает 0 |
* Функция берет значения из области [_WinMapAddress] |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x000000XX - â®çª ¯à¨ ¤«¥¦¨â á«®âã ®ª N |
ਠ¥ª®à४âëå § 票ïå ebx ¨ ecx äãªæ¨ï ¢®§¢à é ¥â 0 |
* ãªæ¨ï ¡¥à¥â § ç¥¨ï ¨§ ®¡« á⨠[_WinMapAddress] |
====================================================================== |
============ Функция 35 - прочитать цвет точки на экране. ============ |
============ ãªæ¨ï 35 - ¯à®ç¨â âì 梥â â®çª¨ íªà ¥. ============ |
====================================================================== |
Параметры: |
à ¬¥âàë: |
* eax = 35 |
* ebx = y*xsize+x, где |
* (x,y) = координаты точки (считая от 0) |
* xsize = размер экрана по горизонтали |
Возвращаемое значение: |
* eax = цвет 0x00RRGGBB |
Замечания: |
* Узнать размеры экрана можно вызовом функции 14. Обратите внимание, |
что она вычитает 1 из обоих размеров. |
* К видеопамяти есть также прямой доступ (без вызовов системных |
функций) через селектор gs. Параметры текущего видеорежима |
можно получить функцией 61. |
* ebx = y*xsize+x, £¤¥ |
* (x,y) = ª®®à¤¨ âë â®çª¨ (áç¨â ï ®â 0) |
* xsize = à §¬¥à íªà ¯® £®à¨§®â «¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 梥â 0x00RRGGBB |
¬¥ç ¨ï: |
* § âì à §¬¥àë íªà ¬®¦® ¢ë§®¢®¬ äãªæ¨¨ 14. ¡à â¨â¥ ¢¨¬ ¨¥, |
çâ® ® ¢ëç¨â ¥â 1 ¨§ ®¡®¨å à §¬¥à®¢. |
* ¢¨¤¥®¯ ¬ï⨠¥áâì â ª¦¥ ¯àאַ© ¤®áâ㯠(¡¥§ ¢ë§®¢®¢ á¨á⥬ëå |
äãªæ¨©) ç¥à¥§ ᥫ¥ªâ®à gs. à ¬¥âàë ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬®¦® ¯®«ãç¨âì äãªæ¨¥© 61. |
====================================================================== |
=============== Функция 36 - прочитать область экрана. =============== |
=============== ãªæ¨ï 36 - ¯à®ç¨â âì ®¡« áâì íªà . =============== |
====================================================================== |
Параметры: |
* eax = 36 - номер функции |
* ebx = указатель на предварительно выделенную область памяти, |
куда будет помещено изображение в формате BBGGRRBBGGRR... |
* ecx = [размер по оси x]*65536 + [размер по оси y] |
* edx = [координата по оси x]*65536 + [координата по оси y] |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Координаты области - это координаты верхнего левого угла |
области относительно экрана. |
* Размер изображения в байтах есть 3*xsize*ysize. |
à ¬¥âàë: |
* eax = 36 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¯à¥¤¢ à¨â¥«ì® ¢ë¤¥«¥ãî ®¡« áâì ¯ ¬ïâ¨, |
ªã¤ ¡ã¤¥â ¯®¬¥é¥® ¨§®¡à ¦¥¨¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ®¡« á⨠- íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
®¡« á⨠®â®á¨â¥«ì® íªà . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize. |
====================================================================== |
==================== Функция 37 - работа с мышью. ==================== |
==================== ãªæ¨ï 37 - à ¡®â á ¬ëèìî. ==================== |
====================================================================== |
-------------- Подфункция 0 - экранные координаты мыши --------------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 0 - номер подфункции |
Возвращаемое значение: |
* eax = x*65536 + y, (x,y)=координаты курсора мыши (считая от 0) |
-------------- ®¤äãªæ¨ï 0 - íªà ë¥ ª®®à¤¨ âë ¬ëè¨ --------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ (áç¨â ï ®â 0) |
---------- Подфункция 1 - координаты мыши относительно окна ---------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = x*65536 + y, (x,y)=координаты курсора мыши относительно |
окна приложения (считая от 0) |
Замечания: |
* Значение вычисляется по формуле (x-xwnd)*65536 + (y-ywnd). |
Если y>=ywnd, то младшее слово неотрицательно и содержит |
относительную y-координату, а старшее - относительную x-координату |
(правильного знака). В противном случае младшее слово отрицательно |
и всё равно содержит относительную y-координату, |
а к старшему слову следует прибавить 1. |
---------- ®¤äãªæ¨ï 1 - ª®®à¤¨ âë ¬ëè¨ ®â®á¨â¥«ì® ®ª ---------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ ®â®á¨â¥«ì® |
®ª ¯à¨«®¦¥¨ï (áç¨â ï ®â 0) |
¬¥ç ¨ï: |
* 票¥ ¢ëç¨á«ï¥âáï ¯® ä®à¬ã«¥ (x-xwnd)*65536 + (y-ywnd). |
᫨ y>=ywnd, â® ¬« ¤è¥¥ á«®¢® ¥®âà¨æ â¥«ì® ¨ ᮤ¥à¦¨â |
®â®á¨â¥«ìãî y-ª®®à¤¨ âã, áâ à襥 - ®â®á¨â¥«ìãî x-ª®®à¤¨ âã |
(¯à ¢¨«ì®£® § ª ). ¯à®â¨¢®¬ á«ãç ¥ ¬« ¤è¥¥ á«®¢® ®âà¨æ â¥«ì® |
¨ ¢áñ à ¢® ᮤ¥à¦¨â ®â®á¨â¥«ìãî y-ª®®à¤¨ âã, |
ª áâ à襬ã á«®¢ã á«¥¤ã¥â ¯à¨¡ ¢¨âì 1. |
----------------- Подфункция 2 - нажатые кнопки мыши ----------------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 2 - номер подфункции |
Возвращаемое значение: |
* eax содержит информацию о нажатых кнопках мыши: |
* бит 0 установлен = левая кнопка нажата |
* бит 1 установлен = правая кнопка нажата |
* бит 2 установлен = средняя кнопка нажата |
* бит 3 установлен = 4-я кнопка нажата |
* бит 4 установлен = 5-я кнопка нажата |
* прочие биты сброшены |
----------------- ®¤äãªæ¨ï 2 - ¦ âë¥ ª®¯ª¨ ¬ëè¨ ----------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® ¦ âëå ª®¯ª å ¬ëè¨: |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â |
* ¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â |
* ¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
------------------ Подфункция 4 - загрузить курсор ------------------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 4 - номер подфункции |
* dx = источник данных: |
* dx = LOAD_FROM_FILE = 0 - данные в файле |
* ecx = указатель на полный путь к файлу курсора |
* файл курсора должен быть в формате .cur, стандартном для |
MS Windows, причём размером 32*32 пикселя |
* dx = LOAD_FROM_MEM = 1 - данные файла уже загружены в память |
* ecx = указатель на данные файла курсора |
* формат данных такой же, как и в предыдущем случае |
* dx = LOAD_INDIRECT = 2 - данные в памяти |
* ecx = указатель на образ курсора в формате ARGB 32*32 пикселя |
* edx = 0xXXYY0002, где |
* XX = x-координата "горячей точки" курсора |
* YY = y-координата |
------------------ ®¤äãªæ¨ï 4 - § £à㧨âì ªãàá®à ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* dx = ¨áâ®ç¨ª ¤ ëå: |
* dx = LOAD_FROM_FILE = 0 - ¤ ë¥ ¢ ä ©«¥ |
* ecx = 㪠§ â¥«ì ¯®«ë© ¯ãâì ª ä ©«ã ªãàá®à |
* ä ©« ªãàá®à ¤®«¦¥ ¡ëâì ¢ ä®à¬ ⥠.cur, áâ ¤ à⮬ ¤«ï |
MS Windows, ¯à¨çñ¬ à §¬¥à®¬ 32*32 ¯¨ªá¥«ï |
* dx = LOAD_FROM_MEM = 1 - ¤ ë¥ ä ©« 㦥 § £àã¦¥ë ¢ ¯ ¬ïâì |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä ©« ªãàá®à |
* ä®à¬ â ¤ ëå â ª®© ¦¥, ª ª ¨ ¢ ¯à¥¤ë¤ã饬 á«ãç ¥ |
* dx = LOAD_INDIRECT = 2 - ¤ ë¥ ¢ ¯ ¬ï⨠|
* ecx = 㪠§ â¥«ì ®¡à § ªãàá®à ¢ ä®à¬ ⥠ARGB 32*32 ¯¨ªá¥«ï |
* edx = 0xXXYY0002, £¤¥ |
* XX = x-ª®®à¤¨ â "£®àï祩 â®çª¨" ªãàá®à |
* YY = y-ª®®à¤¨ â |
* 0 <= XX, YY <= 31 |
Возвращаемое значение: |
* eax = 0 - неудача |
* иначе eax = хэндл курсора |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ªãàá®à |
------------------ Подфункция 5 - установить курсор ------------------ |
Устанавливает новый курсор для окна текущего потока. |
Параметры: |
* eax = 37 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = хэндл курсора |
Возвращаемое значение: |
* eax = хэндл предыдущего установленного курсора |
Замечания: |
* Если передан некорректный хэндл, то функция восстановит курсор |
по умолчанию (стандартную стрелку). В частности, к восстановлению |
курсора по умолчанию приводит передача ecx=0. |
------------------ ®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ªãàá®à ------------------ |
áâ ¢«¨¢ ¥â ®¢ë© ªãàá®à ¤«ï ®ª ⥪ã饣® ¯®â®ª . |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = åí¤« ¯à¥¤ë¤ã饣® ãáâ ®¢«¥®£® ªãàá®à |
¬¥ç ¨ï: |
* ᫨ ¯¥à¥¤ ¥ª®à४âë© åí¤«, â® äãªæ¨ï ¢®ááâ ®¢¨â ªãàá®à |
¯® 㬮«ç ¨î (áâ ¤ àâãî áâ५ªã). ç áâ®áâ¨, ª ¢®ááâ ®¢«¥¨î |
ªãàá®à ¯® 㬮«ç ¨î ¯à¨¢®¤¨â ¯¥à¥¤ ç ecx=0. |
------------------- Подфункция 6 - удалить курсор -------------------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 6 - номер подфункции |
* ecx = хэндл курсора |
Возвращаемое значение: |
* eax разрушается |
Замечания: |
* Курсор должен был быть ранее загружен текущим потоком |
(вызовом подфункции 4). Функция не удаляет системные курсоры и |
курсоры, загруженные другими приложениями. |
* Если удаляется активный (установленный подфункцией 5) курсор, то |
восстанавливается курсор по умолчанию (стандартная стрелка). |
------------------- ®¤äãªæ¨ï 6 - 㤠«¨âì ªãàá®à -------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãàá®à ¤®«¦¥ ¡ë« ¡ëâì à ¥¥ § £à㦥 ⥪ã騬 ¯®â®ª®¬ |
(¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4). ãªæ¨ï ¥ 㤠«ï¥â á¨áâ¥¬ë¥ ªãàá®àë ¨ |
ªãàá®àë, § £àã¦¥ë¥ ¤à㣨¬¨ ¯à¨«®¦¥¨ï¬¨. |
* ᫨ 㤠«ï¥âáï ªâ¨¢ë© (ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 5) ªãàá®à, â® |
¢®ááâ ¢«¨¢ ¥âáï ªãàá®à ¯® 㬮«ç ¨î (áâ ¤ àâ ï áâ५ª ). |
------------------ Подфункция 7 - данные прокрутки ------------------- |
Параметры: |
* eax = 37 - номер функции |
* ebx = 7 - номер подфункции |
Возвращаемое значение: |
------------------ ®¤äãªæ¨ï 7 - ¤ ë¥ ¯à®ªàã⪨ ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [horizontal offset]*65536 + [vertical offset] |
Замечания: |
* Данные доступны только активному окну. |
* После прочтения значения обнуляются. |
* Данные имеют знаковые значения. |
¬¥ç ¨ï: |
* ë¥ ¤®áâã¯ë ⮫쪮 ªâ¨¢®¬ã ®ªã. |
* ®á«¥ ¯à®çâ¥¨ï § ç¥¨ï ®¡ã«ïîâáï. |
* ë¥ ¨¬¥îâ § ª®¢ë¥ § 票ï. |
====================================================================== |
================== Функция 38 - нарисовать отрезок. ================== |
================== ãªæ¨ï 38 - à¨á®¢ âì ®â१®ª. ================== |
====================================================================== |
Параметры: |
* eax = 38 - номер функции |
* ebx = [координата начала по оси x]*65536 + |
[координата конца по оси x] |
* ecx = [координата начала по оси y]*65536 + |
[координата конца по оси y] |
* edx = 0x00RRGGBB - цвет |
edx = 0x01xxxxxx - рисовать инверсный отрезок |
(младшие 24 бита игнорируются) |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Координаты берутся относительно окна. |
* Конечная точка также рисуется. |
à ¬¥âàë: |
* eax = 38 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ç « ¯® ®á¨ x]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ç « ¯® ®á¨ y]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ y] |
* edx = 0x00RRGGBB - 梥â |
edx = 0x01xxxxxx - à¨á®¢ âì ¨¢¥àáë© ®â१®ª |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ®¥ç ï â®çª â ª¦¥ à¨áã¥âáï. |
====================================================================== |
== Функция 39, подфункция 1 - получить размер фонового изображения. == |
== ãªæ¨ï 39, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. == |
====================================================================== |
Параметры: |
* eax = 39 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = [ширина]*65536 + [высота] |
Замечания: |
* Есть парная команда установки размеров фонового изображения - |
подфункция 1 функции 15. После которой, разумеется, следует |
заново определить само изображение. |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
¬¥ç ¨ï: |
* áâì ¯ à ï ª®¬ ¤ ãáâ ®¢ª¨ à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 15. ®á«¥ ª®â®à®©, à §ã¬¥¥âáï, á«¥¤ã¥â |
§ ®¢® ®¯à¥¤¥«¨âì á ¬® ¨§®¡à ¦¥¨¥. |
====================================================================== |
= Функция 39, подфункция 2 - прочитать точку с фонового изображения. = |
= ãªæ¨ï 39, ¯®¤äãªæ¨ï 2 - ¯à®ç¨â âì â®çªã á ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
Параметры: |
* eax = 39 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = смещение |
Возвращаемое значение: |
* eax = 0x00RRGGBB - цвет точки, если смещение допустимо |
(меньше 0x160000-16) |
* eax = 2 - иначе |
Замечания: |
* Не следует полагаться на возвращаемое значение в случае неверного |
смещения, оно может измениться в следующих версиях ядра. |
* Смещение точки с координатами (x,y) вычисляется как (x+y*xsize)*3. |
* Есть парная функция установки точки на фоновом изображении - |
подфункция 2 функции 15. |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00RRGGBB - 梥â â®çª¨, ¥á«¨ ᬥ饨¥ ¤®¯ãá⨬® |
(¬¥ìè¥ 0x160000-16) |
* eax = 2 - ¨ ç¥ |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¢ á«ãç ¥ ¥¢¥à®£® |
ᬥ饨ï, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
* ¬¥é¥¨¥ â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª (x+y*xsize)*3. |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ â®çª¨ ä®®¢®¬ ¨§®¡à ¦¥¨¨ - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 15. |
====================================================================== |
====== Функция 39, подфункция 4 - получить режим отрисовки фона. ===== |
====== ãªæ¨ï 39, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ===== |
====================================================================== |
Параметры: |
* eax = 39 - номер функции |
* ebx = 4 - номер подфункции |
Возвращаемое значение: |
* eax = 1 - замостить |
* eax = 2 - растянуть |
Замечания: |
* Есть парная функция установки режима отрисовки фона - |
подфункция 4 функции 15. |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - § ¬®áâ¨âì |
* eax = 2 - à áâïãâì |
¬¥ç ¨ï: |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 15. |
====================================================================== |
======== Функция 40 - установить маску для ожидаемых событий. ======== |
======== ãªæ¨ï 40 - ãáâ ®¢¨âì ¬ áªã ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩. ======== |
====================================================================== |
Маска для ожидаемых событий влияет на функции работы с событиями 10, |
11, 23 - они сообщают только о событиях, разрешённых этой маской. |
Параметры: |
* eax = 40 - номер функции |
* ebx = маска: бит i соответствует событию i+1 (см. список событий) |
(установленный бит разрешает извещение о событии) |
Возвращаемое значение: |
* eax = предыдущее значение маски |
Замечания: |
* Маска по умолчанию (7=111b) разрешает извещения о перерисовке |
и нажатиях клавиш и кнопок. |
Этого достаточно для большинства приложений. |
* События, запрещённые в маске, всё равно сохраняются, если |
приходят; о них просто не извещают функции работы с событиями. |
* Функции работы с событиями учитывают маску на момент |
вызова функции, а не на момент поступления сообщения. |
᪠¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩ ¢«¨ï¥â äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ 10, |
11, 23 - ®¨ á®®¡é îâ ⮫쪮 ® ᮡëâ¨ïå, à §à¥èñëå í⮩ ¬ ᪮©. |
à ¬¥âàë: |
* eax = 40 - ®¬¥à äãªæ¨¨ |
* ebx = ¬ ᪠: ¡¨â i ᮮ⢥âáâ¢ã¥â ᮡëâ¨î i+1 (á¬. ᯨ᮪ ᮡë⨩) |
(ãáâ ®¢«¥ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥¨¥ ® ᮡë⨨) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¯à¥¤ë¤ã饥 § 票¥ ¬ ᪨ |
¬¥ç ¨ï: |
* ᪠¯® 㬮«ç ¨î (7=111b) à §à¥è ¥â ¨§¢¥é¥¨ï ® ¯¥à¥à¨á®¢ª¥ |
¨ ¦ â¨ïå ª« ¢¨è ¨ ª®¯®ª. |
⮣® ¤®áâ â®ç® ¤«ï ¡®«ìè¨á⢠¯à¨«®¦¥¨©. |
* ®¡ëâ¨ï, § ¯à¥éñë¥ ¢ ¬ ᪥, ¢áñ à ¢® á®åà ïîâáï, ¥á«¨ |
¯à¨å®¤ïâ; ® ¨å ¯à®áâ® ¥ ¨§¢¥é îâ äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨. |
* ãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ ãç¨âë¢ îâ ¬ áªã ¬®¬¥â |
¢ë§®¢ äãªæ¨¨, ¥ ¬®¬¥â ¯®áâ㯫¥¨ï á®®¡é¥¨ï. |
====================================================================== |
=================== Функция 43 - ввод/вывод в порт. ================== |
=================== ãªæ¨ï 43 - ¢¢®¤/¢ë¢®¤ ¢ ¯®àâ. ================== |
====================================================================== |
------------------------ Вывод данных в порт ------------------------- |
Параметры: |
* eax = 43 - номер функции |
* bl = байт для вывода |
* ecx = номер порта 0xnnnn (от 0 до 0xFFFF) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - поток не зарезервировал указанный порт |
------------------------ 뢮¤ ¤ ëå ¢ ¯®àâ ------------------------- |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* bl = ¡ ©â ¤«ï ¢ë¢®¤ |
* ecx = ®¬¥à ¯®àâ 0xnnnn (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « 㪠§ ë© ¯®àâ |
------------------------ Ввод данных из порта ------------------------ |
Параметры: |
* eax = 43 - номер функции |
* ebx игнорируется |
* ecx = 0x8000nnnn, где nnnn = номер порта (от 0 до 0xFFFF) |
Возвращаемое значение: |
* eax = 0 - успешно, при этом ebx = введённый байт |
* eax = 1 - поток не зарезервировал данный порт |
Замечания: |
* Предварительно поток должен зарезервировать за собой |
указанный порт функцией 46. |
* Для зарезервированных портов вместо вызова этих функций |
лучше использовать команды процессора in/out - это значительно |
быстрее и несколько короче и проще. Из незарезервированных |
портов читать всё равно нельзя. |
------------------------ ¢®¤ ¤ ëå ¨§ ¯®àâ ------------------------ |
à ¬¥âàë: |
* eax = 43 - ®¬¥à äãªæ¨¨ |
* ebx ¨£®à¨àã¥âáï |
* ecx = 0x8000nnnn, £¤¥ nnnn = ®¬¥à ¯®àâ (®â 0 ¤® 0xFFFF) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¯à¨ í⮬ ebx = ¢¢¥¤ñë© ¡ ©â |
* eax = 1 - ¯®â®ª ¥ § १¥à¢¨à®¢ « ¤ ë© ¯®àâ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¯®â®ª ¤®«¦¥ § १¥à¢¨à®¢ âì § ᮡ®© |
㪠§ ë© ¯®àâ äãªæ¨¥© 46. |
* «ï § १¥à¢¨à®¢ ëå ¯®à⮢ ¢¬¥áâ® ¢ë§®¢ íâ¨å äãªæ¨© |
«ãçè¥ ¨á¯®«ì§®¢ âì ª®¬ ¤ë ¯à®æ¥áá®à in/out - íâ® § ç¨â¥«ì® |
¡ëáâ॥ ¨ ¥áª®«ìª® ª®à®ç¥ ¨ ¯à®é¥. § ¥§ १¥à¢¨à®¢ ëå |
¯®à⮢ ç¨â âì ¢áñ à ¢® ¥«ì§ï. |
====================================================================== |
= Функция 46 - зарезервировать/освободить группу портов ввода/вывода. |
= ãªæ¨ï 46 - § १¥à¢¨à®¢ âì/®á¢®¡®¤¨âì £à㯯㠯®à⮢ ¢¢®¤ /¢ë¢®¤ . |
====================================================================== |
К зарезервированным портам можно обращаться напрямую из приложения |
командами in/out (рекомендуемый способ) и вызовом функции 43 |
(нерекомендуемый способ). |
Параметры: |
* eax = 46 - номер функции |
* ebx = 0 - зарезервировать, 1 - освободить |
* ecx = номер начала диапазона портов |
* edx = номер конца диапазона портов (включительно) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - ошибка |
Замечания: |
* В случае резервирования портов ошибкой считается выполнение |
одного из условий: |
* начальный адрес больше конечного; |
* указанный диапазон содержит некорректный номер порта |
(корректные - от 0 до 0xFFFF); |
* превышено ограничение на общее число зарезервированных областей |
- допускается максимум 255; |
* указанный диапазон пересекается с одним из |
ранее зарезервированных |
* В случае освобождения портов ошибкой считается попытка |
освобождения диапазона, который ранее не был целиком |
зарезервирован этой же функцией (с такими же значениями ecx,edx). |
* При обнаружении ошибки (в обоих случаях) никаких действий |
не производится. |
* При загрузке система резервирует за собой порты |
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (включительно). |
* При завершении потока автоматически освобождаются все |
зарезервированные им порты. |
§ १¥à¢¨à®¢ ë¬ ¯®àâ ¬ ¬®¦® ®¡à é âìáï ¯àï¬ãî ¨§ ¯à¨«®¦¥¨ï |
ª®¬ ¤ ¬¨ in/out (४®¬¥¤ã¥¬ë© ᯮᮡ) ¨ ¢ë§®¢®¬ äãªæ¨¨ 43 |
(¥à¥ª®¬¥¤ã¥¬ë© ᯮᮡ). |
à ¬¥âàë: |
* eax = 46 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - § १¥à¢¨à®¢ âì, 1 - ®á¢®¡®¤¨âì |
* ecx = ®¬¥à ç « ¤¨ ¯ §® ¯®à⮢ |
* edx = ®¬¥à ª®æ ¤¨ ¯ §® ¯®à⮢ (¢ª«îç¨â¥«ì®) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª |
¬¥ç ¨ï: |
* á«ãç ¥ १¥à¢¨à®¢ ¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¢ë¯®«¥¨¥ |
®¤®£® ¨§ ãá«®¢¨©: |
* ç «ìë© ¤à¥á ¡®«ìè¥ ª®¥ç®£®; |
* 㪠§ ë© ¤¨ ¯ §® ᮤ¥à¦¨â ¥ª®à४âë© ®¬¥à ¯®àâ |
(ª®à४âë¥ - ®â 0 ¤® 0xFFFF); |
* ¯à¥¢ë襮 ®£à ¨ç¥¨¥ ®¡é¥¥ ç¨á«® § १¥à¢¨à®¢ ëå ®¡« á⥩ |
- ¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 255; |
* 㪠§ ë© ¤¨ ¯ §® ¯¥à¥á¥ª ¥âáï á ®¤¨¬ ¨§ |
à ¥¥ § १¥à¢¨à®¢ ëå |
* á«ãç ¥ ®á¢®¡®¦¤¥¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¯®¯ë⪠|
®á¢®¡®¦¤¥¨ï ¤¨ ¯ §® , ª®â®àë© à ¥¥ ¥ ¡ë« 楫¨ª®¬ |
§ १¥à¢¨à®¢ í⮩ ¦¥ äãªæ¨¥© (á â ª¨¬¨ ¦¥ § 票ﬨ ecx,edx). |
* ਠ®¡ à㦥¨¨ ®è¨¡ª¨ (¢ ®¡®¨å á«ãç ïå) ¨ª ª¨å ¤¥©á⢨© |
¥ ¯à®¨§¢®¤¨âáï. |
* ਠ§ £à㧪¥ á¨á⥬ १¥à¢¨àã¥â § ᮡ®© ¯®àâë |
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (¢ª«îç¨â¥«ì®). |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥ |
§ १¥à¢¨à®¢ ë¥ ¨¬ ¯®àâë. |
====================================================================== |
================= Функция 47 - вывести число в окно. ================= |
================= ãªæ¨ï 47 - ¢ë¢¥á⨠ç¨á«® ¢ ®ª®. ================= |
====================================================================== |
Параметры: |
* eax = 47 - номер функции |
* ebx = параметры преобразования числа в текст: |
* bl = 0 - ecx содержит число |
* bl = 1 - ecx содержит указатель на dword/qword-число |
* bh = 0 - отображать в десятичной системе счисления |
* bh = 1 - отображать в шестнадцатеричной системе |
* bh = 2 - отображать в двоичной системе |
* биты 16-21 = сколько цифр отображать |
* биты 22-29 зарезервированы и должны быть установлены в 0 |
* бит 30 установлен = выводить qword (64-битное число); |
при этом должно быть bl = 1 |
* бит 31 установлен = не выводить ведущие нули числа |
* ecx = число (при bl=0) или указатель (при bl=1) |
* edx = [координата по оси x]*65536 + [координата по оси y] |
à ¬¥âàë: |
* eax = 47 - ®¬¥à äãªæ¨¨ |
* ebx = ¯ à ¬¥âàë ¯à¥®¡à §®¢ ¨ï ç¨á« ¢ ⥪áâ: |
* bl = 0 - ecx ᮤ¥à¦¨â ç¨á«® |
* bl = 1 - ecx ᮤ¥à¦¨â 㪠§ ⥫ì dword/qword-ç¨á«® |
* bh = 0 - ®â®¡à ¦ âì ¢ ¤¥áïâ¨ç®© á¨á⥬¥ áç¨á«¥¨ï |
* bh = 1 - ®â®¡à ¦ âì ¢ è¥áâ ¤æ â¥à¨ç®© á¨á⥬¥ |
* bh = 2 - ®â®¡à ¦ âì ¢ ¤¢®¨ç®© á¨á⥬¥ |
* ¡¨âë 16-21 = ᪮«ìª® æ¨äà ®â®¡à ¦ âì |
* ¡¨âë 22-29 § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* ¡¨â 30 ãáâ ®¢«¥ = ¢ë¢®¤¨âì qword (64-¡¨â®¥ ç¨á«®); |
¯à¨ í⮬ ¤®«¦® ¡ëâì bl = 1 |
* ¡¨â 31 ãáâ ®¢«¥ = ¥ ¢ë¢®¤¨âì ¢¥¤ã騥 㫨 ç¨á« |
* ecx = ç¨á«® (¯à¨ bl=0) ¨«¨ 㪠§ ⥫ì (¯à¨ bl=1) |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = 0xX0RRGGBB: |
* RR, GG, BB задают цвет |
* X = ABnn (биты) |
* nn = шрифт (0/1) |
* A игнорируется |
* B=1 - закрашивать фон цветом edi |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Указанная длина не должна превосходить 60. |
* Выводится ровно указанное количество цифр. Если число мало и |
может быть записано меньшим количеством цифр, оно дополняется |
ведущими нулями; если число велико и не может быть записано |
таким количеством цифр, "лишние" ведущие цифры обрезаются. |
* Параметры шрифтов указаны в описании функции 4 (вывода текста). |
* RR, GG, BB § ¤ îâ 梥â |
* X = ABnn (¡¨âë) |
* nn = èà¨äâ (0/1) |
* A ¨£®à¨àã¥âáï |
* B=1 - § ªà 訢 âì ä® æ¢¥â®¬ edi |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ï ¤«¨ ¥ ¤®«¦ ¯à¥¢®á室¨âì 60. |
* 뢮¤¨âáï ஢® 㪠§ ®¥ ª®«¨ç¥á⢮ æ¨äà. ᫨ ç¨á«® ¬ «® ¨ |
¬®¦¥â ¡ëâì § ¯¨á ® ¬¥ì訬 ª®«¨ç¥á⢮¬ æ¨äà, ®® ¤®¯®«ï¥âáï |
¢¥¤ã騬¨ ã«ï¬¨; ¥á«¨ ç¨á«® ¢¥«¨ª® ¨ ¥ ¬®¦¥â ¡ëâì § ¯¨á ® |
â ª¨¬ ª®«¨ç¥á⢮¬ æ¨äà, "«¨è¨¥" ¢¥¤ã騥 æ¨äàë ®¡à¥§ îâáï. |
* à ¬¥âàë èà¨ä⮢ 㪠§ ë ¢ ®¯¨á ¨¨ äãªæ¨¨ 4 (¢ë¢®¤ ⥪áâ ). |
====================================================================== |
======= Функция 48, подфункция 0 - применить настройки экрана. ======= |
======= ãªæ¨ï 48, ¯®¤äãªæ¨ï 0 - ¯à¨¬¥¨âì áâனª¨ íªà . ======= |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 0 - номер подфункции |
* ecx = 0 - зарезервировано |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Функция перерисовывает экран после изменения параметров |
подфункциями 1 и 2. |
* Вызов функции без предшествующих вызовов указанных подфункций |
игнорируется. |
* Вызов функции с ненулевым ecx игнорируется. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - § १¥à¢¨à®¢ ® |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ãªæ¨ï ¯¥à¥à¨á®¢ë¢ ¥â íªà ¯®á«¥ ¨§¬¥¥¨ï ¯ à ¬¥â஢ |
¯®¤äãªæ¨ï¬¨ 1 ¨ 2. |
* 맮¢ äãªæ¨¨ ¡¥§ ¯à¥¤è¥áâ¢ãîé¨å ¢ë§®¢®¢ 㪠§ ëå ¯®¤äãªæ¨© |
¨£®à¨àã¥âáï. |
* 맮¢ äãªæ¨¨ á ¥ã«¥¢ë¬ ecx ¨£®à¨àã¥âáï. |
====================================================================== |
========= Функция 48, подфункция 1 - установить стиль кнопок. ======== |
========= ãªæ¨ï 48, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì áâ¨«ì ª®¯®ª. ======== |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = тип кнопок: |
* 0 = плоские |
* 1 = объёмные |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* После вызова описываемой функции следует перерисовать экран |
подфункцией 0. |
* Тип кнопок влияет только на их прорисовку функцией 8. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ ª®¯®ª: |
* 0 = ¯«®áª¨¥ |
* 1 = ®¡êñ¬ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¨¯ ª®¯®ª ¢«¨ï¥â ⮫쪮 ¨å ¯à®à¨á®¢ªã äãªæ¨¥© 8. |
====================================================================== |
==== Функция 48, подфункция 2 - установить стандартные цвета окон. === |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. === |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = указатель на таблицу цветов |
* edx = размер таблицы цветов |
(должен быть 40 байт для будущей совместимости) |
Формат таблицы цветов указан в описании подфункции 3. |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* После вызова описываемой функции следует перерисовать экран |
подфункцией 0. |
* Таблица стандартных цветов влияет только на приложения, |
которые эту таблицу явным образом получают (подфункцией 3) и |
используют (указывая цвета из неё при вызовах функций рисования). |
* Таблица стандартных цветов входит в скин и устанавливается заново |
при установке скина (подфункции 8). |
* Таблицу цветов можно просматривать/изменять интерактивно с помощью |
приложения desktop. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì â ¡«¨æã 梥⮢ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®à¬ â â ¡«¨æë 梥⮢ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 3. |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®á«¥ ¢ë§®¢ ®¯¨áë¢ ¥¬®© äãªæ¨¨ á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà |
¯®¤äãªæ¨¥© 0. |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢«¨ï¥â ⮫쪮 ¯à¨«®¦¥¨ï, |
ª®â®àë¥ íâã â ¡«¨æã ï¢ë¬ ®¡à §®¬ ¯®«ãç îâ (¯®¤äãªæ¨¥© 3) ¨ |
¨á¯®«ì§ãîâ (㪠§ë¢ ï 梥⠨§ ¥ñ ¯à¨ ¢ë§®¢ å äãªæ¨© à¨á®¢ ¨ï). |
* ¡«¨æ áâ ¤ àâëå 梥⮢ ¢å®¤¨â ¢ ᪨ ¨ ãáâ ¢«¨¢ ¥âáï § ®¢® |
¯à¨ ãáâ ®¢ª¥ ᪨ (¯®¤äãªæ¨¨ 8). |
* ¡«¨æã 梥⮢ ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® á ¯®¬®éìî |
¯à¨«®¦¥¨ï desktop. |
====================================================================== |
===== Функция 48, подфункция 3 - получить стандартные цвета окон. ==== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 3 - ¯®«ãç¨âì áâ ¤ àâë¥ æ¢¥â ®ª®. ==== |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = указатель на буфер размером edx байт, |
куда будет записана таблица |
* edx = размер таблицы цветов |
(должен быть 40 байт для будущей совместимости) |
Возвращаемое значение: |
* функция не возвращает значения |
Формат таблицы цветов: каждый элемент - |
dword-значение цвета 0x00RRGGBB |
* +0: dword: frames - цвет рамки |
* +4: dword: grab - цвет заголовка |
* +8: dword: grab_button - цвет кнопки на полосе заголовка |
* +12 = +0xC: dword: grab_button_text - цвет текста на кнопке |
на полосе заголовка |
* +16 = +0x10: dword: grab_text - цвет текста на заголовке |
* +20 = +0x14: dword: work - цвет рабочей области |
* +24 = +0x18: dword: work_button - цвет кнопки в рабочей области |
* +28 = +0x1C: dword: work_button_text - цвет текста на кнопке |
в рабочей области |
* +32 = +0x20: dword: work_text - цвет текста в рабочей области |
* +36 = +0x24: dword: work_graph - цвет графики в рабочей области |
Замечания: |
* Структура таблицы цветов описана в стандартном включаемом файле |
macros.inc под названием system_colors; например, можно писать: |
sc system_colors ; объявление переменной |
... ; где-то надо вызвать |
; описываемую функцию с ecx=sc |
mov ecx, [sc.work_button_text] ; читаем цвет текста |
; на кнопке в рабочей области |
* Использование/неиспользование этих цветов - дело исключительно |
самой программы. Для использования нужно просто при вызове функций |
рисования указывать цвет, взятый из этой таблицы. |
* При изменении таблицы стандартных цветов (подфункцией 2 с |
последующим применением изменений подфункцией 0 или |
при установке скина подфункцией 8) всем окнам посылается сообщение |
о необходимости перерисовки (событие с кодом 1). |
* Стандартные цвета можно просматривать/изменять интерактивно |
с помощью приложения desktop. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ edx ¡ ©â, |
ªã¤ ¡ã¤¥â § ¯¨á â ¡«¨æ |
* edx = à §¬¥à â ¡«¨æë 梥⮢ |
(¤®«¦¥ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â â ¡«¨æë 梥⮢: ª ¦¤ë© í«¥¬¥â - |
dword-§ 票¥ 梥â 0x00RRGGBB |
* +0: dword: frames - 梥â à ¬ª¨ |
* +4: dword: grab - 梥⠧ £®«®¢ª |
* +8: dword: grab_button - 梥⠪®¯ª¨ ¯®«®á¥ § £®«®¢ª |
* +12 = +0xC: dword: grab_button_text - 梥â ⥪áâ ª®¯ª¥ |
¯®«®á¥ § £®«®¢ª |
* +16 = +0x10: dword: grab_text - 梥â ⥪áâ § £®«®¢ª¥ |
* +20 = +0x14: dword: work - 梥â à ¡®ç¥© ®¡« á⨠|
* +24 = +0x18: dword: work_button - 梥⠪®¯ª¨ ¢ à ¡®ç¥© ®¡« á⨠|
* +28 = +0x1C: dword: work_button_text - 梥â ⥪áâ ª®¯ª¥ |
¢ à ¡®ç¥© ®¡« á⨠|
* +32 = +0x20: dword: work_text - 梥â ⥪áâ ¢ à ¡®ç¥© ®¡« á⨠|
* +36 = +0x24: dword: work_graph - 梥⠣à 䨪¨ ¢ à ¡®ç¥© ®¡« á⨠|
¬¥ç ¨ï: |
* âàãªâãà â ¡«¨æë 梥⮢ ®¯¨á ¢ áâ ¤ à⮬ ¢ª«îç ¥¬®¬ ä ©«¥ |
macros.inc ¯®¤ §¢ ¨¥¬ system_colors; ¯à¨¬¥à, ¬®¦® ¯¨á âì: |
sc system_colors ; ®¡ê¥¨¥ ¯¥à¥¬¥®© |
... ; £¤¥-â® ¤® ¢ë§¢ âì |
; ®¯¨áë¢ ¥¬ãî äãªæ¨î á ecx=sc |
mov ecx, [sc.work_button_text] ; ç¨â ¥¬ 梥â ⥪áâ |
; ª®¯ª¥ ¢ à ¡®ç¥© ®¡« á⨠|
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ íâ¨å 梥⮢ - ¤¥«® ¨áª«îç¨â¥«ì® |
á ¬®© ¯à®£à ¬¬ë. «ï ¨á¯®«ì§®¢ ¨ï 㦮 ¯à®áâ® ¯à¨ ¢ë§®¢¥ äãªæ¨© |
à¨á®¢ ¨ï 㪠§ë¢ âì 梥â, ¢§ïâë© ¨§ í⮩ â ¡«¨æë. |
* ਠ¨§¬¥¥¨¨ â ¡«¨æë áâ ¤ àâëå 梥⮢ (¯®¤äãªæ¨¥© 2 á |
¯®á«¥¤ãî騬 ¯à¨¬¥¥¨¥¬ ¨§¬¥¥¨© ¯®¤äãªæ¨¥© 0 ¨«¨ |
¯à¨ ãáâ ®¢ª¥ ᪨ ¯®¤äãªæ¨¥© 8) ¢á¥¬ ®ª ¬ ¯®áë« ¥âáï á®®¡é¥¨¥ |
® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ á ª®¤®¬ 1). |
* â ¤ àâë¥ æ¢¥â ¬®¦® ¯à®á¬ âਢ âì/¨§¬¥ïâì ¨â¥à ªâ¨¢® |
á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
========== Функция 48, подфункция 4 - получить высоту скина. ========= |
========== ãªæ¨ï 48, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ¢ëá®âã ᪨ . ========= |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 4 - номер подфункции |
Возвращаемое значение: |
* eax = высота скина |
Замечания: |
* Высотой скина по определению считается высота заголовка окон, |
использующих скин. |
* Смотри также общую структуру окна в описании функции 0. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¢ëá®â ᪨ |
¬¥ç ¨ï: |
* ëá®â®© ᪨ ¯® ®¯à¥¤¥«¥¨î áç¨â ¥âáï ¢ëá®â § £®«®¢ª ®ª®, |
¨á¯®«ì§ãîé¨å ᪨. |
* ¬®âਠ⠪¦¥ ®¡éãî áâàãªâãàã ®ª ¢ ®¯¨á ¨¨ äãªæ¨¨ 0. |
====================================================================== |
===== Функция 48, подфункция 5 - получить рабочую область экрана. ==== |
===== ãªæ¨ï 48, ¯®¤äãªæ¨ï 5 - ¯®«ãç¨âì à ¡®çãî ®¡« áâì íªà . ==== |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 5 - номер подфункции |
Возвращаемое значение: |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Замечания: |
* Рабочая область экрана определяет положение и координаты |
максимизированного окна. |
* Рабочая область экрана при нормальной работе есть весь экран |
за вычетом панели (@panel). |
* (left,top) - координаты левого верхнего угла, |
(right,bottom) - координаты правого нижнего. |
Таким образом, размер рабочей области по оси x определяется |
формулой right-left+1, по оси y - формулой bottom-right+1. |
* Смотри также функцию 14, |
позволяющую определить размеры всего экрана. |
* Есть парная функция установки рабочей области - подфункция 6. |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* ¡®ç ï ®¡« áâì íªà ¯à¨ ®à¬ «ì®© à ¡®â¥ ¥áâì ¢¥áì íªà |
§ ¢ëç¥â®¬ ¯ ¥«¨ (@panel). |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ à ¡®ç¥© ®¡« á⨠- ¯®¤äãªæ¨ï 6. |
====================================================================== |
==== Функция 48, подфункция 6 - установить рабочую область экрана. === |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 6 - ãáâ ®¢¨âì à ¡®çãî ®¡« áâì íªà . === |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 6 - номер подфункции |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = [left]*65536 + [right] |
* edx = [top]*65536 + [bottom] |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Рабочая область экрана определяет положение и координаты |
максимизированного окна. |
* Эта функция используется только приложением @panel, |
устанавливающим рабочей областью весь экран за вычетом панели. |
* (left,top) - координаты левого верхнего угла, |
(right,bottom) - координаты правого нижнего. |
Таким образом, размер рабочей области по оси x определяется |
формулой right-left+1, по оси y - формулой bottom-right+1. |
* Если left>=right, то x-координаты рабочей области не изменяются. |
Если left<0, то left не устанавливается. Если right больше |
или равно ширины экрана, то right не устанавливается. |
Аналогично по оси y. |
* Смотри также функцию 14, |
позволяющую определить размеры всего экрана. |
* Есть парная функция получения рабочей области - |
подфункция 5. |
* Эта функция автоматически перерисовывает экран, по ходу дела |
обновляет координаты и размеры максимизированных окон. |
Все окна извещаются о необходимости перерисовки (событие 1). |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¡®ç ï ®¡« áâì íªà ®¯à¥¤¥«ï¥â ¯®«®¦¥¨¥ ¨ ª®®à¤¨ âë |
¬ ªá¨¬¨§¨à®¢ ®£® ®ª . |
* â äãªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¯à¨«®¦¥¨¥¬ @panel, |
ãáâ ¢«¨¢ î騬 à ¡®ç¥© ®¡« áâìî ¢¥áì íªà § ¢ëç¥â®¬ ¯ ¥«¨. |
* (left,top) - ª®®à¤¨ âë «¥¢®£® ¢¥à奣® 㣫 , |
(right,bottom) - ª®®à¤¨ âë ¯à ¢®£® ¨¦¥£®. |
ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï |
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1. |
* ᫨ left>=right, â® x-ª®®à¤¨ âë à ¡®ç¥© ®¡« á⨠¥ ¨§¬¥ïîâáï. |
᫨ left<0, â® left ¥ ãáâ ¢«¨¢ ¥âáï. ᫨ right ¡®«ìè¥ |
¨«¨ à ¢® è¨à¨ë íªà , â® right ¥ ãáâ ¢«¨¢ ¥âáï. |
«®£¨ç® ¯® ®á¨ y. |
* ¬®âਠ⠪¦¥ äãªæ¨î 14, |
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à ¡®ç¥© ®¡« á⨠- |
¯®¤äãªæ¨ï 5. |
* â äãªæ¨ï ¢â®¬ â¨ç¥áª¨ ¯¥à¥à¨á®¢ë¢ ¥â íªà , ¯® 室㠤¥« |
®¡®¢«ï¥â ª®®à¤¨ âë ¨ à §¬¥àë ¬ ªá¨¬¨§¨à®¢ ëå ®ª®. |
ᥠ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
====================================================================== |
====================== Функция 48, подфункция 7 ====================== |
============ Получить область скина для текста заголовка. ============ |
====================== ãªæ¨ï 48, ¯®¤äãªæ¨ï 7 ====================== |
============ ®«ãç¨âì ®¡« áâì ᪨ ¤«ï ⥪áâ § £®«®¢ª . ============ |
====================================================================== |
Возвращает область заголовка окна со скином, предназначенную |
для вывода текста заголовка. |
Параметры: |
* eax = 48 - номер функции |
* ebx = 7 - номер подфункции |
Возвращаемое значение: |
®§¢à é ¥â ®¡« áâì § £®«®¢ª ®ª ᮠ᪨®¬, ¯à¥¤ § ç¥ãî |
¤«ï ¢ë¢®¤ ⥪áâ § £®«®¢ª . |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [left]*65536 + [right] |
* ebx = [top]*65536 + [bottom] |
Замечания: |
* Использование/неиспользование этой функции - |
личное дело приложения. |
* Рекомендуется учитывать значения, возвращаемые этой функцией, |
при выборе места для рисования текста заголовка (функцией 4) или |
какого-нибудь заменителя текста заголовка |
(по усмотрению приложения). |
¬¥ç ¨ï: |
* ᯮ«ì§®¢ ¨¥/¥¨á¯®«ì§®¢ ¨¥ í⮩ äãªæ¨¨ - |
«¨ç®¥ ¤¥«® ¯à¨«®¦¥¨ï. |
* ¥ª®¬¥¤ã¥âáï ãç¨âë¢ âì § 票ï, ¢®§¢à é ¥¬ë¥ í⮩ äãªæ¨¥©, |
¯à¨ ¢ë¡®à¥ ¬¥áâ ¤«ï à¨á®¢ ¨ï ⥪áâ § £®«®¢ª (äãªæ¨¥© 4) ¨«¨ |
ª ª®£®-¨¡ã¤ì § ¬¥¨â¥«ï ⥪áâ § £®«®¢ª |
(¯® ãᬮâà¥¨î ¯à¨«®¦¥¨ï). |
====================================================================== |
==== Функция 48, подфункция 8 - установить используемый скин окон. === |
==== ãªæ¨ï 48, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì ¨á¯®«ì§ã¥¬ë© ᪨ ®ª®. === |
====================================================================== |
Параметры: |
* eax = 48 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = указатель на имя файла скина |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - не удалось загрузить файл |
* eax = 2 - файл не является файлом скина |
Замечания: |
* При успешной загрузке скина все окна извещаются о необходимости |
перерисовки (событие 1). |
* При загрузке система считывает скин из файла default.skn |
на рамдиске. |
* Пользователь может изменять скин статически, создав свой |
default.skn, или динамически с помощью приложения desktop. |
à ¬¥âàë: |
* eax = 48 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¨¬ï ä ©« ᪨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥ 㤠«®áì § £à㧨âì ä ©« |
* eax = 2 - ä ©« ¥ ï¥âáï ä ©«®¬ ᪨ |
¬¥ç ¨ï: |
* ਠãᯥ让 § £à㧪¥ ᪨ ¢á¥ ®ª ¨§¢¥é îâáï ® ¥®¡å®¤¨¬®á⨠|
¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1). |
* ਠ§ £à㧪¥ á¨á⥬ áç¨âë¢ ¥â ᪨ ¨§ ä ©« default.skn |
à ¬¤¨áª¥. |
* ®«ì§®¢ â¥«ì ¬®¦¥â ¨§¬¥ïâì ᪨ áâ â¨ç¥áª¨, ᮧ¤ ¢ ᢮© |
default.skn, ¨«¨ ¤¨ ¬¨ç¥áª¨ á ¯®¬®éìî ¯à¨«®¦¥¨ï desktop. |
====================================================================== |
============ Функция 49 - Advanced Power Management (APM). =========== |
============ ãªæ¨ï 49 - Advanced Power Management (APM). =========== |
====================================================================== |
Параметры: |
* eax = 49 - номер функции |
* dx = номер функции APM (аналог ax в спецификации) |
* bx, cx = параметры функции APM |
Возвращаемое значение: |
* 16-битные регистры ax, bx, cx, dx, si, di и флаг CF |
установлены в соответствии со спецификацией APM |
* старшие половины 32-битных регистров eax, ebx, ecx, |
edx, esi, edi разрушаются |
Замечания: |
* Спецификация APM 1.2 описывается в документе |
à ¬¥âàë: |
* eax = 49 - ®¬¥à äãªæ¨¨ |
* dx = ®¬¥à äãªæ¨¨ APM ( «®£ ax ¢ ᯥæ¨ä¨ª 樨) |
* bx, cx = ¯ à ¬¥âàë äãªæ¨¨ APM |
®§¢à é ¥¬®¥ § 票¥: |
* 16-¡¨âë¥ à¥£¨áâàë ax, bx, cx, dx, si, di ¨ ä« £ CF |
ãáâ ®¢«¥ë ¢ ᮮ⢥âá⢨¨ ᮠᯥæ¨ä¨ª 樥© APM |
* áâ à訥 ¯®«®¢¨ë 32-¡¨âëå ॣ¨áâ஢ eax, ebx, ecx, |
edx, esi, edi à §àãè îâáï |
¬¥ç ¨ï: |
* ¯¥æ¨ä¨ª æ¨ï APM 1.2 ®¯¨áë¢ ¥âáï ¢ ¤®ªã¬¥â¥ |
"Advanced Power Management (APM) BIOS Specification" |
(Revision 1.2), доступном на |
(Revision 1.2), ¤®áâ㯮¬ |
http://www.microsoft.com/whdc/archive/amp_12.mspx; |
кроме того, она включена в известный Interrupt List by Ralf Brown |
ªà®¬¥ ⮣®, ® ¢ª«îç¥ ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). |
====================================================================== |
================= Функция 50 - установка формы окна. ================= |
================= ãªæ¨ï 50 - ãáâ ®¢ª ä®à¬ë ®ª . ================= |
====================================================================== |
Обычные окна представляют собой прямоугольники. С помощью этой функции |
окну можно придать произвольную форму. Форма задаётся набором точек |
внутри обрамляющего прямоугольника, принадлежащих окну. Положение и |
размеры обрамляющего прямоугольника задаются функцией 0 и изменяются |
функцией 67. |
¡ëçë¥ ®ª ¯à¥¤áâ ¢«ïîâ ᮡ®© ¯àאַ㣮«ì¨ª¨. ¯®¬®éìî í⮩ äãªæ¨¨ |
®ªã ¬®¦® ¯à¨¤ âì ¯à®¨§¢®«ìãî ä®à¬ã. ®à¬ § ¤ ñâáï ¡®à®¬ â®ç¥ª |
¢ãâਠ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª , ¯à¨ ¤«¥¦ é¨å ®ªã. ®«®¦¥¨¥ ¨ |
à §¬¥àë ®¡à ¬«ïî饣® ¯àאַ㣮«ì¨ª § ¤ îâáï äãªæ¨¥© 0 ¨ ¨§¬¥ïîâáï |
äãªæ¨¥© 67. |
--------------- Установка данных с информацией о форме --------------- |
Параметры: |
* eax = 50 - номер функции |
* ebx = 0 - номер подфункции |
* ecx = указатель на данные формы (массив байт 0/1) |
Возвращаемое значение: |
* функция не возвращает значения |
--------------- áâ ®¢ª ¤ ëå á ¨ä®à¬ 樥© ® ä®à¬¥ --------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä®à¬ë (¬ áᨢ ¡ ©â 0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
------------------ Установка масштаба данных формы ------------------- |
Параметры: |
* eax = 50 - номер функции |
* ebx = 1 - номер подфункции |
* ecx задаёт масштаб: каждый байт данных определяет |
(2^scale)*(2^scale) пикселей |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Масштаб по умолчанию равен 0 (масштабирующий множитель 1). Если в |
данных формы один байт соответствует одному пикселю, то масштаб |
можно не устанавливать. |
* Обозначим xsize = ширина окна (в пикселях), ysize = высота; |
обратите внимание, что они на единицу больше, чем устанавливаемые |
функциями 0, 67. |
* По определению масштаба xsize и ysize должны делиться на 2^scale. |
* Байт данных по смещению a должен быть 0/1 и |
определяет принадлежность окну квадрата со стороной 2^scale |
(при scale=0 получаем пиксель) и координатами левого верхнего угла |
------------------ áâ ®¢ª ¬ áèâ ¡ ¤ ëå ä®à¬ë ------------------- |
à ¬¥âàë: |
* eax = 50 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx § ¤ ñâ ¬ áèâ ¡: ª ¦¤ë© ¡ ©â ¤ ëå ®¯à¥¤¥«ï¥â |
(2^scale)*(2^scale) ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* áèâ ¡ ¯® 㬮«ç ¨î à ¢¥ 0 (¬ áèâ ¡¨àãî騩 ¬®¦¨â¥«ì 1). ᫨ ¢ |
¤ ëå ä®à¬ë ®¤¨ ¡ ©â ᮮ⢥âáâ¢ã¥â ®¤®¬ã ¯¨ªá¥«î, â® ¬ áèâ ¡ |
¬®¦® ¥ ãáâ ¢«¨¢ âì. |
* ¡®§ 稬 xsize = è¨à¨ ®ª (¢ ¯¨ªá¥«ïå), ysize = ¢ëá®â ; |
®¡à â¨â¥ ¢¨¬ ¨¥, çâ® ®¨ ¥¤¨¨æã ¡®«ìè¥, 祬 ãáâ ¢«¨¢ ¥¬ë¥ |
äãªæ¨ï¬¨ 0, 67. |
* ® ®¯à¥¤¥«¥¨î ¬ áèâ ¡ xsize ¨ ysize ¤®«¦ë ¤¥«¨âìáï 2^scale. |
* ©â ¤ ëå ¯® ᬥ饨î a ¤®«¦¥ ¡ëâì 0/1 ¨ |
®¯à¥¤¥«ï¥â ¯à¨ ¤«¥¦®áâì ®ªã ª¢ ¤à â á® áâ®à®®© 2^scale |
(¯à¨ scale=0 ¯®«ãç ¥¬ ¯¨ªá¥«ì) ¨ ª®®à¤¨ â ¬¨ «¥¢®£® ¢¥à奣® 㣫 |
(a mod (xsize shr scale), a div (xsize shr scale)) |
* Размер данных: (xsize shr scale)*(ysize shr scale). |
* Данные должны присутствовать в памяти и не меняться |
после установки формы. |
* Система просматривает данные о форме при каждой перерисовке окна |
функцией 0. |
* Вызов подфункции 0 с нулевым указателем приводит к возврату |
к прямоугольной форме. |
* §¬¥à ¤ ëå: (xsize shr scale)*(ysize shr scale). |
* ë¥ ¤®«¦ë ¯à¨áãâá⢮¢ âì ¢ ¯ ¬ï⨠¨ ¥ ¬¥ïâìáï |
¯®á«¥ ãáâ ®¢ª¨ ä®à¬ë. |
* ¨á⥬ ¯à®á¬ âਢ ¥â ¤ ë¥ ® ä®à¬¥ ¯à¨ ª ¦¤®© ¯¥à¥à¨á®¢ª¥ ®ª |
äãªæ¨¥© 0. |
* 맮¢ ¯®¤äãªæ¨¨ 0 á ã«¥¢ë¬ 㪠§ ⥫¥¬ ¯à¨¢®¤¨â ª ¢®§¢à âã |
ª ¯àאַ㣮«ì®© ä®à¬¥. |
====================================================================== |
===================== Функция 51 - создать поток. ==================== |
===================== ãªæ¨ï 51 - ᮧ¤ âì ¯®â®ª. ==================== |
====================================================================== |
Параметры: |
* eax = 51 - номер функции |
* ebx = 1 - единственная подфункция |
* ecx = адрес точки входа потока (начальный eip) |
* edx = указатель стэка потока (начальный esp) |
Возвращаемое значение: |
* eax = -1 - ошибка (в системе слишком много потоков) |
* иначе eax = TID - идентификатор потока |
à ¬¥âàë: |
* eax = 51 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ¤à¥á â®çª¨ ¢å®¤ ¯®â®ª ( ç «ìë© eip) |
* edx = 㪠§ ⥫ì áâíª ¯®â®ª ( ç «ìë© esp) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (¢ á¨á⥬¥ ᫨誮¬ ¬®£® ¯®â®ª®¢) |
* ¨ ç¥ eax = TID - ¨¤¥â¨ä¨ª â®à ¯®â®ª |
====================================================================== |
= Функция 52, подфункция 0 - получить конфигурацию сетевого драйвера. |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 0 - номер подфункции |
Возвращаемое значение: |
* eax = двойное слово конфигурации |
Замечания: |
* Слово конфигурации можно установить подфункцией 2. |
* Ядро не использует соответствующую переменную. |
Ценность этой переменной и работающих с ней подфункций 0 и 2 |
представляется сомнительной. |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨 |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ãáâ ®¢¨âì ¯®¤äãªæ¨¥© 2. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®© ¨ à ¡®â îé¨å á ¥© ¯®¤äãªæ¨© 0 ¨ 2 |
¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
======= Функция 52, подфункция 1 - получить локальный IP-адрес. ====== |
======= ãªæ¨ï 52, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì «®ª «ìë© IP- ¤à¥á. ====== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = IP-адрес (4 байта) |
Замечания: |
* Локальный IP-адрес устанавливается подфункцией 3. |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = IP- ¤à¥á (4 ¡ ©â ) |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ãáâ ¢«¨¢ ¥âáï ¯®¤äãªæ¨¥© 3. |
====================================================================== |
Функция 52, подфункция 2 - установить конфигурацию сетевого драйвера. |
ãªæ¨ï 52, ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì ª®ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = двойное слово конфигурации; если младшие 7 бит образуют |
число 3, это воспринимается как запрос на [пере-]инициализацию |
Ethernet-карты, в противном случае Ethernet выключается |
Возвращаемое значение: |
* если не запрошен Ethernet-интерфейс, то возвращается eax=2, |
но это может измениться в будущих версиях ядра |
* если запрошен Ethernet-интерфейс, то eax=0 означает ошибку |
(отсутствие Ethernet-карты), а ненулевое значение - успех |
Замечания: |
* Слово конфигурации можно прочитать подфункцией 0. |
* Ядро не использует соответствующую переменную. |
Ценность этой переменной, подфункции 0 и части подфункции 2, |
устанавливающей эту переменную, представляется сомнительной. |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤¢®©®¥ á«®¢® ª®ä¨£ãà 樨; ¥á«¨ ¬« ¤è¨¥ 7 ¡¨â ®¡à §ãîâ |
ç¨á«® 3, íâ® ¢®á¯à¨¨¬ ¥âáï ª ª § ¯à®á [¯¥à¥-]¨¨æ¨ «¨§ æ¨î |
Ethernet-ª àâë, ¢ ¯à®â¨¢®¬ á«ãç ¥ Ethernet ¢ëª«îç ¥âáï |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® ¢®§¢à é ¥âáï eax=2, |
® íâ® ¬®¦¥â ¨§¬¥¨âìáï ¢ ¡ã¤ãé¨å ¢¥àá¨ïå ï¤à |
* ¥á«¨ § ¯à®è¥ Ethernet-¨â¥à䥩á, â® eax=0 ®§ ç ¥â ®è¨¡ªã |
(®âáãâá⢨¥ Ethernet-ª àâë), ¥ã«¥¢®¥ § 票¥ - ãᯥå |
¬¥ç ¨ï: |
* «®¢® ª®ä¨£ãà 樨 ¬®¦® ¯à®ç¨â âì ¯®¤äãªæ¨¥© 0. |
* ¤à® ¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥ãî. |
¥®áâì í⮩ ¯¥à¥¬¥®©, ¯®¤äãªæ¨¨ 0 ¨ ç á⨠¯®¤äãªæ¨¨ 2, |
ãáâ ¢«¨¢ î饩 íâã ¯¥à¥¬¥ãî, ¯à¥¤áâ ¢«ï¥âáï ᮬ¨â¥«ì®©. |
====================================================================== |
====== Функция 52, подфункция 3 - установить локальный IP-адрес. ===== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 3 - ãáâ ®¢¨âì «®ª «ìë© IP- ¤à¥á. ===== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = IP-адрес (4 байта) |
Возвращаемое значение: |
* текущая реализация возвращает eax=3, но это может быть изменено |
в будущих версиях |
Замечания: |
* Локальный IP-адрес можно получить подфункцией 1. |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = IP- ¤à¥á (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=3, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
¬¥ç ¨ï: |
* ®ª «ìë© IP- ¤à¥á ¬®¦® ¯®«ãç¨âì ¯®¤äãªæ¨¥© 1. |
====================================================================== |
= Функция 52, подфункция 6 - добавить данные в стек входной очереди. = |
= ãªæ¨ï 52, ¯®¤äãªæ¨ï 6 - ¤®¡ ¢¨âì ¤ ë¥ ¢ á⥪ ¢å®¤®© ®ç¥à¥¤¨. = |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 6 - номер подфункции |
* edx = размер данных |
* esi = указатель на данные |
Возвращаемое значение: |
* eax = -1 - ошибка |
* eax = 0 - успешно |
Замечания: |
* Эта функция предназначена только для медленных сетевых драйверов |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* edx = à §¬¥à ¤ ëå |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
* Размер данных не должен превосходить 1500 байт, |
хотя проверок корректности не делается. |
* §¬¥à ¤ ëå ¥ ¤®«¦¥ ¯à¥¢®á室¨âì 1500 ¡ ©â, |
å®âï ¯à®¢¥à®ª ª®à४â®á⨠¥ ¤¥« ¥âáï. |
====================================================================== |
====================== Функция 52, подфункция 8 ====================== |
============= Прочитать данные из сетевой очереди вывода. ============ |
====================== ãªæ¨ï 52, ¯®¤äãªæ¨ï 8 ====================== |
============= à®ç¨â âì ¤ ë¥ ¨§ á¥â¥¢®© ®ç¥à¥¤¨ ¢ë¢®¤ . ============ |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 8 - номер подфункции |
* esi = указатель на буфер размером 1500 байт |
Возвращаемое значение: |
* eax = число прочитанных байт (в текущей реализации |
либо 0 = нет данных, либо 1500) |
* данные скопированы в буфер |
Замечания: |
* Эта функция предназначена только для медленных сетевых драйверов |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¡ãä¥à à §¬¥à®¬ 1500 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢ ⥪ã饩 ॠ«¨§ 樨 |
«¨¡® 0 = ¥â ¤ ëå, «¨¡® 1500) |
* ¤ ë¥ áª®¯¨à®¢ ë ¢ ¡ãä¥à |
¬¥ç ¨ï: |
* â äãªæ¨ï ¯à¥¤ § ç¥ â®«ìª® ¤«ï ¬¥¤«¥ëå á¥â¥¢ëå ¤à ©¢¥à®¢ |
(PPP, SLIP). |
====================================================================== |
=========== Функция 52, подфункция 9 - получить gateway IP. ========== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì gateway IP. ========== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 9 - номер подфункции |
Возвращаемое значение: |
* eax = gateway IP (4 байта) |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = gateway IP (4 ¡ ©â ) |
====================================================================== |
========= Функция 52, подфункция 10 - получить маску подсети. ======== |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì ¬ áªã ¯®¤á¥â¨. ======== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 10 - номер подфункции |
Возвращаемое значение: |
* eax = маска подсети |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¬ ᪠¯®¤á¥â¨ |
====================================================================== |
========= Функция 52, подфункция 11 - установить gateway IP. ========= |
========= ãªæ¨ï 52, ¯®¤äãªæ¨ï 11 - ãáâ ®¢¨âì gateway IP. ========= |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 11 - номер подфункции |
* ecx = gateway IP (4 байта) |
Возвращаемое значение: |
* текущая реализация возвращает eax=11, но это может быть изменено |
в будущих реализациях |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = gateway IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=11, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ॠ«¨§ æ¨ïå |
====================================================================== |
======== Функция 52, подфункция 12 - установить маску подсети. ======= |
======== ãªæ¨ï 52, ¯®¤äãªæ¨ï 12 - ãáâ ®¢¨âì ¬ áªã ¯®¤á¥â¨. ======= |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 12 - номер подфункции |
* ecx = маска подсети |
Возвращаемое значение: |
* текущая реализация возвращает eax=12, но это может быть изменено |
в будущих версиях |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¬ ᪠¯®¤á¥â¨ |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=12, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ ¡ã¤ãé¨å ¢¥àá¨ïå |
====================================================================== |
============ Функция 52, подфункция 13 - получить DNS IP. ============ |
============ ãªæ¨ï 52, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì DNS IP. ============ |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 13 - номер подфункции |
Возвращаемое значение: |
* eax = DNS IP (4 байта) |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = DNS IP (4 ¡ ©â ) |
====================================================================== |
=========== Функция 52, подфункция 14 - установить DNS IP. =========== |
=========== ãªæ¨ï 52, ¯®¤äãªæ¨ï 14 - ãáâ ®¢¨âì DNS IP. =========== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 14 - номер подфункции |
* ecx = DNS IP (4 байта) |
Возвращаемое значение: |
* текущая реализация возвращает eax=14, но это может быть изменено |
в следующих версиях |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = DNS IP (4 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=14, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ á«¥¤ãîé¨å ¢¥àá¨ïå |
====================================================================== |
====== Функция 52, подфункция 15 - получить локальный MAC-адрес. ===== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì «®ª «ìë© MAC- ¤à¥á. ===== |
====================================================================== |
Параметры: |
* eax = 52 - номер функции |
* ebx = 15 - номер подфункции |
* ecx = 0 - читать первые 4 байта, |
ecx = 4 - читать последние 2 байта |
Возвращаемое значение: |
* для ecx=0: eax = первые 4 байта MAC-адреса |
* для ecx=4: ax = последние 2 байта MAC-адреса, |
старшая половина eax разрушается |
* для других ecx: eax = -1 как признак ошибки |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ç¨â âì ¯¥à¢ë¥ 4 ¡ ©â , |
ecx = 4 - ç¨â âì ¯®á«¥¤¨¥ 2 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: eax = ¯¥à¢ë¥ 4 ¡ ©â MAC- ¤à¥á |
* ¤«ï ecx=4: ax = ¯®á«¥¤¨¥ 2 ¡ ©â MAC- ¤à¥á , |
áâ àè ï ¯®«®¢¨ eax à §àãè ¥âáï |
* ¤«ï ¤à㣨å ecx: eax = -1 ª ª ¯à¨§ ª ®è¨¡ª¨ |
====================================================================== |
============ Функция 53, подфункция 0 - открыть UDP-сокет. =========== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. =========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 0 - номер подфункции |
* ecx = локальный порт (учитывается только младшее слово), |
ecx = 0 - предоставить системе выбор локального порта |
* edx = удалённый порт (учитывается только младшее слово) |
* esi = удалённый IP |
Возвращаемое значение: |
* eax = -1 = 0xFFFFFFFF - ошибка; ebx разрушается |
* eax = хэндл сокета (некоторое число, однозначно идентифицирующее |
сокет и имеющее смысл только для системы) - успешно; |
ebx разрушается |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®), |
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì®£® ¯®àâ |
* edx = 㤠«ñë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«ñë© IP |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
============ Функция 53, подфункция 1 - закрыть UDP-сокет. =========== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 1 - § ªàëâì UDP-᮪¥â. =========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = хэндл сокета |
Возвращаемое значение: |
* eax = -1 - неверный хэндл |
* eax = 0 - успешно |
* ebx разрушается |
Замечания: |
* Текущая реализация не закрывает автоматически все сокеты потока |
при его завершении. В частности, не следует прибивать поток |
с кучей открытых сокетов - будет утечка ресурсов. |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¥¢¥àë© åí¤« |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
====================================================================== |
============== Функция 53, подфункция 2 - опрос сокета. ============== |
============== ãªæ¨ï 53, ¯®¤äãªæ¨ï 2 - ®¯à®á ᮪¥â . ============== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = хэндл сокета |
Возвращаемое значение: |
* eax = число полученных байт, 0 для неверного хэндла |
* ebx разрушается |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯®«ãç¥ëå ¡ ©â, 0 ¤«ï ¥¢¥à®£® åí¤« |
* ebx à §àãè ¥âáï |
====================================================================== |
======== Функция 53, подфункция 3 - прочитать байт из сокета. ======== |
======== ãªæ¨ï 53, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì ¡ ©â ¨§ ᮪¥â . ======== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = хэндл сокета |
Возвращаемое значение: |
* если нет принятых данных или указан неверный хэндл: |
eax=0, bl=0, прочие байты ebx разрушаются |
* если были принятые данные: eax=число оставшихся байт |
(возможно, 0), bl=прочитанный байт, прочие байты ebx разрушаются |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¥â ¯à¨ïâëå ¤ ëå ¨«¨ 㪠§ ¥¢¥àë© åí¤«: |
eax=0, bl=0, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
* ¥á«¨ ¡ë«¨ ¯à¨ïâë¥ ¤ ë¥: eax=ç¨á«® ®áâ ¢è¨åáï ¡ ©â |
(¢®§¬®¦®, 0), bl=¯à®ç¨â ë© ¡ ©â, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï |
====================================================================== |
========== Функция 53, подфункция 4 - записать в UDP-сокет. ========== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ UDP-᮪¥â. ========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 4 - номер подфункции |
* ecx = хэндл сокета |
* edx = число байт для записи |
* esi = указатель на данные для записи |
Возвращаемое значение: |
* eax = 0xffffffff - ошибка (неверный хэндл или недостаточно памяти) |
* eax = 0 - успешно |
* ebx разрушается |
Замечания: |
* Число байт для записи не может превышать 1500-28, хотя |
соответствующей проверки не делается. |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ ¥¤®áâ â®ç® ¯ ¬ïâ¨) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-28, å®âï |
ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ Функция 53, подфункция 5 - открыть TCP-сокет. =========== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 5 - ®âªàëâì TCP-᮪¥â. =========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = локальный порт (учитывается только младшее слово), |
ecx = 0 - предоставить системе выбор локального порта |
* edx = удалённый порт (учитывается только младшее слово) |
* esi = удалённый IP |
* edi = режим открытия: SOCKET_PASSIVE=0 или SOCKET_ACTIVE=1 |
Возвращаемое значение: |
* eax = -1 = 0xFFFFFFFF - ошибка; ebx разрушается |
* eax = хэндл сокета (некоторое число, однозначно идентифицирующее |
сокет и имеющее смысл только для системы) - успешно; |
ebx разрушается |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®), |
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì®£® ¯®àâ |
* edx = 㤠«ñë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* esi = 㤠«ñë© IP |
* edi = ०¨¬ ®âªàëâ¨ï: SOCKET_PASSIVE=0 ¨«¨ SOCKET_ACTIVE=1 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï |
* eax = åí¤« ᮪¥â (¥ª®â®à®¥ ç¨á«®, ®¤®§ ç® ¨¤¥â¨ä¨æ¨àãî饥 |
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥè®; |
ebx à §àãè ¥âáï |
====================================================================== |
====== Функция 53, подфункция 6 - получить состояние TCP-сокета. ===== |
====== ãªæ¨ï 53, ¯®¤äãªæ¨ï 6 - ¯®«ãç¨âì á®áâ®ï¨¥ TCP-᮪¥â . ===== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 6 - номер подфункции |
* ecx = хэндл сокета |
Возвращаемое значение: |
* eax = 0 для неверного сокета или статус: одно из |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 ¤«ï ¥¢¥à®£® ᮪¥â ¨«¨ áâ âãá: ®¤® ¨§ |
* TCB_LISTEN = 1 |
* TCB_SYN_SENT = 2 |
* TCB_SYN_RECEIVED = 3 |
2677,1275 → 2677,1275 |
* TCB_LAST_ASK = 9 |
* TCB_TIME_WAIT = 10 |
* TCB_CLOSED = 11 |
* ebx разрушается |
* ebx à §àãè ¥âáï |
====================================================================== |
========== Функция 53, подфункция 7 - записать в TCP-сокет. ========== |
========== ãªæ¨ï 53, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ TCP-᮪¥â. ========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 7 - номер подфункции |
* ecx = хэндл сокета |
* edx = число байт для записи |
* esi = указатель на данные для записи |
Возвращаемое значение: |
* eax = 0xffffffff - ошибка (неверный хэндл или недостаточно памяти) |
* eax = 0 - успешно |
* ebx разрушается |
Замечания: |
* Число байт для записи не может превышать 1500-40, |
хотя соответствующей проверки не делается. |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0xffffffff - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ ¥¤®áâ â®ç® ¯ ¬ïâ¨) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¨á«® ¡ ©â ¤«ï § ¯¨á¨ ¥ ¬®¦¥â ¯à¥¢ëè âì 1500-40, |
å®âï ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ¥ ¤¥« ¥âáï. |
====================================================================== |
============ Функция 53, подфункция 8 - закрыть TCP-сокет. =========== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 8 - § ªàëâì TCP-᮪¥â. =========== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = хэндл сокета |
Возвращаемое значение: |
* eax = -1 - ошибка (неверный хэндл или |
недостаточно памяти для пакета закрытия сокета) |
* eax = 0 - успешно |
* ebx разрушается |
Замечания: |
* Текущая реализация не закрывает автоматически все сокеты потока |
при его завершении. В частности, не следует прибивать поток |
с кучей открытых сокетов - будет утечка ресурсов. |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (¥¢¥àë© åí¤« ¨«¨ |
¥¤®áâ â®ç® ¯ ¬ï⨠¤«ï ¯ ª¥â § ªàëâ¨ï ᮪¥â ) |
* eax = 0 - ãá¯¥è® |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ¥ § ªàë¢ ¥â ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª |
¯à¨ ¥£® § ¢¥à襨¨. ç áâ®áâ¨, ¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª |
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª à¥áãàᮢ. |
====================================================================== |
== Функция 53, подфункция 9 - проверить, свободен ли локальный порт. = |
== ãªæ¨ï 53, ¯®¤äãªæ¨ï 9 - ¯à®¢¥à¨âì, ᢮¡®¤¥ «¨ «®ª «ìë© ¯®àâ. = |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 9 - номер подфункции |
* ecx = номер локального порта (используются только младшие 16 бит) |
Возвращаемое значение: |
* eax = 0 - порт используется |
* eax = 1 - порт свободен |
* ebx разрушается |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à «®ª «ì®£® ¯®àâ (¨á¯®«ì§ãîâáï ⮫쪮 ¬« ¤è¨¥ 16 ¡¨â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¯®à⠨ᯮ«ì§ã¥âáï |
* eax = 1 - ¯®àâ ᢮¡®¤¥ |
* ebx à §àãè ¥âáï |
====================================================================== |
==== Функция 53, подфункция 10 - получить статус кабеля Ethernet. ==== |
==== ãªæ¨ï 53, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì áâ âãá ª ¡¥«ï Ethernet. ==== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 10 - номер подфункции |
Возвращаемое значение: |
* al = -1 - драйвер сетевой карты не загружен или |
не поддерживает эту функцию |
* al = 0 - кабель не подключён |
* al = 1 - кабель подключён |
* ebx разрушается |
Замечания: |
* Текущая реализация ядра поддерживает эту функцию |
только для сетевых карт RTL8139. |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* al = -1 - ¤à ©¢¥à á¥â¥¢®© ª àâë ¥ § £à㦥 ¨«¨ |
¥ ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
* al = 0 - ª ¡¥«ì ¥ ¯®¤ª«îçñ |
* al = 1 - ª ¡¥«ì ¯®¤ª«îçñ |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ï¤à ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
⮫쪮 ¤«ï á¥â¥¢ëå ª àâ RTL8139. |
====================================================================== |
==== Функция 53, подфункция 11 - прочитать данные сетевого стека. ==== |
==== ãªæ¨ï 53, ¯®¤äãªæ¨ï 11 - ¯à®ç¨â âì ¤ ë¥ á¥â¥¢®£® á⥪ . ==== |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 11 - номер подфункции |
* ecx = хэндл сокета |
* edx = указатель на буфер |
* esi = число байт для чтения; |
* esi = 0 - читать все данные (максимум 4096 байт) |
Возвращаемое значение: |
* eax = число прочитанных байт (0 при неверном хэндле) |
* ebx разрушается |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = 㪠§ â¥«ì ¡ãä¥à |
* esi = ç¨á«® ¡ ©â ¤«ï ç⥨ï; |
* esi = 0 - ç¨â âì ¢á¥ ¤ ë¥ (¬ ªá¨¬ã¬ 4096 ¡ ©â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (0 ¯à¨ ¥¢¥à®¬ åí¤«¥) |
* ebx à §àãè ¥âáï |
====================================================================== |
Функция 53, подфункция 255 - отладочная информация сетевого драйвера. |
ãªæ¨ï 53, ¯®¤äãªæ¨ï 255 - ®â« ¤®ç ï ¨ä®à¬ æ¨ï á¥â¥¢®£® ¤à ©¢¥à . |
====================================================================== |
Параметры: |
* eax = 53 - номер функции |
* ebx = 255 - номер подфункции |
* ecx = тип запрашиваемой информации (смотри ниже) |
Возвращаемое значение: |
* eax = запрошенная информация |
* ebx разрушается |
Возможные значения ecx: |
* 100: длина очереди 0 (empty queue) |
* 101: длина очереди 1 (ip-out queue) |
* 102: длина очереди 2 (ip-in queue) |
* 103: длина очереди 3 (net1out queue) |
* 200: число элементов в таблице ARP |
* 201: размер таблицы ARP (в элементах) (20 в текущей версии) |
* 202: прочитать элемент edx таблицы ARP во временный буфер, откуда |
берут информацию 5 последующих типов; |
в этом случае eax неопределён |
* 203: IP-адрес, запомненный типом 202 |
* 204: старшее dword MAC-адреса, запомненного типом 202 |
* 205: младшее word MAC-адреса, запомненного типом 202 |
* 206: слово статуса, запомненное типом 202 |
* 207: слово ttl, запомненное типом 202 |
* 2: общее число полученных IP-пакетов |
* 3: общее число переданных IP-пакетов |
* 4: общее число сдампленных полученных пакетов |
* 5: общее число полученных ARP-пакетов |
* 6: статус драйвера пакетов, 0=неактивен, |
ненулевое значение=активен |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 255 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ⨯ § ¯à 訢 ¥¬®© ¨ä®à¬ 樨 (ᬮâਠ¨¦¥) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = § ¯à®è¥ ï ¨ä®à¬ æ¨ï |
* ebx à §àãè ¥âáï |
®§¬®¦ë¥ § 票ï ecx: |
* 100: ¤«¨ ®ç¥à¥¤¨ 0 (empty queue) |
* 101: ¤«¨ ®ç¥à¥¤¨ 1 (ip-out queue) |
* 102: ¤«¨ ®ç¥à¥¤¨ 2 (ip-in queue) |
* 103: ¤«¨ ®ç¥à¥¤¨ 3 (net1out queue) |
* 200: ç¨á«® í«¥¬¥â®¢ ¢ â ¡«¨æ¥ ARP |
* 201: à §¬¥à â ¡«¨æë ARP (¢ í«¥¬¥â å) (20 ¢ ⥪ã饩 ¢¥àᨨ) |
* 202: ¯à®ç¨â âì í«¥¬¥â edx â ¡«¨æë ARP ¢® ¢à¥¬¥ë© ¡ãä¥à, ®âªã¤ |
¡¥àãâ ¨ä®à¬ æ¨î 5 ¯®á«¥¤ãîé¨å ⨯®¢; |
¢ í⮬ á«ãç ¥ eax ¥®¯à¥¤¥«ñ |
* 203: IP- ¤à¥á, § ¯®¬¥ë© ⨯®¬ 202 |
* 204: áâ à襥 dword MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 205: ¬« ¤è¥¥ word MAC- ¤à¥á , § ¯®¬¥®£® ⨯®¬ 202 |
* 206: á«®¢® áâ âãá , § ¯®¬¥®¥ ⨯®¬ 202 |
* 207: á«®¢® ttl, § ¯®¬¥®¥ ⨯®¬ 202 |
* 2: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå IP-¯ ª¥â®¢ |
* 3: ®¡é¥¥ ç¨á«® ¯¥à¥¤ ëå IP-¯ ª¥â®¢ |
* 4: ®¡é¥¥ ç¨á«® ᤠ¬¯«¥ëå ¯®«ãç¥ëå ¯ ª¥â®¢ |
* 5: ®¡é¥¥ ç¨á«® ¯®«ãç¥ëå ARP-¯ ª¥â®¢ |
* 6: áâ âãá ¤à ©¢¥à ¯ ª¥â®¢, 0=¥ ªâ¨¢¥, |
¥ã«¥¢®¥ § 票¥= ªâ¨¢¥ |
====================================================================== |
====================== Функция 55, подфункция 55 ===================== |
========== Начать проигрывать данные на встроенном спикере. ========== |
====================== ãªæ¨ï 55, ¯®¤äãªæ¨ï 55 ===================== |
========== ç âì ¯à®¨£àë¢ âì ¤ ë¥ ¢áâ஥®¬ ᯨª¥à¥. ========== |
====================================================================== |
Параметры: |
* eax = 55 - номер функции |
* ebx = 55 - номер подфункции |
* esi = указатель на данные |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 55 - ошибка (спикер отключён или занят) |
Данные - это массив элементов переменной длины. |
Формат каждого элемента определяется первым байтом: |
* 0 = конец данных |
* 1..0x80 = задаёт длительность звучания в сотых долях секунды |
ноты, определяемой непосредственным значением частоты |
* следующее слово (2 байта) содержит делитель частоты; |
частота определяется как 1193180/divider |
à ¬¥âàë: |
* eax = 55 - ®¬¥à äãªæ¨¨ |
* ebx = 55 - ®¬¥à ¯®¤äãªæ¨¨ |
* esi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 55 - ®è¨¡ª (ᯨª¥à ®âª«îçñ ¨«¨ § ïâ) |
ë¥ - íâ® ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë. |
®à¬ â ª ¦¤®£® í«¥¬¥â ®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ ¡ ©â®¬: |
* 0 = ª®¥æ ¤ ëå |
* 1..0x80 = § ¤ ñâ ¤«¨â¥«ì®áâì §¢ãç ¨ï ¢ á®âëå ¤®«ïå ᥪã¤ë |
®âë, ®¯à¥¤¥«ï¥¬®© ¥¯®á।áâ¢¥ë¬ § 票¥¬ ç áâ®âë |
* á«¥¤ãî饥 á«®¢® (2 ¡ ©â ) ᮤ¥à¦¨â ¤¥«¨â¥«ì ç áâ®âë; |
ç áâ®â ®¯à¥¤¥«ï¥âáï ª ª 1193180/divider |
* 0x81 = invalid |
* 0x82..0xFF = нота, определяемая октавой и номером: |
* длительность в сотых долях секунды = (первый байт)-0x81 |
* присутствует ещё один байт; |
* (второй байт)=0xFF - пауза |
* иначе он имеет вид a*0x10+b, где b=номер ноты в октаве от 1 |
до 12, a=номер октавы (считая с 0) |
Замечания: |
* Пищание спикером может быть запрещено/разрешено подфункцией 8 |
функции 18. |
* Функция возвращает управление, сообщив куда следует информацию |
о запросе. Само проигрывание идёт независимо от программы. |
* Данные должны сохраняться в памяти по крайней мере |
до конца проигрывания. |
* 0x82..0xFF = ®â , ®¯à¥¤¥«ï¥¬ ï ®ªâ ¢®© ¨ ®¬¥à®¬: |
* ¤«¨â¥«ì®áâì ¢ á®âëå ¤®«ïå ᥪã¤ë = (¯¥à¢ë© ¡ ©â)-0x81 |
* ¯à¨áãâáâ¢ã¥â ¥éñ ®¤¨ ¡ ©â; |
* (¢â®à®© ¡ ©â)=0xFF - ¯ 㧠|
* ¨ ç¥ ® ¨¬¥¥â ¢¨¤ a*0x10+b, £¤¥ b=®¬¥à ®âë ¢ ®ªâ ¢¥ ®â 1 |
¤® 12, a=®¬¥à ®ªâ ¢ë (áç¨â ï á 0) |
¬¥ç ¨ï: |
* ¨é ¨¥ ᯨª¥à®¬ ¬®¦¥â ¡ëâì § ¯à¥é¥®/à §à¥è¥® ¯®¤äãªæ¨¥© 8 |
äãªæ¨¨ 18. |
* ãªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥¨¥, á®®¡é¨¢ ªã¤ á«¥¤ã¥â ¨ä®à¬ æ¨î |
® § ¯à®á¥. ¬® ¯à®¨£àë¢ ¨¥ ¨¤ñâ ¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë. |
* ë¥ ¤®«¦ë á®åà ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©¥© ¬¥à¥ |
¤® ª®æ ¯à®¨£àë¢ ¨ï. |
====================================================================== |
======================= Функция 57 - PCI BIOS. ======================= |
======================= ãªæ¨ï 57 - PCI BIOS. ======================= |
====================================================================== |
Параметры: |
* eax = 57 - номер функции |
* ebp соответствует регистру al в спецификации PCI BIOS |
* остальные регистры - по спецификации PCI BIOS |
Возвращаемое значение: |
* CF не определён |
* остальные регистры - по спецификации PCI BIOS |
Замечания: |
* Многих результатов этой функции можно также добиться вызовом |
соответствующих подфункций функции 62. |
* Функция вызывает расширение PCI32 BIOS, документированное, |
например, в http://alpha1.dyns.net/files/PCI/bios21.pdf. |
* Если BIOS не поддерживает это расширение, поведение функции |
эмулируется (через аналоги подфункций функции 62 режима ядра). |
à ¬¥âàë: |
* eax = 57 - ®¬¥à äãªæ¨¨ |
* ebp ᮮ⢥âáâ¢ã¥â ॣ¨áâàã al ¢ ᯥæ¨ä¨ª 樨 PCI BIOS |
* ®áâ «ìë¥ à¥£¨áâàë - ¯® ᯥæ¨ä¨ª 樨 PCI BIOS |
®§¢à é ¥¬®¥ § 票¥: |
* CF ¥ ®¯à¥¤¥«ñ |
* ®áâ «ìë¥ à¥£¨áâàë - ¯® ᯥæ¨ä¨ª 樨 PCI BIOS |
¬¥ç ¨ï: |
* ®£¨å १ã«ìâ ⮢ í⮩ äãªæ¨¨ ¬®¦® â ª¦¥ ¤®¡¨âìáï ¢ë§®¢®¬ |
ᮮ⢥âáâ¢ãîé¨å ¯®¤äãªæ¨© äãªæ¨¨ 62. |
* ãªæ¨ï ¢ë§ë¢ ¥â à áè¨à¥¨¥ PCI32 BIOS, ¤®ªã¬¥â¨à®¢ ®¥, |
¯à¨¬¥à, ¢ http://alpha1.dyns.net/files/PCI/bios21.pdf. |
* ᫨ BIOS ¥ ¯®¤¤¥à¦¨¢ ¥â íâ® à áè¨à¥¨¥, ¯®¢¥¤¥¨¥ äãªæ¨¨ |
í¬ã«¨àã¥âáï (ç¥à¥§ «®£¨ ¯®¤äãªæ¨© äãªæ¨¨ 62 ०¨¬ ï¤à ). |
====================================================================== |
============== Функция 58 - работа с файловой системой. ============== |
============== ãªæ¨ï 58 - à ¡®â á ä ©«®¢®© á¨á⥬®©. ============== |
====================================================================== |
Параметры: |
à ¬¥âàë: |
* eax = 58 |
* ebx = указатель на информационную структуру |
Возвращаемое значение: |
* eax = 0 - успешно; иначе код ошибки файловой системы |
* в зависимости от подфункции может возвращаться значение и |
в других регистрах |
Общий формат информационной структуры: |
* +0: dword: номер подфункции |
* +4: dword: номер блока |
* +8: dword: размер |
* +12 = +0xC: dword: указатель на данные |
* +16 = +0x10: dword: указатель на память для работы системы |
(4096 байт) |
* +20 = +0x14: n db: ASCIIZ-строка с именем файла |
Уточнения - в документации на соответствующую подфункцию. |
Имя файла нечувствительно к регистру латинских букв, |
русские буквы должны быть заглавными. |
Формат имени файла: |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª |
* +8: dword: à §¬¥à |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¯ ¬ïâì ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã « â¨áª¨å ¡ãª¢, |
àãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì § £« ¢ë¬¨. |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
где /base/number идентифицирует устройство, на котором ищется файл: |
одно из |
* /RD/1 = /RAMDISK/1 для доступа к рамдиску |
* /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу, |
/FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода |
* /HD/x = /HARDDISK/x - устаревший вариант доступа к жёсткому диску |
(в этом случае база определяется подфункцией 7 функции 21), |
x - номер раздела (считая с 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно |
к устройствам IDE0 (Primary Master), IDE1 (Primary Slave), |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD/x = /HARDDISK/x - ãáâ ॢ訩 ¢ ਠ⠤®áâ㯠ª ¦ñá⪮¬ã ¤¨áªã |
(¢ í⮬ á«ãç ¥ ¡ § ®¯à¥¤¥«ï¥âáï ¯®¤äãªæ¨¥© 7 äãªæ¨¨ 21), |
x - ®¬¥à à §¤¥« (áç¨â ï á 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ãáâனá⢠¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - номер раздела на выбранном винчестере, изменяется от 1 до 255 |
(на каждом из винчестеров нумерация начинается с 1) |
Замечания: |
* В первых двух случаях допускается использование FIRST вместо 1, |
SECOND вместо 2, но использовать эту возможность |
не рекомендуется для удобства перехода на будущие расширения. |
* Накладывается ограничение n<=39. |
* Имена папок и файла dir1,...,dirn,file должны быть в формате 8.3: |
имя не более 8 символов, точка, расширение не более 3 символов. |
Хвостовые пробелы игнорируются. Других пробелов быть не должно. |
Если имя занимает ровно 8 символов, точку можно опустить |
(хотя пользоваться этим не рекомендуется для удобства перехода |
на будущие расширения). |
* Функция не поддерживает папок на рамдиске. |
Примеры: |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
¬¥ç ¨ï: |
* ¯¥à¢ëå ¤¢ãå á«ãç ïå ¤®¯ã᪠¥âáï ¨á¯®«ì§®¢ ¨¥ FIRST ¢¬¥áâ® 1, |
SECOND ¢¬¥áâ® 2, ® ¨á¯®«ì§®¢ âì íâã ¢®§¬®¦®áâì |
¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï. |
* ª« ¤ë¢ ¥âáï ®£à ¨ç¥¨¥ n<=39. |
* ¬¥ ¯ ¯®ª ¨ ä ©« dir1,...,dirn,file ¤®«¦ë ¡ëâì ¢ ä®à¬ ⥠8.3: |
¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ ¥ ¡®«¥¥ 3 ᨬ¢®«®¢. |
¢®áâ®¢ë¥ ¯à®¡¥«ë ¨£®à¨àãîâáï. àã£¨å ¯à®¡¥«®¢ ¡ëâì ¥ ¤®«¦®. |
᫨ ¨¬ï § ¨¬ ¥â ஢® 8 ᨬ¢®«®¢, â®çªã ¬®¦® ®¯ãáâ¨âì |
(å®âï ¯®«ì§®¢ âìáï í⨬ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ |
¡ã¤ã騥 à áè¨à¥¨ï). |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
ਬ¥àë: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
Доступные подфункции: |
* подфункция 0 - чтение файла/папки |
* подфункция 8 - LBA-чтение с устройства |
* подфункция 15 - получение информации о файловой системе |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠|
* ¯®¤äãªæ¨ï 15 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«®¢®© á¨á⥬¥ |
====================================================================== |
========== Функция 58, подфункция 0 - прочитать файл/папку. ========== |
========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 0 - ¯à®ç¨â âì ä ©«/¯ ¯ªã. ========== |
====================================================================== |
Параметры: |
à ¬¥âàë: |
* eax = 58 |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 0 = номер подфункции |
* +4: dword: номер блока для чтения (считая с 0) |
* +8: dword: число блоков для чтения |
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные |
* +16 = +0x10: dword: указатель на буфер для работы системы |
(4096 байт) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx = размер файла (в байтах) или |
-1=0xffffffff, если файл не найден |
Замечания: |
* Размер блока - 512 байт. |
* Эта функция устарела, для чтения файлов используйте подфункцию 0 |
функции 70, для чтения папок - подфункцию 1 функции 70. |
* Функция позволяет читать содержимое папки. Из файловых систем |
поддерживается только FAT. Формат FAT-папки описан в любой |
документации по FAT. |
* Размер папки определяется по размеру цепочки кластеров в FAT. |
* Если файл кончился раньше, чем был прочитан последний запрошенный |
блок, то функция прочитает, сколько сможет, после чего вернёт |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = à §¬¥à ä ©« (¢ ¡ ©â å) ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â. |
* â äãªæ¨ï ãáâ ५ , ¤«ï ç⥨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 0 |
äãªæ¨¨ 70, ¤«ï çâ¥¨ï ¯ ¯®ª - ¯®¤äãªæ¨î 1 äãªæ¨¨ 70. |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ᮤ¥à¦¨¬®¥ ¯ ¯ª¨. § ä ©«®¢ëå á¨á⥬ |
¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT. ®à¬ â FAT-¯ ¯ª¨ ®¯¨á ¢ «î¡®© |
¤®ªã¬¥â 樨 ¯® FAT. |
* §¬¥à ¯ ¯ª¨ ®¯à¥¤¥«ï¥âáï ¯® à §¬¥àã 楯®çª¨ ª« áâ¥à®¢ ¢ FAT. |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ |
eax=6 (EOF). |
* Функция позволяет читать корневые папки /rd/1,/fd/x,/hd[n]/x, но |
в первых двух случаях текущая реализация не следует |
установленным правилам: |
для /rd/1: |
* если указано 0 блоков для чтения, считается, |
что запрашивается 1; |
* если запрашивается больше 14 блоков или начальный блок |
не меньше 14-го, то возвращается eax=5 (not found) и ebx=-1; |
* размер корневого каталога рамдиска = 14 блоков, |
0x1C00=7168 байт; но возвращается ebx=0 |
(за исключением случая предыдущего пункта); |
* как ни странно, можно прочитать 14-й блок (там, вообще говоря, |
мусор - напоминаю, счёт ведётся с 0); |
* если был запрошен хотя бы один блок с номером, не меньшим 14, |
то возвращается eax=6(EOF); иначе eax=0. |
Для /fd/x: |
* если начальный блок не меньше 14-го, то возвращается |
eax=5 (not found) и ebx=0; |
* кстати говоря, формат FAT12 допускает дискеты с размером |
корневого каталога меньше или больше 14 блоков; |
* проверки длины не делается; |
* если удалось прочитать данные с дискеты, возвращается |
eax=0,ebx=0; в противном случае eax=10 (access denied), ebx=-1. |
* Функция обрабатывает чтение специальных папок /,/rd,/fd,/hd[n]; |
но результат не соответствует ожидаемому |
(по работе с обычными файлами/папками), не следует установленным |
правилам, может измениться в следующих версиях ядра и потому |
не описывается. Для получения информации об оборудовании |
используйте подфункцию 11 функции 18 или |
читайте соответствующие папки подфункцией 1 функции 70. |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ª®à¥¢ë¥ ¯ ¯ª¨ /rd/1,/fd/x,/hd[n]/x, ® |
¢ ¯¥à¢ëå ¤¢ãå á«ãç ïå ⥪ãé ï ॠ«¨§ æ¨ï ¥ á«¥¤ã¥â |
ãáâ ®¢«¥ë¬ ¯à ¢¨« ¬: |
¤«ï /rd/1: |
* ¥á«¨ 㪠§ ® 0 ¡«®ª®¢ ¤«ï ç⥨ï, áç¨â ¥âáï, |
çâ® § ¯à 訢 ¥âáï 1; |
* ¥á«¨ § ¯à 訢 ¥âáï ¡®«ìè¥ 14 ¡«®ª®¢ ¨«¨ ç «ìë© ¡«®ª |
¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï eax=5 (not found) ¨ ebx=-1; |
* à §¬¥à ª®à¥¢®£® ª â «®£ à ¬¤¨áª = 14 ¡«®ª®¢, |
0x1C00=7168 ¡ ©â; ® ¢®§¢à é ¥âáï ebx=0 |
(§ ¨áª«î票¥¬ á«ãç ï ¯à¥¤ë¤ã饣® ¯ãªâ ); |
* ª ª ¨ áâà ®, ¬®¦® ¯à®ç¨â âì 14-© ¡«®ª (â ¬, ¢®®¡é¥ £®¢®àï, |
¬ãá®à - ¯®¬¨ î, áçñâ ¢¥¤ñâáï á 0); |
* ¥á«¨ ¡ë« § ¯à®è¥ å®âï ¡ë ®¤¨ ¡«®ª á ®¬¥à®¬, ¥ ¬¥ì訬 14, |
â® ¢®§¢à é ¥âáï eax=6(EOF); ¨ ç¥ eax=0. |
«ï /fd/x: |
* ¥á«¨ ç «ìë© ¡«®ª ¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï |
eax=5 (not found) ¨ ebx=0; |
* ªáâ ⨠£®¢®àï, ä®à¬ â FAT12 ¤®¯ã᪠¥â ¤¨áª¥âë á à §¬¥à®¬ |
ª®à¥¢®£® ª â «®£ ¬¥ìè¥ ¨«¨ ¡®«ìè¥ 14 ¡«®ª®¢; |
* ¯à®¢¥àª¨ ¤«¨ë ¥ ¤¥« ¥âáï; |
* ¥á«¨ 㤠«®áì ¯à®ç¨â âì ¤ ë¥ á ¤¨áª¥âë, ¢®§¢à é ¥âáï |
eax=0,ebx=0; ¢ ¯à®â¨¢®¬ á«ãç ¥ eax=10 (access denied), ebx=-1. |
* ãªæ¨ï ®¡à ¡ âë¢ ¥â ç⥨¥ á¯¥æ¨ «ìëå ¯ ¯®ª /,/rd,/fd,/hd[n]; |
® १ã«ìâ â ¥ ᮮ⢥âáâ¢ã¥â ®¦¨¤ ¥¬®¬ã |
(¯® à ¡®â¥ á ®¡ëç묨 ä ©« ¬¨/¯ ¯ª ¬¨), ¥ á«¥¤ã¥â ãáâ ®¢«¥ë¬ |
¯à ¢¨« ¬, ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à ¨ ¯®â®¬ã |
¥ ®¯¨áë¢ ¥âáï. «ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ |
¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 11 äãªæ¨¨ 18 ¨«¨ |
ç¨â ©â¥ ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¨ ¯®¤äãªæ¨¥© 1 äãªæ¨¨ 70. |
====================================================================== |
========= Функция 58, подфункция 8 - LBA-чтение с устройства. ======== |
========= ãªæ¨ï 58, ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠. ======== |
====================================================================== |
Параметры: |
* eax = 58 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 8 = номер подфункции |
* +4: dword: номер блока для чтения (считая с 0) |
* +8: dword: игнорируется (устанавливайте в 1) |
* +12 = +0xC: dword: указатель на буфер, куда будут записаны данные |
(512 байт) |
* +16 = +0x10: dword: указатель на буфер для работы системы |
(4096 байт) |
* +20 = +0x14: ASCIIZ-имя устройства: нечувствительно к регистру, |
одно из /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - номер устройства: 1=IDE0, ..., 4=IDE3. |
Вместо цифр допускается, хотя и не рекомендуется для удобства |
перехода на будущие расширения, |
использование 'first','second','third','fourth'. |
Возвращаемое значение: |
* если указано имя устройства /hd/xxx, где xxx не находится |
в списке выше: |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ¨£®à¨àã¥âáï (ãáâ ¢«¨¢ ©â¥ ¢ 1) |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(512 ¡ ©â) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ãáâனá⢠: ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã, |
®¤® ¨§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - ®¬¥à ãáâனá⢠: 1=IDE0, ..., 4=IDE3. |
¬¥áâ® æ¨äà ¤®¯ã᪠¥âáï, å®âï ¨ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠|
¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï, |
¨á¯®«ì§®¢ ¨¥ 'first','second','third','fourth'. |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ 㪠§ ® ¨¬ï ãáâனá⢠/hd/xxx, £¤¥ xxx ¥ 室¨âáï |
¢ ᯨ᪥ ¢ëè¥: |
* eax = ebx = 1 |
* если указано неправильное имя устройства |
(за исключением предыдущего случая): |
* ¥á«¨ 㪠§ ® ¥¯à ¢¨«ì®¥ ¨¬ï ãáâனá⢠|
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï): |
* eax = 5 |
* ebx не меняется |
* если LBA-доступ запрещён подфункцией 11 функции 21: |
* ebx ¥ ¬¥ï¥âáï |
* ¥á«¨ LBA-¤®áâ㯠§ ¯à¥éñ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21: |
* eax = 2 |
* ebx разрушается |
* для рамдиска: попытка чтения блока за пределами рамдиска |
(18*2*80 блоков) приводит к |
* ebx à §àãè ¥âáï |
* ¤«ï à ¬¤¨áª : ¯®¯ë⪠çâ¥¨ï ¡«®ª § ¯à¥¤¥« ¬¨ à ¬¤¨áª |
(18*2*80 ¡«®ª®¢) ¯à¨¢®¤¨â ª |
* eax = 3 |
* ebx = 0 |
* при успешном чтении: |
* ¯à¨ ãᯥ讬 ç⥨¨: |
* eax = ebx = 0 |
Замечания: |
* Размер блока - 512 байт; читается один блок. |
* Не следует полагаться на возвращаемое значение, |
оно может измениться в следующих версиях. |
* Требуется, чтобы был разрешён LBA-доступ к устройствам |
подфункцией 11 функции 21. Узнать это можно вызовом |
подфункцией 11 функции 26. |
* LBA-чтение дискеты не поддерживается. |
* Функция считывает данные физического жёсткого диска; |
если по каким-то причинам нужны данные конкретного раздела, |
придётся определять начальный сектор этого раздела |
(либо напрямую через MBR, либо из расширенной структуры, |
возвращаемой той же подфункцией 11 функции 18). |
* Функция не проверяет код ошибки жёсткого диска, так что запрос |
несуществующего сектора всё равно что-то прочитает |
(вероятнее всего, нули, но это определяется устройством) и |
это будет считаться успехом (eax=0). |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â; ç¨â ¥âáï ®¤¨ ¡«®ª. |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥, |
®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå. |
* ॡã¥âáï, çâ®¡ë ¡ë« à §à¥èñ LBA-¤®áâ㯠ª ãáâனá⢠¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21. § âì íâ® ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 26. |
* LBA-ç⥨¥ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
* ãªæ¨ï áç¨âë¢ ¥â ¤ ë¥ ä¨§¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ; |
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨ ¬ ã¦ë ¤ ë¥ ª®ªà¥â®£® à §¤¥« , |
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ç «ìë© á¥ªâ®à í⮣® à §¤¥« |
(«¨¡® ¯àï¬ãî ç¥à¥§ MBR, «¨¡® ¨§ à áè¨à¥®© áâàãªâãàë, |
¢®§¢à é ¥¬®© ⮩ ¦¥ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 18). |
* ãªæ¨ï ¥ ¯à®¢¥àï¥â ª®¤ ®è¨¡ª¨ ¦ñá⪮£® ¤¨áª , â ª çâ® § ¯à®á |
¥áãé¥áâ¢ãî饣® ᥪâ®à ¢áñ à ¢® çâ®-â® ¯à®ç¨â ¥â |
(¢¥à®ï⥥ ¢á¥£®, 㫨, ® íâ® ®¯à¥¤¥«ï¥âáï ãáâனá⢮¬) ¨ |
íâ® ¡ã¤¥â áç¨â âìáï ãᯥ宬 (eax=0). |
====================================================================== |
= Функция 58, подфункция 15 - получить информацию о файловой системе. |
= ãªæ¨ï 58, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. |
====================================================================== |
Параметры: |
* eax = 58 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 15 = номер подфункции |
* +4: dword: игнорируется |
* +8: dword: игнорируется |
* +12 = +0xC: dword: игнорируется |
* +16 = +0x10: dword: игнорируется |
* +20 = +0x14: (проверяется только второй символ, сразу после слэша) |
/rd=/RAMDISK или /hd=/HARDDISK |
Возвращаемое значение: |
* если второй символ не принадлежит множеству {'r','R','h','H'}: |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 15 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: ¨£®à¨àã¥âáï |
* +20 = +0x14: (¯à®¢¥àï¥âáï ⮫쪮 ¢â®à®© ᨬ¢®«, áà §ã ¯®á«¥ á«íè ) |
/rd=/RAMDISK ¨«¨ /hd=/HARDDISK |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¢â®à®© ᨬ¢®« ¥ ¯à¨ ¤«¥¦¨â ¬®¦¥áâ¢ã {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* для рамдиска: |
* eax = 0 (успех) |
* ebx = общее число кластеров = 2847 |
* ecx = число свободных кластеров |
* dword [fileinfo] = размер кластера = 512 |
* для жёсткого диска: база и раздел определяются подфункциями 7 и 8 |
функции 21: |
* eax = 0 (успех) |
* ebx = общее число кластеров |
* ecx = число свободных кластеров |
* dword [fileinfo] = размер кластера (в байтах) |
Замечания: |
* Не удивляйтесь странному расположению 4-го возвращаемого |
параметра - когда писался этот код, при системных вызовах |
приложению возвращались только регистры eax,ebx,ecx (из |
pushad-структуры, передающейся как аргумент системной функции). |
Теперь это исправлено, так что, возможно, имеет смысл возвращать |
размер кластера в edx, пока эту функцию не начали использовать. |
* Вообще-то ещё существует подфункция 11 функции 18, возвращающая |
информацию о файловой системе. По расширенной таблице дисковой |
подсистемы можно определить размер кластера (там он хранится |
в секторах) и общее число кластеров для жёстких дисков. |
* ¤«ï à ¬¤¨áª : |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ = 2847 |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à = 512 |
* ¤«ï ¦ñá⪮£® ¤¨áª : ¡ § ¨ à §¤¥« ®¯à¥¤¥«ïîâáï ¯®¤äãªæ¨ï¬¨ 7 ¨ 8 |
äãªæ¨¨ 21: |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à (¢ ¡ ©â å) |
¬¥ç ¨ï: |
* ¥ 㤨¢«ï©â¥áì áâà ®¬ã à ᯮ«®¦¥¨î 4-£® ¢®§¢à é ¥¬®£® |
¯ à ¬¥âà - ª®£¤ ¯¨á «áï íâ®â ª®¤, ¯à¨ á¨á⥬ëå ¢ë§®¢ å |
¯à¨«®¦¥¨î ¢®§¢à é «¨áì ⮫쪮 ॣ¨áâàë eax,ebx,ecx (¨§ |
pushad-áâàãªâãàë, ¯¥à¥¤ î饩áï ª ª à£ã¬¥â á¨á⥬®© äãªæ¨¨). |
¥¯¥àì íâ® ¨á¯à ¢«¥®, â ª çâ®, ¢®§¬®¦®, ¨¬¥¥â á¬ëá« ¢®§¢à é âì |
à §¬¥à ª« áâ¥à ¢ edx, ¯®ª íâã äãªæ¨î ¥ ç «¨ ¨á¯®«ì§®¢ âì. |
* ®®¡é¥-â® ¥éñ áãé¥áâ¢ã¥â ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18, ¢®§¢à é îé ï |
¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥®© â ¡«¨æ¥ ¤¨áª®¢®© |
¯®¤á¨áâ¥¬ë ¬®¦® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à (â ¬ ® åà ¨âáï |
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦ñáâª¨å ¤¨áª®¢. |
====================================================================== |
=========== Функция 60 - Inter Process Communication (IPC). ========== |
=========== ãªæ¨ï 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC применяется для посылок сообщений от одного процесса/потока |
другому. При этом следует предварительно договориться о том, как |
интерпретировать конкретное сообщение. |
IPC ¯à¨¬¥ï¥âáï ¤«ï ¯®áë«®ª á®®¡é¥¨© ®â ®¤®£® ¯à®æ¥áá /¯®â®ª |
¤à㣮¬ã. ਠí⮬ á«¥¤ã¥â ¯à¥¤¢ à¨â¥«ì® ¤®£®¢®à¨âìáï ® ⮬, ª ª |
¨â¥à¯à¥â¨à®¢ âì ª®ªà¥â®¥ á®®¡é¥¨¥. |
-------- Подфункция 1 - установить область для получения IPC --------- |
Вызывается процессом-приёмником. |
Параметры: |
* eax = 60 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = указатель на буфер |
* edx = размер буфера |
Возвращаемое значение: |
* eax = 0 - всегда успешно |
Формат IPC-буфера: |
* +0: dword: если здесь не 0, то буфер считается заблокированным; |
блокируйте/разблокируйте буфер, когда вы с ним активно работаете |
и вам надо, чтобы извне не изменялись данные буфера |
(не поступали новые сообщения) |
* +4: dword: занято места в буфере (в байтах) |
* +8: первое сообщение |
* +8+n: второе сообщение |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ®¡« áâì ¤«ï ¯®«ã票ï IPC --------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¯à¨ñ¬¨ª®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¢á¥£¤ ãá¯¥è® |
®à¬ â IPC-¡ãä¥à : |
* +0: dword: ¥á«¨ §¤¥áì ¥ 0, â® ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬; |
¡«®ª¨àã©â¥/à §¡«®ª¨àã©â¥ ¡ãä¥à, ª®£¤ ¢ë á ¨¬ ªâ¨¢® à ¡®â ¥â¥ |
¨ ¢ ¬ ¤®, çâ®¡ë ¨§¢¥ ¥ ¨§¬¥ï«¨áì ¤ ë¥ ¡ãä¥à |
(¥ ¯®áâ㯠«¨ ®¢ë¥ á®®¡é¥¨ï) |
* +4: dword: § ïâ® ¬¥áâ ¢ ¡ãä¥à¥ (¢ ¡ ©â å) |
* +8: ¯¥à¢®¥ á®®¡é¥¨¥ |
* +8+n: ¢â®à®¥ á®®¡é¥¨¥ |
* ... |
Формат сообщения: |
* +0: dword: PID процесса/потока, пославшего сообщение |
* +4: dword: длина сообщения (не считая этот заголовок) |
* +8: n*byte: данные сообщения |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: PID ¯à®æ¥áá /¯®â®ª , ¯®á« ¢è¥£® á®®¡é¥¨¥ |
* +4: dword: ¤«¨ á®®¡é¥¨ï (¥ áç¨â ï íâ®â § £®«®¢®ª) |
* +8: n*byte: ¤ ë¥ á®®¡é¥¨ï |
--------------- Подфункция 2 - послать сообщение IPC. ---------------- |
Вызывается процессом-инициатором. |
Параметры: |
* eax = 60 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = PID приёмника |
* edx = указатель на данные сообщения |
* esi = длина сообщения (в байтах) |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - приёмник не определил буфер для IPC-сообщений |
(может быть, ещё не успел, а может быть, это не тот поток, |
который нужен) |
* eax = 2 - приёмник заблокировал IPC-буфер; |
попробуйте немного подождать |
* eax = 3 - переполнение IPC-буфера приёмника |
* eax = 4 - процесса/потока с таким PID не существует |
Замечания: |
* Система сразу после записи IPC-сообщения в буфер посылает |
потоку-приёмнику событие с кодом 7 (см. коды событий). |
--------------- ®¤äãªæ¨ï 2 - ¯®á« âì á®®¡é¥¨¥ IPC. ---------------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¨¨æ¨ â®à®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = PID ¯à¨ñ¬¨ª |
* edx = 㪠§ â¥«ì ¤ ë¥ á®®¡é¥¨ï |
* esi = ¤«¨ á®®¡é¥¨ï (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯à¨ñ¬¨ª ¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥¨© |
(¬®¦¥â ¡ëâì, ¥éñ ¥ ãᯥ«, ¬®¦¥â ¡ëâì, íâ® ¥ â®â ¯®â®ª, |
ª®â®àë© ã¦¥) |
* eax = 2 - ¯à¨ñ¬¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à; |
¯®¯à®¡ã©â¥ ¥¬®£® ¯®¤®¦¤ âì |
* eax = 3 - ¯¥à¥¯®«¥¨¥ IPC-¡ãä¥à ¯à¨ñ¬¨ª |
* eax = 4 - ¯à®æ¥áá /¯®â®ª á â ª¨¬ PID ¥ áãé¥áâ¢ã¥â |
¬¥ç ¨ï: |
* ¨á⥬ áà §ã ¯®á«¥ § ¯¨á¨ IPC-á®®¡é¥¨ï ¢ ¡ãä¥à ¯®áë« ¥â |
¯®â®ªã-¯à¨ñ¬¨ªã ᮡë⨥ á ª®¤®¬ 7 (á¬. ª®¤ë ᮡë⨩). |
====================================================================== |
=== Функция 61 - получить параметры для прямого доступа к графике. === |
=== ãªæ¨ï 61 - ¯®«ãç¨âì ¯ à ¬¥âàë ¤«ï ¯àאַ£® ¤®áâ㯠ª £à 䨪¥. === |
====================================================================== |
Программе доступны данные графического экрана (область памяти, которая |
собственно и отображает содержимое экрана) напрямую без вызовов |
системных функций через селектор gs: |
à®£à ¬¬¥ ¤®áâã¯ë ¤ ë¥ £à ä¨ç¥áª®£® íªà (®¡« áâì ¯ ¬ïâ¨, ª®â®à ï |
ᮡá⢥® ¨ ®â®¡à ¦ ¥â ᮤ¥à¦¨¬®¥ íªà ) ¯àï¬ãî ¡¥§ ¢ë§®¢®¢ |
á¨á⥬ëå äãªæ¨© ç¥à¥§ ᥫ¥ªâ®à gs: |
mov eax, [gs:0] |
поместит в eax первый dword буфера, содержащий информацию о цвете |
левой верхней точки (и, возможно, цвета нескольких следующих). |
¯®¬¥áâ¨â ¢ eax ¯¥à¢ë© dword ¡ãä¥à , ᮤ¥à¦ 騩 ¨ä®à¬ æ¨î ® 梥⥠|
«¥¢®© ¢¥à奩 â®çª¨ (¨, ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
mov [gs:0], eax |
при работе в режимах VESA c LFB |
установит цвет левой верхней точки |
(и возможно, цвета нескольких следующих). |
Для интерпретации данных графического экрана требуется знание |
некоторых параметров, которые возвращаются этой функцией. |
Замечания: |
* Параметры графики очень редко меняются при работе системы, |
а именно, только в случаях, когда пользователь работает |
с программой VRR. |
* При изменении видеорежима система перерисовывает все окна |
(событие с кодом 1) и перерисовывает фон (событие 5). |
Эти же события происходят и в других случаях, |
которые встречаются значительно чаще, чем изменение видеорежима. |
* При работе в видеорежимах с LFB селектор gs указывает на |
собственно LFB, так что чтение/запись по gs приводят |
непосредственно к изменению содержимого экрана. При работе в |
видеорежимах без LFB gs указывает на некоторую область данных |
ядра, причём все функции вывода на экран добросовестно выполняют |
двойную работу по записи непосредственно на экран и по записи |
в этот буфер. В результате при чтении содержимого этого буфера |
результаты соответствуют содержимому экрана |
(с, вообще говоря, большим цветовым разрешением), |
а запись игнорируется. |
Исключением является режим 320*200, для которого в главном цикле |
системного потока выполняется обновление экрана в соответствии |
с движениями курсора мыши. |
¯à¨ à ¡®â¥ ¢ ०¨¬ å VESA c LFB |
ãáâ ®¢¨â 梥⠫¥¢®© ¢¥à奩 â®çª¨ |
(¨ ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
«ï ¨â¥à¯à¥â 樨 ¤ ëå £à ä¨ç¥áª®£® íªà âॡã¥âáï § ¨¥ |
¥ª®â®àëå ¯ à ¬¥â஢, ª®â®àë¥ ¢®§¢à é îâáï í⮩ äãªæ¨¥©. |
¬¥ç ¨ï: |
* à ¬¥âàë £à 䨪¨ ®ç¥ì ।ª® ¬¥ïîâáï ¯à¨ à ¡®â¥ á¨á⥬ë, |
¨¬¥®, ⮫쪮 ¢ á«ãç ïå, ª®£¤ ¯®«ì§®¢ ⥫ì à ¡®â ¥â |
á ¯à®£à ¬¬®© VRR. |
* ਠ¨§¬¥¥¨¨ ¢¨¤¥®à¥¦¨¬ á¨á⥬ ¯¥à¥à¨á®¢ë¢ ¥â ¢á¥ ®ª |
(ᮡë⨥ á ª®¤®¬ 1) ¨ ¯¥à¥à¨á®¢ë¢ ¥â ä® (ᮡë⨥ 5). |
⨠¦¥ ᮡëâ¨ï ¯à®¨á室ïâ ¨ ¢ ¤à㣨å á«ãç ïå, |
ª®â®àë¥ ¢áâà¥ç îâáï § ç¨â¥«ì® ç é¥, 祬 ¨§¬¥¥¨¥ ¢¨¤¥®à¥¦¨¬ . |
* à¨ à ¡®â¥ ¢ ¢¨¤¥®à¥¦¨¬ å á LFB ᥫ¥ªâ®à gs 㪠§ë¢ ¥â |
ᮡá⢥® LFB, â ª çâ® ç⥨¥/§ ¯¨áì ¯® gs ¯à¨¢®¤ïâ |
¥¯®á।á⢥® ª ¨§¬¥¥¨î ᮤ¥à¦¨¬®£® íªà . à¨ à ¡®â¥ ¢ |
¢¨¤¥®à¥¦¨¬ å ¡¥§ LFB gs 㪠§ë¢ ¥â ¥ª®â®àãî ®¡« áâì ¤ ëå |
ï¤à , ¯à¨çñ¬ ¢á¥ äãªæ¨¨ ¢ë¢®¤ íªà ¤®¡à®á®¢¥áâ® ¢ë¯®«ïîâ |
¤¢®©ãî à ¡®âã ¯® § ¯¨á¨ ¥¯®á।á⢥® íªà ¨ ¯® § ¯¨á¨ |
¢ íâ®â ¡ãä¥à. १ã«ìâ ⥠¯à¨ ç⥨¨ ᮤ¥à¦¨¬®£® í⮣® ¡ãä¥à |
१ã«ìâ âë ᮮ⢥âáâ¢ãîâ ᮤ¥à¦¨¬®¬ã íªà |
(á, ¢®®¡é¥ £®¢®àï, ¡®«ì訬 æ¢¥â®¢ë¬ à §à¥è¥¨¥¬), |
§ ¯¨áì ¨£®à¨àã¥âáï. |
᪫î票¥¬ ï¥âáï ०¨¬ 320*200, ¤«ï ª®â®à®£® ¢ £« ¢®¬ 横«¥ |
á¨á⥬®£® ¯®â®ª ¢ë¯®«ï¥âáï ®¡®¢«¥¨¥ íªà ¢ ᮮ⢥âá⢨¨ |
á ¤¢¨¦¥¨ï¬¨ ªãàá®à ¬ëè¨. |
------------------------- Разрешение экрана -------------------------- |
Параметры: |
* eax = 61 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* eax = [разрешение по оси x]*65536 + [разрешение по оси y] |
Замечания: |
* Можно использовать функцию 14 с учётом того, что она возвращает |
размеры на 1 меньше. Это полностью эквивалентный способ. |
------------------------- §à¥è¥¨¥ íªà -------------------------- |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [à §à¥è¥¨¥ ¯® ®á¨ x]*65536 + [à §à¥è¥¨¥ ¯® ®á¨ y] |
¬¥ç ¨ï: |
* ®¦® ¨á¯®«ì§®¢ âì äãªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ® ¢®§¢à é ¥â |
à §¬¥àë 1 ¬¥ìè¥. â® ¯®«®áâìî íª¢¨¢ «¥âë© á¯®á®¡. |
------------------------ Число бит на пиксель ------------------------ |
Параметры: |
* eax = 61 - номер функции |
* ebx = 2 - номер подфункции |
Возвращаемое значение: |
* eax = число бит на пиксель (24 или 32) |
------------------------ ¨á«® ¡¨â ¯¨ªá¥«ì ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡¨â ¯¨ªá¥«ì (24 ¨«¨ 32) |
------------------------ Число байт на строку ------------------------ |
Параметры: |
* eax = 61 - номер функции |
* ebx = 3 - номер подфункции |
Возвращаемое значение: |
* eax = число байт, которое занимает одна строка развёртки |
(горизонтальная линия на экране) |
------------------------ ¨á«® ¡ ©â áâபã ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡ ©â, ª®â®à®¥ § ¨¬ ¥â ®¤ áâப à §¢ñà⪨ |
(£®à¨§®â «ì ï «¨¨ï íªà ¥) |
====================================================================== |
===== Функция 62, подфункция 0 - получить версию PCI-интерфейса. ===== |
===== ãªæ¨ï 62, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ¢¥àá¨î PCI-¨â¥à䥩á . ===== |
====================================================================== |
Параметры: |
* eax = 62 - номер функции |
* bl = 0 - номер подфункции |
Возвращаемое значение: |
* eax = -1 - доступ к PCI запрещён; иначе |
* ah.al = версия PCI-интерфейса (ah=версия, al=подверсия) |
* старшее слово eax обнулено |
Замечания: |
* Предварительно должен быть разрешён низкоуровневый доступ к PCI |
для приложений подфункцией 12 функции 21. |
* Если PCI BIOS не поддерживается, то значение ax неопределено. |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* ah.al = ¢¥àá¨ï PCI-¨â¥à䥩á (ah=¢¥àá¨ï, al=¯®¤¢¥àá¨ï) |
* áâ à襥 á«®¢® eax ®¡ã«¥® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ ax ¥®¯à¥¤¥«¥®. |
====================================================================== |
==== Функция 62, подфункция 1 - получить номер последней PCI-шины. === |
==== ãªæ¨ï 62, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ®¬¥à ¯®á«¥¤¥© PCI-è¨ë. === |
====================================================================== |
Параметры: |
* eax = 62 - номер функции |
* bl = 1 - номер подфункции |
Возвращаемое значение: |
* eax = -1 - доступ к PCI запрещён; иначе |
* al = номер последней PCI-шины; оставшиеся байты eax разрушаются |
Замечания: |
* Предварительно должен быть разрешён низкоуровневый доступ к PCI |
для приложений подфункцией 12 функции 21. |
* Если PCI BIOS не поддерживается, то значение al неопределено. |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ®¬¥à ¯®á«¥¤¥© PCI-è¨ë; ®á⠢訥áï ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ al ¥®¯à¥¤¥«¥®. |
====================================================================== |
====================== Функция 62, подфункция 2 ====================== |
== Получить механизм обращения к конфигурационному пространству PCI. = |
====================== ãªæ¨ï 62, ¯®¤äãªæ¨ï 2 ====================== |
== ®«ãç¨âì ¬¥å ¨§¬ ®¡à é¥¨ï ª ª®ä¨£ãà 樮®¬ã ¯à®áâà áâ¢ã PCI. = |
====================================================================== |
Параметры: |
* eax = 62 - номер функции |
* bl = 2 - номер подфункции |
Возвращаемое значение: |
* eax = -1 - доступ к PCI запрещён; иначе |
* al = механизм (1 или 2); прочие байты eax разрушаются |
Замечания: |
* Предварительно должен быть разрешён низкоуровневый доступ к PCI |
для приложений подфункцией 12 функции 21. |
* Механизм обращения выбирается в соответствии |
с характеристиками оборудования. |
* Подфункции чтения и записи автоматически работают |
с выбранным механизмом. |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ¬¥å ¨§¬ (1 ¨«¨ 2); ¯à®ç¨¥ ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ®¡à é¥¨ï ¢ë¡¨à ¥âáï ¢ ᮮ⢥âá⢨¨ |
á å à ªâ¥à¨á⨪ ¬¨ ®¡®à㤮¢ ¨ï. |
* ®¤äãªæ¨¨ çâ¥¨ï ¨ § ¯¨á¨ ¢â®¬ â¨ç¥áª¨ à ¡®â îâ |
á ¢ë¡à ë¬ ¬¥å ¨§¬®¬. |
====================================================================== |
======== Функция 62, подфункции 4,5,6 - прочитать PCI-регистр. ======= |
======== ãªæ¨ï 62, ¯®¤äãªæ¨¨ 4,5,6 - ¯à®ç¨â âì PCI-ॣ¨áâà. ======= |
====================================================================== |
Параметры: |
* eax = 62 - номер функции |
* bl = 4 - читать байт |
* bl = 5 - читать слово |
* bl = 6 - читать двойное слово |
* bh = номер PCI-шины |
* ch = dddddfff, где ddddd = номер устройства на шине, |
fff = номер функции устройства |
* cl = номер регистра (должен быть чётным для bl=5, |
делиться на 4 для bl=6) |
Возвращаемое значение: |
* eax = -1 - ошибка (запрещён доступ к PCI или |
неподдерживаемые параметры); иначе |
* al/ax/eax (в зависимости от запрошенного размера) содержит данные; |
оставшаяся часть регистра eax разрушается |
Замечания: |
* Предварительно должен быть разрешён низкоуровневый доступ к PCI |
для приложений подфункцией 12 функции 21. |
* Механизм доступа 2 поддерживает только 16 устройств на шине и |
игнорирует номер функции. Получить механизм доступа можно вызовом |
подфункции 2. |
* Некоторые регистры стандартны и существуют для всех устройств, |
некоторые определяются конкретным устройством. Список первых |
входит, например, в известный Interrupt List by Ralf Brown |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 4 - ç¨â âì ¡ ©â |
* bl = 5 - ç¨â âì á«®¢® |
* bl = 6 - ç¨â âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=5, |
¤¥«¨âìáï 4 ¤«ï bl=6) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë); ¨ ç¥ |
* al/ax/eax (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â ¤ ë¥; |
®áâ ¢è ïáï ç áâì ॣ¨áâà eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
список вторых должен быть указан в документации по устройству. |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
======= Функция 62, подфункции 8,9,10 - записать в PCI-регистр. ====== |
======= ãªæ¨ï 62, ¯®¤äãªæ¨¨ 8,9,10 - § ¯¨á âì ¢ PCI-ॣ¨áâà. ====== |
====================================================================== |
Параметры: |
* eax = 62 - номер функции |
* bl = 8 - писать байт |
* bl = 9 - писать слово |
* bl = 10 - писать двойное слово |
* bh = номер PCI-шины |
* ch = dddddfff, где ddddd = номер устройства на шине, |
fff = номер функции устройства |
* cl = номер регистра (должен быть чётным для bl=9, |
делиться на 4 для bl=10) |
* dl/dx/edx (в зависимости от запрошенного размера) содержит |
данные для записи |
Возвращаемое значение: |
* eax = -1 - ошибка (запрещён доступ к PCI или |
неподдерживаемые параметры) |
* eax = 0 - успешно |
Замечания: |
* Предварительно должен быть разрешён низкоуровневый доступ к PCI |
для приложений подфункцией 12 функции 21. |
* Механизм доступа 2 поддерживает только 16 устройств на шине и |
игнорирует номер функции. Получить механизм доступа можно вызовом |
подфункции 2. |
* Некоторые регистры стандартны и существуют для всех устройств, |
некоторые определяются конкретным устройством. Список первых |
входит, например, в известный Interrupt List by Ralf Brown; |
список вторых должен быть указан в документации по устройству. |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 8 - ¯¨á âì ¡ ©â |
* bl = 9 - ¯¨á âì á«®¢® |
* bl = 10 - ¯¨á âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=9, |
¤¥«¨âìáï 4 ¤«ï bl=10) |
* dl/dx/edx (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â |
¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë) |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown; |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
================ Функция 63 - работа с доской отладки. =============== |
================ ãªæ¨ï 63 - à ¡®â á ¤®áª®© ®â« ¤ª¨. =============== |
====================================================================== |
Доска отладки представляет собой системный буфер (на 4096 байт), |
в который любая программа может записать (вообще говоря, произвольные) |
данные и из которого другая программа может эти данные прочитать. |
Есть соглашение, в соответствии с которым записываемые данные - |
текстовые строки, интерпретируемые как отладочные сообщения о ходе |
выполнения программы. Ядро в определённых ситуациях также записывает |
на доску отладки сведения о выполнении некоторых функций; |
по соглашению сообщения ядра начинаются с префикса "K : ". |
Для просмотра доски отладки создано приложение board, |
которое считывает данные из буфера и отображает их в своём окне. board |
понимает последовательность кодов 13,10 как переход на новую строку. |
Символ с нулевым кодом в конце строки не обязателен, но и не мешает. |
В связи с появлением отладчика ценность доски отладки несколько |
снизилась, поскольку отладчик позволяет полностью контролировать ход |
выполнения программы, причём для этого не требуется никаких усилий |
со стороны самой программы. Тем не менее во многих случаях |
доска отладки продолжает оставаться полезной. |
®áª ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨áâ¥¬ë© ¡ãä¥à ( 4096 ¡ ©â), |
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬ ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ìë¥) |
¤ ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬ ¬®¦¥â í⨠¤ ë¥ ¯à®ç¨â âì. |
áâì ᮣ« 襨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨áë¢ ¥¬ë¥ ¤ ë¥ - |
⥪áâ®¢ë¥ áâப¨, ¨â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®çë¥ á®®¡é¥¨ï ® 室¥ |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë. ¤à® ¢ ®¯à¥¤¥«ñëå á¨âã æ¨ïå â ª¦¥ § ¯¨áë¢ ¥â |
¤®áªã ®â« ¤ª¨ ᢥ¤¥¨ï ® ¢ë¯®«¥¨¨ ¥ª®â®àëå äãªæ¨©; |
¯® ᮣ« 襨î á®®¡é¥¨ï ï¤à ç¨ îâáï á ¯à¥ä¨ªá "K : ". |
«ï ¯à®á¬®âà ¤®áª¨ ®â« ¤ª¨ ᮧ¤ ® ¯à¨«®¦¥¨¥ board, |
ª®â®à®¥ áç¨âë¢ ¥â ¤ ë¥ ¨§ ¡ãä¥à ¨ ®â®¡à ¦ ¥â ¨å ¢ ᢮ñ¬ ®ª¥. board |
¯®¨¬ ¥â ¯®á«¥¤®¢ ⥫ì®áâì ª®¤®¢ 13,10 ª ª ¯¥à¥å®¤ ®¢ãî áâபã. |
¨¬¢®« á ã«¥¢ë¬ ª®¤®¬ ¢ ª®æ¥ áâப¨ ¥ ®¡ï§ ⥫¥, ® ¨ ¥ ¬¥è ¥â. |
á¢ï§¨ á ¯®ï¢«¥¨¥¬ ®â« ¤ç¨ª 楮áâì ¤®áª¨ ®â« ¤ª¨ ¥áª®«ìª® |
ᨧ¨« áì, ¯®áª®«ìªã ®â« ¤ç¨ª ¯®§¢®«ï¥â ¯®«®áâìî ª®â஫¨à®¢ âì 室 |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë, ¯à¨çñ¬ ¤«ï í⮣® ¥ âॡã¥âáï ¨ª ª¨å ãᨫ¨© |
á® áâ®à®ë á ¬®© ¯à®£à ¬¬ë. ¥¬ ¥ ¬¥¥¥ ¢® ¬®£¨å á«ãç ïå |
¤®áª ®â« ¤ª¨ ¯à®¤®«¦ ¥â ®áâ ¢ âìáï ¯®«¥§®©. |
---------------------------- Запись байта ---------------------------- |
Параметры: |
* eax = 63 - номер функции |
* ebx = 1 - номер подфункции |
* cl = байт данных |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Байт записывается в буфер. Длина буфера - 512 байт. |
При переполнении буфера все полученные данные теряются |
и заполнение начинается снова с нуля. |
* Для вывода на доску отладки более сложных объектов (строк, чисел) |
достаточно этой функции, вызываемой в цикле. Можно не писать |
вручную соответствующий код, а воспользоваться файлом debug.inc, |
входящим в дистрибутив. |
---------------------------- ¯¨áì ¡ ©â ---------------------------- |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ©â § ¯¨áë¢ ¥âáï ¢ ¡ãä¥à. «¨ ¡ãä¥à - 512 ¡ ©â. |
ਠ¯¥à¥¯®«¥¨¨ ¡ãä¥à ¢á¥ ¯®«ãç¥ë¥ ¤ ë¥ â¥àïîâáï |
¨ § ¯®«¥¨¥ ç¨ ¥âáï ᮢ á ã«ï. |
* «ï ¢ë¢®¤ ¤®áªã ®â« ¤ª¨ ¡®«¥¥ á«®¦ëå ®¡ê¥ªâ®¢ (áâப, ç¨á¥«) |
¤®áâ â®ç® í⮩ äãªæ¨¨, ¢ë§ë¢ ¥¬®© ¢ 横«¥. ®¦® ¥ ¯¨á âì |
¢àãçãî ᮮ⢥âáâ¢ãî騩 ª®¤, ¢®á¯®«ì§®¢ âìáï ä ©«®¬ debug.inc, |
¢å®¤ï騬 ¢ ¤¨áâਡã⨢. |
---------------------------- Чтение байта ---------------------------- |
Забирает байт из буфера. |
Параметры: |
* eax = 63 - номер функции |
* ebx = 2 - номер подфункции |
Возвращаемое значение: |
* eax = ebx = 0 - буфер пуст |
* eax = байт, ebx = 1 - байт успешно прочитан |
---------------------------- ⥨¥ ¡ ©â ---------------------------- |
¡¨à ¥â ¡ ©â ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ebx = 0 - ¡ãä¥à ¯ãáâ |
* eax = ¡ ©â, ebx = 1 - ¡ ©â ãá¯¥è® ¯à®ç¨â |
====================================================================== |
========== Функция 64 - перераспределить память приложения. ========== |
========== ãªæ¨ï 64 - ¯¥à¥à á¯à¥¤¥«¨âì ¯ ¬ïâì ¯à¨«®¦¥¨ï. ========== |
====================================================================== |
Параметры: |
* eax = 64 - номер функции |
* ebx = 1 - единственная подфункция |
* ecx = новый размер памяти |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - недостаточно памяти |
Замечания: |
* Есть другой способ выделения/освобождения динамической памяти - |
подфункции 11, 12, 13 функции 68. |
* Функция не может использоваться совместно с 68.11, 68.12, 68.13. |
Вызов функции будет игнорироваться, если приложение создаст |
локальную кучу вызовом 68.11. |
à ¬¥âàë: |
* eax = 64 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ®¢ë© à §¬¥à ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥¤®áâ â®ç® ¯ ¬ï⨠|
¬¥ç ¨ï: |
* áâì ¤à㣮© ᯮᮡ ¢ë¤¥«¥¨ï/®á¢®¡®¦¤¥¨ï ¤¨ ¬¨ç¥áª®© ¯ ¬ï⨠- |
¯®¤äãªæ¨¨ 11, 12, 13 äãªæ¨¨ 68. |
* ãªæ¨ï ¥ ¬®¦¥â ¨á¯®«ì§®¢ âìáï ᮢ¬¥áâ® á 68.11, 68.12, 68.13. |
맮¢ äãªæ¨¨ ¡ã¤¥â ¨£®à¨à®¢ âìáï, ¥á«¨ ¯à¨«®¦¥¨¥ ᮧ¤ áâ |
«®ª «ìãî ªãç㠢맮¢®¬ 68.11. |
====================================================================== |
========= Функция 65 - вывести изображение с палитрой в окно. ======== |
========= ãªæ¨ï 65 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ á ¯ «¨âன ¢ ®ª®. ======== |
====================================================================== |
Параметры: |
* eax = 65 - номер функции |
* ebx = указатель на изображение |
* ecx = [размер по оси x]*65536 + [размер по оси y] |
* edx = [координата по оси x]*65536 + [координата по оси y] |
* esi = число бит на пиксель, должно быть 1,2,4,8,9,15,16,24 или 32 |
* edi = указатель на палитру (2 в степени esi цветов 0x00RRGGBB); |
игнорируется при esi > 8 |
* ebp = смещение данных каждой следующей строки изображения |
относительно предыдущей |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Координаты изображения - это координаты верхнего левого угла |
изображения относительно окна. |
* Формат изображения с 1 битом на пиксель: каждый байт изображения, |
за исключением, быть может, последних байтов строк, содержит |
информацию о цвете 8 пикселей, старший бит соответствует первому |
пикселю. |
* Формат изображения с 2 битами на пиксель: каждый байт изображения, |
за исключением, быть может, последних байтов строк, содержит |
информацию о цвете 4 пикселей, старшие два бита соответствуют |
первому пикселю. |
* Формат изображения с 4 битами на пиксель: каждый байт изображения, |
за исключением последних байтов строк (если ширина изображения |
нечётна), содержит информацию о цвете 2 пикселей, старшая тетрада |
соответствует первому пикселю. |
* Формат изображения с 8 битами на пиксель: каждый байт изображения |
рассматривается как индекс в палитре. |
* Формат изображения с 9 битами на пиксель: каждый байт изображения |
(8 бит) обозначает интенсивность серого для одного пикселя, т.о. |
этот тип изображения идентичен 8 бит на пиксель без палитры. |
* Формат изображения с 15 битами на пиксель: цвет каждого пикселя |
кодируется как (в битовом представлении) 0RRRRRGGGGGBBBBB - |
по 5 пикселей на каждый цвет. |
* Формат изображения с 16 битами на пиксель: цвет каждого пикселя |
кодируется как RRRRRGGGGGGBBBBB (схема 5+6+5). |
* Формат изображения с 24 битами на пиксель: цвет каждого пикселя |
кодируется тремя байтами - последовательно синяя, зелёная, красная |
составляющие цвета. |
* Формат изображения с 32 битами на пиксель: аналогично 24, только |
есть ещё игнорируемый четвёртый байт. |
* Вызов функции 7 эквивалентен вызову этой функции с параметрами |
à ¬¥âàë: |
* eax = 65 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = ç¨á«® ¡¨â ¯¨ªá¥«ì, ¤®«¦® ¡ëâì 1,2,4,8,9,15,16,24 ¨«¨ 32 |
* edi = 㪠§ â¥«ì ¯ «¨âàã (2 ¢ á⥯¥¨ esi 梥⮢ 0x00RRGGBB); |
¨£®à¨àã¥âáï ¯à¨ esi > 8 |
* ebp = ᬥ饨¥ ¤ ëå ª ¦¤®© á«¥¤ãî饩 áâப¨ ¨§®¡à ¦¥¨ï |
®â®á¨â¥«ì® ¯à¥¤ë¤ã饩 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* ®à¬ â ¨§®¡à ¦¥¨ï á 1 ¡¨â®¬ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â |
¨ä®à¬ æ¨î ® 梥⥠8 ¯¨ªá¥«¥©, áâ à訩 ¡¨â ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã |
¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 2 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â |
¨ä®à¬ æ¨î ® 梥⥠4 ¯¨ªá¥«¥©, áâ à訥 ¤¢ ¡¨â ᮮ⢥âáâ¢ãîâ |
¯¥à¢®¬ã ¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 4 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï, |
§ ¨áª«î票¥¬ ¯®á«¥¤¨å ¡ ©â®¢ áâப (¥á«¨ è¨à¨ ¨§®¡à ¦¥¨ï |
¥çñâ ), ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® 梥⥠2 ¯¨ªá¥«¥©, áâ àè ï â¥âà ¤ |
ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã ¯¨ªá¥«î. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 8 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï |
à áᬠâਢ ¥âáï ª ª ¨¤¥ªá ¢ ¯ «¨âà¥. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 9 ¡¨â ¬¨ ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï |
(8 ¡¨â) ®¡®§ ç ¥â ¨â¥á¨¢®áâì á¥à®£® ¤«ï ®¤®£® ¯¨ªá¥«ï, â.®. |
íâ®â ⨯ ¨§®¡à ¦¥¨ï ¨¤¥â¨ç¥ 8 ¡¨â ¯¨ªá¥«ì ¡¥§ ¯ «¨âàë. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 15 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï ª ª (¢ ¡¨â®¢®¬ ¯à¥¤áâ ¢«¥¨¨) 0RRRRRGGGGGBBBBB - |
¯® 5 ¯¨ªá¥«¥© ª ¦¤ë© 梥â. |
* ®à¬ â ¨§®¡à ¦¥¨ï á 16 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï ª ª RRRRRGGGGGGBBBBB (á奬 5+6+5). |
* ®à¬ â ¨§®¡à ¦¥¨ï á 24 ¡¨â ¬¨ ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï |
ª®¤¨àã¥âáï âà¥¬ï ¡ ©â ¬¨ - ¯®á«¥¤®¢ â¥«ì® á¨ïï, §¥«ñ ï, ªà á ï |
á®áâ ¢«ïî騥 梥â . |
* ®à¬ â ¨§®¡à ¦¥¨ï á 32 ¡¨â ¬¨ ¯¨ªá¥«ì: «®£¨ç® 24, ⮫쪮 |
¥áâì ¥éñ ¨£®à¨àã¥¬ë© ç¥â¢ñàâë© ¡ ©â. |
* 맮¢ äãªæ¨¨ 7 íª¢¨¢ «¥â¥ ¢ë§®¢ã í⮩ äãªæ¨¨ á ¯ à ¬¥âà ¬¨ |
esi=24, ebp=0. |
====================================================================== |
================= Функция 66 - работа с клавиатурой. ================= |
================= ãªæ¨ï 66 - à ¡®â á ª« ¢¨ âãன. ================= |
====================================================================== |
Режим ввода влияет на результаты чтения клавиш функцией 2. |
При загрузке программы для неё устанавливается ASCII-режим ввода. |
¥¦¨¬ ¢¢®¤ ¢«¨ï¥â १ã«ìâ âë çâ¥¨ï ª« ¢¨è äãªæ¨¥© 2. |
ਠ§ £à㧪¥ ¯à®£à ¬¬ë ¤«ï ¥ñ ãáâ ¢«¨¢ ¥âáï ASCII-०¨¬ ¢¢®¤ . |
-------- Подфункция 1 - установить режим ввода с клавиатуры. --------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = режим: |
* 0 = обычный (ASCII-символы) |
* 1 = сканкоды |
Возвращаемое значение: |
* функция не возвращает значения |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. --------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬: |
* 0 = ®¡ëçë© (ASCII-ᨬ¢®«ë) |
* 1 = ᪠ª®¤ë |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- Подфункция 2 - получить режим ввода с клавиатуры. ---------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 2 - номер подфункции |
Возвращаемое значение: |
* eax = текущий режим |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ०¨¬ ¢¢®¤ á ª« ¢¨ âãàë. ---------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ⥪ã騩 ०¨¬ |
------- Подфункция 3 - получить состояние управляющих клавиш. -------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 3 - номер подфункции |
Возвращаемое значение: |
* eax = битовая маска: |
* бит 0 (маска 1): левый Shift нажат |
* бит 1 (маска 2): правый Shift нажат |
* бит 2 (маска 4): левый Ctrl нажат |
* бит 3 (маска 8): правый Ctrl нажат |
* бит 4 (маска 0x10): левый Alt нажат |
* бит 5 (маска 0x20): правый Alt нажат |
* бит 6 (маска 0x40): CapsLock включён |
* бит 7 (маска 0x80): NumLock включён |
* бит 8 (маска 0x100): ScrollLock включён |
* бит 9 (маска 0x200): левый Win нажат |
* бит 10 (маска 0x400): правый Win нажат |
* прочие биты сброшены |
------- ®¤äãªæ¨ï 3 - ¯®«ãç¨âì á®áâ®ï¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è. -------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡¨â®¢ ï ¬ ᪠: |
* ¡¨â 0 (¬ ᪠1): «¥¢ë© Shift ¦ â |
* ¡¨â 1 (¬ ᪠2): ¯à ¢ë© Shift ¦ â |
* ¡¨â 2 (¬ ᪠4): «¥¢ë© Ctrl ¦ â |
* ¡¨â 3 (¬ ᪠8): ¯à ¢ë© Ctrl ¦ â |
* ¡¨â 4 (¬ ᪠0x10): «¥¢ë© Alt ¦ â |
* ¡¨â 5 (¬ ᪠0x20): ¯à ¢ë© Alt ¦ â |
* ¡¨â 6 (¬ ᪠0x40): CapsLock ¢ª«îçñ |
* ¡¨â 7 (¬ ᪠0x80): NumLock ¢ª«îçñ |
* ¡¨â 8 (¬ ᪠0x100): ScrollLock ¢ª«îçñ |
* ¡¨â 9 (¬ ᪠0x200): «¥¢ë© Win ¦ â |
* ¡¨â 10 (¬ ᪠0x400): ¯à ¢ë© Win ¦ â |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
----- Подфункция 4 - установить общесистемную "горячую клавишу". ----- |
О нажатии "горячей клавиши" извещаются только приложения, |
установившие её; активное приложение (к которому поступает |
весь нормальный ввод) таких клавиш не получает. |
Извещение заключается в посылке события с кодом 2. |
Прочитать "горячую клавишу" можно так же, как и обычную, - |
функцией 2. |
Параметры: |
* eax = 66 - номер функции |
* ebx = 4 - номер подфункции |
* cl задаёт сканкод клавиши; |
используйте cl=0 для задания комбинаций типа Ctrl+Shift |
* edx = 0xXYZ задаёт возможные состояния управляющих клавиш: |
* Z (младшие 4 бита) задаёт состояние клавиш LShift и RShift: |
* 0 = ни одна из клавиш не должна быть нажата; |
* 1 = ровно одна из клавиш должна быть нажата; |
* 2 = обе клавиши должны быть нажаты; |
* 3 = должна быть нажата LShift, но не RShift; |
* 4 = должна быть нажата RShift, но не LShift |
* Y - аналогично для LCtrl и RCtrl; |
* X - аналогично для LAlt и RAlt |
Возвращаемое значение: |
* eax=0 - успешно |
* eax=1 - слишком много "горячих клавиш" (допускается максимум 256) |
Замечания: |
* Горячая клавиша может срабатывать либо при нажатии, |
либо при отпускании. Сканкод отпускания клавиши на 128 больше, |
чем сканкод нажатия (т.е. установлен старший бит). |
* Несколько приложений могут установить одну и ту же комбинацию; |
о нажатии такой комбинации будут извещаться все такие приложения. |
----- ®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ®¡é¥á¨á⥬ãî "£®àïçãî ª« ¢¨èã". ----- |
¦ ⨨ "£®àï祩 ª« ¢¨è¨" ¨§¢¥é îâáï ⮫쪮 ¯à¨«®¦¥¨ï, |
ãáâ ®¢¨¢è¨¥ ¥ñ; ªâ¨¢®¥ ¯à¨«®¦¥¨¥ (ª ª®â®à®¬ã ¯®áâ㯠¥â |
¢¥áì ®à¬ «ìë© ¢¢®¤) â ª¨å ª« ¢¨è ¥ ¯®«ãç ¥â. |
§¢¥é¥¨¥ § ª«îç ¥âáï ¢ ¯®á뫪¥ ᮡëâ¨ï á ª®¤®¬ 2. |
à®ç¨â âì "£®àïçãî ª« ¢¨èã" ¬®¦® â ª ¦¥, ª ª ¨ ®¡ëçãî, - |
äãªæ¨¥© 2. |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl § ¤ ñâ ᪠ª®¤ ª« ¢¨è¨; |
¨á¯®«ì§ã©â¥ cl=0 ¤«ï § ¤ ¨ï ª®¬¡¨ 権 ⨯ Ctrl+Shift |
* edx = 0xXYZ § ¤ ñâ ¢®§¬®¦ë¥ á®áâ®ï¨ï ã¯à ¢«ïîé¨å ª« ¢¨è: |
* Z (¬« ¤è¨¥ 4 ¡¨â ) § ¤ ñâ á®áâ®ï¨¥ ª« ¢¨è LShift ¨ RShift: |
* 0 = ¨ ®¤ ¨§ ª« ¢¨è ¥ ¤®«¦ ¡ëâì ¦ â ; |
* 1 = ஢® ®¤ ¨§ ª« ¢¨è ¤®«¦ ¡ëâì ¦ â ; |
* 2 = ®¡¥ ª« ¢¨è¨ ¤®«¦ë ¡ëâì ¦ âë; |
* 3 = ¤®«¦ ¡ëâì ¦ â LShift, ® ¥ RShift; |
* 4 = ¤®«¦ ¡ëâì ¦ â RShift, ® ¥ LShift |
* Y - «®£¨ç® ¤«ï LCtrl ¨ RCtrl; |
* X - «®£¨ç® ¤«ï LAlt ¨ RAlt |
®§¢à é ¥¬®¥ § 票¥: |
* eax=0 - ãá¯¥è® |
* eax=1 - ᫨誮¬ ¬®£® "£®àïç¨å ª« ¢¨è" (¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 256) |
¬¥ç ¨ï: |
* ®àïç ï ª« ¢¨è ¬®¦¥â áà ¡ âë¢ âì «¨¡® ¯à¨ ¦ ⨨, |
«¨¡® ¯à¨ ®â¯ã᪠¨¨. ª ª®¤ ®â¯ã᪠¨ï ª« ¢¨è¨ 128 ¡®«ìè¥, |
祬 ᪠ª®¤ ¦ â¨ï (â.¥. ãáâ ®¢«¥ áâ à訩 ¡¨â). |
* ¥áª®«ìª® ¯à¨«®¦¥¨© ¬®£ãâ ãáâ ®¢¨âì ®¤ã ¨ âã ¦¥ ª®¬¡¨ æ¨î; |
® ¦ ⨨ â ª®© ª®¬¡¨ 樨 ¡ã¤ãâ ¨§¢¥é âìáï ¢á¥ â ª¨¥ ¯à¨«®¦¥¨ï. |
------ Подфункция 5 - удалить установленную "горячую клавишу". ------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 5 - номер подфункции |
* cl = сканкод клавиши и edx = 0xXYZ такие же, как и в подфункции 4 |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - нет такой горячей клавиши |
Замечания: |
* При завершении процесса/потока удаляются все установленные им |
горячие клавиши. |
* Вызов функции не влияет на другие приложения. |
Если другое приложение определило эту же комбинацию, |
оно по-прежнему будет получать уведомления. |
------ ®¤äãªæ¨ï 5 - 㤠«¨âì ãáâ ®¢«¥ãî "£®àïçãî ª« ¢¨èã". ------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ᪠ª®¤ ª« ¢¨è¨ ¨ edx = 0xXYZ â ª¨¥ ¦¥, ª ª ¨ ¢ ¯®¤äãªæ¨¨ 4 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥â â ª®© £®àï祩 ª« ¢¨è¨ |
¬¥ç ¨ï: |
* ਠ§ ¢¥à襨¨ ¯à®æ¥áá /¯®â®ª 㤠«ïîâáï ¢á¥ ãáâ ®¢«¥ë¥ ¨¬ |
£®àï稥 ª« ¢¨è¨. |
* 맮¢ äãªæ¨¨ ¥ ¢«¨ï¥â ¤à㣨¥ ¯à¨«®¦¥¨ï. |
᫨ ¤à㣮¥ ¯à¨«®¦¥¨¥ ®¯à¥¤¥«¨«® íâã ¦¥ ª®¬¡¨ æ¨î, |
®® ¯®-¯à¥¦¥¬ã ¡ã¤¥â ¯®«ãç âì 㢥¤®¬«¥¨ï. |
------------- Подфункция 6 - заблокировать обычный ввод. ------------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 6 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Блокируется обычный ввод данных с клавиатуры для установленных |
"горячих" клавиш |
* Для эмуляции мыши через клавиатуру, приложение MOUSEMUL |
------------- ®¤äãªæ¨ï 6 - § ¡«®ª¨à®¢ âì ®¡ëçë© ¢¢®¤. ------------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* «®ª¨àã¥âáï ®¡ëçë© ¢¢®¤ ¤ ëå á ª« ¢¨ âãàë ¤«ï ãáâ ®¢«¥ëå |
"£®àïç¨å" ª« ¢¨è |
* «ï í¬ã«ï樨 ¬ëè¨ ç¥à¥§ ª« ¢¨ âãàã, ¯à¨«®¦¥¨¥ MOUSEMUL |
--------- Подфункция 7 - разблокировать обычный ввод. ---------------- |
Параметры: |
* eax = 66 - номер функции |
* ebx = 7 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Разблокирование результатов ф. 66.6 |
* Для эмуляции мыши через клавиатуру, приложение MOUSEMUL |
--------- ®¤äãªæ¨ï 7 - à §¡«®ª¨à®¢ âì ®¡ëçë© ¢¢®¤. ---------------- |
à ¬¥âàë: |
* eax = 66 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* §¡«®ª¨à®¢ ¨¥ १ã«ìâ ⮢ ä. 66.6 |
* «ï í¬ã«ï樨 ¬ëè¨ ç¥à¥§ ª« ¢¨ âãàã, ¯à¨«®¦¥¨¥ MOUSEMUL |
====================================================================== |
============ Функция 67 - изменить положение/размеры окна. =========== |
============ ãªæ¨ï 67 - ¨§¬¥¨âì ¯®«®¦¥¨¥/à §¬¥àë ®ª . =========== |
====================================================================== |
Параметры: |
* eax = 67 - номер функции |
* ebx = новая x-координата окна |
* ecx = новая y-координата окна |
* edx = новый x-размер окна |
* esi = новый y-размер окна |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Значение -1 для параметра означает "не изменять"; например, для |
перемещения окна без изменения размеров можно указать edx=esi=-1. |
* Предварительно окно должно быть определено функцией 0. |
Она же задаёт начальные координаты и размеры окна. |
* Размеры окна понимаются в смысле функции 0, т.е. |
на один пиксель меньше, чем реальные размеры. |
* Вызов функции для максимизированных окон просто игнорируется. |
* Для окон соответствующих стилей положение и/или размеры могут быть |
изменены пользователем; текущие положение и размеры могут быть |
получены вызовом функции 9. |
* Функция посылает окну событие перерисовки (с кодом 1). |
à ¬¥âàë: |
* eax = 67 - ®¬¥à äãªæ¨¨ |
* ebx = ®¢ ï x-ª®®à¤¨ â ®ª |
* ecx = ®¢ ï y-ª®®à¤¨ â ®ª |
* edx = ®¢ë© x-à §¬¥à ®ª |
* esi = ®¢ë© y-à §¬¥à ®ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 票¥ -1 ¤«ï ¯ à ¬¥âà ®§ ç ¥â "¥ ¨§¬¥ïâì"; ¯à¨¬¥à, ¤«ï |
¯¥à¥¬¥é¥¨ï ®ª ¡¥§ ¨§¬¥¥¨ï à §¬¥à®¢ ¬®¦® 㪠§ âì edx=esi=-1. |
* ।¢ à¨â¥«ì® ®ª® ¤®«¦® ¡ëâì ®¯à¥¤¥«¥® äãªæ¨¥© 0. |
¦¥ § ¤ ñâ ç «ìë¥ ª®®à¤¨ âë ¨ à §¬¥àë ®ª . |
* §¬¥àë ®ª ¯®¨¬ îâáï ¢ á¬ëá«¥ äãªæ¨¨ 0, â.¥. |
®¤¨ ¯¨ªá¥«ì ¬¥ìè¥, 祬 ॠ«ìë¥ à §¬¥àë. |
* 맮¢ äãªæ¨¨ ¤«ï ¬ ªá¨¬¨§¨à®¢ ëå ®ª® ¯à®áâ® ¨£®à¨àã¥âáï. |
* «ï ®ª® ᮮ⢥âáâ¢ãîé¨å á⨫¥© ¯®«®¦¥¨¥ ¨/¨«¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¨§¬¥¥ë ¯®«ì§®¢ ⥫¥¬; ⥪ã騥 ¯®«®¦¥¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì |
¯®«ãç¥ë ¢ë§®¢®¬ äãªæ¨¨ 9. |
* ãªæ¨ï ¯®áë« ¥â ®ªã ᮡë⨥ ¯¥à¥à¨á®¢ª¨ (á ª®¤®¬ 1). |
====================================================================== |
=== Функция 68, подфункция 0 - получить счётчик переключений задач. == |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì áçñâ稪 ¯¥à¥ª«î票© § ¤ ç. == |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 0 - номер подфункции |
Возвращаемое значение: |
* eax = число переключений задач с момента загрузки системы |
(по модулю 2^32) |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯¥à¥ª«î票© § ¤ ç á ¬®¬¥â § £à㧪¨ á¨á⥬ë |
(¯® ¬®¤ã«î 2^32) |
====================================================================== |
====================== Функция 68, подфункция 1 ====================== |
============ Переключиться на следующий поток выполнения. ============ |
====================== ãªæ¨ï 68, ¯®¤äãªæ¨ï 1 ====================== |
============ ¥à¥ª«îç¨âìáï á«¥¤ãî騩 ¯®â®ª ¢ë¯®«¥¨ï. ============ |
====================================================================== |
Функция завершает текущий квант времени, выделенный потоку, |
и переключается на следующий. |
(Какой поток какого процесса будет следующим, предсказать нельзя). |
Позднее, когда до текущего потока дойдёт очередь, |
выполнение возобновится. |
Параметры: |
* eax = 68 - номер функции |
* ebx = 1 - номер подфункции |
Возвращаемое значение: |
* функция не возвращает значения |
ãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ª¢ ⠢६¥¨, ¢ë¤¥«¥ë© ¯®â®ªã, |
¨ ¯¥à¥ª«îç ¥âáï á«¥¤ãî騩. |
( ª®© ¯®â®ª ª ª®£® ¯à®æ¥áá ¡ã¤¥â á«¥¤ãî騬, ¯à¥¤áª § âì ¥«ì§ï). |
®§¤¥¥, ª®£¤ ¤® ⥪ã饣® ¯®â®ª ¤®©¤ñâ ®ç¥à¥¤ì, |
¢ë¯®«¥¨¥ ¢®§®¡®¢¨âáï. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
=============== Функция 68, подфункция 2 - кэш + rdpmc. ============== |
=============== ãªæ¨ï 68, ¯®¤äãªæ¨ï 2 - ªíè + rdpmc. ============== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = требуемое действие: |
* ecx = 0 - разрешить выполнение инструкции rdpmc |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âॡ㥬®¥ ¤¥©á⢨¥: |
* ecx = 0 - à §à¥è¨âì ¢ë¯®«¥¨¥ ¨áâàãªæ¨¨ rdpmc |
(ReaD Performance-Monitoring Counters) |
* ecx = 1 - узнать, включён/выключен кэш |
* ecx = 2 - включить кэш |
* ecx = 3 - выключить кэш |
Возвращаемое значение: |
* для ecx=0: |
* eax = значение cr4 |
* для ecx=1: |
* ecx = 1 - 㧠âì, ¢ª«îçñ/¢ëª«îç¥ ªíè |
* ecx = 2 - ¢ª«îç¨âì ªíè |
* ecx = 3 - ¢ëª«îç¨âì ªíè |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: |
* eax = § 票¥ cr4 |
* ¤«ï ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - кэш включён |
* eax <> 0 - кэш выключен |
* для ecx=2 и ecx=3: |
* функция не возвращает значения |
* eax = 0 - ªíè ¢ª«îçñ |
* eax <> 0 - ªíè ¢ëª«îç¥ |
* ¤«ï ecx=2 ¨ ecx=3: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
========== Функция 68, подфункция 3 - прочитать MSR-регистр. ========= |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 3 - ¯à®ç¨â âì MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; полный список MSR-регистров процессора |
содержится в документации по процессору (например, IA-32 Intel |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
каждое семейство процессоров имеет своё подмножество MSR-регистров. |
Параметры: |
* eax = 68 - номер функции |
* ebx = 3 - номер подфункции |
* ecx игнорируется |
* edx = адрес MSR |
Возвращаемое значение: |
* ebx:eax = старший:младший dword результата |
Замечания: |
* Указание в ecx несуществующего или нереализованного для данного |
процессора MSR повлечёт исключение в ядре, которое прибьёт поток. |
* Предварительно следует определить, поддерживаются ли MSR в целом, |
командой cpuid. Иначе возникнет уже другое исключение в ядре, |
которое всё равно прибьёт поток. |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
®§¢à é ¥¬®¥ § 票¥: |
* ebx:eax = áâ à訩:¬« ¤è¨© dword १ã«ìâ â |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥çñ⠨᪫î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢áñ à ¢® ¯à¨¡ìñâ ¯®â®ª. |
====================================================================== |
========= Функция 68, подфункция 4 - записать в MSR-регистр. ========= |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 4 - § ¯¨á âì ¢ MSR-ॣ¨áâà. ========= |
====================================================================== |
MSR = Model Specific Register; полный список MSR-регистров процессора |
содержится в документации по процессору (например, IA-32 Intel |
MSR = Model Specific Register; ¯®«ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à |
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥â 樨 ¯® ¯à®æ¥áá®àã ( ¯à¨¬¥à, IA-32 Intel |
Architecture Software Developer's Manual, Volume 3, Appendix B); |
каждое семейство процессоров имеет своё подмножество MSR-регистров. |
Параметры: |
* eax = 68 - номер функции |
* ebx = 4 - номер подфункции |
* ecx игнорируется |
* edx = адрес MSR |
* esi:edi = старший:младший dword |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Указание в ecx несуществующего или нереализованного для данного |
процессора MSR повлечёт исключение в ядре, которое прибьёт поток. |
* Предварительно следует определить, поддерживаются ли MSR в целом, |
командой cpuid. Иначе возникнет уже другое исключение в ядре, |
которое всё равно прибьёт поток. |
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬®¦¥á⢮ MSR-ॣ¨áâ஢. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx ¨£®à¨àã¥âáï |
* edx = ¤à¥á MSR |
* esi:edi = áâ à訩:¬« ¤è¨© dword |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥çñ⠨᪫î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢áñ à ¢® ¯à¨¡ìñâ ¯®â®ª. |
====================================================================== |
===== Функция 68, подфункция 11 - инициализировать кучу процесса. ==== |
===== ãªæ¨ï 68, ¯®¤äãªæ¨ï 11 - ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá . ==== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 11 - номер подфункции |
Возвращаемое значение: |
* eax = 0 - неуспех |
* иначе размер созданной кучи |
Замечания: |
* Вызов функции инициализирует кучу, из которой впоследствии можно |
выделять и освобождать блоки памяти подфункциями 12 и 13. |
Размер кучи равен размеру всей свободной памяти приложения. |
* При повторном вызове функции тем же процессом функция вернёт |
размер существующей кучи. |
* После создания кучи вызовы функции 64 игнорируются. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ãᯥå |
* ¨ ç¥ à §¬¥à ᮧ¤ ®© ªãç¨ |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ¨¨æ¨ «¨§¨àã¥â ªãçã, ¨§ ª®â®à®© ¢¯®á«¥¤á⢨¨ ¬®¦® |
¢ë¤¥«ïâì ¨ ®á¢®¡®¦¤ âì ¡«®ª¨ ¯ ¬ï⨠¯®¤äãªæ¨ï¬¨ 12 ¨ 13. |
§¬¥à ªãç¨ à ¢¥ à §¬¥à㠢ᥩ ᢮¡®¤®© ¯ ¬ï⨠¯à¨«®¦¥¨ï. |
* ਠ¯®¢â®à®¬ ¢ë§®¢¥ äãªæ¨¨ ⥬ ¦¥ ¯à®æ¥áᮬ äãªæ¨ï ¢¥àñâ |
à §¬¥à áãé¥áâ¢ãî饩 ªãç¨. |
* ®á«¥ ᮧ¤ ¨ï ªãç¨ ¢ë§®¢ë äãªæ¨¨ 64 ¨£®à¨àãîâáï. |
====================================================================== |
========== Функция 68, подфункция 12 - выделить блок памяти. ========= |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 12 - ¢ë¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ========= |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 12 - номер подфункции |
* ecx = требуемый размер в байтах |
Возвращаемое значение: |
* eax = указатель на выделенный блок |
Замечания: |
* Предварительно следует инициализировать кучу процесса вызовом |
подфункции 11. |
* Функция выделяет целое число страниц (4 Кб) так, что фактический |
размер выделенного блока больше или равен запрошенному. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âà¥¡ã¥¬ë© à §¬¥à ¢ ¡ ©â å |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¢ë¤¥«¥ë© ¡«®ª |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
====================================================================== |
========= Функция 68, подфункция 13 - освободить блок памяти. ======== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 13 - ®á¢®¡®¤¨âì ¡«®ª ¯ ¬ïâ¨. ======== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 13 - номер подфункции |
* ecx = указатель на блок памяти |
Возвращаемое значение: |
* eax = 1 - успешно |
* eax = 0 - неудача |
Замечания: |
* Блок памяти должен быть ранее выделен подфункцией 12 |
или подфункцией 20. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - ãá¯¥è® |
* eax = 0 - ¥ã¤ ç |
¬¥ç ¨ï: |
* «®ª ¯ ¬ï⨠¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 |
¨«¨ ¯®¤äãªæ¨¥© 20. |
====================================================================== |
====================== Функция 68, подфункция 14 ===================== |
====== Ожидать получения сигнала от других приложений/драйверов. ===== |
====================== ãªæ¨ï 68, ¯®¤äãªæ¨ï 14 ===================== |
====== ¦¨¤ âì ¯®«ã票ï ᨣ « ®â ¤àã£¨å ¯à¨«®¦¥¨©/¤à ©¢¥à®¢. ===== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 14 - номер подфункции |
* ecx = указатель на буфер для информации (24 байта) |
Возвращаемое значение: |
* eax разрушается |
* буфер, на который указывает ecx, содержит следующую информацию: |
* +0: dword: идентификатор последующих данных сигнала |
* +4: данные принятого сигнала (20 байт), формат которых |
определяется первым dword-ом |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¨ä®à¬ 樨 (24 ¡ ©â ) |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
* ¡ãä¥à, ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨ä®à¬ æ¨î: |
* +0: dword: ¨¤¥â¨ä¨ª â®à ¯®á«¥¤ãîé¨å ¤ ëå ᨣ « |
* +4: ¤ ë¥ ¯à¨ï⮣® ᨣ « (20 ¡ ©â), ä®à¬ â ª®â®àëå |
®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ dword-®¬ |
====================================================================== |
=========== Функция 68, подфункция 16 - загрузить драйвер. =========== |
=========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 16 - § £à㧨âì ¤à ©¢¥à. =========== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 16 - номер подфункции |
* ecx = указатель на ASCIIZ-строку с именем драйвера |
Возвращаемое значение: |
* eax = 0 - неудача |
* иначе eax = хэндл драйвера |
Замечания: |
* Если драйвер ещё не загружен, он загружается; |
если драйвер уже загружен, ничего не меняется. |
* Имя драйвера чувствительно к регистру символов. |
Максимальная длина имени - 16 символов, включая завершающий |
нулевой символ, остальные символы игнорируются. |
* Драйвер с именем ABC загружается из файла /rd/1/drivers/ABC.obj. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 16 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ¤à ©¢¥à |
¬¥ç ¨ï: |
* ᫨ ¤à ©¢¥à ¥éñ ¥ § £à㦥, ® § £à㦠¥âáï; |
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥, ¨ç¥£® ¥ ¬¥ï¥âáï. |
* ¬ï ¤à ©¢¥à çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã ᨬ¢®«®¢. |
ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ - 16 ᨬ¢®«®¢, ¢ª«îç ï § ¢¥àè î騩 |
ã«¥¢®© ᨬ¢®«, ®áâ «ìë¥ á¨¬¢®«ë ¨£®à¨àãîâáï. |
* à ©¢¥à á ¨¬¥¥¬ ABC § £à㦠¥âáï ¨§ ä ©« /rd/1/drivers/ABC.obj. |
====================================================================== |
========== Функция 68, подфункция 17 - управление драйвером. ========= |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 17 - ã¯à ¢«¥¨¥ ¤à ©¢¥à®¬. ========= |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 17 - номер подфункции |
* ecx = указатель на управляющую структуру: |
* +0: dword: хэндл драйвера |
* +4: dword: код функции драйвера |
* +8: dword: указатель на входные данные |
* +12 = +0xC: dword: размер входных данных |
* +16 = +0x10: dword: указатель на выходные данные |
* +20 = +0x14: dword: размер выходных данных |
Возвращаемое значение: |
* eax = определяется драйвером |
Замечания: |
* Коды функций и структура входных/выходных данных |
определяются драйвером. |
* Предварительно должен быть получен хэндл драйвера подфункцией 16. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ã¯à ¢«ïîéãî áâàãªâãàã: |
* +0: dword: åí¤« ¤à ©¢¥à |
* +4: dword: ª®¤ äãªæ¨¨ ¤à ©¢¥à |
* +8: dword: 㪠§ â¥«ì ¢å®¤ë¥ ¤ ë¥ |
* +12 = +0xC: dword: à §¬¥à ¢å®¤ëå ¤ ëå |
* +16 = +0x10: dword: 㪠§ â¥«ì ¢ëå®¤ë¥ ¤ ë¥ |
* +20 = +0x14: dword: à §¬¥à ¢ë室ëå ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¯à¥¤¥«ï¥âáï ¤à ©¢¥à®¬ |
¬¥ç ¨ï: |
* ®¤ë äãªæ¨© ¨ áâàãªâãà ¢å®¤ëå/¢ë室ëå ¤ ëå |
®¯à¥¤¥«ïîâáï ¤à ©¢¥à®¬. |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¯®«ãç¥ åí¤« ¤à ©¢¥à ¯®¤äãªæ¨¥© 16. |
====================================================================== |
============= Функция 68, подфункция 19 - загрузить DLL. ============= |
============= ãªæ¨ï 68, ¯®¤äãªæ¨ï 19 - § £à㧨âì DLL. ============= |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 19 - номер подфункции |
* ecx = указатель на ASCIIZ-строку с полным путём к DLL |
Возвращаемое значение: |
* eax = 0 - неудача |
* иначе eax = указатель на таблицу экспорта DLL |
Замечания: |
* Таблица экспорта представляет собой массив структур по 2 dword'а, |
заканчивающийся нулём. Первый dword в структуре является |
указателем на имя функции, второй содержит адрес функции. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯®«ë¬ ¯ãâñ¬ ª DLL |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = 㪠§ ⥫ì â ¡«¨æã íªá¯®àâ DLL |
¬¥ç ¨ï: |
* ¡«¨æ íªá¯®à⠯।áâ ¢«ï¥â ᮡ®© ¬ áᨢ áâàãªâãà ¯® 2 dword' , |
§ ª 稢 î騩áï ã«ñ¬. ¥à¢ë© dword ¢ áâàãªâãॠï¥âáï |
㪠§ ⥫¥¬ ¨¬ï äãªæ¨¨, ¢â®à®© ᮤ¥à¦¨â ¤à¥á äãªæ¨¨. |
====================================================================== |
====== Функция 68, подфункция 20 - перераспределить блок памяти. ===== |
====== ãªæ¨ï 68, ¯®¤äãªæ¨ï 20 - ¯¥à¥à á¯à¥¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ===== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 20 - номер подфункции |
* ecx = новый размер в байтах |
* edx = указатель на уже выделенный блок памяти |
Возвращаемое значение: |
* eax = указатель на перераспределённый блок, 0 при ошибке |
Замечания: |
* Предварительно следует инициализировать кучу процесса вызовом |
подфункции 11. |
* Функция выделяет целое число страниц (4 Кб) так, что фактический |
размер выделенного блока больше или равен запрошенному. |
* Если edx=0, то вызов функции эквивалентен выделению памяти |
подфункцией 12. В противном случае блок памяти по адресу edx |
должен быть ранее выделен подфункцией 12 или |
описываемой подфункцией. |
* Если ecx=0, то функция освобождает блок памяти по адресу edx и |
возвращает 0. |
* Содержимое памяти вплоть до наименьшего из старого и нового |
размеров сохраняется. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 20 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¢ë© à §¬¥à ¢ ¡ ©â å |
* edx = 㪠§ ⥫ì 㦥 ¢ë¤¥«¥ë© ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¯¥à¥à á¯à¥¤¥«ñë© ¡«®ª, 0 ¯à¨ ®è¨¡ª¥ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
* ᫨ edx=0, â® ¢ë§®¢ äãªæ¨¨ íª¢¨¢ «¥â¥ ¢ë¤¥«¥¨î ¯ ¬ï⨠|
¯®¤äãªæ¨¥© 12. ¯à®â¨¢®¬ á«ãç ¥ ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx |
¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 ¨«¨ |
®¯¨áë¢ ¥¬®© ¯®¤äãªæ¨¥©. |
* ᫨ ecx=0, â® äãªæ¨ï ®á¢®¡®¦¤ ¥â ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx ¨ |
¢®§¢à é ¥â 0. |
* ®¤¥à¦¨¬®¥ ¯ ¬ï⨠¢¯«®âì ¤® ¨¬¥ì襣® ¨§ áâ ண® ¨ ®¢®£® |
à §¬¥à®¢ á®åà ï¥âáï. |
====================================================================== |
========= Функция 68, подфункция 21 - загрузить драйвер PE. ========== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 21 - § £à㧨âì ¤à ©¢¥à PE. ========== |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 21 - номер подфункции |
* ecx = указатель на ASCIIZ-строку с именем драйвера |
* edx = указатель на командную строку |
Возвращаемое значение: |
* eax = 0 - неудача |
* иначе eax = хэндл драйвера |
Замечания: |
* Если драйвер ещё не загружен, он загружается; |
если драйвер уже загружен, ничего не меняется. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 21 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¤à ©¢¥à |
* edx = 㪠§ â¥«ì ª®¬ ¤ãî áâபã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ¤à ©¢¥à |
¬¥ç ¨ï: |
* ᫨ ¤à ©¢¥à ¥éñ ¥ § £à㦥, ® § £à㦠¥âáï; |
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥, ¨ç¥£® ¥ ¬¥ï¥âáï. |
====================================================================== |
=== Функция 68, подфункция 22 - открыть именованную область памяти. == |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 22 - ®âªàëâì ¨¬¥®¢ ãî ®¡« áâì ¯ ¬ïâ¨. == |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 22 - номер подфункции |
* ecx = имя области. Максимум 31 символ, включая завершающий ноль |
* edx = размер области в байтах для SHM_CREATE и SHM_OPEN_ALWAYS |
* esi = флаги открытия и доступа: |
* SHM_OPEN = 0x00 - открыть существующую область памяти. |
Если область с таким именем не существует, |
функция вернёт код ошибки 5. |
* SHM_OPEN_ALWAYS = 0x04 - открыть существующую или создать новую |
область памяти. |
* SHM_CREATE = 0x08 - создать новую область памяти. |
Если область с таким именем уже существует, |
функция вернёт код ошибки 10. |
* SHM_READ = 0x00 - доступ только на чтение |
* SHM_WRITE = 0x01 - доступ на чтение и запись |
Возвращаемое значение: |
* eax = указатель на область памяти, 0 при ошибке |
* при создании новой области (SHM_CREATE или SHM_OPEN_ALWAYS): |
edx = 0 - успех, иначе - код ошибки |
* при открытии существующей области (SHM_OPEN или SHM_OPEN_ALWAYS): |
edx = код ошибки (при eax=0) или размер области в байтах |
Коды ошибок: |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 22 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¬ï ®¡« áâ¨. ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ®«ì |
* edx = à §¬¥à ®¡« á⨠¢ ¡ ©â å ¤«ï SHM_CREATE ¨ SHM_OPEN_ALWAYS |
* esi = ä« £¨ ®âªàëâ¨ï ¨ ¤®áâ㯠: |
* SHM_OPEN = 0x00 - ®âªàëâì áãé¥áâ¢ãîéãî ®¡« áâì ¯ ¬ïâ¨. |
᫨ ®¡« áâì á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥áâ¢ã¥â, |
äãªæ¨ï ¢¥àñâ ª®¤ ®è¨¡ª¨ 5. |
* SHM_OPEN_ALWAYS = 0x04 - ®âªàëâì áãé¥áâ¢ãîéãî ¨«¨ ᮧ¤ âì ®¢ãî |
®¡« áâì ¯ ¬ïâ¨. |
* SHM_CREATE = 0x08 - ᮧ¤ âì ®¢ãî ®¡« áâì ¯ ¬ïâ¨. |
᫨ ®¡« áâì á â ª¨¬ ¨¬¥¥¬ 㦥 áãé¥áâ¢ã¥â, |
äãªæ¨ï ¢¥àñâ ª®¤ ®è¨¡ª¨ 10. |
* SHM_READ = 0x00 - ¤®áâ㯠⮫쪮 ç⥨¥ |
* SHM_WRITE = 0x01 - ¤®áâ㯠ç⥨¥ ¨ § ¯¨áì |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ®¡« áâì ¯ ¬ïâ¨, 0 ¯à¨ ®è¨¡ª¥ |
* ¯à¨ ᮧ¤ ¨¨ ®¢®© ®¡« á⨠(SHM_CREATE ¨«¨ SHM_OPEN_ALWAYS): |
edx = 0 - ãᯥå, ¨ ç¥ - ª®¤ ®è¨¡ª¨ |
* ¯à¨ ®âªàë⨨ áãé¥áâ¢ãî饩 ®¡« á⨠(SHM_OPEN ¨«¨ SHM_OPEN_ALWAYS): |
edx = ª®¤ ®è¨¡ª¨ (¯à¨ eax=0) ¨«¨ à §¬¥à ®¡« á⨠¢ ¡ ©â å |
®¤ë ®è¨¡®ª: |
* E_NOTFOUND = 5 |
* E_ACCESS = 10 |
* E_NOMEM = 30 |
* E_PARAM = 33 |
Замечания: |
* Предварительно следует инициализировать кучу процесса вызовом |
подфункции 11. |
* Если создаётся новая область, то флаги доступа устанавливают |
максимальные права доступа для остальных процессов. Попытка |
открытия другим потоком с неразрешёнными правами провалится |
с кодом ошибки E_ACCESS. |
* Процесс, создавший область, всегда имеет доступ на запись. |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ᫨ ᮧ¤ ñâáï ®¢ ï ®¡« áâì, â® ä« £¨ ¤®áâ㯠ãáâ ¢«¨¢ îâ |
¬ ªá¨¬ «ìë¥ ¯à ¢ ¤®áâ㯠¤«ï ®áâ «ìëå ¯à®æ¥áᮢ. ®¯ë⪠|
®âªàëâ¨ï ¤à㣨¬ ¯®â®ª®¬ á ¥à §à¥èñ묨 ¯à ¢ ¬¨ ¯à®¢ «¨âáï |
á ª®¤®¬ ®è¨¡ª¨ E_ACCESS. |
* à®æ¥áá, ᮧ¤ ¢è¨© ®¡« áâì, ¢á¥£¤ ¨¬¥¥â ¤®áâ㯠§ ¯¨áì. |
====================================================================== |
=== Функция 68, подфункция 23 - закрыть именованную область памяти. == |
=== ãªæ¨ï 68, ¯®¤äãªæ¨ï 23 - § ªàëâì ¨¬¥®¢ ãî ®¡« áâì ¯ ¬ïâ¨. == |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 23 - номер подфункции |
* ecx = имя области. Максимум 31 символ, включая завершающий ноль |
Возвращаемое значение: |
* eax разрушается |
Замечания: |
* Область памяти физически освобождается (с забыванием всех данных |
и высвобождением физической памяти), когда её закроют |
все открывшие потоки. |
* При завершении потока освобождаются все открытые им |
области памяти. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 23 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¬ï ®¡« áâ¨. ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ®«ì |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¡« áâì ¯ ¬ï⨠䨧¨ç¥áª¨ ®á¢®¡®¦¤ ¥âáï (á § ¡ë¢ ¨¥¬ ¢á¥å ¤ ëå |
¨ ¢ë᢮¡®¦¤¥¨¥¬ 䨧¨ç¥áª®© ¯ ¬ïâ¨), ª®£¤ ¥ñ § ªà®îâ |
¢á¥ ®âªàë¢è¨¥ ¯®â®ª¨. |
* ਠ§ ¢¥à襨¨ ¯®â®ª ®á¢®¡®¦¤ îâáï ¢á¥ ®âªàëâë¥ ¨¬ |
®¡« á⨠¯ ¬ïâ¨. |
====================================================================== |
==== Функция 68, подфункция 24 - установить обработчик исключений. === |
==== ãªæ¨ï 68, ¯®¤äãªæ¨ï 24 - ãáâ ®¢¨âì ®¡à ¡®â稪 ¨áª«î票©. === |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 24 - номер подфункции |
* ecx = адрес нового обработчика исключений |
* edx = маска обрабатываемых исключений |
Возвращаемое значение: |
* eax = адрес старого обработчика исключений (0, если не установлен) |
* ebx = маска старого обработчика исключений |
Замечания: |
* Номер бита в маске исключений соответствует номеру исключения по |
спецификации на процессор (Intel-PC). Так, например, исключения |
FPU имеют номер 16 (#MF), а SSE - 19 (#XF). |
* В данной реализации игнорируется запрос на перехват исключения 7 |
- система обрабатывает #NM самостоятельно. |
* Пользовательский обработчик получает номер исключения параметром |
в стеке. Поэтому правильный выход из обработчика: RET 4. Возврат |
при этом производится на команду, вызвавшую исключение. |
* При передаче управления обработчику исключений сбрасывается |
соответствующий бит в маске исключений. Возникновение этого же |
исключения впоследствии приведёт к умолчальной обработке такового. |
А именно: к завершению работы приложения в отсутствии отладчика, |
приостановка с уведомлением отлаживающего приложения иначе. |
* После завершения критических действий в обработчике пользователя |
восстановление бита маски данного исключения можно сделать |
подфункцией 25. Сброс флагов исключений в модулях FPU и XMM также |
возлагается на обработчик пользователя. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 24 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á ®¢®£® ®¡à ¡®â稪 ¨áª«î票© |
* edx = ¬ ᪠®¡à ¡ âë¢ ¥¬ëå ¨áª«î票© |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤à¥á áâ ண® ®¡à ¡®â稪 ¨áª«î票© (0, ¥á«¨ ¥ ãáâ ®¢«¥) |
* ebx = ¬ ᪠áâ ண® ®¡à ¡®â稪 ¨áª«î票© |
¬¥ç ¨ï: |
* ®¬¥à ¡¨â ¢ ¬ ᪥ ¨áª«î票© ᮮ⢥âáâ¢ã¥â ®¬¥à㠨᪫îç¥¨ï ¯® |
ᯥæ¨ä¨ª 樨 ¯à®æ¥áá®à (Intel-PC). ª, ¯à¨¬¥à, ¨áª«î票ï |
FPU ¨¬¥îâ ®¬¥à 16 (#MF), SSE - 19 (#XF). |
* ¤ ®© ॠ«¨§ 樨 ¨£®à¨àã¥âáï § ¯à®á ¯¥à¥å¢ ⠨᪫î票ï 7 |
- á¨á⥬ ®¡à ¡ âë¢ ¥â #NM á ¬®áâ®ï⥫ì®. |
* ®«ì§®¢ ⥫ì᪨© ®¡à ¡®â稪 ¯®«ãç ¥â ®¬¥à ¨áª«îç¥¨ï ¯ à ¬¥â஬ |
¢ á⥪¥. ®íâ®¬ã ¯à ¢¨«ìë© ¢ë室 ¨§ ®¡à ¡®â稪 : RET 4. ®§¢à â |
¯à¨ í⮬ ¯à®¨§¢®¤¨âáï ª®¬ ¤ã, ¢ë§¢ ¢èãî ¨áª«î票¥. |
* ਠ¯¥à¥¤ ç¥ ã¯à ¢«¥¨ï ®¡à ¡®â稪㠨᪫î票© á¡à áë¢ ¥âáï |
ᮮ⢥âáâ¢ãî騩 ¡¨â ¢ ¬ ᪥ ¨áª«î票©. ®§¨ª®¢¥¨¥ í⮣® ¦¥ |
¨áª«îç¥¨ï ¢¯®á«¥¤á⢨¨ ¯à¨¢¥¤ñâ ª 㬮«ç «ì®© ®¡à ¡®âª¥ â ª®¢®£®. |
¨¬¥®: ª § ¢¥à襨î à ¡®âë ¯à¨«®¦¥¨ï ¢ ®âáãâá⢨¨ ®â« ¤ç¨ª , |
¯à¨®áâ ®¢ª á 㢥¤®¬«¥¨¥¬ ®â« ¦¨¢ î饣® ¯à¨«®¦¥¨ï ¨ ç¥. |
* ®á«¥ § ¢¥àè¥¨ï ªà¨â¨ç¥áª¨å ¤¥©á⢨© ¢ ®¡à ¡®â稪¥ ¯®«ì§®¢ ⥫ï |
¢®ááâ ®¢«¥¨¥ ¡¨â ¬ ᪨ ¤ ®£® ¨áª«îç¥¨ï ¬®¦® ᤥ« âì |
¯®¤äãªæ¨¥© 25. ¡à®á ä« £®¢ ¨áª«î票© ¢ ¬®¤ã«ïå FPU ¨ XMM â ª¦¥ |
¢®§« £ ¥âáï ®¡à ¡®â稪 ¯®«ì§®¢ ⥫ï. |
====================================================================== |
= Функция 68, подфункция 25 - изменить состояние активности сигнала. = |
= ãªæ¨ï 68, ¯®¤äãªæ¨ï 25 - ¨§¬¥¨âì á®áâ®ï¨¥ ªâ¨¢®á⨠ᨣ « . = |
====================================================================== |
Параметры: |
* eax = 68 - номер функции |
* ebx = 25 - номер подфункции |
* ecx = номер сигнала |
* edx = значение устанавливаемой активности (0/1) |
Возвращаемое значение: |
* eax = -1 - задан неверный номер сигнала |
* иначе eax = старое значение активности сигнала (0/1) |
Замечания: |
* В текущей реализации изменяется только маска пользовательского |
обработчика исключений, установленного подфункцией 24. При этом |
номер сигнала соответствует номеру исключения. |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 25 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¬¥à ᨣ « |
* edx = § 票¥ ãáâ ¢«¨¢ ¥¬®© ªâ¨¢®á⨠(0/1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - § ¤ ¥¢¥àë© ®¬¥à ᨣ « |
* ¨ ç¥ eax = áâ ஥ § 票¥ ªâ¨¢®á⨠ᨣ « (0/1) |
¬¥ç ¨ï: |
* ⥪ã饩 ॠ«¨§ 樨 ¨§¬¥ï¥âáï ⮫쪮 ¬ ᪠¯®«ì§®¢ ⥫ì᪮£® |
®¡à ¡®â稪 ¨áª«î票©, ãáâ ®¢«¥®£® ¯®¤äãªæ¨¥© 24. ਠí⮬ |
®¬¥à ᨣ « ᮮ⢥âáâ¢ã¥â ®¬¥à㠨᪫î票ï. |
====================================================================== |
======================== Функция 69 - отладка. ======================= |
======================== ãªæ¨ï 69 - ®â« ¤ª . ======================= |
====================================================================== |
Процесс может загрузить другой процесс как отлаживаемый установкой |
соответствующего бита при вызове подфункции 7 функции 70. |
У процесса может быть только один отладчик; один процесс может |
отлаживать несколько разных. Система уведомляет отладчик о событиях, |
происходящих с отлаживаемым процессом. Сообщения записываются в буфер, |
определённый подфункцией 0. |
Формат сообщения: |
* +0: dword: код сообщения |
* +4: dword: PID отлаживаемого процесса |
* +8: могут присутствовать дополнительные данные, |
определяемые кодом сообщения |
Коды сообщений: |
* 1 = исключение |
* дополнительно передаётся dword-номер исключения |
* процесс приостановлен |
* 2 = процесс завершился |
* приходит при любом завершении: как через системную функцию -1, |
так и при "убийстве" любым другим процессом |
(в том числе самим отладчиком) |
* 3 = отладочное исключение int 1 = #DB |
* дополнительно передаётся dword-образ регистра DR6: |
* биты 0-3: выполнено условие соответствующей точки останова |
(установленной подфункцией 9) |
* бит 14: исключение произошло из-за режима |
пошаговой трассировки (установлен флаг TF) |
* процесс приостановлен |
При завершении отладчика прибиваются все отлаживаемые процессы. |
Если отладчик этого не хочет, он должен предварительно отключиться |
подфункцией 3. |
à®æ¥áá ¬®¦¥â § £à㧨âì ¤à㣮© ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© ãáâ ®¢ª®© |
ᮮ⢥âáâ¢ãî饣® ¡¨â ¯à¨ ¢ë§®¢¥ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 70. |
¯à®æ¥áá ¬®¦¥â ¡ëâì ⮫쪮 ®¤¨ ®â« ¤ç¨ª; ®¤¨ ¯à®æ¥áá ¬®¦¥â |
®â« ¦¨¢ âì ¥áª®«ìª® à §ëå. ¨á⥬ 㢥¤®¬«ï¥â ®â« ¤ç¨ª ® ᮡëâ¨ïå, |
¯à®¨á室ïé¨å á ®â« ¦¨¢ ¥¬ë¬ ¯à®æ¥áᮬ. ®®¡é¥¨ï § ¯¨áë¢ îâáï ¢ ¡ãä¥à, |
®¯à¥¤¥«ñë© ¯®¤äãªæ¨¥© 0. |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: ª®¤ á®®¡é¥¨ï |
* +4: dword: PID ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* +8: ¬®£ãâ ¯à¨áãâá⢮¢ âì ¤®¯®«¨â¥«ìë¥ ¤ ë¥, |
®¯à¥¤¥«ï¥¬ë¥ ª®¤®¬ á®®¡é¥¨ï |
®¤ë á®®¡é¥¨©: |
* 1 = ¨áª«î票¥ |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¬¥à ¨áª«î票ï |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
* 2 = ¯à®æ¥áá § ¢¥à訫áï |
* ¯à¨å®¤¨â ¯à¨ «î¡®¬ § ¢¥à襨¨: ª ª ç¥à¥§ á¨á⥬ãî äãªæ¨î -1, |
â ª ¨ ¯à¨ "㡨©á⢥" «î¡ë¬ ¤à㣨¬ ¯à®æ¥áᮬ |
(¢ ⮬ ç¨á«¥ á ¬¨¬ ®â« ¤ç¨ª®¬) |
* 3 = ®â« ¤®ç®¥ ¨áª«î票¥ int 1 = #DB |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¡à § ॣ¨áâà DR6: |
* ¡¨âë 0-3: ¢ë¯®«¥® ãá«®¢¨¥ ᮮ⢥âáâ¢ãî饩 â®çª¨ ®áâ ®¢ |
(ãáâ ®¢«¥®© ¯®¤äãªæ¨¥© 9) |
* ¡¨â 14: ¨áª«î票¥ ¯à®¨§®è«® ¨§-§ ०¨¬ |
¯®è £®¢®© âà áá¨à®¢ª¨ (ãáâ ®¢«¥ ä« £ TF) |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
ਠ§ ¢¥à襨¨ ®â« ¤ç¨ª ¯à¨¡¨¢ îâáï ¢á¥ ®â« ¦¨¢ ¥¬ë¥ ¯à®æ¥ááë. |
᫨ ®â« ¤ç¨ª í⮣® ¥ å®ç¥â, ® ¤®«¦¥ ¯à¥¤¢ à¨â¥«ì® ®âª«îç¨âìáï |
¯®¤äãªæ¨¥© 3. |
Все подфункции применимы только к процессам/потокам, запущенным |
из текущего функцией 70 с установленным флагом отладки. |
Отладка многопоточных программ пока не поддерживается. |
Полный список подфункций: |
* подфункция 0 - определить область данных для отладочных сообщений |
* подфункция 1 - получить состояние регистров отлаживаемого потока |
* подфункция 2 - установить состояние регистров отлаживаемого потока |
* подфункция 3 - отключиться от отлаживаемого процесса |
* подфункция 4 - приостановить отлаживаемый поток |
* подфункция 5 - возобновить выполнение отлаживаемого потока |
* подфункция 6 - прочитать из памяти отлаживаемого процесса |
* подфункция 7 - записать в память отлаживаемого процесса |
* подфункция 8 - завершить отлаживаемый поток |
* подфункция 9 - установить/снять аппаратную точку останова |
ᥠ¯®¤äãªæ¨¨ ¯à¨¬¥¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ãé¥ë¬ |
¨§ ⥪ã饣® äãªæ¨¥© 70 á ãáâ ®¢«¥ë¬ ä« £®¬ ®â« ¤ª¨. |
â« ¤ª ¬®£®¯®â®çëå ¯à®£à ¬¬ ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
®«ë© ᯨ᮪ ¯®¤äãªæ¨©: |
* ¯®¤äãªæ¨ï 0 - ®¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨© |
* ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 5 - ¢®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 6 - ¯à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 9 - ãáâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ |
====================================================================== |
====================== Функция 69, подфункция 0 ====================== |
========= Определить область данных для отладочных сообщений. ======== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 0 ====================== |
========= ¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨©. ======== |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 0 - номер подфункции |
* ecx = указатель |
Формат области данных: |
* +0: dword: N = размер буфера (не считая этого заголовка) |
* +4: dword: занято в буфере |
* +8: N*byte: буфер |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Если поле размера отрицательно, буфер считается заблокированным |
и при поступлении нового сообщения система будет ждать. |
Для синхронизации обрамляйте всю работу с буфером операциями |
блокировки/разблокировки |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì |
®à¬ â ®¡« á⨠¤ ëå: |
* +0: dword: N = à §¬¥à ¡ãä¥à (¥ áç¨â ï í⮣® § £®«®¢ª ) |
* +4: dword: § ïâ® ¢ ¡ãä¥à¥ |
* +8: N*byte: ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯®«¥ à §¬¥à ®âà¨æ ⥫ì®, ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬ |
¨ ¯à¨ ¯®áâ㯫¥¨¨ ®¢®£® á®®¡é¥¨ï á¨á⥬ ¡ã¤¥â ¦¤ âì. |
«ï á¨åந§ 樨 ®¡à ¬«ï©â¥ ¢áî à ¡®âã á ¡ãä¥à®¬ ®¯¥à æ¨ï¬¨ |
¡«®ª¨à®¢ª¨/à §¡«®ª¨à®¢ª¨ |
neg [bufsize] |
* Данные в буфере трактуются как массив элементов переменной длины - |
сообщений. Формат сообщения указан в общем описании. |
* ë¥ ¢ ¡ãä¥à¥ âà ªâãîâáï ª ª ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë - |
á®®¡é¥¨©. ®à¬ â á®®¡é¥¨ï 㪠§ ¢ ®¡é¥¬ ®¯¨á ¨¨. |
====================================================================== |
====================== Функция 69, подфункция 1 ====================== |
========= Получить состояние регистров отлаживаемого потока. ========= |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 1 ====================== |
========= ®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ========= |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = идентификатор потока |
* edx = длина структуры контекста, должно быть 0x28=40 байт |
* esi = указатель на структуру контекста |
Возвращаемое значение: |
* функция не возвращает значения |
Формат структуры контекста: (FPU пока не поддерживается) |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ : (FPU ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
3956,728 → 3956,728 |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
Замечания: |
* Если поток выполняет код 0-кольца, возвращается |
состояние регистров 3-кольца. |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ¢®§¢à é ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== Функция 69, подфункция 2 ====================== |
======== Установить состояние регистров отлаживаемого потока. ======== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 2 ====================== |
======== áâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ======== |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 2 - номер подфункции |
* ecx = идентификатор потока |
* edx = длина структуры контекста, должно быть 0x28=40 байт |
* esi = указатель на структуру контекста |
Возвращаемое значение: |
* функция не возвращает значения |
Формат структуры контекста указан в описании подфункции 1. |
Замечания: |
* Если поток выполняет код 0-кольца, устанавливается |
состояние регистров 3-кольца. |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1. |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ãáâ ¢«¨¢ ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
== Функция 69, подфункция 3 - отключиться от отлаживаемого процесса. = |
== ãªæ¨ï 69, ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . = |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 3 - номер подфункции |
* ecx = идентификатор |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Если процесс был приостановлен, он возобновляет выполнение. |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá ¡ë« ¯à¨®áâ ®¢«¥, ® ¢®§®¡®¢«ï¥â ¢ë¯®«¥¨¥. |
====================================================================== |
==== Функция 69, подфункция 4 - приостановить отлаживаемый поток. ==== |
==== ãªæ¨ï 69, ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ==== |
====================================================================== |
Параметры: |
* eax = 69 - номер процесса |
* ebx = 4 - номер подфункции |
* ecx = идентификатор |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
à ¬¥âàë: |
* eax = 69 - ®¬¥à ¯à®æ¥áá |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== Функция 69, подфункция 5 ====================== |
============ Возобновить выполнение отлаживаемого потока. ============ |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 5 ====================== |
============ ®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ============ |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 5 - номер подфункции |
* ecx = идентификатор |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== Функция 69, подфункция 6 ====================== |
============= Прочитать из памяти отлаживаемого процесса. ============ |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 6 ====================== |
============= à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . ============ |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 6 - номер подфункции |
* ecx = идентификатор |
* edx = сколько байт читать |
* esi = адрес памяти отлаживаемого процесса |
* edi = указатель на буфер для данных |
Возвращаемое значение: |
* eax = -1 при ошибке (неверный PID или буфер) |
* иначе eax = число прочитанных байт (возможно, 0, |
если в esi слишком большое значение) |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ç¨â âì |
* esi = ¤à¥á ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* edi = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
Функция 69, подфункция 7 - записать в память отлаживаемого процесса. |
ãªæ¨ï 69, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 7 - номер подфункции |
* ecx = идентификатор |
* edx = сколько байт писать |
* esi = адрес памяти в отлаживаемом процессе |
* edi = указатель на данные |
Возвращаемое значение: |
* eax = -1 при ошибке (неверный PID или буфер) |
* иначе eax = число записанных байт (возможно, 0, |
если в esi слишком большое значение) |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ¯¨á âì |
* esi = ¤à¥á ¯ ¬ï⨠¢ ®â« ¦¨¢ ¥¬®¬ ¯à®æ¥áᥠ|
* edi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====== Функция 69, подфункция 8 - завершить отлаживаемый поток. ====== |
====== ãªæ¨ï 69, ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ====== |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 8 - номер подфункции |
* ecx = идентификатор |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
* Функция аналогична подфункции 2 функции 18 с двумя отличиями: |
требуется выполнение первого замечания и принимается PID, |
а не номер слота. |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ãªæ¨ï «®£¨ç ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 á ¤¢ã¬ï ®â«¨ç¨ï¬¨: |
âॡã¥âáï ¢ë¯®«¥¨¥ ¯¥à¢®£® § ¬¥ç ¨ï ¨ ¯à¨¨¬ ¥âáï PID, |
¥ ®¬¥à á«®â . |
====================================================================== |
====================== Функция 69, подфункция 9 ====================== |
============= Установить/снять аппаратную точку останова. ============ |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 9 ====================== |
============= áâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ . ============ |
====================================================================== |
Параметры: |
* eax = 69 - номер функции |
* ebx = 9 - номер подфункции |
* ecx = идентификатор потока |
* dl = индекс точки останова, от 0 до 3 включительно |
* dh = флаги: |
* если старший бит сброшен - установить точку останова: |
* биты 0-1 - условие: |
* 00 = точка останова на выполнение |
* 01 = точка останова на запись |
* 11 = точка останова на чтение/запись |
* биты 2-3 - длина; для точек останова на исполнение должно быть |
00, в противном случае одно из |
* 00 = байт |
* 01 = слово |
* 11 = двойное слово |
* esi = адрес точки останова; должен быть выровнен |
соответственно длине (т.е. должен быть чётным для |
точек останова на слово, кратен 4 для двойного слова) |
* если старший бит установлен - сбросить точку останова |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - ошибка во входных данных |
* eax = 2 - (зарезервировано, никогда не возвращается |
в текущей реализации) с этим индексом уже установлена |
глобальная точка останова |
Замечания: |
* Процесс должен быть загружен для отладки (как указано в |
общем описании). |
* Аппаратные точки останова реализуются через DRx-регистры |
процессора, отсюда все ограничения. |
* Функция может переустановить ранее установленную ей же |
точку останова (никак не сообщая об этом). |
Ведите список установленных точек останова в отладчике. |
* Срабатывание точки останова заключается в генерировании |
отладочного исключения #DB, о котором система сообщает отладчику. |
* Точка останова на запись и чтение/запись срабатывает после |
выполнения вызвавшей её инструкции. |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* dl = ¨¤¥ªá â®çª¨ ®áâ ®¢ , ®â 0 ¤® 3 ¢ª«îç¨â¥«ì® |
* dh = ä« £¨: |
* ¥á«¨ áâ à訩 ¡¨â á¡à®è¥ - ãáâ ®¢¨âì â®çªã ®áâ ®¢ : |
* ¡¨âë 0-1 - ãá«®¢¨¥: |
* 00 = â®çª ®áâ ®¢ ¢ë¯®«¥¨¥ |
* 01 = â®çª ®áâ ®¢ § ¯¨áì |
* 11 = â®çª ®áâ ®¢ ç⥨¥/§ ¯¨áì |
* ¡¨âë 2-3 - ¤«¨ ; ¤«ï â®ç¥ª ®áâ ®¢ ¨á¯®«¥¨¥ ¤®«¦® ¡ëâì |
00, ¢ ¯à®â¨¢®¬ á«ãç ¥ ®¤® ¨§ |
* 00 = ¡ ©â |
* 01 = á«®¢® |
* 11 = ¤¢®©®¥ á«®¢® |
* esi = ¤à¥á â®çª¨ ®áâ ®¢ ; ¤®«¦¥ ¡ëâì ¢ë஢¥ |
ᮮ⢥âá⢥® ¤«¨¥ (â.¥. ¤®«¦¥ ¡ëâì çñâë¬ ¤«ï |
â®ç¥ª ®áâ ®¢ á«®¢®, ªà ⥠4 ¤«ï ¤¢®©®£® á«®¢ ) |
* ¥á«¨ áâ à訩 ¡¨â ãáâ ®¢«¥ - á¡à®á¨âì â®çªã ®áâ ®¢ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª ¢® ¢å®¤ëå ¤ ëå |
* eax = 2 - (§ १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï |
¢ ⥪ã饩 ॠ«¨§ 樨) á í⨬ ¨¤¥ªá®¬ 㦥 ãáâ ®¢«¥ |
£«®¡ «ì ï â®çª ®áâ ®¢ |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ¯¯ à âë¥ â®çª¨ ®áâ ®¢ ॠ«¨§ãîâáï ç¥à¥§ DRx-ॣ¨áâàë |
¯à®æ¥áá®à , ®âáî¤ ¢á¥ ®£à ¨ç¥¨ï. |
* ãªæ¨ï ¬®¦¥â ¯¥à¥ãáâ ®¢¨âì à ¥¥ ãáâ ®¢«¥ãî ¥© ¦¥ |
â®çªã ®áâ ®¢ (¨ª ª ¥ á®®¡é ï ®¡ í⮬). |
¥¤¨â¥ ᯨ᮪ ãáâ ®¢«¥ëå â®ç¥ª ®áâ ®¢ ¢ ®â« ¤ç¨ª¥. |
* à ¡ âë¢ ¨¥ â®çª¨ ®áâ ®¢ § ª«îç ¥âáï ¢ £¥¥à¨à®¢ ¨¨ |
®â« ¤®ç®£® ¨áª«î票ï #DB, ® ª®â®à®¬ á¨á⥬ á®®¡é ¥â ®â« ¤ç¨ªã. |
* ®çª ®áâ ®¢ § ¯¨áì ¨ ç⥨¥/§ ¯¨áì áà ¡ âë¢ ¥â ¯®á«¥ |
¢ë¯®«¥¨ï ¢ë§¢ ¢è¥© ¥ñ ¨áâàãªæ¨¨. |
====================================================================== |
= Функция 70 - работа с файловой системой с поддержкой длинных имён. = |
= ãªæ¨ï 70 - à ¡®â á ä ©«®¢®© á¨á⥬®© á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
Параметры: |
à ¬¥âàë: |
* eax = 70 |
* ebx = указатель на информационную структуру |
Возвращаемое значение: |
* eax = 0 - успешно; иначе код ошибки файловой системы |
* в зависимости от подфункции может возвращаться значение и |
в других регистрах |
Общий формат информационной структуры: |
* +0: dword: номер подфункции |
* +4: dword: смещение в файле |
* +8: dword: старший dword смещения (должен быть 0) или поле флагов |
* +12 = +0xC: dword: размер |
* +16 = +0x10: dword: указатель на данные |
* +20 = +0x14: n db: ASCIIZ-строка с именем файла |
или |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ᬥ饨¥ ¢ ä ©«¥ |
* +8: dword: áâ à訩 dword ᬥ饨ï (¤®«¦¥ ¡ëâì 0) ¨«¨ ¯®«¥ ä« £®¢ |
* +12 = +0xC: dword: à §¬¥à |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Уточнения - в документации на соответствующую подфункцию. |
Имя файла нечувствительно к регистру букв. Русские буквы должны быть |
записаны в кодировке cp866 (DOS). |
Формат имени файла: |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâà㠡㪢. ãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì |
§ ¯¨á ë ¢ ª®¤¨à®¢ª¥ cp866 (DOS). |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
где /base/number идентифицирует устройство, на котором ищется файл: |
одно из |
* /RD/1 = /RAMDISK/1 для доступа к рамдиску |
* /FD/1 = /FLOPPYDISK/1 для доступа к первому флоппи-дисководу, |
/FD/2 = /FLOPPYDISK/2 для второго флоппи-дисковода |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x для доступа соответственно |
к жёстким дискам на IDE0 (Primary Master), IDE1 (Primary Slave), |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ¦ñá⪨¬ ¤¨áª ¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - номер раздела на выбранном винчестере, изменяется от 1 до 255 |
(на каждом из винчестеров нумерация начинается с 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 для доступа соответственно |
к CD на IDE0 (Primary Master), IDE1 (Primary Slave), |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª CD IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
* /SYS - определяет системную папку; при обычной загрузке системы |
с дискеты эквивалентно /RD/1 |
Примеры: |
* /SYS - ®¯à¥¤¥«ï¥â á¨á⥬ãî ¯ ¯ªã; ¯à¨ ®¡ë箩 § £à㧪¥ á¨á⥬ë |
á ¤¨áª¥âë íª¢¨¢ «¥â® /RD/1 |
ਬ¥àë: |
* '/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/2/menuet/pics/tanzania.bmp',0 |
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 |
* '/sys/MySuperApp.ini',0 |
Также функция поддерживает относительные имена. Если путь начинается |
не с '/', то он считается относительно текущей папки. Получить или |
установить текущую папку можно с помощью сисфункции 30. |
ª¦¥ äãªæ¨ï ¯®¤¤¥à¦¨¢ ¥â ®â®á¨â¥«ìë¥ ¨¬¥ . ᫨ ¯ãâì ç¨ ¥âáï |
¥ á '/', â® ® áç¨â ¥âáï ®â®á¨â¥«ì® ⥪ã饩 ¯ ¯ª¨. ®«ãç¨âì ¨«¨ |
ãáâ ®¢¨âì ⥪ãéãî ¯ ¯ªã ¬®¦® á ¯®¬®éìî á¨áäãªæ¨¨ 30. |
Доступные подфункции: |
* подфункция 0 - чтение файла |
* подфункция 1 - чтение папки |
* подфункция 2 - создание/перезапись файла |
* подфункция 3 - запись в существующий файл |
* подфункция 4 - установка размера файла |
* подфункция 5 - получение атрибутов файла/папки |
* подфункция 6 - установка атрибутов файла/папки |
* подфункция 7 - запуск программы |
* подфункция 8 - удаление файла/папки |
* подфункция 9 - создание папки |
Для CD-приводов в связи с аппаратными ограничениями доступны |
только подфункции 0,1,5 и 7, вызов других подфункций завершится |
ошибкой с кодом 2. |
При первом обращении подфункций 0,1,5,7 к устройствам ATAPI |
(CD и DVD) производится блокировка ручного управления механизмом |
лотка. Это связано с кэшированием данных, полученных от привода. |
Разблокировка осуществляется при обращении подфункции 4 функции 24 |
к соответствующему устройству. |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« |
* ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 2 - ᮧ¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« |
* ¯®¤äãªæ¨ï 3 - § ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©« |
* ¯®¤äãªæ¨ï 4 - ãáâ ®¢ª à §¬¥à ä ©« |
* ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë |
* ¯®¤äãªæ¨ï 8 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨ |
«ï CD-¯à¨¢®¤®¢ ¢ á¢ï§¨ á ¯¯ à â묨 ®£à ¨ç¥¨ï¬¨ ¤®áâã¯ë |
⮫쪮 ¯®¤äãªæ¨¨ 0,1,5 ¨ 7, ¢ë§®¢ ¤àã£¨å ¯®¤äãªæ¨© § ¢¥àè¨âáï |
®è¨¡ª®© á ª®¤®¬ 2. |
ਠ¯¥à¢®¬ ®¡à 饨¨ ¯®¤äãªæ¨© 0,1,5,7 ª ãáâனá⢠¬ ATAPI |
(CD ¨ DVD) ¯à®¨§¢®¤¨âáï ¡«®ª¨à®¢ª àã箣® ã¯à ¢«¥¨ï ¬¥å ¨§¬®¬ |
«®âª . â® á¢ï§ ® á ªíè¨à®¢ ¨¥¬ ¤ ëå, ¯®«ãç¥ëå ®â ¯à¨¢®¤ . |
§¡«®ª¨à®¢ª ®áãé¥á⢫ï¥âáï ¯à¨ ®¡à 饨¨ ¯®¤äãªæ¨¨ 4 äãªæ¨¨ 24 |
ª ᮮ⢥âáâ¢ãî饬ã ãáâனáâ¢ã. |
====================================================================== |
= Функция 70, подфункция 0 - чтение файла с поддержкой длинных имён. = |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 0 = номер подфункции |
* +4: dword: позиция в файле (в байтах) |
* +8: dword: 0 (зарезервировано под старший dword позиции) |
* +12 = +0xC: dword: сколько байт читать |
* +16 = +0x10: dword: указатель на буфер, куда будут записаны данные |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ® ¯®¤ áâ à訩 dword ¯®§¨æ¨¨) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx = число прочитанных байт или |
-1=0xffffffff, если файл не найден |
Замечания: |
* Если файл кончился раньше, чем был прочитан последний запрошенный |
блок, то функция прочитает, сколько сможет, после чего вернёт |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ¯à®ç¨â ëå ¡ ©â ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ |
eax=6 (EOF). |
* Функция не позволяет читать папки |
(вернётся eax=10, access denied). |
* ãªæ¨ï ¥ ¯®§¢®«ï¥â ç¨â âì ¯ ¯ª¨ |
(¢¥àñâáï eax=10, access denied). |
====================================================================== |
= Функция 70, подфункция 1 - чтение папки с поддержкой длинных имён. = |
= ãªæ¨ï 70, ¯®¤äãªæ¨ï 1 - ç⥨¥ ¯ ¯ª¨ á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 1 = номер подфункции |
* +4: dword: индекс начального блока (считая с 0) |
* +8: dword: поле флагов: |
* бит 0 (маска 1): в каком формате возвращать имена, |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 1 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨¤¥ªá ç «ì®£® ¡«®ª (áç¨â ï á 0) |
* +8: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0 (¬ ᪠1): ¢ ª ª®¬ ä®à¬ ⥠¢®§¢à é âì ¨¬¥ , |
0=ANSI, 1=UNICODE |
* прочие биты зарезервированы и должны быть установлены в 0 |
для будущей совместимости |
* +12 = +0xC: dword: сколько блоков читать |
* +16 = +0x10: dword: указатель на буфер, куда будут записаны |
данные, размер буфера должен быть не меньше 32 + [+12]*560 байт |
* +20 = +0x14: ASCIIZ-имя папки, правила формирования имён указаны в |
общем описании |
или |
* ¯à®ç¨¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®á⨠|
* +12 = +0xC: dword: ᪮«ìª® ¡«®ª®¢ ç¨â âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë |
¤ ë¥, à §¬¥à ¡ãä¥à ¤®«¦¥ ¡ëâì ¥ ¬¥ìè¥ 32 + [+12]*560 ¡ ©â |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx = число файлов, информация о которых была записана в буфер, |
или -1=0xffffffff, если папка не найдена |
Структура буфера: |
* +0: 32*byte: заголовок |
* +32 = +0x20: n1*byte: блок с информацией о файле 1 |
* +32+n1: n2*byte: блок с информацией о файле 2 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® ä ©«®¢, ¨ä®à¬ æ¨ï ® ª®â®àëå ¡ë« § ¯¨á ¢ ¡ãä¥à, |
¨«¨ -1=0xffffffff, ¥á«¨ ¯ ¯ª ¥ ©¤¥ |
âàãªâãà ¡ãä¥à : |
* +0: 32*byte: § £®«®¢®ª |
* +32 = +0x20: n1*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 1 |
* +32+n1: n2*byte: ¡«®ª á ¨ä®à¬ 樥© ® ä ©«¥ 2 |
* ... |
Структура заголовка: |
* +0: dword: версия структуры (текущая версия = 1) |
* +4: dword: количество размещённых блоков; не больше, чем запрошено |
в поле +12 информационной структуры; может быть меньше, |
если в папке кончились файлы (то же самое, что и в ebx) |
* +8: dword: общее число файлов в папке |
* +12 = +0xC: 20*byte: зарезервировано (нули) |
Структура блока данных входа каталога (БДВК): |
* +0: dword: атрибуты файла: |
* бит 0 (маска 1): файл только для чтения |
* бит 1 (маска 2): файл является скрытым |
* бит 2 (маска 4): файл является системным |
* бит 3 (маска 8): это не файл, а метка тома |
(на заданном разделе встречается не более одного раза и |
только в корневой папке) |
* бит 4 (маска 0x10): это папка |
* бит 5 (маска 0x20): файл не архивировался - многие программы |
архивации имеют опцию, по которой архивируются только файлы |
с установленным этим битом, после чего этот бит сбрасывается - |
это может быть полезно для автоматического создания |
backup-архивов, ибо при записи бит обычно устанавливается |
(не в Kolibri, правда) |
* +4: byte: тип данных имени: |
(совпадает с битом 0 флагов информационной структуры) |
* 0 = ASCII = 1-байтное представление каждого символа |
* 1 = UNICODE = 2-байтное представление каждого символа |
* +5: 3*byte: зарезервировано (нули) |
* +8: 4*byte: время создания файла |
* +12 = +0xC: 4*byte: дата создания файла |
* +16 = +0x10: 4*byte: время последнего доступа (чтение или запись) |
* +20 = +0x14: 4*byte: дата последнего доступа |
* +24 = +0x18: 4*byte: время последней модификации |
* +28 = +0x1C: 4*byte: дата последней модификации |
* +32 = +0x20: qword: размер файла в байтах (до 16777216 Тб) |
* +40 = +0x28: имя |
* для формата ASCII: максимальная длина имени 263 символа |
(263 байта), байт после имени имеет значение 0 |
* для формата UNICODE: максимальная длина имени 259 символов |
(518 байт), два байта после имени имеют значение 0 |
Формат времени: |
* +0: byte: секунды |
* +1: byte: минуты |
* +2: byte: часы |
* +3: byte: зарезервировано (0) |
* например, 23.59.59 записывается как (в hex) 3B 3B 17 00 |
Формат даты: |
* +0: byte: день |
* +1: byte: месяц |
* +2: word: год |
* например, 25.11.1979 записывается как (в hex) 19 0B BB 07 |
Замечания: |
* Если в БДВК присутствует имя в ASCII, то длина БДВК составляет |
304 байта, если в UNICODE - 560 байт. Значение длины выравнено |
на целое кратное 16 байт |
(для ускорения обработки в кэш-памяти CPU). |
* Первый символ после имени нулевой (ASCIIZ-строка). Дальнейшие |
данные содержат мусор. |
* Если файлы в папке кончились раньше, чем было прочитано |
запрошенное количество, то функция прочитает, сколько сможет, |
после чего вернёт eax=6 (EOF). |
* Любая папка на диске, кроме корневой, содержит два специальных |
входа "." и "..", идентифицирующих соответственно саму папку и |
родительскую папку. |
* Функция позволяет также читать виртуальные папки "/", "/rd", |
"/fd", "/hd[n]", при этом атрибуты подпапок полагаются равными |
0x10, а времена и даты обнулены. Альтернативный способ получения |
информации об оборудовании - подфункция 11 функции 18. |
âàãªâãà § £®«®¢ª : |
* +0: dword: ¢¥àá¨ï áâàãªâãàë (⥪ãé ï ¢¥àá¨ï = 1) |
* +4: dword: ª®«¨ç¥á⢮ à §¬¥éñëå ¡«®ª®¢; ¥ ¡®«ìè¥, 祬 § ¯à®è¥® |
¢ ¯®«¥ +12 ¨ä®à¬ 樮®© áâàãªâãàë; ¬®¦¥â ¡ëâì ¬¥ìè¥, |
¥á«¨ ¢ ¯ ¯ª¥ ª®ç¨«¨áì ä ©«ë (â® ¦¥ á ¬®¥, çâ® ¨ ¢ ebx) |
* +8: dword: ®¡é¥¥ ç¨á«® ä ©«®¢ ¢ ¯ ¯ª¥ |
* +12 = +0xC: 20*byte: § १¥à¢¨à®¢ ® (㫨) |
âàãªâãà ¡«®ª ¤ ëå ¢å®¤ ª â «®£ (): |
* +0: dword: âਡãâë ä ©« : |
* ¡¨â 0 (¬ ᪠1): ä ©« ⮫쪮 ¤«ï ç⥨ï |
* ¡¨â 1 (¬ ᪠2): ä ©« ï¥âáï áªàëâë¬ |
* ¡¨â 2 (¬ ᪠4): ä ©« ï¥âáï á¨áâ¥¬ë¬ |
* ¡¨â 3 (¬ ᪠8): íâ® ¥ ä ©«, ¬¥âª ⮬ |
( § ¤ ®¬ à §¤¥«¥ ¢áâà¥ç ¥âáï ¥ ¡®«¥¥ ®¤®£® à § ¨ |
⮫쪮 ¢ ª®à¥¢®© ¯ ¯ª¥) |
* ¡¨â 4 (¬ ᪠0x10): íâ® ¯ ¯ª |
* ¡¨â 5 (¬ ᪠0x20): ä ©« ¥ à娢¨à®¢ «áï - ¬®£¨¥ ¯à®£à ¬¬ë |
à娢 樨 ¨¬¥îâ ®¯æ¨î, ¯® ª®â®à®© à娢¨àãîâáï ⮫쪮 ä ©«ë |
á ãáâ ®¢«¥ë¬ í⨬ ¡¨â®¬, ¯®á«¥ 祣® íâ®â ¡¨â á¡à áë¢ ¥âáï - |
íâ® ¬®¦¥â ¡ëâì ¯®«¥§® ¤«ï ¢â®¬ â¨ç¥áª®£® ᮧ¤ ¨ï |
backup- à娢®¢, ¨¡® ¯à¨ § ¯¨á¨ ¡¨â ®¡ëç® ãáâ ¢«¨¢ ¥âáï |
(¥ ¢ Kolibri, ¯à ¢¤ ) |
* +4: byte: ⨯ ¤ ëå ¨¬¥¨: |
(ᮢ¯ ¤ ¥â á ¡¨â®¬ 0 ä« £®¢ ¨ä®à¬ 樮®© áâàãªâãàë) |
* 0 = ASCII = 1-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* 1 = UNICODE = 2-¡ ©â®¥ ¯à¥¤áâ ¢«¥¨¥ ª ¦¤®£® ᨬ¢®« |
* +5: 3*byte: § १¥à¢¨à®¢ ® (㫨) |
* +8: 4*byte: ¢à¥¬ï ᮧ¤ ¨ï ä ©« |
* +12 = +0xC: 4*byte: ¤ â ᮧ¤ ¨ï ä ©« |
* +16 = +0x10: 4*byte: ¢à¥¬ï ¯®á«¥¤¥£® ¤®áâ㯠(ç⥨¥ ¨«¨ § ¯¨áì) |
* +20 = +0x14: 4*byte: ¤ â ¯®á«¥¤¥£® ¤®áâ㯠|
* +24 = +0x18: 4*byte: ¢à¥¬ï ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +28 = +0x1C: 4*byte: ¤ â ¯®á«¥¤¥© ¬®¤¨ä¨ª 樨 |
* +32 = +0x20: qword: à §¬¥à ä ©« ¢ ¡ ©â å (¤® 16777216 ¡) |
* +40 = +0x28: ¨¬ï |
* ¤«ï ä®à¬ â ASCII: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 263 ᨬ¢®« |
(263 ¡ ©â ), ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥¥â § 票¥ 0 |
* ¤«ï ä®à¬ â UNICODE: ¬ ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ 259 ᨬ¢®«®¢ |
(518 ¡ ©â), ¤¢ ¡ ©â ¯®á«¥ ¨¬¥¨ ¨¬¥îâ § 票¥ 0 |
®à¬ ⠢६¥¨: |
* +0: byte: ᥪã¤ë |
* +1: byte: ¬¨ãâë |
* +2: byte: ç áë |
* +3: byte: § १¥à¢¨à®¢ ® (0) |
* ¯à¨¬¥à, 23.59.59 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 3B 3B 17 00 |
®à¬ â ¤ âë: |
* +0: byte: ¤¥ì |
* +1: byte: ¬¥áïæ |
* +2: word: £®¤ |
* ¯à¨¬¥à, 25.11.1979 § ¯¨áë¢ ¥âáï ª ª (¢ hex) 19 0B BB 07 |
¬¥ç ¨ï: |
* ᫨ ¢ ¯à¨áãâáâ¢ã¥â ¨¬ï ¢ ASCII, â® ¤«¨ á®áâ ¢«ï¥â |
304 ¡ ©â , ¥á«¨ ¢ UNICODE - 560 ¡ ©â. 票¥ ¤«¨ë ¢ëà ¢¥® |
楫®¥ ªà ⮥ 16 ¡ ©â |
(¤«ï ãáª®à¥¨ï ®¡à ¡®âª¨ ¢ ªíè-¯ ¬ï⨠CPU). |
* ¥à¢ë© ᨬ¢®« ¯®á«¥ ¨¬¥¨ ã«¥¢®© (ASCIIZ-áâப ). «ì¥©è¨¥ |
¤ ë¥ á®¤¥à¦ â ¬ãá®à. |
* ᫨ ä ©«ë ¢ ¯ ¯ª¥ ª®ç¨«¨áì à ìè¥, 祬 ¡ë«® ¯à®ç¨â ® |
§ ¯à®è¥®¥ ª®«¨ç¥á⢮, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, |
¯®á«¥ 祣® ¢¥àñâ eax=6 (EOF). |
* î¡ ï ¯ ¯ª ¤¨áª¥, ªà®¬¥ ª®à¥¢®©, ᮤ¥à¦¨â ¤¢ á¯¥æ¨ «ìëå |
¢å®¤ "." ¨ "..", ¨¤¥â¨ä¨æ¨àãîé¨å ᮮ⢥âá⢥® á ¬ã ¯ ¯ªã ¨ |
த¨â¥«ìáªãî ¯ ¯ªã. |
* ãªæ¨ï ¯®§¢®«ï¥â â ª¦¥ ç¨â âì ¢¨àâã «ìë¥ ¯ ¯ª¨ "/", "/rd", |
"/fd", "/hd[n]", ¯à¨ í⮬ âਡãâë ¯®¤¯ ¯®ª ¯®« £ îâáï à ¢ë¬¨ |
0x10, ¢à¥¬¥ ¨ ¤ âë ®¡ã«¥ë. «ìâ¥à â¨¢ë© á¯®á®¡ ¯®«ã票ï |
¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ - ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18. |
====================================================================== |
====================== Функция 70, подфункция 2 ====================== |
======== Создание/перезапись файла с поддержкой длинных имён. ======== |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 2 ====================== |
======== ®§¤ ¨¥/¯¥à¥§ ¯¨áì ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. ======== |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 2 = номер подфункции |
* +4: dword: 0 (зарезервировано) |
* +8: dword: 0 (зарезервировано) |
* +12 = +0xC: dword: сколько байт писать |
* +16 = +0x10: dword: указатель на данные |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 2 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx = число записанных байт (возможно, 0) |
Замечания: |
* Если файл с таким именем не существовал, он создаётся; если |
существовал, то перезаписывается. |
* Если свободного места на диске недостаточно, то функция запишет, |
сколько сможет, после чего вернёт код ошибки 8. |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ᫨ ä ©« á â ª¨¬ ¨¬¥¥¬ ¥ áãé¥á⢮¢ «, ® ᮧ¤ ñâáï; ¥á«¨ |
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç®, â® äãªæ¨ï § ¯¨è¥â, |
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ ª®¤ ®è¨¡ª¨ 8. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
====================== Функция 70, подфункция 3 ====================== |
======== Запись в существующий файл с поддержкой длинных имён. ======= |
====================== ãªæ¨ï 70, ¯®¤äãªæ¨ï 3 ====================== |
======== ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©« á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. ======= |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 3 = номер подфункции |
* +4: dword: позиция в файле (в байтах) |
* +8: dword: старший dword позиции (должен быть 0 для FAT) |
* +12 = +0xC: dword: сколько байт писать |
* +16 = +0x10: dword: указатель на данные |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 3 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å) |
* +8: dword: áâ à訩 dword ¯®§¨æ¨¨ (¤®«¦¥ ¡ëâì 0 ¤«ï FAT) |
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx = число записанных байт (возможно, 0) |
Замечания: |
* Файл должен уже существовать, иначе вернётся eax=5. |
* Единственным результатом записи 0 байт является установка в |
атрибутах файла даты/времени модификации и доступа в текущую. |
* Если начальная и/или конечная позиция выходит за пределы файла |
(за исключением предыдущего случая), файл расширяется до |
необходимого размера нулевыми символами. |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0) |
¬¥ç ¨ï: |
* ©« ¤®«¦¥ 㦥 áãé¥á⢮¢ âì, ¨ ç¥ ¢¥àñâáï eax=5. |
* ¤¨áâ¢¥ë¬ à¥§ã«ìâ ⮬ § ¯¨á¨ 0 ¡ ©â ï¥âáï ãáâ ®¢ª ¢ |
âਡãâ å ä ©« ¤ âë/¢à¥¬¥¨ ¬®¤¨ä¨ª 樨 ¨ ¤®áâ㯠¢ ⥪ãéãî. |
* ᫨ ç «ì ï ¨/¨«¨ ª®¥ç ï ¯®§¨æ¨ï ¢ë室¨â § ¯à¥¤¥«ë ä ©« |
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï), ä ©« à áè¨àï¥âáï ¤® |
¥®¡å®¤¨¬®£® à §¬¥à ã«¥¢ë¬¨ ᨬ¢®« ¬¨. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
========= Функция 70, подфункция 4 - установка размера файла. ======== |
========= ãªæ¨ï 70, ¯®¤äãªæ¨ï 4 - ãáâ ®¢ª à §¬¥à ä ©« . ======== |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 4 = номер подфункции |
* +4: dword: младший dword нового размера файла |
* +8: dword: старший dword нового размера файла |
(должен быть 0 для FAT) |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: 0 (зарезервировано) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 4 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¬« ¤è¨© dword ®¢®£® à §¬¥à ä ©« |
* +8: dword: áâ à訩 dword ®¢®£® à §¬¥à ä ©« |
(¤®«¦¥ ¡ëâì 0 ¤«ï FAT) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx разрушается |
Замечания: |
* Если новый размер файла меньше старого, файл усекается. Если |
новый размер больше старого, файл расширяется нулевыми символами. |
Если новый размер равен старому, единственным результатом вызова |
является установка даты/времени модификации и доступа в текущие. |
* Если свободного места на диске недостаточно для расширения файла, |
то функция расширит насколько возможно, после чего вернёт |
код ошибки 8. |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ᫨ ®¢ë© à §¬¥à ä ©« ¬¥ìè¥ áâ ண®, ä ©« ãᥪ ¥âáï. ᫨ |
®¢ë© à §¬¥à ¡®«ìè¥ áâ ண®, ä ©« à áè¨àï¥âáï ã«¥¢ë¬¨ ᨬ¢®« ¬¨. |
᫨ ®¢ë© à §¬¥à à ¢¥ áâ ஬ã, ¥¤¨áâ¢¥ë¬ à¥§ã«ìâ ⮬ ¢ë§®¢ |
ï¥âáï ãáâ ®¢ª ¤ âë/¢à¥¬¥¨ ¬®¤¨ä¨ª 樨 ¨ ¤®áâ㯠¢ ⥪ã騥. |
* ᫨ ᢮¡®¤®£® ¬¥áâ ¤¨áª¥ ¥¤®áâ â®ç® ¤«ï à áè¨à¥¨ï ä ©« , |
â® äãªæ¨ï à áè¨à¨â ᪮«ìª® ¢®§¬®¦®, ¯®á«¥ 祣® ¢¥àñâ |
ª®¤ ®è¨¡ª¨ 8. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
=== Функция 70, подфункция 5 - получение информации о файле/папке. === |
=== ãªæ¨ï 70, ¯®¤äãªæ¨ï 5 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«¥/¯ ¯ª¥. === |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 5 = номер подфункции |
* +4: dword: 0 (зарезервировано) |
* +8: dword: 0 (зарезервировано) |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: указатель на буфер, куда будут записаны данные |
(40 байт) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 5 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(40 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx разрушается |
Информация о файле возвращается в формате БДВК |
(блока данных входа каталога), указанном в описании |
подфункции 1, но без имени файла |
(то есть первые 40 = 0x28 байт). |
Замечания: |
* Функция не поддерживает виртуальные папки типа /, /rd и |
корневые папки типа /rd/1. |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
ä®à¬ æ¨ï ® ä ©«¥ ¢®§¢à é ¥âáï ¢ ä®à¬ ⥠|
(¡«®ª ¤ ëå ¢å®¤ ª â «®£ ), 㪠§ ®¬ ¢ ®¯¨á ¨¨ |
¯®¤äãªæ¨¨ 1, ® ¡¥§ ¨¬¥¨ ä ©« |
(â® ¥áâì ¯¥à¢ë¥ 40 = 0x28 ¡ ©â). |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
====================================================================== |
===== Функция 70, подфункция 6 - установка атрибутов файла/папки. ==== |
===== ãªæ¨ï 70, ¯®¤äãªæ¨ï 6 - ãáâ ®¢ª âਡã⮢ ä ©« /¯ ¯ª¨. ==== |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 6 = номер подфункции |
* +4: dword: 0 (зарезервировано) |
* +8: dword: 0 (зарезервировано) |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: указатель на буфер с атрибутами (32 байта) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 6 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à á âਡãâ ¬¨ (32 ¡ ©â ) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx разрушается |
Атрибуты файла - первые 32 байта в БДВК (блоке данных входа каталога), |
формат которого указан в описании подфункции 1 |
(то есть без имени и размера файла). Атрибут файл/папка/метка тома |
(биты 3,4 в dword'е +0) не меняется. |
Байт +4 (формат имени) игнорируется. |
Замечания: |
* Функция не поддерживает виртуальные папки типа /, /rd и |
корневые папки типа /rd/1. |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
âਡãâë ä ©« - ¯¥à¢ë¥ 32 ¡ ©â ¢ (¡«®ª¥ ¤ ëå ¢å®¤ ª â «®£ ), |
ä®à¬ â ª®â®à®£® 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1 |
(â® ¥áâì ¡¥§ ¨¬¥¨ ¨ à §¬¥à ä ©« ). âਡãâ ä ©«/¯ ¯ª /¬¥âª ⮬ |
(¡¨âë 3,4 ¢ dword'¥ +0) ¥ ¬¥ï¥âáï. |
©â +4 (ä®à¬ â ¨¬¥¨) ¨£®à¨àã¥âáï. |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ìë¥ ¯ ¯ª¨ ⨯ /, /rd ¨ |
ª®à¥¢ë¥ ¯ ¯ª¨ ⨯ /rd/1. |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
====================================================================== |
============ Функция 70, подфункция 7 - запуск программы. ============ |
============ ãªæ¨ï 70, ¯®¤äãªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë. ============ |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 7 = номер подфункции |
* +4: dword: поле флагов: |
* бит 0: запустить процесс как отлаживаемый |
* остальные биты зарезервированы и должны быть установлены в 0 |
* +8: dword: 0 или указатель на ASCIIZ-строку с параметрами |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: 0 (зарезервировано) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 7 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¯®«¥ ä« £®¢: |
* ¡¨â 0: § ¯ãáâ¨âì ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© |
* ®áâ «ìë¥ ¡¨âë § १¥à¢¨à®¢ ë ¨ ¤®«¦ë ¡ëâì ãáâ ®¢«¥ë ¢ 0 |
* +8: dword: 0 ¨«¨ 㪠§ ⥫ì ASCIIZ-áâபã á ¯ à ¬¥âà ¬¨ |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax > 0 - программа загружена, eax содержит PID |
* eax < 0 - произошла ошибка, -eax содержит |
код ошибки файловой системы |
* ebx разрушается |
Замечания: |
* Командная строка должна заканчиваться символом с кодом 0 |
(ASCIIZ-строка); учитываются либо все символы до завершающего нуля |
включительно, либо первые 256 символов, в зависимости от того, |
что меньше. |
* Если процесс запускается как отлаживаемый, он создаётся |
в замороженном состоянии; для запуска используйте |
подфункцию 5 функции 69. |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax > 0 - ¯à®£à ¬¬ § £à㦥 , eax ᮤ¥à¦¨â PID |
* eax < 0 - ¯à®¨§®è« ®è¨¡ª , -eax ᮤ¥à¦¨â |
ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ®¬ ¤ ï áâப ¤®«¦ § ª 稢 âìáï ᨬ¢®«®¬ á ª®¤®¬ 0 |
(ASCIIZ-áâப ); ãç¨âë¢ îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ã«ï |
¢ª«îç¨â¥«ì®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®, |
çâ® ¬¥ìè¥. |
* ᫨ ¯à®æ¥áá § ¯ã᪠¥âáï ª ª ®â« ¦¨¢ ¥¬ë©, ® ᮧ¤ ñâáï |
¢ § ¬®à®¦¥®¬ á®áâ®ï¨¨; ¤«ï § ¯ã᪠¨á¯®«ì§ã©â¥ |
¯®¤äãªæ¨î 5 äãªæ¨¨ 69. |
====================================================================== |
========== Функция 70, подфункция 8 - удаление файла/папки. ========== |
========== ãªæ¨ï 70, ¯®¤äãªæ¨ï 8 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨. ========== |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 8 = номер подфункции |
* +4: dword: 0 (зарезервировано) |
* +8: dword: 0 (зарезервировано) |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: 0 (зарезервировано) |
* +20 = +0x14: ASCIIZ-имя файла, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем файла |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx разрушается |
Замечания: |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* Можно удалять только пустые папки (попытка удаления непустой папки |
приведёт к ошибке с кодом 10, "доступ запрещён"). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
* ®¦® 㤠«ïâì ⮫쪮 ¯ãáâë¥ ¯ ¯ª¨ (¯®¯ë⪠㤠«¥¨ï ¥¯ãá⮩ ¯ ¯ª¨ |
¯à¨¢¥¤ñâ ª ®è¨¡ª¥ á ª®¤®¬ 10, "¤®áâ㯠§ ¯à¥éñ"). |
====================================================================== |
============= Функция 70, подфункция 9 - создание папки. ============= |
============= ãªæ¨ï 70, ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨. ============= |
====================================================================== |
Параметры: |
* eax = 70 - номер функции |
* ebx = указатель на информационную структуру |
Формат информационной структуры: |
* +0: dword: 9 = номер подфункции |
* +4: dword: 0 (зарезервировано) |
* +8: dword: 0 (зарезервировано) |
* +12 = +0xC: dword: 0 (зарезервировано) |
* +16 = +0x10: dword: 0 (зарезервировано) |
* +20 = +0x14: ASCIIZ-имя папки, правила формирования имён указаны в |
общем описании |
или |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 9 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd указатель на ASCIIZ-строку с именем папки |
Возвращаемое значение: |
* eax = 0 - успешно, иначе код ошибки файловой системы |
* ebx разрушается |
Замечания: |
* Функция не поддерживается для CD (вернётся код ошибки 2). |
* Родительская папка должна уже существовать. |
* Если папка уже существует, функция завершится успешно (eax=0). |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¯ ¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
* ®¤¨â¥«ìáª ï ¯ ¯ª ¤®«¦ 㦥 áãé¥á⢮¢ âì. |
* ᫨ ¯ ¯ª 㦥 áãé¥áâ¢ã¥â, äãªæ¨ï § ¢¥àè¨âáï ãá¯¥è® (eax=0). |
====================================================================== |
=== Функция 71, подфункция 1 - установить заголовок окна программы. == |
=== ãªæ¨ï 71, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì § £®«®¢®ª ®ª ¯à®£à ¬¬ë. == |
====================================================================== |
Параметры: |
* eax = 71 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = адрес строки заголовка |
Возвращаемое значение: |
* функция не возвращает значения |
Замечания: |
* Строка заголовка должна быть в формате ASCIIZ. В заголовке |
отображается не более 255 символов независимо от полной длины |
строки. |
* Чтобы убрать заголовок, передайте NULL в ecx. |
à ¬¥âàë: |
* eax = 71 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á áâப¨ § £®«®¢ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* âப § £®«®¢ª ¤®«¦ ¡ëâì ¢ ä®à¬ ⥠ASCIIZ. § £®«®¢ª¥ |
®â®¡à ¦ ¥âáï ¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ¥§ ¢¨á¨¬® ®â ¯®«®© ¤«¨ë |
áâப¨. |
* ⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx. |
====================================================================== |
================ Функция 72 - послать сообщение окну. ================ |
================ ãªæ¨ï 72 - ¯®á« âì á®®¡é¥¨¥ ®ªã. ================ |
====================================================================== |
--- Подфункция 1 - послать сообщение с параметром активному окну. ---- |
Параметры: |
* eax = 72 - номер функции |
* ebx = 1 - номер подфункции |
* ecx = код события: 2 или 3 |
* edx = код клавиши для ecx=2, идентификатор кнопки для ecx=3 |
Возвращаемое значение: |
* eax = 0 - успешно |
* eax = 1 - буфер заполнен |
--- ®¤äãªæ¨ï 1 - ¯®á« âì á®®¡é¥¨¥ á ¯ à ¬¥â஬ ªâ¨¢®¬ã ®ªã. ---- |
à ¬¥âàë: |
* eax = 72 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ª®¤ ᮡëâ¨ï: 2 ¨«¨ 3 |
* edx = ª®¤ ª« ¢¨è¨ ¤«ï ecx=2, ¨¤¥â¨ä¨ª â®à ª®¯ª¨ ¤«ï ecx=3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¡ãä¥à § ¯®«¥ |
====================================================================== |
===================== Функция 73 - blit bitmap ===================== |
===================== ãªæ¨ï 73 - blit bitmap ===================== |
====================================================================== |
блит - копирование битового массив |
¡«¨â - ª®¯¨à®¢ ¨¥ ¡¨â®¢®£® ¬ áᨢ |
Параметры: |
* eax = 73 - номер функции |
à ¬¥âàë: |
* eax = 73 - ®¬¥à äãªæ¨¨ |
* ebx = ROP и опциональные флаги |
* ebx = ROP ¨ ®¯æ¨® «ìë¥ ä« £¨ |
31 6 5 4 3 0 |
[ reserved ][T][B][ROP] |
ROP - код растровых операций |
0: копировать |
1-15: Зарезервировано |
B - блит на фоновую поферхность |
T - блит с прозрачностью |
ROP - ª®¤ à áâ஢ëå ®¯¥à 権 |
0: ª®¯¨à®¢ âì |
1-15: १¥à¢¨à®¢ ® |
B - ¡«¨â ä®®¢ãî ¯®ä¥àå®áâì |
T - ¡«¨â á ¯à®§à ç®áâìî |
* ecx = указатель на параметры функции |
смещение цели и отсечение |
+0 signed dword: смещение по X окна, для целевого прямоугольника |
верхний левый угол |
+4 signed dword: смещение по Y окна, для целевого прямоугольника |
верхний левый угол |
+8 dword: ширина целевого прямоугольника |
+12 dword: высота целевого прямоугольника |
* ecx = 㪠§ â¥«ì ¯ à ¬¥âàë äãªæ¨¨ |
ᬥ饨¥ 楫¨ÿ¨ ®âá¥ç¥¨¥ |
+0 signed dword: ᬥ饨¥ ¯® X ®ª , ¤«ï 楫¥¢®£® ¯àאַ㣮«ì¨ª |
¢¥à娩 «¥¢ë© 㣮« |
+4 signed dword: ᬥ饨¥ ¯® Y ®ª , ¤«ï 楫¥¢®£® ¯àאַ㣮«ì¨ª |
¢¥à娩 «¥¢ë© 㣮« |
+8 dword: è¨à¨ 楫¥¢®£® ¯àאַ㣮«ì¨ª |
+12 dword: ¢ëá®â 楫¥¢®£® ¯àאַ㣮«ì¨ª |
смещение исходника и отсечение |
+16 signed dword: смещение по X bitmap, для исходного прямоугольника |
верхний левый угол |
+20 signed dword: смещение по Y bitmap, для исходного прямоугольника |
верхний левый угол |
+24 dword: ширина исходного прямоугольника |
+28 dword: высота исходного прямоугольника |
ᬥ饨¥ ¨á室¨ª ÿ¨ ®âá¥ç¥¨¥ |
+16 signed dword: ᬥ饨¥ ¯® X bitmap, ¤«ï ¨á室®£® ¯àאַ㣮«ì¨ª |
¢¥à娩 «¥¢ë© 㣮« |
+20 signed dword: ᬥ饨¥ ¯® Y bitmap, ¤«ï ¨á室®£® ¯àאַ㣮«ì¨ª |
¢¥à娩 «¥¢ë© 㣮« |
+24 dword: è¨à¨ ¨á室®£® ¯àאַ㣮«ì¨ª |
+28 dword: ¢ëá®â ¨á室®£® ¯àאַ㣮«ì¨ª |
+32: dword: данные bitmap - должны быть 32bpp |
+36: dword: размер строки bitmap в байтах |
+32: dword: ¤ ë¥ bitmap - ¤®«¦ë ¡ëâì 32bpp |
+36: dword: à §¬¥à áâப¨ bitmap ¢ ¡ ©â å |
Возвращаемое значение: |
* функция не возвращает значения |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
========== Функция -1 - завершить выполнение потока/процесса ========= |
========== ãªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«¥¨¥ ¯®â®ª /¯à®æ¥áá ========= |
====================================================================== |
Параметры: |
* eax = -1 - номер функции |
Возвращаемое значение: |
* функция не возвращает ни значения, ни управления |
Замечания: |
* Если процесс явно не создавал потоков, то у него есть только |
один поток, завершение которого приводит к завершению процесса. |
* Если текущий поток - последний в процессе, то его завершение |
также приводит к завершению процесса. |
* Эта функция завершает текущий поток. Другой поток можно прибить |
вызовом подфункции 2 функции 18. |
à ¬¥âàë: |
* eax = -1 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â ¨ § 票ï, ¨ ã¯à ¢«¥¨ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá  ¥ ᮧ¤ ¢ « ¯®â®ª®¢, â® ã ¥£® ¥áâì ⮫쪮 |
®¤¨ ¯®â®ª, § ¢¥à襨¥ ª®â®à®£® ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* ᫨ ⥪ã騩 ¯®â®ª - ¯®á«¥¤¨© ¢ ¯à®æ¥áá¥, â® ¥£® § ¢¥à襨¥ |
â ª¦¥ ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* â äãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ¯®â®ª. à㣮© ¯®â®ª ¬®¦® ¯à¨¡¨âì |
¢ë§®¢®¬ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18. |
====================================================================== |
=========================== Список событий =========================== |
=========================== ¯¨á®ª ᮡë⨩ =========================== |
====================================================================== |
Очередное событие можно получить вызовом одной из функций 10 |
(ожидать события), 11 (проверить без ожидания), 23 |
(ожидать в течение заданного времени). |
Эти функции возвращают только те события, которые входят в маску, |
устанавливаемую функцией 40. По умолчанию это первые три, чего |
вполне достаточно для многих приложений. |
Коды событий: |
* 1 = сообщение о перерисовке (сбрасывается при вызове функции 0) |
* 2 = нажата клавиша на клавиатуре (поступает, только когда окно |
активно) или нажата "горячая клавиша"; |
сбрасывается, когда все клавиши из буфера считаны функцией 2 |
* 3 = нажата кнопка, определённая ранее функцией 8 (или кнопка |
закрытия, созданная неявно функцией 0; кнопка минимизации |
обрабатывается системой и о ней сообщения не приходит; |
поступает, только когда окно активно; сбрасывается, когда все |
кнопки из буфера считаны функцией 17) |
* 4 = зарезервировано (в текущей реализации никогда не приходит даже |
при размаскировке функцией 40) |
* 5 = завершилась перерисовка фона рабочего стола |
* 6 = событие от мыши (что-то случилось - нажатие на кнопку мыши |
или перемещение; сбрасывается при прочтении) |
* 7 = произошло событие IPC (смотри функцию 60 - Inter Process |
Communication; сбрасывается при прочтении) |
* 8 = произошло сетевое событие (сбрасывается при прочтении; |
смотри работу с сетью) |
* 9 = произошло отладочное событие (сбрасывается при прочтении; |
смотри отладочную подсистему) |
* 16..31 = произошло событие с соответствующим IRQ |
(16=IRQ0, 31=IRQ15) (сбрасывается при считывании всех данных IRQ) |
ç¥à¥¤®¥ ᮡë⨥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ®¤®© ¨§ äãªæ¨© 10 |
(®¦¨¤ âì ᮡëâ¨ï), 11 (¯à®¢¥à¨âì ¡¥§ ®¦¨¤ ¨ï), 23 |
(®¦¨¤ âì ¢ â¥ç¥¨¥ § ¤ ®£® ¢à¥¬¥¨). |
⨠äãªæ¨¨ ¢®§¢à é îâ ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î íâ® ¯¥à¢ë¥ âà¨, 祣® |
¢¯®«¥ ¤®áâ â®ç® ¤«ï ¬®£¨å ¯à¨«®¦¥¨©. |
®¤ë ᮡë⨩: |
* 1 = á®®¡é¥¨¥ ® ¯¥à¥à¨á®¢ª¥ (á¡à áë¢ ¥âáï ¯à¨ ¢ë§®¢¥ äãªæ¨¨ 0) |
* 2 = ¦ â ª« ¢¨è ª« ¢¨ âãॠ(¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® |
ªâ¨¢®) ¨«¨ ¦ â "£®àïç ï ª« ¢¨è "; |
á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ ª« ¢¨è¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 2 |
* 3 = ¦ â ª®¯ª , ®¯à¥¤¥«ñ ï à ¥¥ äãªæ¨¥© 8 (¨«¨ ª®¯ª |
§ ªàëâ¨ï, ᮧ¤ ï ¥ï¢® äãªæ¨¥© 0; ª®¯ª ¬¨¨¬¨§ 樨 |
®¡à ¡ âë¢ ¥âáï á¨á⥬®© ¨ ® ¥© á®®¡é¥¨ï ¥ ¯à¨å®¤¨â; |
¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® ªâ¨¢®; á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ |
ª®¯ª¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 17) |
* 4 = § १¥à¢¨à®¢ ® (¢ ⥪ã饩 ॠ«¨§ 樨 ¨ª®£¤ ¥ ¯à¨å®¤¨â ¤ ¦¥ |
¯à¨ à §¬ ᪨஢ª¥ äãªæ¨¥© 40) |
* 5 = § ¢¥à訫 áì ¯¥à¥à¨á®¢ª ä® à ¡®ç¥£® á⮫ |
* 6 = ᮡë⨥ ®â ¬ëè¨ (çâ®-â® á«ã稫®áì - ¦ ⨥ ª®¯ªã ¬ëè¨ |
¨«¨ ¯¥à¥¬¥é¥¨¥; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 7 = ¯à®¨§®è«® ᮡë⨥ IPC (ᬮâਠäãªæ¨î 60 - Inter Process |
Communication; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 8 = ¯à®¨§®è«® á¥â¥¢®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâà¨ à ¡®âã á á¥âìî) |
* 9 = ¯à®¨§®è«® ®â« ¤®ç®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâਠ®â« ¤®çãî ¯®¤á¨á⥬ã) |
* 16..31 = ¯à®¨§®è«® ᮡë⨥ á ᮮ⢥âáâ¢ãî騬 IRQ |
(16=IRQ0, 31=IRQ15) (á¡à áë¢ ¥âáï ¯à¨ áç¨âë¢ ¨¨ ¢á¥å ¤ ëå IRQ) |
====================================================================== |
==================== Коды ошибок файловой системы ==================== |
==================== ®¤ë ®è¨¡®ª ä ©«®¢®© á¨á⥬ë ==================== |
====================================================================== |
* 0 = успешно |
* 1 = не определена база и/или раздел жёсткого диска (подфункциями |
7, 8 функции 21) |
* 2 = функция не поддерживается для данной файловой системы |
* 3 = неизвестная файловая система |
* 4 = зарезервировано, никогда не возвращается в текущей реализации |
* 5 = файл не найден |
* 6 = файл закончился |
* 7 = указатель вне памяти приложения |
* 8 = диск заполнен |
* 9 = таблица FAT разрушена |
* 10 = доступ запрещён |
* 11 = ошибка устройства |
При запуске программы возможны также следующие коды ошибок: |
* 30 = 0x1E = недостаточно памяти |
* 31 = 0x1F = файл не является исполнимым |
* 32 = 0x20 = слишком много процессов |
* 0 = ãá¯¥è® |
* 1 = ¥ ®¯à¥¤¥«¥ ¡ § ¨/¨«¨ à §¤¥« ¦ñá⪮£® ¤¨áª (¯®¤äãªæ¨ï¬¨ |
7, 8 äãªæ¨¨ 21) |
* 2 = äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ®© ä ©«®¢®© á¨á⥬ë |
* 3 = ¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬ |
* 4 = § १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï ¢ ⥪ã饩 ॠ«¨§ 樨 |
* 5 = ä ©« ¥ ©¤¥ |
* 6 = ä ©« § ª®ç¨«áï |
* 7 = 㪠§ â¥«ì ¢¥ ¯ ¬ï⨠¯à¨«®¦¥¨ï |
* 8 = ¤¨áª § ¯®«¥ |
* 9 = â ¡«¨æ FAT à §àãè¥ |
* 10 = ¤®áâ㯠§ ¯à¥éñ |
* 11 = ®è¨¡ª ãáâனá⢠|
ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: |
* 30 = 0x1E = ¥¤®áâ â®ç® ¯ ¬ï⨠|
* 31 = 0x1F = ä ©« ¥ ï¥âáï ¨á¯®«¨¬ë¬ |
* 32 = 0x20 = ᫨誮¬ ¬®£® ¯à®æ¥áᮢ |
/kernel/trunk/docs/sysfuncs.txt |
---|
2923,9 → 2923,9 |
* if one want to read 0 blocks, function considers, |
that he requested 1; |
* if one requests more than 14 blocks or starting block is |
not less than 14, function returns eax=5 (not found) and ebx=-1; |
not less than 14, function returns eax=5 (not found) è ebx=-1; |
* size of ramdisk root folder is 14 blocks, |
0x1C00=7168 bytes; but function returns ebx=0 |
0x1C00=7168 áàéò; but function returns ebx=0 |
(except of the case of previous item); |
* strangely enough, it is possible to read 14th block (which |
generally contains a garbage - I remind, the indexing begins |
2994,7 → 2994,7 |
data of the concrete partition are required, application must |
define starting sector of this partition (either directly |
through MBR, or from the full structure returned by |
subfunction 11 of function 18). |
ïîäôóíêöèåé 11 ôóíêöèè 18). |
* Function does not check error code of hard disk, so request of |
nonexisting sector reads something (most probably it will be |
zeroes, but this is defined by device) and this is considered |
3868,7 → 3868,7 |
* in addition dword-image of the register DR6 is given: |
* bits 0-3: condition of the corresponding breakpoint (set by |
subfunction 9) is satisfied |
* bit 14: exception has occured because of the trace mode |
* áèò 14: exception has occured because of the trace mode |
(flag TF is set TF) |
* process is suspended |
When debugger terminates, all debugged processes are killed. |
4440,7 → 4440,7 |
Format of the information structure: |
* +0: dword: 7 = subfunction number |
* +4: dword: flags field: |
* bit 0: start process as debugged |
* áèò 0: start process as debugged |
* other bits are reserved and must be set to 0 |
* +8: dword: 0 or pointer to ASCIIZ-string with parameters |
* +12 = +0xC: dword: 0 (reserved) |
/kernel/trunk/docs/loader_doc.txt |
---|
8,46 → 8,46 |
; (english text below) |
;------------------------------------------ |
; Интерфейс сохранения параметров |
; Èíòåðôåéñ ñîõðàíåíèÿ ïàðàìåòðîâ |
;------------------------------------------ |
Если при передаче управления ядру загрузчик устанавливает AX='KL', |
то в DS:SI ядро ожидает дальнего указателя на следующую структуру: |
db версия структуры, должна быть 1 |
dw флаги: |
бит 0 установлен = присутствует образ рамдиска в памяти |
dd дальний указатель на процедуру сохранения параметров |
может быть 0, если загрузчик не поддерживает |
Процедура сохранения параметров должна записать первый сектор ядра |
kernel.mnt назад на то место, откуда она его считала; возврат из |
процедуры осуществляется по retf. |
Åñëè ïðè ïåðåäà÷å óïðàâëåíèÿ ÿäðó çàãðóç÷èê óñòàíàâëèâàåò AX='KL', |
òî â DS:SI ÿäðî îæèäàåò äàëüíåãî óêàçàòåëÿ íà ñëåäóþùóþ ñòðóêòóðó: |
db âåðñèÿ ñòðóêòóðû, äîëæíà áûòü 1 |
dw ôëàãè: |
áèò 0 óñòàíîâëåí = ïðèñóòñòâóåò îáðàç ðàìäèñêà â ïàìÿòè |
dd äàëüíèé óêàçàòåëü íà ïðîöåäóðó ñîõðàíåíèÿ ïàðàìåòðîâ |
ìîæåò áûòü 0, åñëè çàãðóç÷èê íå ïîääåðæèâàåò |
Ïðîöåäóðà ñîõðàíåíèÿ ïàðàìåòðîâ äîëæíà çàïèñàòü ïåðâûé ñåêòîð ÿäðà |
kernel.mnt íàçàä íà òî ìåñòî, îòêóäà îíà åãî ñ÷èòàëà; âîçâðàò èç |
ïðîöåäóðû îñóùåñòâëÿåòñÿ ïî retf. |
;------------------------------------------ |
; Указание загрузчиком системного каталога |
; Óêàçàíèå çàãðóç÷èêîì ñèñòåìíîãî êàòàëîãà |
;------------------------------------------ |
Перед передачей управления ядру могут быть установлены следующие регистры: |
Ïåðåä ïåðåäà÷åé óïðàâëåíèÿ ÿäðó ìîãóò áûòü óñòàíîâëåíû ñëåäóþùèå ðåãèñòðû: |
CX='HA' |
DX='RD' |
Это указывает на то, что регистр BX указывает на системный раздел. Каталог /kolibri/ на |
этом разделе является системным, к нему можно обращаться как к /sys/ |
Ýòî óêàçûâàåò íà òî, ÷òî ðåãèñòð BX óêàçûâàåò íà ñèñòåìíûé ðàçäåë. Êàòàëîã /kolibri/ íà |
ýòîì ðàçäåëå ÿâëÿåòñÿ ñèñòåìíûì, ê íåìó ìîæíî îáðàùàòüñÿ êàê ê /sys/ |
Возможные значения регистра BL (указывает на устройство): |
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BL (óêàçûâàåò íà óñòðîéñòâî): |
'a' - Primary Master |
'b' - Primary Slave |
'c' - Secondary Master |
'd' - Secondary Slave |
'r' - RAM диск |
'm' - Приводы CD-ROM |
'r' - RAM äèñê |
'm' - Ïðèâîäû CD-ROM |
Возможные значения регистра BH (указывает на раздел): |
для BL='a','b','c','d','r' - указывает на раздел, где расположен системный каталог |
для BL='m',указывает на номер физического устройства, с которого надо начинать поиск системного каталога. |
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BH (óêàçûâàåò íà ðàçäåë): |
äëÿ BL='a','b','c','d','r' - óêàçûâàåò íà ðàçäåë, ãäå ðàñïîëîæåí ñèñòåìíûé êàòàëîã |
äëÿ BL='m',óêàçûâàåò íà íîìåð ôèçè÷åñêîãî óñòðîéñòâà, ñ êîòîðîãî íàäî íà÷èíàòü ïîèñê ñèñòåìíîãî êàòàëîãà. |
примеры значений регистра BX: |
ïðèìåðû çíà÷åíèé ðåãèñòðà BX: |
'a1' - /hd0/1/ |
'a2' - /hd0/2/ |
'b1' - /hd1/1/ |
'd4' - /hd3/4/ |
'm0' - поиск по сидюкам каталога kolibri |
'm0' - ïîèñê ïî ñèäþêàì êàòàëîãà kolibri |
'r1' - /rd/1/ |
/kernel/trunk/drivers/intelac97.asm |
---|
21,7 → 21,7 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
/kernel/trunk/drivers/apm.asm |
---|
297,7 → 297,7 |
ret |
; ДАННЫЕ ПРОГРАММЫ |
; |
title db '',0 |
flags dw 0 |
/kernel/trunk/drivers/com_mouse.asm |
---|
174,68 → 174,68 |
align 4 |
MSMouseSearch: |
; ПОИСК МЫШИ ЧЕРЕЗ COM-ПОРТЫ |
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ |
MouseSearch: |
; Устанавливаем скорость |
; приема/передачи 1200 бод |
; Óñòàíàâëèâàåì ñêîðîñòü |
; ïðèåìà/ïåðåäà÷è 1200 áîä |
; in bx COM Port Base Address |
mov DX, bx |
add DX, 3 |
in AL, DX |
or AL, 80h ;установить бит DLAB |
or AL, 80h ;óñòàíîâèòü áèò DLAB |
out DX, AL |
mov DX, bx |
mov AL, 60h ;1200 бод |
mov AL, 60h ;1200 áîä |
out DX, AL |
inc DX |
mov AL, 0 |
out DX, AL |
; Установить длину слова 7 бит, 1 стоповый бит, |
; четность не контролировать |
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò, |
; ÷åòíîñòü íå êîíòðîëèðîâàòü |
mov DX, bx |
add DX, 3 |
mov AL, 00000010b |
out DX, AL |
; Запретить все прерывани |
; Çàïðåòèòü âñå ïðåðûâàíè |
mov dx, bx |
inc dx |
mov AL, 0 |
out DX, AL |
; Проверить, что устройство подключено и являетс |
; мышью типа MSMouse |
; Отключить питание мыши и прерывани |
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ |
; ìûøüþ òèïà MSMouse |
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè |
mov DX, bx |
add EDX, 4 ;регистр управления модемом |
mov AL, 0 ;сбросить DTR, RTS и OUT2 |
add EDX, 4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì |
mov AL, 0 ;ñáðîñèòü DTR, RTS è OUT2 |
out DX, AL |
; Ожидать 5 "тиков" (0,2 с) |
; Îæèäàòü 5 "òèêîâ" (0,2 ñ) |
mov ecx, 0xFFFF |
loop $ |
; Включить питание мыши |
; Âêëþ÷èòü ïèòàíèå ìûøè |
mov al, 1 |
out dx, al |
mov ecx, 0xFFFF |
loop $ |
; Очистить регистр данных |
; Î÷èñòèòü ðåãèñòð äàííûõ |
mov dx, bx |
in AL, DX |
add edx, 4 |
mov AL, 1011b ;установить DTR и RTS и OUT2 |
mov AL, 1011b ;óñòàíîâèòü DTR è RTS è OUT2 |
out DX, AL |
mov ecx, 0x1FFFF |
; Цикл опроса порта |
; Öèêë îïðîñà ïîðòà |
WaitData: |
; Ожидать еще 10 "тиков" |
; Îæèäàòü åùå 10 "òèêîâ" |
dec ecx |
; cmp ecx,0 |
jz NoMouse |
; Проверить наличие идентификационного байта |
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà |
mov DX, bx |
add DX, 5 |
in AL, DX |
test AL, 1 ;Данные готовы? |
test AL, 1 ;Äàííûå ãîòîâû? |
jz WaitData |
; Ввести данные |
; Ââåñòè äàííûå |
mov DX, bx |
in AL, DX |
NoMouse: |
257,27 → 257,27 |
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h) |
add edx, 5 ; xFDh |
in al, dx |
test al, 1 ; Данные готовы? |
test al, 1 ; Äàííûå ãîòîâû? |
jz .Error |
; Ввести данные |
; Ââåñòè äàííûå |
sub edx, 5 |
in al, dx |
; Сбросить старший незначащий бит |
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò |
and al, 01111111b |
; Определить порядковый номер принимаемого байта |
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2 |
ja .Error |
jz .ThirdByte |
jp .SecondByte |
; Сохранить первый байт данных |
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ |
.FirstByte: |
test al, 1000000b ; Первый байт посылки? |
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè? |
jz .Error |
mov [esi+COM_MOUSE_DATA.FirstByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Сохранить второй байт данных |
; Ñîõðàíèòü âòîðîé áàéò äàííûõ |
.SecondByte: |
test al, 1000000b |
jnz .Error |
284,14 → 284,14 |
mov [esi+COM_MOUSE_DATA.SecondByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Сохранить третий байт данных |
; Ñîõðàíèòü òðåòèé áàéò äàííûõ |
.ThirdByte: |
test al, 1000000b |
jnz .Error |
mov [esi+COM_MOUSE_DATA.ThirdByte], al |
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 |
; (Пакет данных от мыши принят полностью). |
; Записать новое значение состояния кнопок мыши |
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ). |
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
mov ah, al |
shr al, 3 |
302,7 → 302,7 |
movzx eax, al |
mov [BTN_DOWN], eax |
; Прибавить перемещение по X к координате X |
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
shl al, 6 |
or al, [esi+COM_MOUSE_DATA.SecondByte] |
311,7 → 311,7 |
movzx eax, ax |
mov [MOUSE_X], eax |
; Прибавить перемещение по Y к координате Y |
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
and al, 00001100b |
shl al, 4 |
327,8 → 327,8 |
jmp .EndMouseInterrupt |
.Error: |
; Произошел сбой в порядке передачи информации от |
; мыши, обнулить счетчик байтов пакета данных |
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò |
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ |
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 |
.EndMouseInterrupt: |
340,9 → 340,9 |
align 4 |
struc COM_MOUSE_DATA { |
; Номер принимаемого от мыши байта |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
.MouseByteNumber db ? |
; Трехбайтовая структура данных, передаваемая мышью |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
.FirstByte db ? |
.SecondByte db ? |
.ThirdByte db ? |
/kernel/trunk/drivers/emu10k1x.asm |
---|
19,7 → 19,7 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 ¥¤®áâã¯ë |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
/kernel/trunk/drivers/ensoniq.asm |
---|
17,7 → 17,7 |
REMAP_IRQ equ 0 |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010101000b |
/kernel/trunk/drivers/fm801.asm |
---|
17,7 → 17,7 |
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
/kernel/trunk/drivers/sis.asm |
---|
21,7 → 21,7 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
/kernel/trunk/drivers/vt823x.asm |
---|
19,7 → 19,7 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 недоступны |
;irq 0,1,2,8,12,13 ¥¤®áâã¯ë |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
/kernel/trunk/fs/fat12.inc |
---|
119,9 → 119,9 |
call read_flp_fat |
cmp [FDC_Status], 0 |
jne fdc_status_error_3_1 |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 1; Сторона |
mov [FDD_Sector], 2; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 1; Ñòîðîíà |
mov [FDD_Sector], 2; Ñåêòîð |
call SeekTrack |
mov dh, 14 |
l.20_1: |
253,9 → 253,9 |
jne unnecessary_root_read |
cmp [root_read], 1 |
je unnecessary_root_read |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 1; Сторона |
mov [FDD_Sector], 2; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 1; Ñòîðîíà |
mov [FDD_Sector], 2; Ñåêòîð |
mov edi, FLOPPY_BUFF |
call SeekTrack |
read_flp_root_1: |
282,9 → 282,9 |
jne unnecessary_flp_fat |
cmp [flp_fat], 1 |
je unnecessary_flp_fat |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 0; Сторона |
mov [FDD_Sector], 2; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 0; Ñòîðîíà |
mov [FDD_Sector], 2; Ñåêòîð |
mov edi, FLOPPY_BUFF |
call SeekTrack |
read_flp_fat_1: |
351,9 → 351,9 |
check_label: |
pushad |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 0; Сторона |
mov [FDD_Sector], 1; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 0; Ñòîðîíà |
mov [FDD_Sector], 1; Ñåêòîð |
call SetUserInterrupts |
call FDDMotorON |
call RecalibrateFDD |
392,9 → 392,9 |
jne unnecessary_root_save |
cmp [root_read], 0 |
je unnecessary_root_save |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 1; Сторона |
mov [FDD_Sector], 2; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 1; Ñòîðîíà |
mov [FDD_Sector], 2; Ñåêòîð |
mov esi, FLOPPY_BUFF |
call SeekTrack |
save_flp_root_1: |
421,9 → 421,9 |
cmp [flp_fat], 0 |
je unnecessary_flp_fat_save |
call restorefatchain_flp |
mov [FDD_Track], 0; Цилиндр |
mov [FDD_Head], 0; Сторона |
mov [FDD_Sector], 2; Сектор |
mov [FDD_Track], 0; Öèëèíäð |
mov [FDD_Head], 0; Ñòîðîíà |
mov [FDD_Sector], 2; Ñåêòîð |
mov esi, FLOPPY_BUFF |
call SeekTrack |
save_flp_fat_1: |
/kernel/trunk/fs/fs.inc |
---|
441,7 → 441,7 |
fs_noharddisk: |
; \begin{diamond}[18.03.2006] |
mov eax, 5 ; file not found |
; а может быть, возвращать другой код ошибки? |
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè? |
mov ebx, [esp+24+24]; do not change ebx in application |
; \end{diamond}[18.03.2006] |
713,14 → 713,14 |
;* output eax - number |
;******************************************* |
StringToNumber: |
; ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД |
; Вход: |
; EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh |
; Выход: |
; CF - индикатор ошибок: |
; 0 - ошибок нет; |
; 1 - ошибка |
; Если CF=0, то AX - число. |
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ |
; Âõîä: |
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh |
; Âûõîä: |
; CF - èíäèêàòîð îøèáîê: |
; 0 - îøèáîê íåò; |
; 1 - îøèáêà |
; Åñëè CF=0, òî AX - ÷èñëî. |
push bx |
push cx |
/kernel/trunk/fs/part_set.inc |
---|
77,10 → 77,10 |
.inode_size dd ? |
.count_pointer_in_block dd ? ; block_size / 4 |
.count_pointer_in_block_square dd ? ; (block_size / 4)**2 |
.ext2_save_block dd ? ; блок на глобальную 1 процедуру |
.ext2_temp_block dd ? ; блок для мелких процедур |
.ext2_save_inode dd ? ; inode на глобальную процедуру |
.ext2_temp_inode dd ? ; inode для мелких процедур |
.ext2_save_block dd ? ; ¡«®ª £«®¡ «ìãî 1 ¯à®æ¥¤ãàã |
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà |
.ext2_save_inode dd ? ; inode £«®¡ «ìãî ¯à®æ¥¤ãàã |
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà |
.sb dd ? ; superblock |
.groups_count dd ? |
if $ > fs_dependent_data_end |
278,7 → 278,7 |
;pop edx |
test_ext_partition_0: |
pop eax ; просто выкидываем из стека |
pop eax ; ¯à®áâ® ¢ëª¨¤ë¢ ¥¬ ¨§ á⥪ |
mov al, [ebx+0x1be+4]; get extended partition type |
call scan_extended_types |
jnz test_ext_partition_1 |
368,7 → 368,7 |
; mov edx, [PARTITION_END] |
; sub edx, eax |
; inc edx ; edx = length of partition зачем оно нам?? |
; inc edx ; edx = length of partition § 祬 ®® ¬?? |
; mov [hd_setup],1 |
mov ebx, buffer |
/kernel/trunk/fs/iso9660.inc |
---|
137,7 → 137,7 |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+10] ; реальный размер файловой секции |
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
159,7 → 159,7 |
jb .incomplete_sector |
; we may read and memmove complete sector |
mov [CDDataBuf_pointer], edx |
call ReadCDWRetr; читаем сектор файла |
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode], 0 |
jne .noaccess_3 |
add edx, 2048 |
170,7 → 170,7 |
.incomplete_sector: |
; we must read and memmove incomplete sector |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr; читаем сектор файла |
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode], 0 |
jne .noaccess_3 |
push ecx |
240,7 → 240,7 |
.found_dir: |
mov eax, [edi+2] ; eax=cluster |
mov [CDSectorAddress], eax |
mov eax, [edi+10] ; размер директрории |
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè |
.doit: |
; init header |
push eax ecx |
252,7 → 252,7 |
mov byte [edx], 1 ; version |
mov [cd_mem_location], edx |
add [cd_mem_location], 32 |
; начинаем переброску БДВК в УСВК |
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ |
;.mainloop: |
mov [cd_counter_block], dword 0 |
dec dword [CDSectorAddress] |
260,12 → 260,12 |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; читаем сектор директории |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
call .get_names_from_buffer |
sub eax, 2048 |
; директория закончилась? |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
ja .read_to_buffer |
mov edi, [cd_counter_block] |
mov [edx+8], edi |
310,17 → 310,17 |
call uni2ansi_char |
cld |
stosb |
; проверка конца файла |
; ïðîâåðêà êîíöà ôàéëà |
mov ax, [esi] |
cmp ax, word 3B00h; сепаратор конца файла ';' |
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_1 |
; проверка для файлов не заканчивающихся сепаратором |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp esi, eax |
je .cd_get_parameters_of_file_1 |
; проверка конца папки |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp esi, eax |
347,17 → 347,17 |
jbe .unicode_parent_directory |
cld |
movsw |
; проверка конца файла |
; ïðîâåðêà êîíöà ôàéëà |
mov ax, [esi] |
cmp ax, word 3B00h; сепаратор конца файла ';' |
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_2 |
; проверка для файлов не заканчивающихся сепаратором |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp esi, eax |
je .cd_get_parameters_of_file_2 |
; проверка конца папки |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp esi, eax |
386,60 → 386,60 |
cd_get_parameters_of_file: |
mov edi, [cd_mem_location] |
cd_get_parameters_of_file_1: |
; получаем атрибуты файла |
; ïîëó÷àåì àòðèáóòû ôàéëà |
xor eax, eax |
; файл не архивировался |
; ôàéë íå àðõèâèðîâàëñÿ |
inc eax |
shl eax, 1 |
; это каталог? |
; ýòî êàòàëîã? |
test [ebp-8], byte 2 |
jz .file |
inc eax |
.file: |
; метка тома не как в FAT, в этом виде отсутсвует |
; файл не является системным |
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò |
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì |
shl eax, 3 |
; файл является скрытым? (атрибут существование) |
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå) |
test [ebp-8], byte 1 |
jz .hidden |
inc eax |
.hidden: |
shl eax, 1 |
; файл всегда только для чтения, так как это CD |
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD |
inc eax |
mov [edi], eax |
; получаем время для файла |
;час |
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà |
;÷àñ |
movzx eax, byte [ebp-12] |
shl eax, 8 |
;минута |
;ìèíóòà |
mov al, [ebp-11] |
shl eax, 8 |
;секунда |
;ñåêóíäà |
mov al, [ebp-10] |
;время создания файла |
;âðåìÿ ñîçäàíèÿ ôàéëà |
mov [edi+8], eax |
;время последнего доступа |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+16], eax |
;время последней записи |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+24], eax |
; получаем дату для файла |
;год |
; ïîëó÷àåì äàòó äëÿ ôàéëà |
;ãîä |
movzx eax, byte [ebp-15] |
add eax, 1900 |
shl eax, 8 |
;месяц |
;ìåñÿö |
mov al, [ebp-14] |
shl eax, 8 |
;день |
;äåíü |
mov al, [ebp-13] |
;дата создания файла |
;äàòà ñîçäàíèÿ ôàéëà |
mov [edi+12], eax |
;время последнего доступа |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+20], eax |
;время последней записи |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+28], eax |
; получаем тип данных имени |
; ïîëó÷àåì òèï äàííûõ èìåíè |
xor eax, eax |
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE |
jnz .unicode_1 |
449,7 → 449,7 |
inc eax |
mov [edi+4], eax |
@@: |
; получаем размер файла в байтах |
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ |
xor eax, eax |
mov [edi+32+4], eax |
mov eax, [ebp-23] |
503,7 → 503,7 |
; out: CF=1 - file not found |
; else CF=0 and [cd_current_pointer_of_input] direntry |
push eax esi |
; 16 сектор начало набора дескрипторов томов |
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ |
call WaitUnitReady |
cmp [DevErrorCode], 0 |
510,7 → 510,7 |
jne .access_denied |
call prevent_medium_removal |
; тестовое чтение |
; òåñòîâîå ÷òåíèå |
mov [CDSectorAddress], dword 16 |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr;_1 |
517,7 → 517,7 |
cmp [DevErrorCode], 0 |
jne .access_denied |
; вычисление последней сессии |
; âû÷èñëåíèå ïîñëåäíåé ñåññèè |
call WaitUnitReady |
cmp [DevErrorCode], 0 |
jne .access_denied |
539,37 → 539,37 |
jne .access_denied |
.start_check: |
; проверка на вшивость |
; ïðîâåðêà íà âøèâîñòü |
cmp [CDDataBuf+1], dword 'CD00' |
jne .access_denied |
cmp [CDDataBuf+5], byte '1' |
jne .access_denied |
; сектор является терминатором набор дескрипторов томов? |
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ? |
cmp [CDDataBuf], byte 0xff |
je .access_denied |
; сектор является дополнительным и улучшенным дескриптором тома? |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf], byte 0x2 |
jne .start |
; сектор является дополнительным дескриптором тома? |
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà? |
cmp [CDDataBuf+6], byte 0x1 |
jne .start |
; параметры root директрории |
mov eax, [CDDataBuf+0x9c+2]; начало root директрории |
; ïàðàìåòðû root äèðåêòðîðèè |
mov eax, [CDDataBuf+0x9c+2]; íà÷àëî root äèðåêòðîðèè |
mov [CDSectorAddress], eax |
mov eax, [CDDataBuf+0x9c+10]; размер root директрории |
mov eax, [CDDataBuf+0x9c+10]; ðàçìåð root äèðåêòðîðèè |
cmp byte [esi], 0 |
jnz @f |
mov [cd_current_pointer_of_input], CDDataBuf+0x9c |
jmp .done |
@@: |
; начинаем поиск |
; íà÷èíàåì ïîèñê |
.mainloop: |
dec dword [CDSectorAddress] |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; читаем сектор директории |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode], 0 |
jne .access_denied |
push ebp |
577,27 → 577,27 |
pop ebp |
jnc .found |
sub eax, 2048 |
; директория закончилась? |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
cmp eax, 0 |
ja .read_to_buffer |
; нет искомого элемента цепочки |
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè |
.access_denied: |
pop esi eax |
mov [cd_appl_data], 1 |
stc |
ret |
; искомый элемент цепочки найден |
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí |
.found: |
; конец пути файла |
; êîíåö ïóòè ôàéëà |
cmp byte [esi-1], 0 |
jz .done |
.nested: |
mov eax, [cd_current_pointer_of_input] |
push dword [eax+2] |
pop dword [CDSectorAddress] ; начало директории |
mov eax, [eax+2+8]; размер директории |
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè |
mov eax, [eax+2+8]; ðàçìåð äèðåêòîðèè |
jmp .mainloop |
; указатель файла найден |
; óêàçàòåëü ôàéëà íàéäåí |
.done: |
test ebp, ebp |
jz @f |
629,13 → 629,13 |
mov ebp, [cd_current_pointer_of_input_2] |
mov [cd_current_pointer_of_input], ebp |
mov eax, [ebp] |
test eax, eax ; входы закончились? |
test eax, eax ; âõîäû çàêîí÷èëèñü? |
jz .next_sector |
cmp ebp, CDDataBuf+2048 ; буфер закончился? |
cmp ebp, CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ? |
jae .next_sector |
movzx eax, byte [ebp] |
add [cd_current_pointer_of_input_2], eax; следующий вход каталога |
add ebp, 33; указатель установлен на начало имени |
add [cd_current_pointer_of_input_2], eax; ñëåäóþùèé âõîä êàòàëîãà |
add ebp, 33; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè |
pop eax |
clc |
ret |
669,9 → 669,9 |
scasw |
jne .name_not_coincide |
.coincides: |
cmp [esi], byte '/'; разделитель пути, конец имени текущего элемента |
cmp [esi], byte '/'; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
cmp [esi], byte 0; разделитель пути, конец имени текущего элемента |
cmp [esi], byte 0; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
jmp .loop |
.name_not_coincide: |
679,16 → 679,16 |
stc |
ret |
.done: |
; проверка конца файла |
cmp [edi], word 3B00h; сепаратор конца файла ';' |
; ïðîâåðêà êîíöà ôàéëà |
cmp [edi], word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';' |
je .done_1 |
; проверка для файлов не заканчивающихся сепаратором |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax, byte [ebp-33] |
add eax, ebp |
sub eax, 34 |
cmp edi, eax |
je .done_1 |
; проверка конца папки |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax, byte [ebp-1] |
add eax, ebp |
cmp edi, eax |
708,14 → 708,14 |
jb .ret |
cmp al, 'Z' |
jbe .az |
cmp al, 0x80 ; 'А' |
cmp al, '' |
jb .ret |
cmp al, 0x90 ; 'Р' |
cmp al, '' |
jb .rus1 |
cmp al, 0x9F ; 'Я' |
cmp al, '' |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 0xE0-0x90 |
add al, 'à'-'' |
.ret: |
ret |
.rus1: |
744,10 → 744,10 |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 0xF0 ; 'Ё' in cp866 |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 0xF1 ; 'ё' in cp866 |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
/kernel/trunk/boot/bootcode.inc |
---|
428,7 → 428,7 |
.nopci: |
; \end{Mario79} |
mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование |
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå |
out 0x60, al |
xor cx, cx |
wait_loop: ; variant 2 |
847,21 → 847,21 |
xor dx, dx |
div bx |
if lang eq ru |
; подождите 5 секунд, 4/3/2 секунды, 1 секунду |
; ¯®¤®¦¤¨â¥ 5 ᥪã¤, 4/3/2 ᥪã¤ë, 1 ᥪã¤ã |
cmp al, 5 |
mov cl, ' ' |
jae @f |
cmp al, 1 |
mov cl, 0xE3 ; 'у' in cp866 |
mov cl, 'ã' |
jz @f |
mov cl, 0xEB ; 'ы' in cp866 |
mov cl, 'ë' |
@@: |
mov [time_str+9], cl |
else if lang eq et |
cmp al, 1 |
ja @f |
mov byte [time_str+9], ' ' |
mov byte [time_str+10], ' ' |
mov [time_str+9], ' ' |
mov [time_str+10], ' ' |
@@: |
else if lang eq sp |
; esperar 5/4/3/2 segundos, 1 segundo |
/kernel/trunk/boot/bootsp.inc |
---|
11,93 → 11,93 |
; |
;====================================================================== |
; Para modificar éste archivo es necesario abrirlo con codificación CP850 |
; Para modificar ste archivo es necesario abrirlo con codificaci¢n CP850 |
$Revision: 2455 $ |
d80x25_bottom: |
cp850 '║ KolibriOS está basado en MenuetOS y viene ABSOLUTAMENTE ' |
cp850 'SIN GARANTíA ║' |
cp850 '║ Lee el archivo COPYING por más detalles ' |
cp850 ' ║' |
db 186,' KolibriOS est basado en MenuetOS y viene ABSOLUTAMENTE ' |
db 'SIN GARANT¡A ',186 |
db 186,' Lee el archivo COPYING por m s detalles ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
msg_apm: cp850 " APM x.x ", 0 |
novesa: cp850 "Monitor: EGA/CGA",13,10,0 |
s_vesa: cp850 "Versión de VESA: " |
msg_apm db " APM x.x ", 0 |
novesa db "Monitor: EGA/CGA",13,10,0 |
s_vesa db "Versi¢n de VESA: " |
.ver db "?.?",13,10,0 |
gr_mode: cp850 "Selecciona un modo de video: ",13,10,0 |
gr_mode db "Selecciona un modo de video: ",13,10,0 |
ask_bd: cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0 |
ask_bd db "¨Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0 |
if defined extended_primary_loader |
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0 |
bdev db "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0 |
else |
bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);" |
cp850 13,10,"║ " |
cp850 "3-usar imagen precargada en el reinicio del núcleo;" |
cp850 13,10,"║ " |
cp850 "4-crear imagen vacía]: ",0 |
bdev db "Cargar unidad ram desde [1-disquete; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-usar imagen precargada en el reinicio del n£cleo;" |
db 13,10,186," " |
db "4-crear imagen vac¡a]: ",0 |
end if |
prnotfnd: cp850 "Fatal - Modo de video no encontrado.",0 |
prnotfnd db "Fatal - Modo de video no encontrado.",0 |
not386: cp850 "Fatal - CPU 386+ requerido.",0 |
fatalsel: cp850 "Fatal - Modo de gráficos no soportado por hardware.",0 |
pres_key: cp850 "Presiona una tecla para seleccionar otro modo de video.",0 |
badsect: cp850 13,10,"║ Fatal - Sector mal. Reemplaze el disquete.",0 |
memmovefailed:cp850 13,10,"║ Fatal - Int 0x15 move failed.",0 |
okt: cp850 " ... BIEN" |
linef: cp850 13,10,0 |
diskload: cp850 "Cargando disquete: 00 %",8,8,8,8,0 |
pros: cp850 "00" |
backspace2:cp850 8,8,0 |
not386 db "Fatal - CPU 386+ requerido.",0 |
fatalsel db "Fatal - Modo de gr ficos no soportado por hardware.",0 |
pres_key db "Presiona una tecla para seleccionar otro modo de video.",0 |
badsect db 13,10,186," Fatal - Sector mal. Reemplaze el disquete.",0 |
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 |
okt db " ... BIEN" |
linef db 13,10,0 |
diskload db "Cargando disquete: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg:cp850 "Presiona [abcd] para cambiar la configuración, [Enter] para continuar",13,10,0 |
time_msg: cp850 " o espera " |
time_str: cp850 " 5 segundos" |
cp850 " para que inicie automáticamente",13,10,0 |
current_cfg_msg:cp850 "Configuración actual:",13,10,0 |
curvideo_msg:cp850 " [a] Modo de video: ",0 |
start_msg db "Presiona [abcd] para cambiar la configuraci¢n, [Enter] para continuar",13,10,0 |
time_msg db " o espera " |
time_str db " 5 segundos" |
db " para que inicie autom ticamente",13,10,0 |
current_cfg_msg db "Configuraci¢n actual:",13,10,0 |
curvideo_msg db " [a] Modo de video: ",0 |
mode0: cp850 "320x200, EGA/CGA 256 colores",13,10,0 |
mode9: cp850 "640x480, VGA 16 colores",13,10,0 |
mode0 db "320x200, EGA/CGA 256 colores",13,10,0 |
mode9 db "640x480, VGA 16 colores",13,10,0 |
usebd_msg:cp850 " [b] Agregar discos visibles por el BIOS:",0 |
on_msg: cp850 " activado",13,10,0 |
off_msg: cp850 " desactivado",13,10,0 |
usebd_msg db " [b] Agregar discos visibles por el BIOS:",0 |
on_msg db " activado",13,10,0 |
off_msg db " desactivado",13,10,0 |
preboot_device_msg:cp850 " [c] Imagen de disquete: ",0 |
preboot_device_msg db " [c] Imagen de disquete: ",0 |
if defined extended_primary_loader |
preboot_device_msgs dw 0,pdm1,pdm2,0 |
pdm1: cp850 "disquete real",13,10,0 |
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0 |
pdm1 db "disquete real",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
else |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
pdm1: cp850 "disquete real",13,10,0 |
pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0 |
pdm3: cp850 "usar imagen ya cargada",13,10,0 |
pdm4: cp850 "crear imagen vacía",13,10,0 |
pdm1 db "disquete real",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "usar imagen ya cargada",13,10,0 |
pdm4 db "crear imagen vac¡a",13,10,0 |
end if |
loading_msg:cp850 "Cargando KolibriOS...",0 |
loading_msg db "Cargando KolibriOS...",0 |
if ~ defined extended_primary_loader |
save_quest:cp850 "¿Recordar configuración actual? [s/n]: ",0 |
loader_block_error:cp850 "Bootloader inválido, no puedo continuar. Detenido.",0 |
save_quest db "¨Recordar configuraci¢n actual? [s/n]: ",0 |
loader_block_error db "Bootloader inv lido, no puedo continuar. Detenido.",0 |
end if |
_st:cp850 '║ ┌───────────────────────────────┬─┐',13,10,0 |
_r1:cp850 '║ │ 320x200 EGA/CGA 256 colores │ │',13,10,0 |
_r2:cp850 '║ │ 640x480 VGA 16 colores │ │',13,10,0 |
_rs:cp850 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 |
_bt:cp850 '║ └───────────────────────────────┴─┘',13,10,0 |
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0 |
_r1 db 186,' ³ 320x200 EGA/CGA 256 colores ³ ³',13,10,0 |
_r2 db 186,' ³ 640x480 VGA 16 colores ³ ³',13,10,0 |
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0 |
remark1:cp850 "Los valores por defecto puede que no funcionen en algunas configuraciones.",0 |
remark2:cp850 "Si el sistema no inicia, prueba deshabilitar la opción [b].",0 |
remark1 db "Los valores por defecto puede que no funcionen en algunas configuraciones.",0 |
remark2 db "Si el sistema no inicia, prueba deshabilitar la opci¢n [b].",0 |
remarks dw remark1, remark2 |
num_remarks = 2 |
/kernel/trunk/boot/booten.inc |
---|
89,11 → 89,11 |
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 |
end if |
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 |
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0 |
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0 |
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 |
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0 |
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0 |
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0 |
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0 |
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0 |
remark1 db "Default values were selected to match most of configurations, but not all.",0 |
remark2 db "If the system does not boot, try to disable the item [b].",0 |
/kernel/trunk/boot/bootvesa.inc |
---|
78,7 → 78,7 |
mi VBE_ModeInfo |
modes_table: |
end virtual |
cursor_pos dw 0 ;временное хранение курсора. |
cursor_pos dw 0 ;âðåìåííîå õðàíåíèå êóðñîðà. |
home_cursor dw 0 ;current shows rows a table |
end_cursor dw 0 ;end of position current shows rows a table |
scroll_start dw 0 ;start position of scroll bar |
189,7 → 189,7 |
lfs si, [es:vi.VideoModePtr] |
mov bx, modes_table |
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢ |
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢ |
mov word [es:bx], 640 |
mov word [es:bx+2], 480 |
mov word [es:bx+6], 0x13 |
/kernel/trunk/boot/bootet.inc |
---|
15,87 → 15,87 |
d80x25_bottom: |
latin1 '║ KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI' |
latin1 'ITA ║' |
latin1 '║ Naha faili COPYING detailid ' |
latin1 ' ║' |
db 186,' KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI' |
db 'ITA ',186 |
db 186,' Naha faili COPYING detailid ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
msg_apm: latin1 " APM x.x ", 0 |
novesa: latin1 "Ekraan: EGA/CGA",13,10,0 |
s_vesa: latin1 "Vesa versioon: " |
msg_apm db " APM x.x ", 0 |
novesa db "Ekraan: EGA/CGA",13,10,0 |
s_vesa db "Vesa versioon: " |
.ver db "?.?",13,10,0 |
gr_mode: latin1 "Vali videomode: ",13,10,0 |
gr_mode db "Vali videomode: ",13,10,0 |
ask_bd: latin1 "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0 |
ask_bd db "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0 |
if defined extended_primary_loader |
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0 |
bdev db "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0 |
else |
bdev: latin1 "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);" |
latin1 13,10,"║ " |
latin1 "3-kasuta eellaaditud mäluketast kerneli restardist;" |
latin1 13,10,"║ " |
latin1 "4-loo tühi pilt]: ",0 |
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-kasuta eellaaditud mäluketast kerneli restardist;" |
db 13,10,186," " |
db "4-loo tühi pilt]: ",0 |
end if |
prnotfnd: latin1 "Fataalne - Videoreziimi ei leitud.",0 |
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 |
not386: latin1 "Fataalne - CPU 386+ on vajalik.",0 |
fatalsel: latin1 "Fataalne - Graafilist reziimi riistvara ei toeta.",0 |
pres_key: latin1 "Vajutage suvalist klahvi, et valida uus videomode.",0 |
badsect: latin1 13,10,"║ Fataalne - Vigane sektor. Asenda diskett.",0 |
memmovefailed:latin1 13,10,"║ Fataalne - Int 0x15 liigutamine ebaõnnestus.",0 |
okt: latin1 " ... OK" |
linef: latin1 13,10,0 |
diskload: latin1 "Loen disketti: 00 %",8,8,8,8,0 |
pros: latin1 "00" |
backspace2:latin1 8,8,0 |
not386 db "Fataalne - CPU 386+ on vajalik.",0 |
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 |
pres_key db "Vajutage suvalist klahvi, et valida uus videomode.",0 |
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 |
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db "Loen disketti: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg:latin1 "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0 |
time_msg: latin1 " või oota " |
time_str: latin1 " 5 sekundit" |
latin1 " automaatseks jätkamiseks",13,10,0 |
current_cfg_msg:latin1 "Praegused seaded:",13,10,0 |
curvideo_msg:latin1 " [a] Videoreziim: ",0 |
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0 |
time_msg db " või oota " |
time_str db " 5 sekundit" |
db " automaatseks jätkamiseks",13,10,0 |
current_cfg_msg db "Praegused seaded:",13,10,0 |
curvideo_msg db " [a] Videoreziim: ",0 |
mode0: latin1 "320x200, EGA/CGA 256 värvi",0 |
mode9: latin1 "640x480, VGA 16 värvi",0 |
mode0 db "320x200, EGA/CGA 256 värvi",0 |
mode9 db "640x480, VGA 16 värvi",0 |
usebd_msg:latin1 " [b] Lisa kettad nahtavaks BIOS:",0 |
on_msg: latin1 " sees",13,10,0 |
off_msg: latin1 " väljas",13,10,0 |
usebd_msg db " [b] Lisa kettad nahtavaks BIOS:",0 |
on_msg db " sees",13,10,0 |
off_msg db " väljas",13,10,0 |
preboot_device_msg:latin1 " [c] Disketi kujutis: ",0 |
preboot_device_msg db " [c] Disketi kujutis: ",0 |
if defined extended_primary_loader |
preboot_device_msgs dw 0,pdm1,pdm2,0 |
pdm1: latin1 "reaalne diskett",13,10,0 |
pdm2: latin1 "kolibri.img",13,10,0 |
pdm1 db "reaalne diskett",13,10,0 |
pdm2 db "kolibri.img",13,10,0 |
else |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
pdm1: latin1 "reaalne diskett",13,10,0 |
pdm2: latin1 "C:\kolibri.img (FAT32)",13,10,0 |
pdm3: latin1 "kasuta juba laaditud kujutist",13,10,0 |
pdm4: latin1 "loo tühi pilt",13,10,0 |
pdm1 db "reaalne diskett",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "kasuta juba laaditud kujutist",13,10,0 |
pdm4 db "loo tühi pilt",13,10,0 |
end if |
loading_msg:latin1 "Laadin KolibriOS...",0 |
loading_msg db "Laadin KolibriOS...",0 |
if ~ defined extended_primary_loader |
save_quest:latin1 "Jäta meelde praegused seaded? [y/n]: ",0 |
loader_block_error:latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 |
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0 |
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 |
end if |
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 |
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0 |
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0 |
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 |
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0 |
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0 |
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0 |
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0 |
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0 |
remark1:latin1 "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0 |
remark2:latin1 "Kui susteem ei kaivitu, proovige lulitada kirje [b].",0 |
remark1 db "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0 |
remark2 db "Kui susteem ei kaivitu, proovige lulitada kirje [b].",0 |
remarks dw remark1, remark2 |
num_remarks = 2 |
/kernel/trunk/boot/bootge.inc |
---|
89,11 → 89,11 |
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 |
end if |
_st:latin1 '║ ┌───────────────────────────────┬─┐',13,10,0 |
_r1:latin1 '║ │ 320x200 EGA/CGA 256 colors │ │',13,10,0 |
_r2:latin1 '║ │ 640x480 VGA 16 colors │ │',13,10,0 |
_rs:latin1 '║ │ ????x????@?? SVGA VESA │ │',13,10,0 |
_bt:latin1 '║ └───────────────────────────────┴─┘',13,10,0 |
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0 |
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0 |
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0 |
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0 |
remark1 db "Die Standardwerte sind fur die meisten gewahlt, aber nicht fur jedermann.",0 |
remark2 db "Wenn das System nicht bootet, versuchen, das Element [b] deaktivieren.",0 |
/kernel/trunk/boot/bootru.inc |
---|
15,83 → 15,87 |
d80x25_bottom: |
cp866 '║ KolibriOS основана на MenuetOS и НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║' |
cp866 '║ Подробнее смотрите в файле COPYING.TXT ║' |
db 186,' KolibriOS ®á®¢ MenuetOS ¨ ' |
db ' A. ',186 |
db 186,' ®¤à®¡¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
msg_apm: cp866 " APM x.x ", 0 |
novesa: cp866 "Видеокарта: EGA/CGA",13,10,0 |
s_vesa: cp866 "Версия VESA: " |
.ver db "?.?",13,10,0 |
msg_apm db " APM x.x ", 0 |
novesa db "¨¤¥®ª àâ : EGA/CGA",13,10,0 |
s_vesa db "¥àá¨ï VESA: " |
.ver db "?.?",13,10,0 |
gr_mode: cp866 "Выберите видеорежим: ",13,10,0 |
gr_mode db "ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0 |
ask_bd: cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0 |
ask_bd db "®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-¥â]: ",0 |
if defined extended_primary_loader |
bdev: cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0 |
bdev db " £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-kolibri.img ¨§ ¯ ¯ª¨ § £à㧪¨]: ",0 |
else |
bdev: cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10 |
cp866 "║ 3-использовать уже загруженный образ;",13,10 |
cp866 "║ 4-создать чистый образ]: ",0 |
bdev db " £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §;" |
db 13,10,186," " |
db "4-ᮧ¤ âì ç¨áâë© ®¡à §]: ",0 |
end if |
prnotfnd: cp866 "Ошибка - Видеорежим не найден.",0 |
prnotfnd db "訡ª - ¨¤¥®à¥¦¨¬ ¥ ©¤¥.",0 |
not386: cp866 "Ошибка - Требуется процессор 386+.",0 |
fatalsel: cp866 "Ошибка - Выбранный видеорежим не поддерживается.",0 |
pres_key: cp866 "Нажимите любую клавишу, для перехода в выбор режимов.",0 |
badsect: cp866 13,10,"║ Ошибка - Дискета повреждена. Попробуйте другую.",0 |
memmovefailed:cp866 13,10,"║ Ошибка - Int 0x15 move failed.",0 |
okt: cp866 " ... OK" |
linef: cp866 13,10,0 |
diskload: cp866 "Загрузка дискеты: 00 %",8,8,8,8,0 |
pros: cp866 "00" |
backspace2:cp866 8,8,0 |
boot_dev db 0 |
start_msg:cp866 "Нажмите [abcd] для изменения настроек, [Enter] для продолжения загрузки",13,10,0 |
time_msg: cp866 " или подождите " |
time_str: cp866 " 5 секунд " |
cp866 " до автоматического продолжения",13,10,0 |
current_cfg_msg:cp866 "Текущие настройки:",13,10,0 |
curvideo_msg:cp866 " [a] Видеорежим: ",0 |
not386 db "訡ª - ॡã¥âáï ¯à®æ¥áá®à 386+.",0 |
fatalsel db "訡ª - ë¡à ë© ¢¨¤¥®à¥¦¨¬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0 |
pres_key db " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤ ¢ ¢ë¡®à ०¨¬®¢.",0 |
badsect db 13,10,186," 訡ª - ¨áª¥â ¯®¢à¥¦¤¥ . ®¯à®¡ã©â¥ ¤àã£ãî.",0 |
memmovefailed db 13,10,186," 訡ª - Int 0x15 move failed.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db " £à㧪 ¤¨áª¥âë: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 |
start_msg db " ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥¨ï § £à㧪¨",13,10,0 |
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ " |
time_str db " 5 ᥪ㭤 " |
db " ¤® ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥¨ï",13,10,0 |
current_cfg_msg db "¥ªã騥 áâனª¨:",13,10,0 |
curvideo_msg db " [a] ¨¤¥®à¥¦¨¬: ",0 |
mode0: cp866 "320x200, EGA/CGA 256 цветов",13,10,0 |
mode9: cp866 "640x480, VGA 16 цветов",13,10,0 |
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0 |
mode9 db "640x480, VGA 16 梥⮢",13,10,0 |
usebd_msg:cp866 " [b] Добавить диски, видимые через BIOS:",0 |
on_msg: cp866 " вкл",13,10,0 |
off_msg: cp866 " выкл",13,10,0 |
usebd_msg db " [b] ®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0 |
on_msg db " ¢ª«",13,10,0 |
off_msg db " ¢ëª«",13,10,0 |
preboot_device_msg:cp866 " [c] Образ дискеты: ",0 |
preboot_device_msg db " [c] ¡à § ¤¨áª¥âë: ",0 |
if defined extended_primary_loader |
preboot_device_msgs dw 0,pdm1,pdm2,0 |
pdm1: cp866 "настоящая дискета",13,10,0 |
pdm2: cp866 "kolibri.img из папки загрузки",13,10,0 |
pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0 |
pdm2 db "kolibri.img ¨§ ¯ ¯ª¨ § £à㧪¨",13,10,0 |
else |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4 |
pdm1: cp866 "настоящая дискета",13,10,0 |
pdm2: cp866 "C:\kolibri.img (FAT32)",13,10,0 |
pdm3: cp866 "использовать уже загруженный образ",13,10,0 |
pdm4: cp866 "создать чистый образ",13,10,0 |
pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §",13,10,0 |
pdm4 db "ᮧ¤ âì ç¨áâë© ®¡à §",13,10,0 |
end if |
loading_msg:cp866 "Идёт загрузка KolibriOS...",0 |
loading_msg db "¤ñâ § £à㧪 KolibriOS...",0 |
if ~ defined extended_primary_loader ; saving not supported in this case |
save_quest:cp866 "Запомнить текущие настройки? [y/n]: ",0 |
loader_block_error:cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0 |
save_quest db " ¯®¬¨âì ⥪ã騥 áâனª¨? [y/n]: ",0 |
loader_block_error db "訡ª ¢ ¤ ëå ç «ì®£® § £àã§ç¨ª , ¯à®¤®«¦¥¨¥ ¥¢®§¬®¦®.",0 |
end if |
_st:cp866 '║ ┌───────────────────────────────┬─┐ ',13,10,0 |
_r1:cp866 '║ │ 320x200 EGA/CGA 256 цветов │ │ ',13,10,0 |
_r2:cp866 '║ │ 640x480 VGA 16 цветов │ │ ',13,10,0 |
_rs:cp866 '║ │ ????x????@?? SVGA VESA │ │ ',13,10,0 |
_bt:cp866 '║ └───────────────────────────────┴─┘ ',13,10,0 |
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0 |
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0 |
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0 |
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0 |
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0 |
remark1:cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех.",0 |
remark2:cp866 "Если у Вас не грузится система, попробуйте отключить пункт [b].",0 |
remark1 db " ç¥¨ï ¯® 㬮«ç ¨î ¢ë¡à ë ¤«ï 㤮¡á⢠¡®«ìè¨á⢠, ® ¥ ¢á¥å.",0 |
remark2 db " ᫨ ã á ¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ãªâ [b].",0 |
remarks dw remark1, remark2 |
num_remarks = 2 |
/kernel/trunk/boot/et.inc |
---|
9,7 → 9,7 |
; Full ASCII code font |
; only õ and ä added |
; only õ and ä added |
; Kaitz |
ET_FNT: |
fontfile file "ETFONT.FNT" |
/kernel/trunk/boot/ru.inc |
---|
11,9 → 11,9 |
; Generated by RUFNT.EXE |
; By BadBugsKiller (C) |
; Modifyed by BadBugsKiller 12.01.2004 17:45 |
; Шрифт уменьшен в размере и теперь состоит из 2-ух частей, |
; содержащих только символы русского алфавита. |
; символы в кодировке ASCII (ДОС'овская), кодовая страница 866. |
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé, |
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà. |
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòðàíèöà 866. |
RU_FNT1: |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
/kernel/trunk/data32sp.inc |
---|
1,40 → 1,40 |
boot_initirq: cp850 'Inicializar IRQ',0 |
boot_picinit: cp850 'Inicializar PIC',0 |
boot_v86machine: cp850 'Inicializar sistema V86',0 |
boot_inittimer: cp850 'Inicializar reloj del sistema (IRQ0)',0 |
boot_initapic: cp850 'Prueba inicializar APIC',0 |
boot_enableirq: cp850 'Habilitar interrupciones 2, 6, 13, 14, 15',0 |
boot_enablint_ide:cp850 'Habiliar interrupciones en controladores IDE',0 |
boot_detectfloppy:cp850 'Buscar unidades de disquete',0 |
boot_detecthdcd: cp850 'Buscar discos duros y unidades ATAPI',0 |
boot_getcache: cp850 'Tomar memoria para caché',0 |
boot_detectpart: cp850 'Buscar particiones en discos',0 |
boot_init_sys: cp850 'Inicializar directorio del sistema /sys',0 |
boot_loadlibs: cp850 'Cargando librerías (.obj)',0 |
boot_memdetect: cp850 'Determinando cantidad de memoria',0 |
boot_tss: cp850 'Configurando TSSs',0 |
boot_cpuid: cp850 'Leyendo CPUIDs',0 |
; boot_devices: cp850 'Detectando dispositivos',0 |
boot_setmouse: cp850 'Configurando el ratón',0 |
boot_windefs: cp850 'Setting window defaults',0 |
boot_bgr: cp850 'Calculating background',0 |
boot_resirqports: cp850 'Reservando IRQs y puertos',0 |
boot_setostask: cp850 'Configurando tarea OS',0 |
boot_allirqs: cp850 'Desenmascarando IRQs',0 |
boot_tsc: cp850 'Leyendo TSC',0 |
boot_cpufreq: cp850 'La frequencia del CPU es ',' ',' MHz',0 |
boot_pal_ega: cp850 'Configurando paleta EGA/CGA 320x200',0 |
boot_pal_vga: cp850 'Configurando paleta VGA 640x480',0 |
boot_failed: cp850 'Fallo al iniciar la primer aplicación',0 |
boot_mtrr: cp850 'Configurando MTRR',0 |
boot_initirq db 'Inicializar IRQ',0 |
boot_picinit db 'Inicializar PIC',0 |
boot_v86machine db 'Inicializar sistema V86',0 |
boot_inittimer db 'Inicializar reloj del sistema (IRQ0)',0 |
boot_initapic db 'Prueba inicializar APIC',0 |
boot_enableirq db 'Habilitar interrupciones 2, 6, 13, 14, 15',0 |
boot_enablint_ide db 'Habiliar interrupciones en controladores IDE',0 |
boot_detectfloppy db 'Buscar unidades de disquete',0 |
boot_detecthdcd db 'Buscar discos duros y unidades ATAPI',0 |
boot_getcache db 'Tomar memoria para cach',0 |
boot_detectpart db 'Buscar particiones en discos',0 |
boot_init_sys db 'Inicializar directorio del sistema /sys',0 |
boot_loadlibs db 'Cargando librer¡as (.obj)',0 |
boot_memdetect db 'Determinando cantidad de memoria',0 |
boot_tss db 'Configurando TSSs',0 |
boot_cpuid db 'Leyendo CPUIDs',0 |
; boot_devices db 'Detectando dispositivos',0 |
boot_setmouse db 'Configurando el rat¢n',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reservando IRQs y puertos',0 |
boot_setostask db 'Configurando tarea OS',0 |
boot_allirqs db 'Desenmascarando IRQs',0 |
boot_tsc db 'Leyendo TSC',0 |
boot_cpufreq db 'La frequencia del CPU es ',' ',' MHz',0 |
boot_pal_ega db 'Configurando paleta EGA/CGA 320x200',0 |
boot_pal_vga db 'Configurando paleta VGA 640x480',0 |
boot_failed db 'Fallo al iniciar la primer aplicaci¢n',0 |
boot_mtrr db 'Configurando MTRR',0 |
boot_APIC_found: cp850 'APIC habilitado', 0 |
boot_APIC_nfound: cp850 'APIC no encontrado', 0 |
boot_APIC_found db 'APIC habilitado', 0 |
boot_APIC_nfound db 'APIC no encontrado', 0 |
if preboot_blogesc |
boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0 |
boot_tasking db 'Todo configurado - presiona ESC para iniciar',0 |
end if |
msg_version: cp850 'versión incompatible del controlador',13,10,0 |
msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0 |
msg_version db 'versi¢n incompatible del controlador',13,10,0 |
msg_www db 'por favor, visita www.kolibrios.org',13,10,0 |
ud_user_message:cp850 'Error: instrucción no soportada por el procesador',0 |
ud_user_message db 'Error: instrucci¢n no soportada por el procesador',0 |
/kernel/trunk/kernelsp.inc |
---|
1,4 → 1,4 |
; Éste archivo debe ser editado con codificación CP866 |
; ste archivo debe ser editado con codificaci¢n CP866 |
version: cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0 |
diff16 "fin del código del kernel",0,$ |
version db 'Kolibri OS versi¢n 0.7.7.0+ ',13,10,13,10,0 |
diff16 "fin del c¢digo del kernel",0,$ |
/kernel/trunk/bootloader/readme |
---|
5,25 → 5,25 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Загрузочный сектор для ОС Колибри (FAT12, дискета) |
£à㧮çë© á¥ªâ®à ¤«ï ®«¨¡à¨ (FAT12, ¤¨áª¥â ) |
- Описание |
Позволяет загружать KERNEL.MNT с дискет/образов |
объёмом 1.44M, 1.68M, 1.72M и 2.88M |
Для выбора объёма диска, для которого надо собрать |
загрузочный сектор, необходимо в файле boot_fat12.asm |
раскомментировать строку вида: |
- ¯¨á ¨¥ |
®§¢®«ï¥â § £à㦠âì KERNEL.MNT á ¤¨áª¥â/®¡à §®¢ |
®¡êñ¬®¬ 1.44M, 1.68M, 1.72M ¨ 2.88M |
«ï ¢ë¡®à ®¡êñ¬ ¤¨áª , ¤«ï ª®â®à®£® ¤® ᮡà âì |
§ £à㧮çë© á¥ªâ®à, ¥®¡å®¤¨¬® ¢ ä ©«¥ boot_fat12.asm |
à ᪮¬¬¥â¨à®¢ âì áâப㠢¨¤ : |
include 'floppy????.inc' |
для необходимого объёма диска. Доступные варианты: |
¤«ï ¥®¡å®¤¨¬®£® ®¡êñ¬ ¤¨áª . ®áâã¯ë¥ ¢ ਠâë: |
floppy1440.inc, |
floppy1680.inc, |
floppy1743.inc и floppy2880.inc |
floppy1743.inc ¨ floppy2880.inc |
- Сборка |
- ¡®àª |
fasm boot_fat12.asm |
- Для записи загрузочного сектора на диск/образ под Linux |
можно воспользоваться следующей командой: |
- «ï § ¯¨á¨ § £à㧮箣® ᥪâ®à ¤¨áª/®¡à § ¯®¤ Linux |
¬®¦® ¢®á¯®«ì§®¢ âìáï á«¥¤ãî饩 ª®¬ ¤®©: |
dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc |
--------------------------------------------------------------------- |
/kernel/trunk/bootloader/extended_primary_loader/after_win/kordldr.win.txt |
---|
24,368 → 24,368 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Нет повести печальнее на свете, |
Чем повесть о заклинившем Reset'е... |
Íåò ïîâåñòè ïå÷àëüíåå íà ñâåòå, |
×åì ïîâåñòü î çàêëèíèâøåì Reset'å... |
Загрузчик для FAT- и NTFS-томов для случаев, когда основной бутсектор загружает |
Windows, для носителей с размером сектора 512 байт. |
Çàãðóç÷èê äëÿ FAT- è NTFS-òîìîâ äëÿ ñëó÷àåâ, êîãäà îñíîâíîé áóòñåêòîð çàãðóæàåò |
Windows, äëÿ íîñèòåëåé ñ ðàçìåðîì ñåêòîðà 512 áàéò. |
===================================================================== |
Требования для работы: |
1) Все используемые файлы должны быть читабельны. |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 592K свободной базовой памяти. |
4) Пути к используемым файлам не должны содержать символических ссылок NTFS |
(жёсткие ссылки допускаются). |
5) Используемые файлы не должны быть сжатыми или разреженными файлами |
(актуально для NTFS, для FAT выполнено автоматически). |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè. |
4) Ïóòè ê èñïîëüçóåìûì ôàéëàì íå äîëæíû ñîäåðæàòü ñèìâîëè÷åñêèõ ññûëîê NTFS |
(æ¸ñòêèå ññûëêè äîïóñêàþòñÿ). |
5) Èñïîëüçóåìûå ôàéëû íå äîëæíû áûòü ñæàòûìè èëè ðàçðåæåííûìè ôàéëàìè |
(àêòóàëüíî äëÿ NTFS, äëÿ FAT âûïîëíåíî àâòîìàòè÷åñêè). |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 08.08.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
спецификация NTFS: file://C:/windows/system32/drivers/ntfs.sys |
и file://C:/ntldr либо file://C:/bootmgr |
неофициальное описание NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
официальное описание bcdedit для Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx |
официальное описание работы с базой данных загрузчика Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx |
формат таблицы разделов жёсткого диска: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 08.08.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
ñïåöèôèêàöèÿ NTFS: file://C:/windows/system32/drivers/ntfs.sys |
è file://C:/ntldr ëèáî file://C:/bootmgr |
íåîôèöèàëüíîå îïèñàíèå NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543 |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
îôèöèàëüíîå îïèñàíèå bcdedit äëÿ Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx |
îôèöèàëüíîå îïèñàíèå ðàáîòû ñ áàçîé äàííûõ çàãðóç÷èêà Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx |
ôîðìàò òàáëèöû ðàçäåëîâ æ¸ñòêîãî äèñêà: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx |
===================================================================== |
Схема используемой памяти: |
600-2000 код загрузчика (и данные) |
2000-3000 стек |
3000-3200 сектор MBR |
3200-3400 бутсектор логического диска |
3400-3C00 информация о кэше для таблиц FAT16/FAT32: |
для FAT16 - массив на 0x100 байт, каждый байт равен |
0 или 1 в зависимости от того, загружен ли |
соответствующий сектор таблицы FAT16; |
для FAT32 - 100h входов по 8 байт: 4 байта |
(две ссылки - вперёд и назад) для организации L2-списка |
всех прочитанных секторов в порядке возрастания |
последнего времени использования + 4 байта для номера |
сектора; при переполнении кэша выкидывается элемент из |
головы списка, то есть тот, к которому дольше всех |
не было обращений |
3400-3440 информация о кэше для файловых записей NTFS в |
таком же формате, как и кэш для FAT32, но на 8 входов |
3480-34C0 заголовки для кэшей записей индекса NTFS |
3500-3D00 информация о кэшах записей индекса NTFS: с каждой |
файловой записью связан свой кэш для |
соответствующего индекса |
4000-8000 место для информации об атрибутах для NTFS |
60000-80000 таблица FAT12 / место под таблицу FAT16 / |
кэш для таблицы FAT32 / кэш для структур NTFS |
80000-90000 текущий рассматриваемый кластер |
90000-92000 FAT: кэш для корневой папки |
92000-... FAT: кэш для некорневых папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 7 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
600-2000 êîä çàãðóç÷èêà (è äàííûå) |
2000-3000 ñòåê |
3000-3200 ñåêòîð MBR |
3200-3400 áóòñåêòîð ëîãè÷åñêîãî äèñêà |
3400-3C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèö FAT16/FAT32: |
äëÿ FAT16 - ìàññèâ íà 0x100 áàéò, êàæäûé áàéò ðàâåí |
0 èëè 1 â çàâèñèìîñòè îò òîãî, çàãðóæåí ëè |
ñîîòâåòñòâóþùèé ñåêòîð òàáëèöû FAT16; |
äëÿ FAT32 - 100h âõîäîâ ïî 8 áàéò: 4 áàéòà |
(äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ îðãàíèçàöèè L2-ñïèñêà |
âñåõ ïðî÷èòàííûõ ñåêòîðîâ â ïîðÿäêå âîçðàñòàíèÿ |
ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ + 4 áàéòà äëÿ íîìåðà |
ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà âûêèäûâàåòñÿ ýëåìåíò èç |
ãîëîâû ñïèñêà, òî åñòü òîò, ê êîòîðîìó äîëüøå âñåõ |
íå áûëî îáðàùåíèé |
3400-3440 èíôîðìàöèÿ î êýøå äëÿ ôàéëîâûõ çàïèñåé NTFS â |
òàêîì æå ôîðìàòå, êàê è êýø äëÿ FAT32, íî íà 8 âõîäîâ |
3480-34C0 çàãîëîâêè äëÿ êýøåé çàïèñåé èíäåêñà NTFS |
3500-3D00 èíôîðìàöèÿ î êýøàõ çàïèñåé èíäåêñà NTFS: ñ êàæäîé |
ôàéëîâîé çàïèñüþ ñâÿçàí ñâîé êýø äëÿ |
ñîîòâåòñòâóþùåãî èíäåêñà |
4000-8000 ìåñòî äëÿ èíôîðìàöèè îá àòðèáóòàõ äëÿ NTFS |
60000-80000 òàáëèöà FAT12 / ìåñòî ïîä òàáëèöó FAT16 / |
êýø äëÿ òàáëèöû FAT32 / êýø äëÿ ñòðóêòóð NTFS |
80000-90000 òåêóùèé ðàññìàòðèâàåìûé êëàñòåð |
90000-92000 FAT: êýø äëÿ êîðíåâîé ïàïêè |
92000-... FAT: êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
0a. Загрузка из-под DOS и Win9x: установка kordldr.win осуществляется |
размещением команды install=c:\kordldr.win в первой строке config.sys; |
при этом основной загрузчик системы загружает kordldr.win как обычный |
com-файл, в какой-то сегмент по смещению 100h и передаёт управление |
в начало кода (xxxx:0100). |
0б. Загрузка из-под WinNT/2000/XP: установка kordldr.win осуществляется |
добавлением строки наподобие c:\kordldr.win="KordOS" в секцию |
[operating systems] файла boot.ini; если загружаемый файл имеет размер |
не менее 8 Кб (0x2000 байт) и по смещению 3 содержит сигнатуру 'NTFS' |
(в случае kordldr.win так и есть), то основной загрузчик каждой из |
этих систем загружает kordldr.win по адресу 0D00:0000 и передаёт |
управление на адрес 0D00:0256. |
0в. Загрузка из-под Vista: установка kordldr.win осуществляется манипуляциями |
с базой данных основного загрузчика через bcdedit и подробно описана в |
инструкции к kordldr.win; основной загрузчик загружает целиком |
kordldr.win по адресу 0000:7C00 и передаёт управление в начало кода. |
1. При загрузке из-под DOS/9x основной загрузчик не ожидает, что загруженная |
им программа окажется в свою очередь загрузчиком, и в этом случае |
kordldr.win оказывается в условиях, когда основной загрузчик уже |
установил какое-то окружение, в частности, перехватил некоторые |
прерывания. Поэтому перед остальными действиями загрузчик должен |
восстановить систему в начальное состояние. (При загрузке под |
NT-линейкой такой проблемы не возникает, поскольку там основной |
загрузчик ничего в системе не трогает.) Поэтому перед собственно |
инициализацией KordOS при работе из-под DOS/9x производятся |
дополнительные действия. Первым делом kordldr проверяет, какой из |
случаев 0а и 0в имеет место (случай 0б отличается тем, что передаёт |
управление не на начало кода): определяет значение ip (команда call |
помещает в стек адрес следующей после call инструкции, команда pop si |
выталкивает его в регистр si), и если оно равно 100h, то kordldr |
загружен как com-файл из-под DOS/9x. Тогда он спрашивает подтверждения |
у пользователя (поскольку в этой схеме kordldr загружается всегда, |
он должен оставить возможность продолжить загрузку DOS/9x). Если |
пользователь хочет продолжить обычную загрузку, kordldr завершается. |
Иначе используется тот факт, что при выдаче прерывания перезагрузки |
int 19h система предварительно снимает все свои перехваты BIOSовских |
прерываний, а потом в свою очередь выдаёт int 19h уже BIOSу. Так что |
kordldr устанавливает свой обработчик трассировочного прерывания, |
устанавливает флаг трассировки и передаёт управление DOSовскому |
обработчику. Обработчик трассировочного прерывания ничего не делает |
до тех пор, пока следующей инструкцией не оказывается int 19h, а |
в этот момент отбирает управление и продолжает загрузку KordOS. |
При этом BIOSовские обработчики восстановлены за исключением, |
быть может, прерывания таймера int 8, которое, возможно, восстановлено |
до команды jmp far на оригинальный обработчик. В последнем случае его |
нужно восстановить явно. |
2. Загрузчик перемещает свой код на адрес 0000:0600. |
3. (метка real_entry) Загрузчик устанавливает сегментные регистры ds = es = 0, |
настраивает стек ss:sp = 0000:3000 и устанавливает bp так, чтобы |
все данные можно было адресовать через [bp+N] с однобайтовым N |
(в дальнейшем они так и будут адресоваться для освобождения ds и |
экономии на размере кода). Разрешает прерывания на случай, если |
они были запрещены. Выдаёт сообщение о начале загрузки, начинающееся |
с весёлой рожицы (символ с ASCII-кодом 2). |
4. Определяет характеристики жёсткого диска, указанного в качестве |
загрузочного: проверяет поддержку LBA (функция 41h прерывания 13h), |
если LBA не поддерживается, то определяет геометрию - число дорожек |
и число секторов на дорожке (функция 8 прерывания 13h), эти параметры |
нужны функции чтения с диска. |
5. (метка new_partition_ex) Устраивает цикл по разделам жёсткого диска. |
Цель цикла - для каждого логического диска попытаться загрузиться с |
него (действия по загрузке с конкретного логического диска начинаются |
с метки not_extended), при ошибке загрузки управление передаётся |
назад этому циклу (метка next_partition), и поиск подходящего раздела |
продолжается. На выходе заполняется одна переменная partition_start, |
имеющая смысл начала текущего рассматриваемого логического диска, |
но по ходу дела из-за приколов таблиц разделов используются ещё четыре |
переменных. cur_partition_ofs - фактически счётчик цикла, формально |
указатель на текущий вход в текущей загрузочной записи. Сама |
загрузочная запись считывается в память начиная с адреса 3000h. |
Три оставшихся нужны для правильной работы с расширенными разделами. |
В каждой загрузочной записи помещается не более 4 записей о разделах. |
Поэтому главной загрузочной записи, размещающейся в первом физическом |
секторе диска, может не хватить, и обычно создаётся так называемый |
расширенный раздел с расширенными загрузочными записями, формат |
которых почти идентичен главной. Расширенный раздел может быть только |
один, но в нём может быть много логических дисков и расширенных |
загрузочных записей. Расширенные загрузочные записи организованы |
в односвязный список, в каждой такой записи первый вход указывает |
на соответствующий логический диск, а второй - на следующую расширенную |
загрузочную запись. |
При этом в главной загрузочной записи все адреса разделов являются |
абсолютными номерами секторов. В расширенных же записях адреса разделов |
относительны, причём с разными базами: адрес логического диска |
указывается относительно расширенной записи, а адрес следующей |
расширенной записи указывается относительно начала расширенного |
раздела. Такой разнобой выглядит несколько странно, но имеет место |
быть. Три оставшихся переменных содержат: extended_part_start - |
начало расширенного раздела; extended_parent - текущая рассматриваемая |
расширенная загрузочная запись; extended_part_cur - следующая |
загрузочная запись для рассмотрения. |
Цикл выглядит так: просматриваются все разделы, указанные в текущей |
(главной или расширенной) загрузочной записи; для нормальных разделов |
(они же логические диски) происходит переход на not_extended, где |
устанавливается partition_start и начинается собственно загрузка |
(последующие шаги); при встрече с разделом, тип которого указывает |
на расширенность (5 или 0xF), код запоминает начало этого раздела |
(в главной загрузочной записи такой тип означает расширенный раздел, |
в расширенной - только указатель на следующую расширенную запись, |
в обоих случаях он может встретиться только один раз в данной записи); |
когда код доходит до конца списка, все нормальные разделы, описываемые |
в этой записи, уже просмотрены, так что код с чистой совестью переходит |
к следующей расширенной записи. Если он её не встретил, значит, уже |
все логические разделы были подвергнуты попыткам загрузиться, и все |
безрезультатно, так что выводится ругательство и работа останавливается |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
0a. Çàãðóçêà èç-ïîä DOS è Win9x: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ |
ðàçìåùåíèåì êîìàíäû install=c:\kordldr.win â ïåðâîé ñòðîêå config.sys; |
ïðè ýòîì îñíîâíîé çàãðóç÷èê ñèñòåìû çàãðóæàåò kordldr.win êàê îáû÷íûé |
com-ôàéë, â êàêîé-òî ñåãìåíò ïî ñìåùåíèþ 100h è ïåðåäà¸ò óïðàâëåíèå |
â íà÷àëî êîäà (xxxx:0100). |
0á. Çàãðóçêà èç-ïîä WinNT/2000/XP: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ |
äîáàâëåíèåì ñòðîêè íàïîäîáèå c:\kordldr.win="KordOS" â ñåêöèþ |
[operating systems] ôàéëà boot.ini; åñëè çàãðóæàåìûé ôàéë èìååò ðàçìåð |
íå ìåíåå 8 Êá (0x2000 áàéò) è ïî ñìåùåíèþ 3 ñîäåðæèò ñèãíàòóðó 'NTFS' |
(â ñëó÷àå kordldr.win òàê è åñòü), òî îñíîâíîé çàãðóç÷èê êàæäîé èç |
ýòèõ ñèñòåì çàãðóæàåò kordldr.win ïî àäðåñó 0D00:0000 è ïåðåäà¸ò |
óïðàâëåíèå íà àäðåñ 0D00:0256. |
0â. Çàãðóçêà èç-ïîä Vista: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ ìàíèïóëÿöèÿìè |
ñ áàçîé äàííûõ îñíîâíîãî çàãðóç÷èêà ÷åðåç bcdedit è ïîäðîáíî îïèñàíà â |
èíñòðóêöèè ê kordldr.win; îñíîâíîé çàãðóç÷èê çàãðóæàåò öåëèêîì |
kordldr.win ïî àäðåñó 0000:7C00 è ïåðåäà¸ò óïðàâëåíèå â íà÷àëî êîäà. |
1. Ïðè çàãðóçêå èç-ïîä DOS/9x îñíîâíîé çàãðóç÷èê íå îæèäàåò, ÷òî çàãðóæåííàÿ |
èì ïðîãðàììà îêàæåòñÿ â ñâîþ î÷åðåäü çàãðóç÷èêîì, è â ýòîì ñëó÷àå |
kordldr.win îêàçûâàåòñÿ â óñëîâèÿõ, êîãäà îñíîâíîé çàãðóç÷èê óæå |
óñòàíîâèë êàêîå-òî îêðóæåíèå, â ÷àñòíîñòè, ïåðåõâàòèë íåêîòîðûå |
ïðåðûâàíèÿ. Ïîýòîìó ïåðåä îñòàëüíûìè äåéñòâèÿìè çàãðóç÷èê äîëæåí |
âîññòàíîâèòü ñèñòåìó â íà÷àëüíîå ñîñòîÿíèå. (Ïðè çàãðóçêå ïîä |
NT-ëèíåéêîé òàêîé ïðîáëåìû íå âîçíèêàåò, ïîñêîëüêó òàì îñíîâíîé |
çàãðóç÷èê íè÷åãî â ñèñòåìå íå òðîãàåò.) Ïîýòîìó ïåðåä ñîáñòâåííî |
èíèöèàëèçàöèåé KordOS ïðè ðàáîòå èç-ïîä DOS/9x ïðîèçâîäÿòñÿ |
äîïîëíèòåëüíûå äåéñòâèÿ. Ïåðâûì äåëîì kordldr ïðîâåðÿåò, êàêîé èç |
ñëó÷àåâ 0à è 0â èìååò ìåñòî (ñëó÷àé 0á îòëè÷àåòñÿ òåì, ÷òî ïåðåäà¸ò |
óïðàâëåíèå íå íà íà÷àëî êîäà): îïðåäåëÿåò çíà÷åíèå ip (êîìàíäà call |
ïîìåùàåò â ñòåê àäðåñ ñëåäóþùåé ïîñëå call èíñòðóêöèè, êîìàíäà pop si |
âûòàëêèâàåò åãî â ðåãèñòð si), è åñëè îíî ðàâíî 100h, òî kordldr |
çàãðóæåí êàê com-ôàéë èç-ïîä DOS/9x. Òîãäà îí ñïðàøèâàåò ïîäòâåðæäåíèÿ |
ó ïîëüçîâàòåëÿ (ïîñêîëüêó â ýòîé ñõåìå kordldr çàãðóæàåòñÿ âñåãäà, |
îí äîëæåí îñòàâèòü âîçìîæíîñòü ïðîäîëæèòü çàãðóçêó DOS/9x). Åñëè |
ïîëüçîâàòåëü õî÷åò ïðîäîëæèòü îáû÷íóþ çàãðóçêó, kordldr çàâåðøàåòñÿ. |
Èíà÷å èñïîëüçóåòñÿ òîò ôàêò, ÷òî ïðè âûäà÷å ïðåðûâàíèÿ ïåðåçàãðóçêè |
int 19h ñèñòåìà ïðåäâàðèòåëüíî ñíèìàåò âñå ñâîè ïåðåõâàòû BIOSîâñêèõ |
ïðåðûâàíèé, à ïîòîì â ñâîþ î÷åðåäü âûäà¸ò int 19h óæå BIOSó. Òàê ÷òî |
kordldr óñòàíàâëèâàåò ñâîé îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ, |
óñòàíàâëèâàåò ôëàã òðàññèðîâêè è ïåðåäà¸ò óïðàâëåíèå DOSîâñêîìó |
îáðàáîò÷èêó. Îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ íè÷åãî íå äåëàåò |
äî òåõ ïîð, ïîêà ñëåäóþùåé èíñòðóêöèåé íå îêàçûâàåòñÿ int 19h, à |
â ýòîò ìîìåíò îòáèðàåò óïðàâëåíèå è ïðîäîëæàåò çàãðóçêó KordOS. |
Ïðè ýòîì BIOSîâñêèå îáðàáîò÷èêè âîññòàíîâëåíû çà èñêëþ÷åíèåì, |
áûòü ìîæåò, ïðåðûâàíèÿ òàéìåðà int 8, êîòîðîå, âîçìîæíî, âîññòàíîâëåíî |
äî êîìàíäû jmp far íà îðèãèíàëüíûé îáðàáîò÷èê.  ïîñëåäíåì ñëó÷àå åãî |
íóæíî âîññòàíîâèòü ÿâíî. |
2. Çàãðóç÷èê ïåðåìåùàåò ñâîé êîä íà àäðåñ 0000:0600. |
3. (ìåòêà real_entry) Çàãðóç÷èê óñòàíàâëèâàåò ñåãìåíòíûå ðåãèñòðû ds = es = 0, |
íàñòðàèâàåò ñòåê ss:sp = 0000:3000 è óñòàíàâëèâàåò bp òàê, ÷òîáû |
âñå äàííûå ìîæíî áûëî àäðåñîâàòü ÷åðåç [bp+N] ñ îäíîáàéòîâûì N |
(â äàëüíåéøåì îíè òàê è áóäóò àäðåñîâàòüñÿ äëÿ îñâîáîæäåíèÿ ds è |
ýêîíîìèè íà ðàçìåðå êîäà). Ðàçðåøàåò ïðåðûâàíèÿ íà ñëó÷àé, åñëè |
îíè áûëè çàïðåùåíû. Âûäà¸ò ñîîáùåíèå î íà÷àëå çàãðóçêè, íà÷èíàþùååñÿ |
ñ âåñ¸ëîé ðîæèöû (ñèìâîë ñ ASCII-êîäîì 2). |
4. Îïðåäåëÿåò õàðàêòåðèñòèêè æ¸ñòêîãî äèñêà, óêàçàííîãî â êà÷åñòâå |
çàãðóçî÷íîãî: ïðîâåðÿåò ïîääåðæêó LBA (ôóíêöèÿ 41h ïðåðûâàíèÿ 13h), |
åñëè LBA íå ïîääåðæèâàåòñÿ, òî îïðåäåëÿåò ãåîìåòðèþ - ÷èñëî äîðîæåê |
è ÷èñëî ñåêòîðîâ íà äîðîæêå (ôóíêöèÿ 8 ïðåðûâàíèÿ 13h), ýòè ïàðàìåòðû |
íóæíû ôóíêöèè ÷òåíèÿ ñ äèñêà. |
5. (ìåòêà new_partition_ex) Óñòðàèâàåò öèêë ïî ðàçäåëàì æ¸ñòêîãî äèñêà. |
Öåëü öèêëà - äëÿ êàæäîãî ëîãè÷åñêîãî äèñêà ïîïûòàòüñÿ çàãðóçèòüñÿ ñ |
íåãî (äåéñòâèÿ ïî çàãðóçêå ñ êîíêðåòíîãî ëîãè÷åñêîãî äèñêà íà÷èíàþòñÿ |
ñ ìåòêè not_extended), ïðè îøèáêå çàãðóçêè óïðàâëåíèå ïåðåäà¸òñÿ |
íàçàä ýòîìó öèêëó (ìåòêà next_partition), è ïîèñê ïîäõîäÿùåãî ðàçäåëà |
ïðîäîëæàåòñÿ. Íà âûõîäå çàïîëíÿåòñÿ îäíà ïåðåìåííàÿ partition_start, |
èìåþùàÿ ñìûñë íà÷àëà òåêóùåãî ðàññìàòðèâàåìîãî ëîãè÷åñêîãî äèñêà, |
íî ïî õîäó äåëà èç-çà ïðèêîëîâ òàáëèö ðàçäåëîâ èñïîëüçóþòñÿ åù¸ ÷åòûðå |
ïåðåìåííûõ. cur_partition_ofs - ôàêòè÷åñêè ñ÷¸ò÷èê öèêëà, ôîðìàëüíî |
óêàçàòåëü íà òåêóùèé âõîä â òåêóùåé çàãðóçî÷íîé çàïèñè. Ñàìà |
çàãðóçî÷íàÿ çàïèñü ñ÷èòûâàåòñÿ â ïàìÿòü íà÷èíàÿ ñ àäðåñà 3000h. |
Òðè îñòàâøèõñÿ íóæíû äëÿ ïðàâèëüíîé ðàáîòû ñ ðàñøèðåííûìè ðàçäåëàìè. |
 êàæäîé çàãðóçî÷íîé çàïèñè ïîìåùàåòñÿ íå áîëåå 4 çàïèñåé î ðàçäåëàõ. |
Ïîýòîìó ãëàâíîé çàãðóçî÷íîé çàïèñè, ðàçìåùàþùåéñÿ â ïåðâîì ôèçè÷åñêîì |
ñåêòîðå äèñêà, ìîæåò íå õâàòèòü, è îáû÷íî ñîçäà¸òñÿ òàê íàçûâàåìûé |
ðàñøèðåííûé ðàçäåë ñ ðàñøèðåííûìè çàãðóçî÷íûìè çàïèñÿìè, ôîðìàò |
êîòîðûõ ïî÷òè èäåíòè÷åí ãëàâíîé. Ðàñøèðåííûé ðàçäåë ìîæåò áûòü òîëüêî |
îäèí, íî â í¸ì ìîæåò áûòü ìíîãî ëîãè÷åñêèõ äèñêîâ è ðàñøèðåííûõ |
çàãðóçî÷íûõ çàïèñåé. Ðàñøèðåííûå çàãðóçî÷íûå çàïèñè îðãàíèçîâàíû |
â îäíîñâÿçíûé ñïèñîê, â êàæäîé òàêîé çàïèñè ïåðâûé âõîä óêàçûâàåò |
íà ñîîòâåòñòâóþùèé ëîãè÷åñêèé äèñê, à âòîðîé - íà ñëåäóþùóþ ðàñøèðåííóþ |
çàãðóçî÷íóþ çàïèñü. |
Ïðè ýòîì â ãëàâíîé çàãðóçî÷íîé çàïèñè âñå àäðåñà ðàçäåëîâ ÿâëÿþòñÿ |
àáñîëþòíûìè íîìåðàìè ñåêòîðîâ. Â ðàñøèðåííûõ æå çàïèñÿõ àäðåñà ðàçäåëîâ |
îòíîñèòåëüíû, ïðè÷¸ì ñ ðàçíûìè áàçàìè: àäðåñ ëîãè÷åñêîãî äèñêà |
óêàçûâàåòñÿ îòíîñèòåëüíî ðàñøèðåííîé çàïèñè, à àäðåñ ñëåäóþùåé |
ðàñøèðåííîé çàïèñè óêàçûâàåòñÿ îòíîñèòåëüíî íà÷àëà ðàñøèðåííîãî |
ðàçäåëà. Òàêîé ðàçíîáîé âûãëÿäèò íåñêîëüêî ñòðàííî, íî èìååò ìåñòî |
áûòü. Òðè îñòàâøèõñÿ ïåðåìåííûõ ñîäåðæàò: extended_part_start - |
íà÷àëî ðàñøèðåííîãî ðàçäåëà; extended_parent - òåêóùàÿ ðàññìàòðèâàåìàÿ |
ðàñøèðåííàÿ çàãðóçî÷íàÿ çàïèñü; extended_part_cur - ñëåäóþùàÿ |
çàãðóçî÷íàÿ çàïèñü äëÿ ðàññìîòðåíèÿ. |
Öèêë âûãëÿäèò òàê: ïðîñìàòðèâàþòñÿ âñå ðàçäåëû, óêàçàííûå â òåêóùåé |
(ãëàâíîé èëè ðàñøèðåííîé) çàãðóçî÷íîé çàïèñè; äëÿ íîðìàëüíûõ ðàçäåëîâ |
(îíè æå ëîãè÷åñêèå äèñêè) ïðîèñõîäèò ïåðåõîä íà not_extended, ãäå |
óñòàíàâëèâàåòñÿ partition_start è íà÷èíàåòñÿ ñîáñòâåííî çàãðóçêà |
(ïîñëåäóþùèå øàãè); ïðè âñòðå÷å ñ ðàçäåëîì, òèï êîòîðîãî óêàçûâàåò |
íà ðàñøèðåííîñòü (5 èëè 0xF), êîä çàïîìèíàåò íà÷àëî ýòîãî ðàçäåëà |
(â ãëàâíîé çàãðóçî÷íîé çàïèñè òàêîé òèï îçíà÷àåò ðàñøèðåííûé ðàçäåë, |
â ðàñøèðåííîé - òîëüêî óêàçàòåëü íà ñëåäóþùóþ ðàñøèðåííóþ çàïèñü, |
â îáîèõ ñëó÷àÿõ îí ìîæåò âñòðåòèòüñÿ òîëüêî îäèí ðàç â äàííîé çàïèñè); |
êîãäà êîä äîõîäèò äî êîíöà ñïèñêà, âñå íîðìàëüíûå ðàçäåëû, îïèñûâàåìûå |
â ýòîé çàïèñè, óæå ïðîñìîòðåíû, òàê ÷òî êîä ñ ÷èñòîé ñîâåñòüþ ïåðåõîäèò |
ê ñëåäóþùåé ðàñøèðåííîé çàïèñè. Åñëè îí å¸ íå âñòðåòèë, çíà÷èò, óæå |
âñå ëîãè÷åñêèå ðàçäåëû áûëè ïîäâåðãíóòû ïîïûòêàì çàãðóçèòüñÿ, è âñå |
áåçðåçóëüòàòíî, òàê ÷òî âûâîäèòñÿ ðóãàòåëüñòâî è ðàáîòà îñòàíàâëèâàåòñÿ |
(jmp $). |
Может возникнуть вопрос, зачем нужна такая сложная схема и почему |
нельзя узнать нужный логический диск заранее или хотя бы ограничиться |
первым попавшимся логическим диском, не крутя цикл. Так вот, вариант |
с предварительным определением нужного раздела в данном случае не |
используется, поскольку повлёк бы за собой нетривиальные лишние |
действия по установке (в текущем виде установку можно провести вручную, |
и она сводится к указанию системному загрузчику на существование |
kordldr); кстати, в альтернативной версии загрузки после |
Windows-загрузчика, когда установка осуществляется не вручную, а |
специальной программой под Windows, используется модифицированная |
версия, в которой как раз начальный физический сектор нужного раздела |
прописывается установщиком. Сам kordldr не может установить, с какого |
раздела его загрузил Windows-загрузчик (и вообще под NT/2000/XP обязан |
быть файлом на диске C:\). Вариант с первым попавшимся логическим |
диском был реализован в первой версии загрузчика, но по ходу дела |
обнаружилось, что таки нужно крутить цикл: во-вторых, может быть |
приятным, что сама система может стоять вовсе не на системном C:\, а и |
на других дисках; во-первых, диск C: может и не быть первым логическим |
разделом - Vista любит создавать скрытый первичный раздел перед |
системным, и тогда диск C: становится вторым логическим. |
6. Извещает пользователя о том, что происходит попытка загрузки с очередного |
логического диска. |
7. Читает первый сектор логического диска и определяет файловую систему. |
И в FAT, и в NTFS поле со смещением +11 содержит число байт в секторе |
и должно совпадать с характеристикой физического носителя, то есть |
200h байт. И в FAT, и в NTFS поле со смещением +13 содержит число |
секторов в кластере и должно быть степенью двойки. |
Критерий NTFS: поле со смещением +3 содержит строку NTFS и поле со |
смещением +16 нулевое (в FAT оно содержит число таблиц FAT и обязано |
быть ненулевым). |
Критерий FAT: загрузчик вычисляет число кластеров, определяет |
предположительный тип (FAT12/FAT16/FAT32) и проверяет байт по смещению |
+38 для FAT12/16, +66 для FAT32 (он должен быть равен 0x29). |
После определения типа файловой системы извещает пользователя об |
определённом типе. Если файловая система не распознана, выдаёт |
соответствующее сообщение и переходит к следующему логическому диску. |
8a. Для FAT12-томов: засовывает в стек идентификатор файловой системы - |
константу '12'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT12-обработчик; считывает в память всю |
таблицу FAT12 (она не превосходит 0x1800 байт = 6 Кб), при ошибке |
чтения пытается использовать другие копии FAT. |
8б. Для FAT16-томов: засовывает в стек идентификатор файловой системы - |
константу '16'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию |
о кэше секторов FAT (массив байт с возможными значениями 0 и 1, |
означающими, был ли уже загружен соответствующий сектор - всего в |
таблице FAT16 не более 0x100 секторов) - ни один сектор ещё не |
загружен, все байты нулевые. |
8в. Для FAT32-томов: засовывает в стек идентификатор файловой системы - |
константу '32'; устанавливает указатель на функцию получения следующего |
в цепочке FAT кластера на FAT16-обработчик; инициализирует информацию |
о кэше секторов FAT (формат информации описан выше, в распределении |
используемой загрузчиком памяти) - ни один сектор ещё не загружен. |
8г. Общее для FAT-томов: определяет значения служебных переменных |
root_start (первый сектор корневого каталога в FAT12/16, игнорируется |
при обработке FAT32-томов), data_start (начало данных с поправкой, |
вводимой для того, чтобы кластер N начинался с сектора |
N*sectors_per_cluster+data_start), root_clus (первый кластер корневого |
каталога в FAT32, 0 в FAT12/16); устанавливает указатель на функцию |
загрузки файла на FAT-обработчик. |
8д. Для NTFS-томов: засовывает в стек идентификатор файловой системы - |
константу 'nt'; определяет значение служебной переменной frs_size |
(размер в байтах файловой записи, File Record Segment), для полной |
корректности проверяет, что это значение (равное 0x400 байт на всех |
реальных NTFS-томах - единственный способ изменить его заключается |
в пересоздании всех системных структур вручную) не превосходит 0x1000 |
и кратно размеру сектора 0x200 байт; инициализирует кэш файловых |
записей - ничего ещё не загружено; считывает первый кластер $MFT |
и загружает информацию о расположении на диске всей таблицы $MFT |
(атрибут 0x80, $Data); устанавливает указатель на функцию загрузки |
файла на NTFS-обработчик. |
9. (метка load_secondary) Вызывает функцию загрузки файла для файла вторичного |
загрузчика. При обнаружении ошибки переходит на обработчик ошибок с |
соответствующим сообщением. |
10. Устанавливает регистры для вторичного загрузчика: al='h' (жёсткий диск), |
ah=номер диска (для готового бинарника - 0 (BIOS-идентификатор 80h), |
может быть изменён путём модификации константы в исходнике или |
специальным установщиком), bx=идентификатор файловой системы (берётся |
из стека, куда ранее был засунут на шаге 8), ds:si=указатель на |
callback-функцию. |
11. Передаёт управление вторичному загрузчику дальним переходом на 1000:0000. |
Ìîæåò âîçíèêíóòü âîïðîñ, çà÷åì íóæíà òàêàÿ ñëîæíàÿ ñõåìà è ïî÷åìó |
íåëüçÿ óçíàòü íóæíûé ëîãè÷åñêèé äèñê çàðàíåå èëè õîòÿ áû îãðàíè÷èòüñÿ |
ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì äèñêîì, íå êðóòÿ öèêë. Òàê âîò, âàðèàíò |
ñ ïðåäâàðèòåëüíûì îïðåäåëåíèåì íóæíîãî ðàçäåëà â äàííîì ñëó÷àå íå |
èñïîëüçóåòñÿ, ïîñêîëüêó ïîâë¸ê áû çà ñîáîé íåòðèâèàëüíûå ëèøíèå |
äåéñòâèÿ ïî óñòàíîâêå (â òåêóùåì âèäå óñòàíîâêó ìîæíî ïðîâåñòè âðó÷íóþ, |
è îíà ñâîäèòñÿ ê óêàçàíèþ ñèñòåìíîìó çàãðóç÷èêó íà ñóùåñòâîâàíèå |
kordldr); êñòàòè, â àëüòåðíàòèâíîé âåðñèè çàãðóçêè ïîñëå |
Windows-çàãðóç÷èêà, êîãäà óñòàíîâêà îñóùåñòâëÿåòñÿ íå âðó÷íóþ, à |
ñïåöèàëüíîé ïðîãðàììîé ïîä Windows, èñïîëüçóåòñÿ ìîäèôèöèðîâàííàÿ |
âåðñèÿ, â êîòîðîé êàê ðàç íà÷àëüíûé ôèçè÷åñêèé ñåêòîð íóæíîãî ðàçäåëà |
ïðîïèñûâàåòñÿ óñòàíîâùèêîì. Ñàì kordldr íå ìîæåò óñòàíîâèòü, ñ êàêîãî |
ðàçäåëà åãî çàãðóçèë Windows-çàãðóç÷èê (è âîîáùå ïîä NT/2000/XP îáÿçàí |
áûòü ôàéëîì íà äèñêå C:\). Âàðèàíò ñ ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì |
äèñêîì áûë ðåàëèçîâàí â ïåðâîé âåðñèè çàãðóç÷èêà, íî ïî õîäó äåëà |
îáíàðóæèëîñü, ÷òî òàêè íóæíî êðóòèòü öèêë: âî-âòîðûõ, ìîæåò áûòü |
ïðèÿòíûì, ÷òî ñàìà ñèñòåìà ìîæåò ñòîÿòü âîâñå íå íà ñèñòåìíîì C:\, à è |
íà äðóãèõ äèñêàõ; âî-ïåðâûõ, äèñê C: ìîæåò è íå áûòü ïåðâûì ëîãè÷åñêèì |
ðàçäåëîì - Vista ëþáèò ñîçäàâàòü ñêðûòûé ïåðâè÷íûé ðàçäåë ïåðåä |
ñèñòåìíûì, è òîãäà äèñê C: ñòàíîâèòñÿ âòîðûì ëîãè÷åñêèì. |
6. Èçâåùàåò ïîëüçîâàòåëÿ î òîì, ÷òî ïðîèñõîäèò ïîïûòêà çàãðóçêè ñ î÷åðåäíîãî |
ëîãè÷åñêîãî äèñêà. |
7. ×èòàåò ïåðâûé ñåêòîð ëîãè÷åñêîãî äèñêà è îïðåäåëÿåò ôàéëîâóþ ñèñòåìó. |
È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +11 ñîäåðæèò ÷èñëî áàéò â ñåêòîðå |
è äîëæíî ñîâïàäàòü ñ õàðàêòåðèñòèêîé ôèçè÷åñêîãî íîñèòåëÿ, òî åñòü |
200h áàéò. È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +13 ñîäåðæèò ÷èñëî |
ñåêòîðîâ â êëàñòåðå è äîëæíî áûòü ñòåïåíüþ äâîéêè. |
Êðèòåðèé NTFS: ïîëå ñî ñìåùåíèåì +3 ñîäåðæèò ñòðîêó NTFS è ïîëå ñî |
ñìåùåíèåì +16 íóëåâîå (â FAT îíî ñîäåðæèò ÷èñëî òàáëèö FAT è îáÿçàíî |
áûòü íåíóëåâûì). |
Êðèòåðèé FAT: çàãðóç÷èê âû÷èñëÿåò ÷èñëî êëàñòåðîâ, îïðåäåëÿåò |
ïðåäïîëîæèòåëüíûé òèï (FAT12/FAT16/FAT32) è ïðîâåðÿåò áàéò ïî ñìåùåíèþ |
+38 äëÿ FAT12/16, +66 äëÿ FAT32 (îí äîëæåí áûòü ðàâåí 0x29). |
Ïîñëå îïðåäåëåíèÿ òèïà ôàéëîâîé ñèñòåìû èçâåùàåò ïîëüçîâàòåëÿ îá |
îïðåäåë¸ííîì òèïå. Åñëè ôàéëîâàÿ ñèñòåìà íå ðàñïîçíàíà, âûäà¸ò |
ñîîòâåòñòâóþùåå ñîîáùåíèå è ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó. |
8a. Äëÿ FAT12-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '12'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT12-îáðàáîò÷èê; ñ÷èòûâàåò â ïàìÿòü âñþ |
òàáëèöó FAT12 (îíà íå ïðåâîñõîäèò 0x1800 áàéò = 6 Êá), ïðè îøèáêå |
÷òåíèÿ ïûòàåòñÿ èñïîëüçîâàòü äðóãèå êîïèè FAT. |
8á. Äëÿ FAT16-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '16'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ |
î êýøå ñåêòîðîâ FAT (ìàññèâ áàéò ñ âîçìîæíûìè çíà÷åíèÿìè 0 è 1, |
îçíà÷àþùèìè, áûë ëè óæå çàãðóæåí ñîîòâåòñòâóþùèé ñåêòîð - âñåãî â |
òàáëèöå FAT16 íå áîëåå 0x100 ñåêòîðîâ) - íè îäèí ñåêòîð åù¸ íå |
çàãðóæåí, âñå áàéòû íóëåâûå. |
8â. Äëÿ FAT32-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó '32'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî |
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ |
î êýøå ñåêòîðîâ FAT (ôîðìàò èíôîðìàöèè îïèñàí âûøå, â ðàñïðåäåëåíèè |
èñïîëüçóåìîé çàãðóç÷èêîì ïàìÿòè) - íè îäèí ñåêòîð åù¸ íå çàãðóæåí. |
8ã. Îáùåå äëÿ FAT-òîìîâ: îïðåäåëÿåò çíà÷åíèÿ ñëóæåáíûõ ïåðåìåííûõ |
root_start (ïåðâûé ñåêòîð êîðíåâîãî êàòàëîãà â FAT12/16, èãíîðèðóåòñÿ |
ïðè îáðàáîòêå FAT32-òîìîâ), data_start (íà÷àëî äàííûõ ñ ïîïðàâêîé, |
ââîäèìîé äëÿ òîãî, ÷òîáû êëàñòåð N íà÷èíàëñÿ ñ ñåêòîðà |
N*sectors_per_cluster+data_start), root_clus (ïåðâûé êëàñòåð êîðíåâîãî |
êàòàëîãà â FAT32, 0 â FAT12/16); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ |
çàãðóçêè ôàéëà íà FAT-îáðàáîò÷èê. |
8ä. Äëÿ NTFS-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû - |
êîíñòàíòó 'nt'; îïðåäåëÿåò çíà÷åíèå ñëóæåáíîé ïåðåìåííîé frs_size |
(ðàçìåð â áàéòàõ ôàéëîâîé çàïèñè, File Record Segment), äëÿ ïîëíîé |
êîððåêòíîñòè ïðîâåðÿåò, ÷òî ýòî çíà÷åíèå (ðàâíîå 0x400 áàéò íà âñåõ |
ðåàëüíûõ NTFS-òîìàõ - åäèíñòâåííûé ñïîñîá èçìåíèòü åãî çàêëþ÷àåòñÿ |
â ïåðåñîçäàíèè âñåõ ñèñòåìíûõ ñòðóêòóð âðó÷íóþ) íå ïðåâîñõîäèò 0x1000 |
è êðàòíî ðàçìåðó ñåêòîðà 0x200 áàéò; èíèöèàëèçèðóåò êýø ôàéëîâûõ |
çàïèñåé - íè÷åãî åù¸ íå çàãðóæåíî; ñ÷èòûâàåò ïåðâûé êëàñòåð $MFT |
è çàãðóæàåò èíôîðìàöèþ î ðàñïîëîæåíèè íà äèñêå âñåé òàáëèöû $MFT |
(àòðèáóò 0x80, $Data); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ çàãðóçêè |
ôàéëà íà NTFS-îáðàáîò÷èê. |
9. (ìåòêà load_secondary) Âûçûâàåò ôóíêöèþ çàãðóçêè ôàéëà äëÿ ôàéëà âòîðè÷íîãî |
çàãðóç÷èêà. Ïðè îáíàðóæåíèè îøèáêè ïåðåõîäèò íà îáðàáîò÷èê îøèáîê ñ |
ñîîòâåòñòâóþùèì ñîîáùåíèåì. |
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='h' (æ¸ñòêèé äèñê), |
ah=íîìåð äèñêà (äëÿ ãîòîâîãî áèíàðíèêà - 0 (BIOS-èäåíòèôèêàòîð 80h), |
ìîæåò áûòü èçìåí¸í ïóò¸ì ìîäèôèêàöèè êîíñòàíòû â èñõîäíèêå èëè |
ñïåöèàëüíûì óñòàíîâùèêîì), bx=èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû (áåð¸òñÿ |
èç ñòåêà, êóäà ðàíåå áûë çàñóíóò íà øàãå 8), ds:si=óêàçàòåëü íà |
callback-ôóíêöèþ. |
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó äàëüíèì ïåðåõîäîì íà 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
Чтение файла: |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:3000, bp=dat: пара ss:bp при работе с остальным |
кодом должна указывать на 0:dat. |
2. Разбирает переданные параметры и вызывает процедуру загрузки файла. |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
×òåíèå ôàéëà: |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:3000, bp=dat: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:dat. |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò ïðîöåäóðó çàãðóçêè ôàéëà. |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры. |
Процедура чтения секторов (read): |
на входе должно быть установлено: |
Âñïîìîãàòåëüíûå ïðîöåäóðû. |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:dat |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор (относительно начала логического диска) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, |
флаг CF установлен, если возникла ошибка чтения |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя номер первого сектора логического диска, |
найденный при переборе дисков. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ íîìåð ïåðâîãî ñåêòîðà ëîãè÷åñêîãî äèñêà, |
íàéäåííûé ïðè ïåðåáîðå äèñêîâ. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура обработки ошибок (find_error_si и find_error_sp): |
на входе: указатель на сообщение об ошибке в si либо на верхушке стека |
0. Если вызывается find_error_si, она помещает переданный указатель в стек. |
1. Если ошибка произошла в процессе работы callback-функции, то |
(метка error_in_callback) обработчик просто возвращает управление |
вызвавшему коду, рапортуя о ненайденном файле. |
2. Если же ошибка произошла до передачи управления вторичному загрузчику, |
обработчик выводит сообщение типа "Error: <текущий объект>: <ошибка>" |
и (восстановив стек) переходит к следующему логическому диску. |
Ïðîöåäóðà îáðàáîòêè îøèáîê (find_error_si è find_error_sp): |
íà âõîäå: óêàçàòåëü íà ñîîáùåíèå îá îøèáêå â si ëèáî íà âåðõóøêå ñòåêà |
0. Åñëè âûçûâàåòñÿ find_error_si, îíà ïîìåùàåò ïåðåäàííûé óêàçàòåëü â ñòåê. |
1. Åñëè îøèáêà ïðîèçîøëà â ïðîöåññå ðàáîòû callback-ôóíêöèè, òî |
(ìåòêà error_in_callback) îáðàáîò÷èê ïðîñòî âîçâðàùàåò óïðàâëåíèå |
âûçâàâøåìó êîäó, ðàïîðòóÿ î íåíàéäåííîì ôàéëå. |
2. Åñëè æå îøèáêà ïðîèçîøëà äî ïåðåäà÷è óïðàâëåíèÿ âòîðè÷íîìó çàãðóç÷èêó, |
îáðàáîò÷èê âûâîäèò ñîîáùåíèå òèïà "Error: <òåêóùèé îáúåêò>: <îøèáêà>" |
è (âîññòàíîâèâ ñòåê) ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó. |
Процедура чтения файла/атрибута по известному размещению на диске |
Ïðîöåäóðà ÷òåíèÿ ôàéëà/àòðèáóòà ïî èçâåñòíîìó ðàçìåùåíèþ íà äèñêå |
(read_file_chunk): |
на входе должно быть установлено: |
ds:si = указатель на информацию о размещении |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
ecx = лимит числа секторов для чтения, старшее слово должно быть 0 |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные, |
флаг CF установлен, если возникла ошибка чтения |
1. Определяет, является ли атрибут резидентным (возможно только в NTFS |
и означает, что данные файла/атрибута уже были целиком прочитаны при |
обработке информации о файле) или нерезидентным (означает, что данные |
хранятся где-то на диске, и имеется информация о том, где именно). |
2. Для резидентных атрибутов (метка read_file_chunk.resident) просто копирует |
данные по месту назначения (с учётом указанного лимита). |
3. Для нерезидентных атрибутов информация состоит из пар <размер очередного |
фрагмента файла в кластерах, стартовый кластер фрагмента>; процедура |
читает фрагменты, пока файл не закончится или пока не будет достигнут |
указанный лимит. |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ds:si = óêàçàòåëü íà èíôîðìàöèþ î ðàçìåùåíèè |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
ecx = ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ, ñòàðøåå ñëîâî äîëæíî áûòü 0 |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ |
1. Îïðåäåëÿåò, ÿâëÿåòñÿ ëè àòðèáóò ðåçèäåíòíûì (âîçìîæíî òîëüêî â NTFS |
è îçíà÷àåò, ÷òî äàííûå ôàéëà/àòðèáóòà óæå áûëè öåëèêîì ïðî÷èòàíû ïðè |
îáðàáîòêå èíôîðìàöèè î ôàéëå) èëè íåðåçèäåíòíûì (îçíà÷àåò, ÷òî äàííûå |
õðàíÿòñÿ ãäå-òî íà äèñêå, è èìååòñÿ èíôîðìàöèÿ î òîì, ãäå èìåííî). |
2. Äëÿ ðåçèäåíòíûõ àòðèáóòîâ (ìåòêà read_file_chunk.resident) ïðîñòî êîïèðóåò |
äàííûå ïî ìåñòó íàçíà÷åíèÿ (ñ ó÷¸òîì óêàçàííîãî ëèìèòà). |
3. Äëÿ íåðåçèäåíòíûõ àòðèáóòîâ èíôîðìàöèÿ ñîñòîèò èç ïàð <ðàçìåð î÷åðåäíîãî |
ôðàãìåíòà ôàéëà â êëàñòåðàõ, ñòàðòîâûé êëàñòåð ôðàãìåíòà>; ïðîöåäóðà |
÷èòàåò ôðàãìåíòû, ïîêà ôàéë íå çàêîí÷èòñÿ èëè ïîêà íå áóäåò äîñòèãíóò |
óêàçàííûé ëèìèò. |
Процедура просмотра кэша (cache_lookup): |
на входе должно быть установлено: |
eax = искомое значение |
ss:si = указатель на структуру-заголовок кэша |
на выходе: ss:di = указатель на вход в кэше; флаг CF установлен, если значение |
было только что добавлено, и сброшен, если оно уже было в кэше. |
1. Просматривает кэш в поисках указанного значения. Если значение найдено |
(при этом флаг CF оказывается сброшенным), переходит к шагу 4. |
2. Если кэш уже заполнен, удаляет из кэша самый старый вход (он находится в |
голове двусвязного списка), иначе добавляет к кэшу ещё один вход. |
3. Устанавливает в полученном входе указанное значение. Устанавливает флаг |
CF, последующие шаги не меняют состояния флагов. Переходит к шагу 5. |
4. Удаляет вход из списка. |
5. Добавляет сектор в конец списка (самый новый вход). |
Ïðîöåäóðà ïðîñìîòðà êýøà (cache_lookup): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
eax = èñêîìîå çíà÷åíèå |
ss:si = óêàçàòåëü íà ñòðóêòóðó-çàãîëîâîê êýøà |
íà âûõîäå: ss:di = óêàçàòåëü íà âõîä â êýøå; ôëàã CF óñòàíîâëåí, åñëè çíà÷åíèå |
áûëî òîëüêî ÷òî äîáàâëåíî, è ñáðîøåí, åñëè îíî óæå áûëî â êýøå. |
1. Ïðîñìàòðèâàåò êýø â ïîèñêàõ óêàçàííîãî çíà÷åíèÿ. Åñëè çíà÷åíèå íàéäåíî |
(ïðè ýòîì ôëàã CF îêàçûâàåòñÿ ñáðîøåííûì), ïåðåõîäèò ê øàãó 4. |
2. Åñëè êýø óæå çàïîëíåí, óäàëÿåò èç êýøà ñàìûé ñòàðûé âõîä (îí íàõîäèòñÿ â |
ãîëîâå äâóñâÿçíîãî ñïèñêà), èíà÷å äîáàâëÿåò ê êýøó åù¸ îäèí âõîä. |
3. Óñòàíàâëèâàåò â ïîëó÷åííîì âõîäå óêàçàííîå çíà÷åíèå. Óñòàíàâëèâàåò ôëàã |
CF, ïîñëåäóþùèå øàãè íå ìåíÿþò ñîñòîÿíèÿ ôëàãîâ. Ïåðåõîäèò ê øàãó 5. |
4. Óäàëÿåò âõîä èç ñïèñêà. |
5. Äîáàâëÿåò ñåêòîð â êîíåö ñïèñêà (ñàìûé íîâûé âõîä). |
/kernel/trunk/bootloader/extended_primary_loader/cdfs/bootsect.txt |
---|
26,393 → 26,393 |
Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.? |
Бутсектор для загрузки с CD/DVD с файловой системой ISO-9660. |
(ISO-9660 и её расширения - стандарт для CD; DVD может использовать |
либо ISO-9660, либо UDF.) |
Áóòñåêòîð äëÿ çàãðóçêè ñ CD/DVD ñ ôàéëîâîé ñèñòåìîé ISO-9660. |
(ISO-9660 è å¸ ðàñøèðåíèÿ - ñòàíäàðò äëÿ CD; DVD ìîæåò èñïîëüçîâàòü |
ëèáî ISO-9660, ëèáî UDF.) |
===================================================================== |
Требования для работы: |
1) Сам бутсектор и все используемые файлы должны быть читабельны. |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 452K свободной базовой памяти. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð è âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 452K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 14.09.2008): |
стандарт ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf |
стандарт загрузочного CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 14.09.2008): |
ñòàíäàðò ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf |
ñòàíäàðò çàãðóçî÷íîãî CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Схема используемой памяти: |
1000-1800 временный буфер для чтения одиночных секторов |
...-7C00 стек |
7C00-8400 код бутсектора |
8400-8A00 информация о кэше для папок: массив входов следующего |
формата: |
dw следующий элемент в L2-списке закэшированных папок, |
упорядоченном по времени использования |
(голова списка - самый старый); |
dw предыдущий элемент в том же списке; |
dd первый сектор папки; |
dw размер папки в байтах; |
dw сегмент кэша |
60000-... содержимое Path Table, если она используется |
+ кэш для папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
1000-1800 âðåìåííûé áóôåð äëÿ ÷òåíèÿ îäèíî÷íûõ ñåêòîðîâ |
...-7C00 ñòåê |
7C00-8400 êîä áóòñåêòîðà |
8400-8A00 èíôîðìàöèÿ î êýøå äëÿ ïàïîê: ìàññèâ âõîäîâ ñëåäóþùåãî |
ôîðìàòà: |
dw ñëåäóþùèé ýëåìåíò â L2-ñïèñêå çàêýøèðîâàííûõ ïàïîê, |
óïîðÿäî÷åííîì ïî âðåìåíè èñïîëüçîâàíèÿ |
(ãîëîâà ñïèñêà - ñàìûé ñòàðûé); |
dw ïðåäûäóùèé ýëåìåíò â òîì æå ñïèñêå; |
dd ïåðâûé ñåêòîð ïàïêè; |
dw ðàçìåð ïàïêè â áàéòàõ; |
dw ñåãìåíò êýøà |
60000-... ñîäåðæèìîå Path Table, åñëè îíà èñïîëüçóåòñÿ |
+ êýø äëÿ ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. При передаче управления загрузочному коду в случае CD/DVD пара cs:ip |
равна не 0:7C00, а на 07C0:0000. Поэтому сначала загрузчик делает |
дальний прыжок на самого себя с целью получить cs=0 (в некоторых |
местах используется адресация переменных загрузчика через cs, поскольку |
и ds, и es могут быть заняты под другие сегменты). |
2. Настраивает стек ss:sp = 0:7C00 (непосредственно перед основным кодом) |
и сегментные регистры ds=es=0. Форсирует сброшенный флаг направления |
и разрешённые прерывания. Сохраняет идентификатор загрузочного диска |
в специальную переменную. |
3. Проверяет поддержку LBA. Для CD/DVD носителя BIOS обязана предоставлять |
LBA-функции. |
4. Ищет описатель тома CD (Primary Volume Descriptor, PVD): по стандарту |
ISO9660 со смещения 10h начинается цепочка описателей тома, |
завершающаяся специальным описателем (Volume Descriptor Set |
Terminator). Код по очереди считывает все сектора, пока не наткнётся |
либо на искомый описатель, либо на терминатор. Во втором случае |
выдаётся соответствующее сообщение, и загрузка прекращается. |
Вообще говоря, в случае мультисессионных CD основной каталог содержимого CD |
располагается в последней сессии. И спецификация ElTorito загрузочного |
CD оперирует также с последней сессией. Однако на практике оказывается, |
что: во-первых, реальные BIOSы не понимают мультисессионных CD и |
всегда используют первую сессию; во-вторых, BIOSовский int 13h просто |
не позволяет получить информацию о последней сессии. В связи с этим |
загрузчик также использует первую сессию. (В-третьих, в одной из BIOS |
обнаружилась заготовка, которая в случае запроса сектора 10h, в котором |
во всех нормальных случаях и располагается PVD, перенаправляет его |
на сектор 10h+(начало сессии). Если бы этот BIOS ещё и грузился с |
последней сессии, то благодаря заготовке загрузчик без всяких |
модификаций также читал бы последнюю сессию.) |
5. (метка pvd_found) Считывает из PVD некоторую информацию о томе во |
внутренние переменные: размер логического блока (согласно спецификации, |
должен быть степенью двойки от 512 до размера логического сектора, |
равного 2048 для CD и DVD); положение на диске корневой папки; |
вычисляет число блоков в секторе (из предыдущего примечания следует, |
что оно всегда целое и само является степенью двойки). |
6. Получает размер базовой памяти вызовом int 12h; на его основе вычисляет |
размер пространства, которое может использовать загрузчик (от |
адреса 6000:0000 до конца доступной памяти). |
7. Загружает таблицу путей CD (Path Table) - область данных, которая содержит |
базовую информацию обо всех папках на диске. Если таблица слишком |
велика (больше 62K или больше половины доступной памяти), то она |
игнорируется. Если таблица путей недоступна, то запрос типа |
dir1/dir2/dir3/file приведёт к последовательному разбору корневой |
папки и папок dir1,dir2,dir3; если доступна, то достаточно разобрать |
саму таблицу путей (где записано положение папки dir1/dir2/dir3) |
и папку dir3. Если таблица загружена, то соответственно уменьшается |
объём оставшейся доступной памяти и увеличивается указатель на |
свободную область. |
8. Запоминает общий размер и начало кэша для папок (вся оставшаяся после п.7 |
доступная память отводится под этот кэш). |
9. Выдаёт запрос на чтение файла вторичного загрузчика kord/loader. При ошибке |
печатает соответствующее сообщение и прекращает загрузку с CD. |
10. Устанавливает регистры для вторичного загрузчика: al='c' идентифицирует |
тип устройства - CD/DVD; ah=BIOS-идентификатор диска; bx='is' |
идентифицирует файловую систему ISO-9660; ds:si указывает на |
callback-функцию, которую может вызывать вторичный загрузчик. |
11. Передаёт управление вторичному загрузчику, совершая дальний прыжок |
на адрес, куда kord/loader был загружен. |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Ïðè ïåðåäà÷å óïðàâëåíèÿ çàãðóçî÷íîìó êîäó â ñëó÷àå CD/DVD ïàðà cs:ip |
ðàâíà íå 0:7C00, à íà 07C0:0000. Ïîýòîìó ñíà÷àëà çàãðóç÷èê äåëàåò |
äàëüíèé ïðûæîê íà ñàìîãî ñåáÿ ñ öåëüþ ïîëó÷èòü cs=0 (â íåêîòîðûõ |
ìåñòàõ èñïîëüçóåòñÿ àäðåñàöèÿ ïåðåìåííûõ çàãðóç÷èêà ÷åðåç cs, ïîñêîëüêó |
è ds, è es ìîãóò áûòü çàíÿòû ïîä äðóãèå ñåãìåíòû). |
2. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (íåïîñðåäñòâåííî ïåðåä îñíîâíûì êîäîì) |
è ñåãìåíòíûå ðåãèñòðû ds=es=0. Ôîðñèðóåò ñáðîøåííûé ôëàã íàïðàâëåíèÿ |
è ðàçðåø¸ííûå ïðåðûâàíèÿ. Ñîõðàíÿåò èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà |
â ñïåöèàëüíóþ ïåðåìåííóþ. |
3. Ïðîâåðÿåò ïîääåðæêó LBA. Äëÿ CD/DVD íîñèòåëÿ BIOS îáÿçàíà ïðåäîñòàâëÿòü |
LBA-ôóíêöèè. |
4. Èùåò îïèñàòåëü òîìà CD (Primary Volume Descriptor, PVD): ïî ñòàíäàðòó |
ISO9660 ñî ñìåùåíèÿ 10h íà÷èíàåòñÿ öåïî÷êà îïèñàòåëåé òîìà, |
çàâåðøàþùàÿñÿ ñïåöèàëüíûì îïèñàòåëåì (Volume Descriptor Set |
Terminator). Êîä ïî î÷åðåäè ñ÷èòûâàåò âñå ñåêòîðà, ïîêà íå íàòêí¸òñÿ |
ëèáî íà èñêîìûé îïèñàòåëü, ëèáî íà òåðìèíàòîð. Âî âòîðîì ñëó÷àå |
âûäà¸òñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå, è çàãðóçêà ïðåêðàùàåòñÿ. |
Âîîáùå ãîâîðÿ, â ñëó÷àå ìóëüòèñåññèîííûõ CD îñíîâíîé êàòàëîã ñîäåðæèìîãî CD |
ðàñïîëàãàåòñÿ â ïîñëåäíåé ñåññèè. È ñïåöèôèêàöèÿ ElTorito çàãðóçî÷íîãî |
CD îïåðèðóåò òàêæå ñ ïîñëåäíåé ñåññèåé. Îäíàêî íà ïðàêòèêå îêàçûâàåòñÿ, |
÷òî: âî-ïåðâûõ, ðåàëüíûå BIOSû íå ïîíèìàþò ìóëüòèñåññèîííûõ CD è |
âñåãäà èñïîëüçóþò ïåðâóþ ñåññèþ; âî-âòîðûõ, BIOSîâñêèé int 13h ïðîñòî |
íå ïîçâîëÿåò ïîëó÷èòü èíôîðìàöèþ î ïîñëåäíåé ñåññèè.  ñâÿçè ñ ýòèì |
çàãðóç÷èê òàêæå èñïîëüçóåò ïåðâóþ ñåññèþ. (Â-òðåòüèõ, â îäíîé èç BIOS |
îáíàðóæèëàñü çàãîòîâêà, êîòîðàÿ â ñëó÷àå çàïðîñà ñåêòîðà 10h, â êîòîðîì |
âî âñåõ íîðìàëüíûõ ñëó÷àÿõ è ðàñïîëàãàåòñÿ PVD, ïåðåíàïðàâëÿåò åãî |
íà ñåêòîð 10h+(íà÷àëî ñåññèè). Åñëè áû ýòîò BIOS åù¸ è ãðóçèëñÿ ñ |
ïîñëåäíåé ñåññèè, òî áëàãîäàðÿ çàãîòîâêå çàãðóç÷èê áåç âñÿêèõ |
ìîäèôèêàöèé òàêæå ÷èòàë áû ïîñëåäíþþ ñåññèþ.) |
5. (ìåòêà pvd_found) Ñ÷èòûâàåò èç PVD íåêîòîðóþ èíôîðìàöèþ î òîìå âî |
âíóòðåííèå ïåðåìåííûå: ðàçìåð ëîãè÷åñêîãî áëîêà (ñîãëàñíî ñïåöèôèêàöèè, |
äîëæåí áûòü ñòåïåíüþ äâîéêè îò 512 äî ðàçìåðà ëîãè÷åñêîãî ñåêòîðà, |
ðàâíîãî 2048 äëÿ CD è DVD); ïîëîæåíèå íà äèñêå êîðíåâîé ïàïêè; |
âû÷èñëÿåò ÷èñëî áëîêîâ â ñåêòîðå (èç ïðåäûäóùåãî ïðèìå÷àíèÿ ñëåäóåò, |
÷òî îíî âñåãäà öåëîå è ñàìî ÿâëÿåòñÿ ñòåïåíüþ äâîéêè). |
6. Ïîëó÷àåò ðàçìåð áàçîâîé ïàìÿòè âûçîâîì int 12h; íà åãî îñíîâå âû÷èñëÿåò |
ðàçìåð ïðîñòðàíñòâà, êîòîðîå ìîæåò èñïîëüçîâàòü çàãðóç÷èê (îò |
àäðåñà 6000:0000 äî êîíöà äîñòóïíîé ïàìÿòè). |
7. Çàãðóæàåò òàáëèöó ïóòåé CD (Path Table) - îáëàñòü äàííûõ, êîòîðàÿ ñîäåðæèò |
áàçîâóþ èíôîðìàöèþ îáî âñåõ ïàïêàõ íà äèñêå. Åñëè òàáëèöà ñëèøêîì |
âåëèêà (áîëüøå 62K èëè áîëüøå ïîëîâèíû äîñòóïíîé ïàìÿòè), òî îíà |
èãíîðèðóåòñÿ. Åñëè òàáëèöà ïóòåé íåäîñòóïíà, òî çàïðîñ òèïà |
dir1/dir2/dir3/file ïðèâåä¸ò ê ïîñëåäîâàòåëüíîìó ðàçáîðó êîðíåâîé |
ïàïêè è ïàïîê dir1,dir2,dir3; åñëè äîñòóïíà, òî äîñòàòî÷íî ðàçîáðàòü |
ñàìó òàáëèöó ïóòåé (ãäå çàïèñàíî ïîëîæåíèå ïàïêè dir1/dir2/dir3) |
è ïàïêó dir3. Åñëè òàáëèöà çàãðóæåíà, òî ñîîòâåòñòâåííî óìåíüøàåòñÿ |
îáú¸ì îñòàâøåéñÿ äîñòóïíîé ïàìÿòè è óâåëè÷èâàåòñÿ óêàçàòåëü íà |
ñâîáîäíóþ îáëàñòü. |
8. Çàïîìèíàåò îáùèé ðàçìåð è íà÷àëî êýøà äëÿ ïàïîê (âñÿ îñòàâøàÿñÿ ïîñëå ï.7 |
äîñòóïíàÿ ïàìÿòü îòâîäèòñÿ ïîä ýòîò êýø). |
9. Âûäà¸ò çàïðîñ íà ÷òåíèå ôàéëà âòîðè÷íîãî çàãðóç÷èêà kord/loader. Ïðè îøèáêå |
ïå÷àòàåò ñîîòâåòñòâóþùåå ñîîáùåíèå è ïðåêðàùàåò çàãðóçêó ñ CD. |
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='c' èäåíòèôèöèðóåò |
òèï óñòðîéñòâà - CD/DVD; ah=BIOS-èäåíòèôèêàòîð äèñêà; bx='is' |
èäåíòèôèöèðóåò ôàéëîâóþ ñèñòåìó ISO-9660; ds:si óêàçûâàåò íà |
callback-ôóíêöèþ, êîòîðóþ ìîæåò âûçûâàòü âòîðè÷íûé çàãðóç÷èê. |
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó, ñîâåðøàÿ äàëüíèé ïðûæîê |
íà àäðåñ, êóäà kord/loader áûë çàãðóæåí. |
Функция обратного вызова для вторичного загрузчика (callback): |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
Перенаправляет запрос соответствующей локальной процедуре (load_file при |
первом запросе на загрузку файла, loadloop.loadnew при последующих |
запросах на продолжение загрузки файла). |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà (callback): |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
Ïåðåíàïðàâëÿåò çàïðîñ ñîîòâåòñòâóþùåé ëîêàëüíîé ïðîöåäóðå (load_file ïðè |
ïåðâîì çàïðîñå íà çàãðóçêó ôàéëà, loadloop.loadnew ïðè ïîñëåäóþùèõ |
çàïðîñàõ íà ïðîäîëæåíèå çàãðóçêè ôàéëà). |
Вспомогательные процедуры. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения секторов (read_sectors): |
на входе должно быть установлено: |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор |
cx = число секторов |
на выходе: |
es:bx указывает на конец буфера, в который были прочитаны данные |
если произошла ошибка чтения, флаг CF установлен |
1. В цикле (шаги 2-4) читает секторы, следит за тем, чтобы на каждой итерации |
число читаемых секторов не превосходило 7Fh (требование спецификации |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð |
cx = ÷èñëî ñåêòîðîâ |
íà âûõîäå: |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí |
1.  öèêëå (øàãè 2-4) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå ñïåöèôèêàöèè |
EDD BIOS). |
2. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
3. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
4. Вызывает BIOS. Если BIOS рапортует об ошибке, очищает стек, |
устанавливает CF=1 и выходит из процедуры. |
Очищает стек от пакета, сформированного на предыдущем шаге. |
5. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 2. |
2. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
3. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
4. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, î÷èùàåò ñòåê, |
óñòàíàâëèâàåò CF=1 è âûõîäèò èç ïðîöåäóðû. |
Î÷èùàåò ñòåê îò ïàêåòà, ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
5.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 2. |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
Процедура загрузки файла (load_file): |
на входе: |
ds:di = указатель на информационную структуру, описанную в спецификации |
на загрузчик, а также в комментариях к коду |
на выходе: |
bx = статус: 0=успех, 1=файл слишком большой, прочитана только часть, |
2=файл не найден, 3=ошибка чтения |
dx:ax = размер файла, 0xFFFFFFFF, если файл не найден |
1. Если подготовительный код загрузил таблицу путей, то ищет папку в таблице, |
иначе переходит сразу к шагу 4, установив eax = начальный блок |
корневой папки. |
2. Устанавливает es:di на начало таблицы путей. Ограничение на размер |
гарантирует, что вся таблица помещается в сегменте 6000h. |
Инициализирует dx (в котором будет хранится номер текущего входа в |
таблице, считая с 1), cx (размер оставшегося участка таблицы), |
bx (номер входа, соответствующего родительской папке для текущего |
рассматриваемого участка пути). |
3. В цикле ищет вход с нужным родительским элементом и нужным именем. Элементы |
таблицы путей упорядочены (подробно о порядке написано в спецификации), |
так что если родительский элемент для очередного входа больше нужного, |
то нужного входа в таблице нет совсем, и в этом случае происходит |
выход из процедуры с bx=2, ax=dx=0xFFFF. Если обнаружился элемент, |
соответствующий очередной папке в запрошенном пути, то на рассмотрение |
выносится следующая компонента пути. Если эта компонента последняя, |
то осталось найти файл в папке, и код переходит к пункту 4, |
установив eax = начальный блок этой папки. Если же нет, то эта |
компонента должна задавать имя папки, и код возвращается к пункту 3, |
скорректировав указатель на имя ds:si и номер родительского входа bx. |
4. (parse_dir) На этом шаге заданы начальный логический блок папки в eax |
и указатель на имя файла относительно этой папки в ds:si. Если |
папку искали по таблице путей, то имя файла уже не содержит подпапок; |
если же нет, то подпапки вполне возможны. |
5. Файлы в ISO-9660 могут состоять из нескольких кусков (File Section), каждый |
из которых задаётся отдельным входом в папке. Информация обо всех |
таких кусках при просмотре папки запоминается в области, начинающейся |
с адреса 0000:2000. Переменная cur_desc_end содержит указатель на |
конец этой области, он же указатель, куда будет помещена информация |
при обнаружении следующего входа. (Папки, согласно спецификации, |
должны задаваться одним куском.) |
6. Код сначала ищет запрошенную папку в кэше папок. |
7. (parse_dir.found) Если папка уже есть в кэше, то она удаляется из списка, |
отсортированного по давности последнего обращения и код переходит к |
п.15. (Следующим действием станет добавление папки в конец списка.) |
8. (parse_dir.notfound) Если же папки нет в кэше, то её придётся загружать |
с диска. Сначала загружается первый сектор (физический сектор, |
содержащий первый логический блок). При ошибке ввода/вывода |
происходит немедленный выход из процедуры с bx=3, dx=ax=0xFFFF. |
Первый элемент папки содержит информацию о самой этой папке, конкретно |
загрузчик интересуется её размером. |
9. Если размер папки слишком большой (больше или равен 64K либо больше половины |
общего размера кэша), то кэшироваться она не будет. В этом случае код |
считывает папку посекторно во временный буфер (0000:1000) и посекторно |
сканирует на наличие запрошенного имени, пока не найдёт такого имени |
или пока не кончатся данные. (Цикл начинается со сканирования, |
поскольку первая часть данных уже прочитана.) В конце код переходит |
к п.17. |
10. (parse_dir.yescache) Если принято решение о кэшировании папки, то нужно |
обеспечить достаточное количество свободного места. Для этого может |
понадобиться выкинуть какое-то количество старых данных (цикл |
parse_dir.freeloop). Но если просто выкидывать, то, вообще говоря, |
свободное пространство окажется разорванным на несколько фрагментов. |
Поэтому при выкидывании какой-то папки из кэша загрузчик перемещает |
все следующие за ней данные назад по памяти и соответственно |
корректирует информацию о местонахождении данных в информации о кэше. |
При этом новое пространство всегда добавляется в конец доступной |
памяти. Цикл выкидывания продолжается, пока не освободится место, |
достаточное для хранения папки. Из-за ограничений на размер кэшируемых |
папок в конце концов место найдётся. |
11. Выделяется новый элемент кэша. Все удалённые на шаге 10 элементы |
организуются в единый список свободных элементов; если он непуст, |
то очередной элемент берётся из этого списка; если же пуст, то |
берётся совсем новый элемент из области памяти, предназначенной для |
элементов кэша. |
12. В новом элементе заполняются поля начального блока, сегмента с данными, |
размера в байтах. |
13. Уже прочитанные данные первого физического сектора пересылаются на |
законное место в кэше. |
14. Если все данные не исчерпываются первым сектором, то догружаются оставшиеся |
данные с диска. При ошибке чтения, как и раньше, происходит выход из |
процедуры с bx=3, ax=dx=0xFFFF. |
15. (parse_dir.scan) Новый элемент добавляется в конец списка всех элементов |
кэша. |
16. Загрузчик ищет запрошенное имя в загруженных данных папки. |
(Из-за ограничений на размер кэшируемой папки все данные располагаются |
в одном сегменте.) |
17. (parse_dir.scandone) Если в процессе сканирования папки не было найдено |
никаких кусков файла, то cur_desc_end такой же, каким был вначале. |
В этом случае процедура рапортует о ненайденном файле и выходит. |
18. (filefound) Пропускает текущую компоненту имени. Если она была не последней |
(то есть подпапкой, в которой нужно производить дальнейший поиск), |
то код проверяет, что найденный вход - действительно подпапка, |
устанавливает новый стартовый блок и возвращается к п.4. |
Если же последней, то код проверяет, что найденный вход - регулярный |
файл и начинает загрузку файла. |
19. Нормализует указатель, по которому требуется прочитать файл. Под |
нормализацией понимается преобразование типа |
1234:FC08 -> (1234+0FC0):0008, которое не меняет суммарного адреса, |
но гарантирует отсутствие переполнений: в приведённом примере попытка |
переслать 400h байт по rep movsb приведёт к тому, что последние 8 |
байт запишутся не в нужное место, а на 64K раньше. Далее нормализация |
будет производиться после каждой пересылки. В cur_limit помещает |
предельный размер для чтения в байтах. |
20. (loadloop) В цикле по найденным фрагментам файла загружает эти фрагменты |
(пункты 21-27). |
21. Обнуляет переменную [cur_start], имеющую смысл числа байт, которое |
нужно пропустить с начала фрагмента. |
22. (loadloop.loadnew) На эту метку управление может попасть либо с предыдущего |
шага, либо напрямую из callback-процедуры при запросе на продолжение |
чтения. Для этого и нужна вышеупомянутая переменная [cur_start] - |
при продолжении чтения, прервавшегося из-за конца буфера посередине |
фрагмента, там будет записано соответствующее значение. |
23. Определяет текущую длину (хранится в esi) как минимум из длины фрагмента |
и максимальной длины остатка. Если второе строго меньше, то |
запоминает, что файл слишком большой и прочитан только частично. |
Определяет новое значение числа прочитанных байт во фрагменте |
для возможных будущих вызовов [cur_start]. |
24. Переводит пропускаемое число байт в число логических блоков и байт |
в первом блоке, последнее число записывает в переменную [first_byte], |
откуда её позднее достанет read_many_bytes.with_first. |
25. Если фрагмент записан в обычном режиме (non-interleaved mode), то код |
определяет начальный блок фрагмента и вызывает вспомогательную функцию |
чтения блоков. При ошибке чтения устанавливает bx=3 (код ошибки чтения) |
и выходит из цикла к п.28. |
26. Если фрагмент записан в чередуемом режиме (interleaved mode), то сначала |
код пропускает нужное количество непрерывных частей, а потом |
в цикле загружает непрерывные части с помощью той же функции, |
в промежутках между частями увеличивая номер начального блока. |
Пока не кончится фрагмент или пока не наберётся запрошенное число байт. |
При ошибке чтения делает то же самое, что и в предыдущем случае. |
27. (loadloop.loadcontinue) Если фрагменты ещё не кончились и предельный размер |
ещё не достигнут, переходит к следующему фрагменту и п.20. В противном |
случае устанавливает bx=0 либо bx=1 в зависимости от того, было ли |
переполнение в п.23. |
28. (loadloop.calclen) Подсчитывает общую длину файла, суммируя длины всех |
фрагментов. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
íà âõîäå: |
ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó, îïèñàííóþ â ñïåöèôèêàöèè |
íà çàãðóç÷èê, à òàêæå â êîììåíòàðèÿõ ê êîäó |
íà âûõîäå: |
bx = ñòàòóñ: 0=óñïåõ, 1=ôàéë ñëèøêîì áîëüøîé, ïðî÷èòàíà òîëüêî ÷àñòü, |
2=ôàéë íå íàéäåí, 3=îøèáêà ÷òåíèÿ |
dx:ax = ðàçìåð ôàéëà, 0xFFFFFFFF, åñëè ôàéë íå íàéäåí |
1. Åñëè ïîäãîòîâèòåëüíûé êîä çàãðóçèë òàáëèöó ïóòåé, òî èùåò ïàïêó â òàáëèöå, |
èíà÷å ïåðåõîäèò ñðàçó ê øàãó 4, óñòàíîâèâ eax = íà÷àëüíûé áëîê |
êîðíåâîé ïàïêè. |
2. Óñòàíàâëèâàåò es:di íà íà÷àëî òàáëèöû ïóòåé. Îãðàíè÷åíèå íà ðàçìåð |
ãàðàíòèðóåò, ÷òî âñÿ òàáëèöà ïîìåùàåòñÿ â ñåãìåíòå 6000h. |
Èíèöèàëèçèðóåò dx (â êîòîðîì áóäåò õðàíèòñÿ íîìåð òåêóùåãî âõîäà â |
òàáëèöå, ñ÷èòàÿ ñ 1), cx (ðàçìåð îñòàâøåãîñÿ ó÷àñòêà òàáëèöû), |
bx (íîìåð âõîäà, ñîîòâåòñòâóþùåãî ðîäèòåëüñêîé ïàïêå äëÿ òåêóùåãî |
ðàññìàòðèâàåìîãî ó÷àñòêà ïóòè). |
3. Â öèêëå èùåò âõîä ñ íóæíûì ðîäèòåëüñêèì ýëåìåíòîì è íóæíûì èìåíåì. Ýëåìåíòû |
òàáëèöû ïóòåé óïîðÿäî÷åíû (ïîäðîáíî î ïîðÿäêå íàïèñàíî â ñïåöèôèêàöèè), |
òàê ÷òî åñëè ðîäèòåëüñêèé ýëåìåíò äëÿ î÷åðåäíîãî âõîäà áîëüøå íóæíîãî, |
òî íóæíîãî âõîäà â òàáëèöå íåò ñîâñåì, è â ýòîì ñëó÷àå ïðîèñõîäèò |
âûõîä èç ïðîöåäóðû ñ bx=2, ax=dx=0xFFFF. Åñëè îáíàðóæèëñÿ ýëåìåíò, |
ñîîòâåòñòâóþùèé î÷åðåäíîé ïàïêå â çàïðîøåííîì ïóòè, òî íà ðàññìîòðåíèå |
âûíîñèòñÿ ñëåäóþùàÿ êîìïîíåíòà ïóòè. Åñëè ýòà êîìïîíåíòà ïîñëåäíÿÿ, |
òî îñòàëîñü íàéòè ôàéë â ïàïêå, è êîä ïåðåõîäèò ê ïóíêòó 4, |
óñòàíîâèâ eax = íà÷àëüíûé áëîê ýòîé ïàïêè. Åñëè æå íåò, òî ýòà |
êîìïîíåíòà äîëæíà çàäàâàòü èìÿ ïàïêè, è êîä âîçâðàùàåòñÿ ê ïóíêòó 3, |
ñêîððåêòèðîâàâ óêàçàòåëü íà èìÿ ds:si è íîìåð ðîäèòåëüñêîãî âõîäà bx. |
4. (parse_dir) Íà ýòîì øàãå çàäàíû íà÷àëüíûé ëîãè÷åñêèé áëîê ïàïêè â eax |
è óêàçàòåëü íà èìÿ ôàéëà îòíîñèòåëüíî ýòîé ïàïêè â ds:si. Åñëè |
ïàïêó èñêàëè ïî òàáëèöå ïóòåé, òî èìÿ ôàéëà óæå íå ñîäåðæèò ïîäïàïîê; |
åñëè æå íåò, òî ïîäïàïêè âïîëíå âîçìîæíû. |
5. Ôàéëû â ISO-9660 ìîãóò ñîñòîÿòü èç íåñêîëüêèõ êóñêîâ (File Section), êàæäûé |
èç êîòîðûõ çàäà¸òñÿ îòäåëüíûì âõîäîì â ïàïêå. Èíôîðìàöèÿ îáî âñåõ |
òàêèõ êóñêàõ ïðè ïðîñìîòðå ïàïêè çàïîìèíàåòñÿ â îáëàñòè, íà÷èíàþùåéñÿ |
ñ àäðåñà 0000:2000. Ïåðåìåííàÿ cur_desc_end ñîäåðæèò óêàçàòåëü íà |
êîíåö ýòîé îáëàñòè, îí æå óêàçàòåëü, êóäà áóäåò ïîìåùåíà èíôîðìàöèÿ |
ïðè îáíàðóæåíèè ñëåäóþùåãî âõîäà. (Ïàïêè, ñîãëàñíî ñïåöèôèêàöèè, |
äîëæíû çàäàâàòüñÿ îäíèì êóñêîì.) |
6. Êîä ñíà÷àëà èùåò çàïðîøåííóþ ïàïêó â êýøå ïàïîê. |
7. (parse_dir.found) Åñëè ïàïêà óæå åñòü â êýøå, òî îíà óäàëÿåòñÿ èç ñïèñêà, |
îòñîðòèðîâàííîãî ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ è êîä ïåðåõîäèò ê |
ï.15. (Ñëåäóþùèì äåéñòâèåì ñòàíåò äîáàâëåíèå ïàïêè â êîíåö ñïèñêà.) |
8. (parse_dir.notfound) Åñëè æå ïàïêè íåò â êýøå, òî å¸ ïðèä¸òñÿ çàãðóæàòü |
ñ äèñêà. Ñíà÷àëà çàãðóæàåòñÿ ïåðâûé ñåêòîð (ôèçè÷åñêèé ñåêòîð, |
ñîäåðæàùèé ïåðâûé ëîãè÷åñêèé áëîê). Ïðè îøèáêå ââîäà/âûâîäà |
ïðîèñõîäèò íåìåäëåííûé âûõîä èç ïðîöåäóðû ñ bx=3, dx=ax=0xFFFF. |
Ïåðâûé ýëåìåíò ïàïêè ñîäåðæèò èíôîðìàöèþ î ñàìîé ýòîé ïàïêå, êîíêðåòíî |
çàãðóç÷èê èíòåðåñóåòñÿ å¸ ðàçìåðîì. |
9. Åñëè ðàçìåð ïàïêè ñëèøêîì áîëüøîé (áîëüøå èëè ðàâåí 64K ëèáî áîëüøå ïîëîâèíû |
îáùåãî ðàçìåðà êýøà), òî êýøèðîâàòüñÿ îíà íå áóäåò.  ýòîì ñëó÷àå êîä |
ñ÷èòûâàåò ïàïêó ïîñåêòîðíî âî âðåìåííûé áóôåð (0000:1000) è ïîñåêòîðíî |
ñêàíèðóåò íà íàëè÷èå çàïðîøåííîãî èìåíè, ïîêà íå íàéä¸ò òàêîãî èìåíè |
èëè ïîêà íå êîí÷àòñÿ äàííûå. (Öèêë íà÷èíàåòñÿ ñî ñêàíèðîâàíèÿ, |
ïîñêîëüêó ïåðâàÿ ÷àñòü äàííûõ óæå ïðî÷èòàíà.)  êîíöå êîä ïåðåõîäèò |
ê ï.17. |
10. (parse_dir.yescache) Åñëè ïðèíÿòî ðåøåíèå î êýøèðîâàíèè ïàïêè, òî íóæíî |
îáåñïå÷èòü äîñòàòî÷íîå êîëè÷åñòâî ñâîáîäíîãî ìåñòà. Äëÿ ýòîãî ìîæåò |
ïîíàäîáèòüñÿ âûêèíóòü êàêîå-òî êîëè÷åñòâî ñòàðûõ äàííûõ (öèêë |
parse_dir.freeloop). Íî åñëè ïðîñòî âûêèäûâàòü, òî, âîîáùå ãîâîðÿ, |
ñâîáîäíîå ïðîñòðàíñòâî îêàæåòñÿ ðàçîðâàííûì íà íåñêîëüêî ôðàãìåíòîâ. |
Ïîýòîìó ïðè âûêèäûâàíèè êàêîé-òî ïàïêè èç êýøà çàãðóç÷èê ïåðåìåùàåò |
âñå ñëåäóþùèå çà íåé äàííûå íàçàä ïî ïàìÿòè è ñîîòâåòñòâåííî |
êîððåêòèðóåò èíôîðìàöèþ î ìåñòîíàõîæäåíèè äàííûõ â èíôîðìàöèè î êýøå. |
Ïðè ýòîì íîâîå ïðîñòðàíñòâî âñåãäà äîáàâëÿåòñÿ â êîíåö äîñòóïíîé |
ïàìÿòè. Öèêë âûêèäûâàíèÿ ïðîäîëæàåòñÿ, ïîêà íå îñâîáîäèòñÿ ìåñòî, |
äîñòàòî÷íîå äëÿ õðàíåíèÿ ïàïêè. Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìûõ |
ïàïîê â êîíöå êîíöîâ ìåñòî íàéä¸òñÿ. |
11. Âûäåëÿåòñÿ íîâûé ýëåìåíò êýøà. Âñå óäàë¸ííûå íà øàãå 10 ýëåìåíòû |
îðãàíèçóþòñÿ â åäèíûé ñïèñîê ñâîáîäíûõ ýëåìåíòîâ; åñëè îí íåïóñò, |
òî î÷åðåäíîé ýëåìåíò áåð¸òñÿ èç ýòîãî ñïèñêà; åñëè æå ïóñò, òî |
áåð¸òñÿ ñîâñåì íîâûé ýëåìåíò èç îáëàñòè ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ |
ýëåìåíòîâ êýøà. |
12.  íîâîì ýëåìåíòå çàïîëíÿþòñÿ ïîëÿ íà÷àëüíîãî áëîêà, ñåãìåíòà ñ äàííûìè, |
ðàçìåðà â áàéòàõ. |
13. Óæå ïðî÷èòàííûå äàííûå ïåðâîãî ôèçè÷åñêîãî ñåêòîðà ïåðåñûëàþòñÿ íà |
çàêîííîå ìåñòî â êýøå. |
14. Åñëè âñå äàííûå íå èñ÷åðïûâàþòñÿ ïåðâûì ñåêòîðîì, òî äîãðóæàþòñÿ îñòàâøèåñÿ |
äàííûå ñ äèñêà. Ïðè îøèáêå ÷òåíèÿ, êàê è ðàíüøå, ïðîèñõîäèò âûõîä èç |
ïðîöåäóðû ñ bx=3, ax=dx=0xFFFF. |
15. (parse_dir.scan) Íîâûé ýëåìåíò äîáàâëÿåòñÿ â êîíåö ñïèñêà âñåõ ýëåìåíòîâ |
êýøà. |
16. Çàãðóç÷èê èùåò çàïðîøåííîå èìÿ â çàãðóæåííûõ äàííûõ ïàïêè. |
(Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìîé ïàïêè âñå äàííûå ðàñïîëàãàþòñÿ |
â îäíîì ñåãìåíòå.) |
17. (parse_dir.scandone) Åñëè â ïðîöåññå ñêàíèðîâàíèÿ ïàïêè íå áûëî íàéäåíî |
íèêàêèõ êóñêîâ ôàéëà, òî cur_desc_end òàêîé æå, êàêèì áûë âíà÷àëå. |
 ýòîì ñëó÷àå ïðîöåäóðà ðàïîðòóåò î íåíàéäåííîì ôàéëå è âûõîäèò. |
18. (filefound) Ïðîïóñêàåò òåêóùóþ êîìïîíåíòó èìåíè. Åñëè îíà áûëà íå ïîñëåäíåé |
(òî åñòü ïîäïàïêîé, â êîòîðîé íóæíî ïðîèçâîäèòü äàëüíåéøèé ïîèñê), |
òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - äåéñòâèòåëüíî ïîäïàïêà, |
óñòàíàâëèâàåò íîâûé ñòàðòîâûé áëîê è âîçâðàùàåòñÿ ê ï.4. |
Åñëè æå ïîñëåäíåé, òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - ðåãóëÿðíûé |
ôàéë è íà÷èíàåò çàãðóçêó ôàéëà. |
19. Íîðìàëèçóåò óêàçàòåëü, ïî êîòîðîìó òðåáóåòñÿ ïðî÷èòàòü ôàéë. Ïîä |
íîðìàëèçàöèåé ïîíèìàåòñÿ ïðåîáðàçîâàíèå òèïà |
1234:FC08 -> (1234+0FC0):0008, êîòîðîå íå ìåíÿåò ñóììàðíîãî àäðåñà, |
íî ãàðàíòèðóåò îòñóòñòâèå ïåðåïîëíåíèé: â ïðèâåä¸ííîì ïðèìåðå ïîïûòêà |
ïåðåñëàòü 400h áàéò ïî rep movsb ïðèâåä¸ò ê òîìó, ÷òî ïîñëåäíèå 8 |
áàéò çàïèøóòñÿ íå â íóæíîå ìåñòî, à íà 64K ðàíüøå. Äàëåå íîðìàëèçàöèÿ |
áóäåò ïðîèçâîäèòüñÿ ïîñëå êàæäîé ïåðåñûëêè. Â cur_limit ïîìåùàåò |
ïðåäåëüíûé ðàçìåð äëÿ ÷òåíèÿ â áàéòàõ. |
20. (loadloop) Â öèêëå ïî íàéäåííûì ôðàãìåíòàì ôàéëà çàãðóæàåò ýòè ôðàãìåíòû |
(ïóíêòû 21-27). |
21. Îáíóëÿåò ïåðåìåííóþ [cur_start], èìåþùóþ ñìûñë ÷èñëà áàéò, êîòîðîå |
íóæíî ïðîïóñòèòü ñ íà÷àëà ôðàãìåíòà. |
22. (loadloop.loadnew) Íà ýòó ìåòêó óïðàâëåíèå ìîæåò ïîïàñòü ëèáî ñ ïðåäûäóùåãî |
øàãà, ëèáî íàïðÿìóþ èç callback-ïðîöåäóðû ïðè çàïðîñå íà ïðîäîëæåíèå |
÷òåíèÿ. Äëÿ ýòîãî è íóæíà âûøåóïîìÿíóòàÿ ïåðåìåííàÿ [cur_start] - |
ïðè ïðîäîëæåíèè ÷òåíèÿ, ïðåðâàâøåãîñÿ èç-çà êîíöà áóôåðà ïîñåðåäèíå |
ôðàãìåíòà, òàì áóäåò çàïèñàíî ñîîòâåòñòâóþùåå çíà÷åíèå. |
23. Îïðåäåëÿåò òåêóùóþ äëèíó (õðàíèòñÿ â esi) êàê ìèíèìóì èç äëèíû ôðàãìåíòà |
è ìàêñèìàëüíîé äëèíû îñòàòêà. Åñëè âòîðîå ñòðîãî ìåíüøå, òî |
çàïîìèíàåò, ÷òî ôàéë ñëèøêîì áîëüøîé è ïðî÷èòàí òîëüêî ÷àñòè÷íî. |
Îïðåäåëÿåò íîâîå çíà÷åíèå ÷èñëà ïðî÷èòàííûõ áàéò âî ôðàãìåíòå |
äëÿ âîçìîæíûõ áóäóùèõ âûçîâîâ [cur_start]. |
24. Ïåðåâîäèò ïðîïóñêàåìîå ÷èñëî áàéò â ÷èñëî ëîãè÷åñêèõ áëîêîâ è áàéò |
â ïåðâîì áëîêå, ïîñëåäíåå ÷èñëî çàïèñûâàåò â ïåðåìåííóþ [first_byte], |
îòêóäà å¸ ïîçäíåå äîñòàíåò read_many_bytes.with_first. |
25. Åñëè ôðàãìåíò çàïèñàí â îáû÷íîì ðåæèìå (non-interleaved mode), òî êîä |
îïðåäåëÿåò íà÷àëüíûé áëîê ôðàãìåíòà è âûçûâàåò âñïîìîãàòåëüíóþ ôóíêöèþ |
÷òåíèÿ áëîêîâ. Ïðè îøèáêå ÷òåíèÿ óñòàíàâëèâàåò bx=3 (êîä îøèáêè ÷òåíèÿ) |
è âûõîäèò èç öèêëà ê ï.28. |
26. Åñëè ôðàãìåíò çàïèñàí â ÷åðåäóåìîì ðåæèìå (interleaved mode), òî ñíà÷àëà |
êîä ïðîïóñêàåò íóæíîå êîëè÷åñòâî íåïðåðûâíûõ ÷àñòåé, à ïîòîì |
â öèêëå çàãðóæàåò íåïðåðûâíûå ÷àñòè ñ ïîìîùüþ òîé æå ôóíêöèè, |
â ïðîìåæóòêàõ ìåæäó ÷àñòÿìè óâåëè÷èâàÿ íîìåð íà÷àëüíîãî áëîêà. |
Ïîêà íå êîí÷èòñÿ ôðàãìåíò èëè ïîêà íå íàáåð¸òñÿ çàïðîøåííîå ÷èñëî áàéò. |
Ïðè îøèáêå ÷òåíèÿ äåëàåò òî æå ñàìîå, ÷òî è â ïðåäûäóùåì ñëó÷àå. |
27. (loadloop.loadcontinue) Åñëè ôðàãìåíòû åù¸ íå êîí÷èëèñü è ïðåäåëüíûé ðàçìåð |
åù¸ íå äîñòèãíóò, ïåðåõîäèò ê ñëåäóþùåìó ôðàãìåíòó è ï.20. Â ïðîòèâíîì |
ñëó÷àå óñòàíàâëèâàåò bx=0 ëèáî bx=1 â çàâèñèìîñòè îò òîãî, áûëî ëè |
ïåðåïîëíåíèå â ï.23. |
28. (loadloop.calclen) Ïîäñ÷èòûâàåò îáùóþ äëèíó ôàéëà, ñóììèðóÿ äëèíû âñåõ |
ôðàãìåíòîâ. |
Процедура проверки, является ли текущая компонента имени файла последней |
Ïðîöåäóðà ïðîâåðêè, ÿâëÿåòñÿ ëè òåêóùàÿ êîìïîíåíòà èìåíè ôàéëà ïîñëåäíåé |
(is_last_component): |
на входе: ds:si = указатель на имя |
на выходе: флаг CF установлен, если есть последующие компоненты |
В цикле загружает символы имени в поисках нулевого и '/'; если нашёлся первый, |
то выходит (при этом CF=0); если нашёлся второй, то устанавливает CF |
и выходит. |
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ |
íà âûõîäå: ôëàã CF óñòàíîâëåí, åñëè åñòü ïîñëåäóþùèå êîìïîíåíòû |
 öèêëå çàãðóæàåò ñèìâîëû èìåíè â ïîèñêàõ íóëåâîãî è '/'; åñëè íàø¸ëñÿ ïåðâûé, |
òî âûõîäèò (ïðè ýòîì CF=0); åñëè íàø¸ëñÿ âòîðîé, òî óñòàíàâëèâàåò CF |
è âûõîäèò. |
Процедуры проверки на совпадение текущей компоненты имени файла с именем |
текущего элемента (test_filename1 для таблицы путей, test_filename2 для папки): |
на входе: ds:si = указатель на имя, es:di = указатель на элемент |
таблицы путей для test_filename1, папки для test_filename2 |
на выходе: CF установлен, если имена не совпадают |
В цикле проверяет совпадение приведённых к верхнему регистру очередных символов |
имён файла и элемента. Условия выхода из цикла: закончилось имя файла |
в ds:si (то есть, очередной символ - нулевой либо '/') - совпадение |
возможно только в ситуации типа имени "filename.ext" и элемента |
"filename.ext;1" (в ISO9660 ";1" - версия файла, элементы с одинаковыми |
именами в папке отсортированы по убыванию версий); |
несовпадение символов - означает, что имена не совпадают; |
закончилось имя элемента - нужно проверить, закончилось ли при этом имя |
файла, и в зависимости от этого принимать решение о совпадении. |
Ïðîöåäóðû ïðîâåðêè íà ñîâïàäåíèå òåêóùåé êîìïîíåíòû èìåíè ôàéëà ñ èìåíåì |
òåêóùåãî ýëåìåíòà (test_filename1 äëÿ òàáëèöû ïóòåé, test_filename2 äëÿ ïàïêè): |
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ, es:di = óêàçàòåëü íà ýëåìåíò |
òàáëèöû ïóòåé äëÿ test_filename1, ïàïêè äëÿ test_filename2 |
íà âûõîäå: CF óñòàíîâëåí, åñëè èìåíà íå ñîâïàäàþò |
 öèêëå ïðîâåðÿåò ñîâïàäåíèå ïðèâåä¸ííûõ ê âåðõíåìó ðåãèñòðó î÷åðåäíûõ ñèìâîëîâ |
èì¸í ôàéëà è ýëåìåíòà. Óñëîâèÿ âûõîäà èç öèêëà: çàêîí÷èëîñü èìÿ ôàéëà |
â ds:si (òî åñòü, î÷åðåäíîé ñèìâîë - íóëåâîé ëèáî '/') - ñîâïàäåíèå |
âîçìîæíî òîëüêî â ñèòóàöèè òèïà èìåíè "filename.ext" è ýëåìåíòà |
"filename.ext;1" (â ISO9660 ";1" - âåðñèÿ ôàéëà, ýëåìåíòû ñ îäèíàêîâûìè |
èìåíàìè â ïàïêå îòñîðòèðîâàíû ïî óáûâàíèþ âåðñèé); |
íåñîâïàäåíèå ñèìâîëîâ - îçíà÷àåò, ÷òî èìåíà íå ñîâïàäàþò; |
çàêîí÷èëîñü èìÿ ýëåìåíòà - íóæíî ïðîâåðèòü, çàêîí÷èëîñü ëè ïðè ýòîì èìÿ |
ôàéëà, è â çàâèñèìîñòè îò ýòîãî ïðèíèìàòü ðåøåíèå î ñîâïàäåíèè. |
Процедура приведения символа в верхний регистр (toupper): |
на входе: ASCII-символ |
на выходе: тот же символ в верхнем регистре (он сам, если понятие регистра к |
нему неприменимо) |
Из символов в диапазоне 'a' - 'z' включительно вычитает константу 'a'-'A', |
остальные символы не трогает. |
Ïðîöåäóðà ïðèâåäåíèÿ ñèìâîëà â âåðõíèé ðåãèñòð (toupper): |
íà âõîäå: ASCII-ñèìâîë |
íà âûõîäå: òîò æå ñèìâîë â âåðõíåì ðåãèñòðå (îí ñàì, åñëè ïîíÿòèå ðåãèñòðà ê |
íåìó íåïðèìåíèìî) |
Èç ñèìâîëîâ â äèàïàçîíå 'a' - 'z' âêëþ÷èòåëüíî âû÷èòàåò êîíñòàíòó 'a'-'A', |
îñòàëüíûå ñèìâîëû íå òðîãàåò. |
Процедура поиска файла в данных папки (scan_for_filename_in_sector): |
на входе: |
ds:si = указатель на имя файла |
es:bx = указатель на начало данных папки |
es:dx = указатель на конец данных папки |
на выходе: |
CF сброшен, если найден финальный фрагмент файла |
(и дальше сканировать папку не нужно) |
в область для информации о фрагментах файла записывается найденное |
В цикле просматривает все входы папки, пропуская те, у которых установлен |
бит Associated (это специальные входы, дополняющие основные). Если |
имя очередного входа совпадает с именем файла, то запоминает новый |
фрагмент. Если фрагмент финальный (не установлен бит Multi-Extent), |
то код выходит с CF=0. Если достигнут конец данных, то код выходит |
с CF=1. Если очередной вход нулевой (первый байт настоящего входа |
содержит длину и не может быть нулём), то процедура переходит к |
рассмотрению следующего логического блока. При этом потенциально |
возможно переполнение при добавлении размера блока; поскольку такой |
сценарий означает, что процедура вызвана для кэшированной папки |
с размером почти 64K и началом данных bx=0 (это свойство вызывающего |
кода), а размер блока - степень двойки, то после переполнения всегда |
bx=0, так что это можно обнаружить по взведённому ZF после сложения; |
в этом случае также происходит выход (а после переполнения CF=1). |
Ïðîöåäóðà ïîèñêà ôàéëà â äàííûõ ïàïêè (scan_for_filename_in_sector): |
íà âõîäå: |
ds:si = óêàçàòåëü íà èìÿ ôàéëà |
es:bx = óêàçàòåëü íà íà÷àëî äàííûõ ïàïêè |
es:dx = óêàçàòåëü íà êîíåö äàííûõ ïàïêè |
íà âûõîäå: |
CF ñáðîøåí, åñëè íàéäåí ôèíàëüíûé ôðàãìåíò ôàéëà |
(è äàëüøå ñêàíèðîâàòü ïàïêó íå íóæíî) |
â îáëàñòü äëÿ èíôîðìàöèè î ôðàãìåíòàõ ôàéëà çàïèñûâàåòñÿ íàéäåííîå |
 öèêëå ïðîñìàòðèâàåò âñå âõîäû ïàïêè, ïðîïóñêàÿ òå, ó êîòîðûõ óñòàíîâëåí |
áèò Associated (ýòî ñïåöèàëüíûå âõîäû, äîïîëíÿþùèå îñíîâíûå). Åñëè |
èìÿ î÷åðåäíîãî âõîäà ñîâïàäàåò ñ èìåíåì ôàéëà, òî çàïîìèíàåò íîâûé |
ôðàãìåíò. Åñëè ôðàãìåíò ôèíàëüíûé (íå óñòàíîâëåí áèò Multi-Extent), |
òî êîä âûõîäèò ñ CF=0. Åñëè äîñòèãíóò êîíåö äàííûõ, òî êîä âûõîäèò |
ñ CF=1. Åñëè î÷åðåäíîé âõîä íóëåâîé (ïåðâûé áàéò íàñòîÿùåãî âõîäà |
ñîäåðæèò äëèíó è íå ìîæåò áûòü íóë¸ì), òî ïðîöåäóðà ïåðåõîäèò ê |
ðàññìîòðåíèþ ñëåäóþùåãî ëîãè÷åñêîãî áëîêà. Ïðè ýòîì ïîòåíöèàëüíî |
âîçìîæíî ïåðåïîëíåíèå ïðè äîáàâëåíèè ðàçìåðà áëîêà; ïîñêîëüêó òàêîé |
ñöåíàðèé îçíà÷àåò, ÷òî ïðîöåäóðà âûçâàíà äëÿ êýøèðîâàííîé ïàïêè |
ñ ðàçìåðîì ïî÷òè 64K è íà÷àëîì äàííûõ bx=0 (ýòî ñâîéñòâî âûçûâàþùåãî |
êîäà), à ðàçìåð áëîêà - ñòåïåíü äâîéêè, òî ïîñëå ïåðåïîëíåíèÿ âñåãäà |
bx=0, òàê ÷òî ýòî ìîæíî îáíàðóæèòü ïî âçâåä¸ííîìó ZF ïîñëå ñëîæåíèÿ; |
â ýòîì ñëó÷àå òàêæå ïðîèñõîäèò âûõîä (à ïîñëå ïåðåïîëíåíèÿ CF=1). |
Процедура перевода логического блока в номер сектора: |
на входе: eax = логический блок |
на выходе: eax = физический сектор, dx = номер логического блока в секторе |
Осуществляет обычное деление 32-битного числа на 32-битное (число логических |
блоков в секторе, хранящееся во внутренней переменной). |
Ïðîöåäóðà ïåðåâîäà ëîãè÷åñêîãî áëîêà â íîìåð ñåêòîðà: |
íà âõîäå: eax = ëîãè÷åñêèé áëîê |
íà âûõîäå: eax = ôèçè÷åñêèé ñåêòîð, dx = íîìåð ëîãè÷åñêîãî áëîêà â ñåêòîðå |
Îñóùåñòâëÿåò îáû÷íîå äåëåíèå 32-áèòíîãî ÷èñëà íà 32-áèòíîå (÷èñëî ëîãè÷åñêèõ |
áëîêîâ â ñåêòîðå, õðàíÿùååñÿ âî âíóòðåííåé ïåðåìåííîé). |
Процедура загрузки физического сектора, содержащего указанный логический блок |
Ïðîöåäóðà çàãðóçêè ôèçè÷åñêîãî ñåêòîðà, ñîäåðæàùåãî óêàçàííûé ëîãè÷åñêèé áëîê |
(load_phys_sector_for_lb_force): |
на входе: eax = логический блок; |
si - индикатор, задающий, следует ли читать данные в случае, |
если логический блок начинается с начала физического: |
si = 0 - не нужно, si ненулевой - нужно |
на выходе: |
физический сектор загружен по адресу 0000:1000 |
si указывает на данные логического блока |
CF установлен при ошибке чтения |
Преобразует предыдущей процедурой номер логического блока в номер физического |
сектора и номер логического блока внутри сектора; если последняя |
величина нулевая и никаких действий в этом случае не запрошено (si=0), |
то ничего и не делает; иначе устанавливает si в соответствии с ней |
и читает сектор. |
íà âõîäå: eax = ëîãè÷åñêèé áëîê; |
si - èíäèêàòîð, çàäàþùèé, ñëåäóåò ëè ÷èòàòü äàííûå â ñëó÷àå, |
åñëè ëîãè÷åñêèé áëîê íà÷èíàåòñÿ ñ íà÷àëà ôèçè÷åñêîãî: |
si = 0 - íå íóæíî, si íåíóëåâîé - íóæíî |
íà âûõîäå: |
ôèçè÷åñêèé ñåêòîð çàãðóæåí ïî àäðåñó 0000:1000 |
si óêàçûâàåò íà äàííûå ëîãè÷åñêîãî áëîêà |
CF óñòàíîâëåí ïðè îøèáêå ÷òåíèÿ |
Ïðåîáðàçóåò ïðåäûäóùåé ïðîöåäóðîé íîìåð ëîãè÷åñêîãî áëîêà â íîìåð ôèçè÷åñêîãî |
ñåêòîðà è íîìåð ëîãè÷åñêîãî áëîêà âíóòðè ñåêòîðà; åñëè ïîñëåäíÿÿ |
âåëè÷èíà íóëåâàÿ è íèêàêèõ äåéñòâèé â ýòîì ñëó÷àå íå çàïðîøåíî (si=0), |
òî íè÷åãî è íå äåëàåò; èíà÷å óñòàíàâëèâàåò si â ñîîòâåòñòâèè ñ íåé |
è ÷èòàåò ñåêòîð. |
Процедуры чтения нужного числа байт из непрерывной цепочки логических блоков |
(read_many_bytes и read_many_bytes.with_first): |
на входе: |
eax = логический блок |
esi = число байт для чтения |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
cur_limit = размер буфера (не меньше esi) |
на выходе: |
es:bx указывает на конец буфера, в который были прочитаны данные |
если произошла ошибка чтения, флаг CF установлен |
cur_limit соответствующим образом уменьшен |
Отличие двух процедур: вторая дополнительно принимает во внимание переменную |
[first_byte], начиная чтение первого блока со смещения [first_byte]; |
соответственно, первая читает блок с начала, обнуляя [first_byte] |
при входе. |
1. Отдельно считывает первый физический сектор во временную область 0000:1000, |
если первый логический блок начинается не с начала сектора. При |
ошибке чтения выходит из процедуры. |
2. Пересылает нужную часть данных (возможно, 0 байт), прочитанных в п.1, |
в буфер. Нормализует указатель на буфер. |
3. Если все необходимые данные уже прочитаны, выходит из процедуры. |
4. Дальнейшие данные находятся в нескольких физических секторах, при этом, |
возможно, последний сектор считывать нужно не целиком. |
5. Если в буфере есть место для считывания всех секторов, то сразу читаются |
все сектора, после чего указатель на буфер нужным образом уменьшается. |
6. Если же нет, то считываются все сектора, кроме последнего, после чего |
последний сектор считывается отдельно во временную область, и уже |
оттуда нужная часть данных копируется в буфер. |
Ïðîöåäóðû ÷òåíèÿ íóæíîãî ÷èñëà áàéò èç íåïðåðûâíîé öåïî÷êè ëîãè÷åñêèõ áëîêîâ |
(read_many_bytes è read_many_bytes.with_first): |
íà âõîäå: |
eax = ëîãè÷åñêèé áëîê |
esi = ÷èñëî áàéò äëÿ ÷òåíèÿ |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
cur_limit = ðàçìåð áóôåðà (íå ìåíüøå esi) |
íà âûõîäå: |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí |
cur_limit ñîîòâåòñòâóþùèì îáðàçîì óìåíüøåí |
Îòëè÷èå äâóõ ïðîöåäóð: âòîðàÿ äîïîëíèòåëüíî ïðèíèìàåò âî âíèìàíèå ïåðåìåííóþ |
[first_byte], íà÷èíàÿ ÷òåíèå ïåðâîãî áëîêà ñî ñìåùåíèÿ [first_byte]; |
ñîîòâåòñòâåííî, ïåðâàÿ ÷èòàåò áëîê ñ íà÷àëà, îáíóëÿÿ [first_byte] |
ïðè âõîäå. |
1. Îòäåëüíî ñ÷èòûâàåò ïåðâûé ôèçè÷åñêèé ñåêòîð âî âðåìåííóþ îáëàñòü 0000:1000, |
åñëè ïåðâûé ëîãè÷åñêèé áëîê íà÷èíàåòñÿ íå ñ íà÷àëà ñåêòîðà. Ïðè |
îøèáêå ÷òåíèÿ âûõîäèò èç ïðîöåäóðû. |
2. Ïåðåñûëàåò íóæíóþ ÷àñòü äàííûõ (âîçìîæíî, 0 áàéò), ïðî÷èòàííûõ â ï.1, |
â áóôåð. Íîðìàëèçóåò óêàçàòåëü íà áóôåð. |
3. Åñëè âñå íåîáõîäèìûå äàííûå óæå ïðî÷èòàíû, âûõîäèò èç ïðîöåäóðû. |
4. Äàëüíåéøèå äàííûå íàõîäÿòñÿ â íåñêîëüêèõ ôèçè÷åñêèõ ñåêòîðàõ, ïðè ýòîì, |
âîçìîæíî, ïîñëåäíèé ñåêòîð ñ÷èòûâàòü íóæíî íå öåëèêîì. |
5. Åñëè â áóôåðå åñòü ìåñòî äëÿ ñ÷èòûâàíèÿ âñåõ ñåêòîðîâ, òî ñðàçó ÷èòàþòñÿ |
âñå ñåêòîðà, ïîñëå ÷åãî óêàçàòåëü íà áóôåð íóæíûì îáðàçîì óìåíüøàåòñÿ. |
6. Åñëè æå íåò, òî ñ÷èòûâàþòñÿ âñå ñåêòîðà, êðîìå ïîñëåäíåãî, ïîñëå ÷åãî |
ïîñëåäíèé ñåêòîð ñ÷èòûâàåòñÿ îòäåëüíî âî âðåìåííóþ îáëàñòü, è óæå |
îòòóäà íóæíàÿ ÷àñòü äàííûõ êîïèðóåòñÿ â áóôåð. |
/kernel/trunk/bootloader/extended_primary_loader/fat1x/bootsect.txt |
---|
24,337 → 24,337 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Встречаются вирус и FAT. |
- Привет, ты кто? |
- Я? Вирус. |
- A я AFT, то есть TAF, то есть FTA, черт, совсем запутался... |
Âñòðå÷àþòñÿ âèðóñ è FAT. |
- Ïðèâåò, òû êòî? |
- ß? Âèðóñ. |
- A ÿ AFT, òî åñòü TAF, òî åñòü FTA, ÷åðò, ñîâñåì çàïóòàëñÿ... |
Бутсектор для FAT12/FAT16-тома на носителе с размером сектора 0x200 = 512 байт. |
Áóòñåêòîð äëÿ FAT12/FAT16-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò. |
===================================================================== |
Есть две версии в зависимости от того, поддерживает ли носитель LBA, |
выбор осуществляется установкой константы use_lba в первой строке исходника. |
Требования для работы: |
1) Сам бутсектор, первая копия FAT и все используемые файлы |
должны быть читабельны. |
2) Минимальный процессор - 80186. |
3) В системе должно быть как минимум 592K свободной базовой памяти. |
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA, |
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû |
äîëæíû áûòü ÷èòàáåëüíû. |
2) Ìèíèìàëüíûé ïðîöåññîð - 80186. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки валидны на момент написания этого файла, 15.05.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè âàëèäíû íà ìîìåíò íàïèñàíèÿ ýòîãî ôàéëà, 15.05.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Максимальное количество кластеров на FAT12-томе - 0xFF4 = 4084; каждый кластер |
занимает 12 бит в таблице FAT, так что общий размер не превосходит |
0x17EE = 6126 байт. Вся таблица помещается в памяти. |
Максимальное количество кластеров на FAT16-томе - 0xFFF4 = 65524; каждый |
кластер занимает 16 бит в таблице FAT, так что общий размер не превосходит |
0x1FFE8 = 131048 байт. Вся таблица также помещается в памяти, однако в |
этом случае несколько нецелесообразно считывать всю таблицу, поскольку |
на практике нужна только небольшая её часть. Поэтому место в памяти |
резервируется, но данные считываются только в момент, когда к ним |
действительно идёт обращение. |
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT12-òîìå - 0xFF4 = 4084; êàæäûé êëàñòåð |
çàíèìàåò 12 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò |
0x17EE = 6126 áàéò. Âñÿ òàáëèöà ïîìåùàåòñÿ â ïàìÿòè. |
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT16-òîìå - 0xFFF4 = 65524; êàæäûé |
êëàñòåð çàíèìàåò 16 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò |
0x1FFE8 = 131048 áàéò. Âñÿ òàáëèöà òàêæå ïîìåùàåòñÿ â ïàìÿòè, îäíàêî â |
ýòîì ñëó÷àå íåñêîëüêî íåöåëåñîîáðàçíî ñ÷èòûâàòü âñþ òàáëèöó, ïîñêîëüêó |
íà ïðàêòèêå íóæíà òîëüêî íåáîëüøàÿ å¸ ÷àñòü. Ïîýòîìó ìåñòî â ïàìÿòè |
ðåçåðâèðóåòñÿ, íî äàííûå ñ÷èòûâàþòñÿ òîëüêî â ìîìåíò, êîãäà ê íèì |
äåéñòâèòåëüíî èä¸ò îáðàùåíèå. |
Схема используемой памяти: |
...-7C00 стек |
7C00-7E00 код бутсектора |
7E00-8200 вспомогательный файл загрузчика (kordldr.f1x) |
8200-8300 список загруженных секторов таблицы FAT16 |
(1 = соответствующий сектор загружен) |
60000-80000 загруженная таблица FAT12 / место для таблицы FAT16 |
80000-90000 текущий кластер текущей рассматриваемой папки |
90000-92000 кэш для корневой папки |
92000-... кэш для некорневых папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 7 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
...-7C00 ñòåê |
7C00-7E00 êîä áóòñåêòîðà |
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f1x) |
8200-8300 ñïèñîê çàãðóæåííûõ ñåêòîðîâ òàáëèöû FAT16 |
(1 = ñîîòâåòñòâóþùèé ñåêòîð çàãðóæåí) |
60000-80000 çàãðóæåííàÿ òàáëèöà FAT12 / ìåñòî äëÿ òàáëèöû FAT16 |
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè |
90000-92000 êýø äëÿ êîðíåâîé ïàïêè |
92000-... êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед |
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало |
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - |
это освобождает ds и экономит на размере кода). |
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h |
прерывания 13h. Если нет, переходит на код обработки ошибок с |
сообщением об отсутствии LBA. |
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и |
записывает полученные данные поверх BPB. Если вызов завершился ошибкой, |
предполагает уже существующие данные корректными. |
3. Вычисляет некоторые параметры FAT-тома: начальный сектор корневой папки |
и начальный сектор данных. Кладёт их в стек; впоследствии они |
всегда будут лежать в стеке и адресоваться через bp. |
4. Считывает начало корневой папки по адресу 9000:0000. Число считываемых |
секторов - минимум из размера корневой папки, указанного в BPB, и 16 |
(размер кэша для корневой папки - 2000h байт = 16 секторов). |
5. Ищет в корневой папке элемент kordldr.f1x. Если не находит, или если |
он оказывается папкой, или если файл имеет нулевую длину - |
переходит на код обработки ошибок с сообщением о |
ненайденном загрузчике. |
Замечание: на этом этапе загрузки искать можно только в корневой |
папке и только имена, заданные в формате файловой системе FAT |
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны |
быть заглавными, при необходимости имя и расширение дополняются |
пробелами, разделяющей точки нет, завершающего нуля нет). |
6. Загружает первый кластер файла kordldr.f1x по адресу 0:7E00 и передаёт |
ему управление. При этом в регистрах dx:ax оказывается абсолютный |
номер первого сектора kordldr.f1x, а в cx - число считанных секторов |
(равное размеру кластера). |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä |
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî |
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] - |
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). |
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h |
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ |
ñîîáùåíèåì îá îòñóòñòâèè LBA. |
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è |
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé, |
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè. |
3. Âû÷èñëÿåò íåêîòîðûå ïàðàìåòðû FAT-òîìà: íà÷àëüíûé ñåêòîð êîðíåâîé ïàïêè |
è íà÷àëüíûé ñåêòîð äàííûõ. Êëàä¸ò èõ â ñòåê; âïîñëåäñòâèè îíè |
âñåãäà áóäóò ëåæàòü â ñòåêå è àäðåñîâàòüñÿ ÷åðåç bp. |
4. Ñ÷èòûâàåò íà÷àëî êîðíåâîé ïàïêè ïî àäðåñó 9000:0000. ×èñëî ñ÷èòûâàåìûõ |
ñåêòîðîâ - ìèíèìóì èç ðàçìåðà êîðíåâîé ïàïêè, óêàçàííîãî â BPB, è 16 |
(ðàçìåð êýøà äëÿ êîðíåâîé ïàïêè - 2000h áàéò = 16 ñåêòîðîâ). |
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f1x. Åñëè íå íàõîäèò, èëè åñëè |
îí îêàçûâàåòñÿ ïàïêîé, èëè åñëè ôàéë èìååò íóëåâóþ äëèíó - |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î |
íåíàéäåííîì çàãðóç÷èêå. |
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé |
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT |
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû |
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ |
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò). |
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f1x ïî àäðåñó 0:7E00 è ïåðåäà¸ò |
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðàõ dx:ax îêàçûâàåòñÿ àáñîëþòíûé |
íîìåð ïåðâîãî ñåêòîðà kordldr.f1x, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ |
(ðàâíîå ðàçìåðó êëàñòåðà). |
Вспомогательные процедуры бутсектора. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения секторов (read_sectors и read_sectors2): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors è read_sectors2): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
dx:ax = стартовый сектор (относительно начала логического диска |
для read_sectors, относительно начала данных для read_sectors2) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные |
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора |
в номер относительно начала логического диска, прибавляя номер сектора |
начала данных, хранящийся в стеке как [bp-8]. |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя значение соответствующего поля из BPB. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
dx:ax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà |
äëÿ read_sectors, îòíîñèòåëüíî íà÷àëà äàííûõ äëÿ read_sectors2) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà |
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà |
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-8]. |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура поиска элемента по имени в уже прочитанных данных папки |
Ïðîöåäóðà ïîèñêà ýëåìåíòà ïî èìåíè â óæå ïðî÷èòàííûõ äàííûõ ïàïêè |
(scan_for_filename): |
на входе должно быть установлено: |
ds:si = указатель на имя файла в формате FAT (11 байт, 8 на имя, |
3 на расширение, все буквы заглавные, если имя/расширение |
короче, оно дополняется до максимума пробелами) |
es = сегмент данных папки |
cx = число элементов в прочитанных данных |
на выходе: ZF определяет, нужно ли продолжать разбор данных папки |
(ZF=1, если либо найден запрошенный элемент, либо достигнут |
конец папки); CF определяет, удалось ли найти элемент с искомым именем |
(CF=1, если не удалось); если удалось, то es:di указывает на него. |
scan_for_filename считает, что данные папки размещаются начиная с es:0. |
Первой командой процедура обнуляет di. Затем просто в цикле по элементам папки |
проверяет имена. |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (11 áàéò, 8 íà èìÿ, |
3 íà ðàñøèðåíèå, âñå áóêâû çàãëàâíûå, åñëè èìÿ/ðàñøèðåíèå |
êîðî÷å, îíî äîïîëíÿåòñÿ äî ìàêñèìóìà ïðîáåëàìè) |
es = ñåãìåíò äàííûõ ïàïêè |
cx = ÷èñëî ýëåìåíòîâ â ïðî÷èòàííûõ äàííûõ |
íà âûõîäå: ZF îïðåäåëÿåò, íóæíî ëè ïðîäîëæàòü ðàçáîð äàííûõ ïàïêè |
(ZF=1, åñëè ëèáî íàéäåí çàïðîøåííûé ýëåìåíò, ëèáî äîñòèãíóò |
êîíåö ïàïêè); CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ýëåìåíò ñ èñêîìûì èìåíåì |
(CF=1, åñëè íå óäàëîñü); åñëè óäàëîñü, òî es:di óêàçûâàåò íà íåãî. |
scan_for_filename ñ÷èòàåò, ÷òî äàííûå ïàïêè ðàçìåùàþòñÿ íà÷èíàÿ ñ es:0. |
Ïåðâîé êîìàíäîé ïðîöåäóðà îáíóëÿåò di. Çàòåì ïðîñòî â öèêëå ïî ýëåìåíòàì ïàïêè |
ïðîâåðÿåò èìåíà. |
Процедура поиска элемента в корневой папке (lookup_in_root_dir): |
на входе должно быть установлено: |
Ïðîöåäóðà ïîèñêà ýëåìåíòà â êîðíåâîé ïàïêå (lookup_in_root_dir): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
ds:si = указатель на имя файла в формате FAT (см. выше) |
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то |
CF сброшен и es:di указывает на элемент папки |
Начинает с просмотра кэшированной (начальной) части корневой папки. В цикле |
сканирует элементы; если по результатам сканирования обнаруживает, |
что нужно читать папку дальше, то считывает не более 0x10000 = 64K |
байт (ограничение введено по двум причинам: во-первых, чтобы заведомо |
не вылезти за пределы используемой памяти, во-вторых, сканирование |
предполагает, что все обрабатываемые элементы располагаются в одном |
сегменте) и продолжает цикл. |
Сканирование прекращается в трёх случаях: обнаружен искомый элемент; |
кончились элементы в папке (судя по числу элементов, указанному в BPB); |
очередной элемент папки сигнализирует о конце (первый байт нулевой). |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå) |
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî |
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè |
Íà÷èíàåò ñ ïðîñìîòðà êýøèðîâàííîé (íà÷àëüíîé) ÷àñòè êîðíåâîé ïàïêè.  öèêëå |
ñêàíèðóåò ýëåìåíòû; åñëè ïî ðåçóëüòàòàì ñêàíèðîâàíèÿ îáíàðóæèâàåò, |
÷òî íóæíî ÷èòàòü ïàïêó äàëüøå, òî ñ÷èòûâàåò íå áîëåå 0x10000 = 64K |
áàéò (îãðàíè÷åíèå ââåäåíî ïî äâóì ïðè÷èíàì: âî-ïåðâûõ, ÷òîáû çàâåäîìî |
íå âûëåçòè çà ïðåäåëû èñïîëüçóåìîé ïàìÿòè, âî-âòîðûõ, ñêàíèðîâàíèå |
ïðåäïîëàãàåò, ÷òî âñå îáðàáàòûâàåìûå ýëåìåíòû ðàñïîëàãàþòñÿ â îäíîì |
ñåãìåíòå) è ïðîäîëæàåò öèêë. |
Ñêàíèðîâàíèå ïðåêðàùàåòñÿ â òð¸õ ñëó÷àÿõ: îáíàðóæåí èñêîìûé ýëåìåíò; |
êîí÷èëèñü ýëåìåíòû â ïàïêå (ñóäÿ ïî ÷èñëó ýëåìåíòîâ, óêàçàííîìó â BPB); |
î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå (ïåðâûé áàéò íóëåâîé). |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
===================================================================== |
Работа вспомогательного загрузчика kordldr.f1x: |
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. |
В зависимости от этого устанавливает смещения используемых процедур |
бутсектора. Критерий проверки: scan_for_filename должна начинаться |
с инструкции 'xor di,di' с кодом 31 FF (вообще-то эта инструкция может |
с равным успехом ассемблироваться и как 33 FF, но fasm генерирует |
именно такую форму). |
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска |
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с |
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента |
место должно быть, отсюда ограничение в 592 Kb (94000h байт). |
Замечание: этот размер не может превосходить 0A0000h байт и |
на практике оказывается немного (на 1-2 килобайта) меньшим из-за |
наличия дополнительной области данных BIOS "вверху" базовой памяти. |
3. Определяет тип файловой системы: FAT12 или FAT16. Согласно официальной |
спецификации от Microsoft (версия 1.03 спецификации датирована, |
к слову, 06 декабря 2000 года), разрядность FAT определяется |
исключительно числом кластеров: максимальное число кластеров на |
FAT12-томе равно 4094 = 0xFF4. Согласно здравому смыслу, на FAT12 |
может быть 0xFF5 кластеров, но не больше: кластеры нумеруются с 2, |
а число 0xFF7 не может быть корректным номером кластера. |
Win95/98/Me следует здравому смыслу: разграничение FAT12/16 делается |
по максимуму 0xFF5. Драйвер FAT в WinNT/2k/XP/Vista вообще поступает |
явно неверно, считая, что 0xFF6 (или меньше) кластеров означает |
FAT12-том, в результате получается, что последний кластер |
(в случае 0xFF6) неадресуем. Основной загрузчик osloader.exe |
[встроен в ntldr] для NT/2k/XP делает так же. Первичный загрузчик |
[бутсектор FAT12/16 загружает первый сектор ntldr, и разбор FAT-таблицы |
лежит на нём] в NT/2k подвержен той же ошибке. В XP её таки исправили |
в соответствии со спецификацией. Linux при определении FAT12/FAT16 |
честно следует спецификации. |
Здесь код основан всё же на спецификации. 9x мертва, а в линейке NT |
Microsoft если и будет исправлять ошибки, то согласно собственному |
описанию. |
4. Для FAT12: загружает в память первую копию таблицы FAT по адресу 6000:0000. |
Если размер, указанный в BPB, превосходит 12 секторов, |
это означает, что заявленный размер слишком большой (это не считается |
ошибкой файловой системы), и читаются только 12 секторов (таблица FAT12 |
заведомо влезает в такой объём данных). |
Для FAT16: инициализирует внутренние данные, указывая, что никакой сектор |
FAT не загружен (они будут подгружаться позднее, когда понадобятся |
и только те, которые понадобятся). |
5. Если кластер равен сектору, то бутсектор загрузил только часть файла |
kordldr.f1x, и загрузчик подгружает вторую свою часть, используя |
значения регистров на входе в kordldr.f1x. |
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не |
найден, или оказался папкой, или оказался слишком большим, то переходит |
на код обработки ошибок из бутсектора с сообщением |
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f1x: |
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà. |
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð |
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: scan_for_filename äîëæíà íà÷èíàòüñÿ |
ñ èíñòðóêöèè 'xor di,di' ñ êîäîì 31 FF (âîîáùå-òî ýòà èíñòðóêöèÿ ìîæåò |
ñ ðàâíûì óñïåõîì àññåìáëèðîâàòüñÿ è êàê 33 FF, íî fasm ãåíåðèðóåò |
èìåííî òàêóþ ôîðìó). |
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà |
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ |
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà |
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò). |
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è |
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà |
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè. |
3. Îïðåäåëÿåò òèï ôàéëîâîé ñèñòåìû: FAT12 èëè FAT16. Ñîãëàñíî îôèöèàëüíîé |
ñïåöèôèêàöèè îò Microsoft (âåðñèÿ 1.03 ñïåöèôèêàöèè äàòèðîâàíà, |
ê ñëîâó, 06 äåêàáðÿ 2000 ãîäà), ðàçðÿäíîñòü FAT îïðåäåëÿåòñÿ |
èñêëþ÷èòåëüíî ÷èñëîì êëàñòåðîâ: ìàêñèìàëüíîå ÷èñëî êëàñòåðîâ íà |
FAT12-òîìå ðàâíî 4094 = 0xFF4. Ñîãëàñíî çäðàâîìó ñìûñëó, íà FAT12 |
ìîæåò áûòü 0xFF5 êëàñòåðîâ, íî íå áîëüøå: êëàñòåðû íóìåðóþòñÿ ñ 2, |
à ÷èñëî 0xFF7 íå ìîæåò áûòü êîððåêòíûì íîìåðîì êëàñòåðà. |
Win95/98/Me ñëåäóåò çäðàâîìó ñìûñëó: ðàçãðàíè÷åíèå FAT12/16 äåëàåòñÿ |
ïî ìàêñèìóìó 0xFF5. Äðàéâåð FAT â WinNT/2k/XP/Vista âîîáùå ïîñòóïàåò |
ÿâíî íåâåðíî, ñ÷èòàÿ, ÷òî 0xFF6 (èëè ìåíüøå) êëàñòåðîâ îçíà÷àåò |
FAT12-òîì, â ðåçóëüòàòå ïîëó÷àåòñÿ, ÷òî ïîñëåäíèé êëàñòåð |
(â ñëó÷àå 0xFF6) íåàäðåñóåì. Îñíîâíîé çàãðóç÷èê osloader.exe |
[âñòðîåí â ntldr] äëÿ NT/2k/XP äåëàåò òàê æå. Ïåðâè÷íûé çàãðóç÷èê |
[áóòñåêòîð FAT12/16 çàãðóæàåò ïåðâûé ñåêòîð ntldr, è ðàçáîð FAT-òàáëèöû |
ëåæèò íà í¸ì] â NT/2k ïîäâåðæåí òîé æå îøèáêå.  XP å¸ òàêè èñïðàâèëè |
â ñîîòâåòñòâèè ñî ñïåöèôèêàöèåé. Linux ïðè îïðåäåëåíèè FAT12/FAT16 |
÷åñòíî ñëåäóåò ñïåöèôèêàöèè. |
Çäåñü êîä îñíîâàí âñ¸ æå íà ñïåöèôèêàöèè. 9x ìåðòâà, à â ëèíåéêå NT |
Microsoft åñëè è áóäåò èñïðàâëÿòü îøèáêè, òî ñîãëàñíî ñîáñòâåííîìó |
îïèñàíèþ. |
4. Äëÿ FAT12: çàãðóæàåò â ïàìÿòü ïåðâóþ êîïèþ òàáëèöû FAT ïî àäðåñó 6000:0000. |
Åñëè ðàçìåð, óêàçàííûé â BPB, ïðåâîñõîäèò 12 ñåêòîðîâ, |
ýòî îçíà÷àåò, ÷òî çàÿâëåííûé ðàçìåð ñëèøêîì áîëüøîé (ýòî íå ñ÷èòàåòñÿ |
îøèáêîé ôàéëîâîé ñèñòåìû), è ÷èòàþòñÿ òîëüêî 12 ñåêòîðîâ (òàáëèöà FAT12 |
çàâåäîìî âëåçàåò â òàêîé îáú¸ì äàííûõ). |
Äëÿ FAT16: èíèöèàëèçèðóåò âíóòðåííèå äàííûå, óêàçûâàÿ, ÷òî íèêàêîé ñåêòîð |
FAT íå çàãðóæåí (îíè áóäóò ïîäãðóæàòüñÿ ïîçäíåå, êîãäà ïîíàäîáÿòñÿ |
è òîëüêî òå, êîòîðûå ïîíàäîáÿòñÿ). |
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà |
kordldr.f1x, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ |
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f1x. |
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå |
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò |
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì |
"Fatal error: cannot load the secondary loader". |
Замечание: на этом этапе имя файла уже можно указывать вместе с путём |
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов |
по-прежнему нет. |
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. |
Это нужно, чтобы последующие обращения к коду бутсектора в случае |
ошибок чтения не выводил соответствующее сообщение с последующей |
перезагрузкой, а рапортовал об ошибке чтения, которую мог бы |
как-нибудь обработать вторичный загрузчик. |
8. Если загрузочный диск имеет идентификатор меньше 0x80, |
то устанавливает al='f' ("floppy"), ah=идентификатор диска, |
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). |
Устанавливает bx='12', если тип файловой системы - FAT12, и |
bx='16' в случае FAT16. Устанавливает si=смещение функции обратного |
вызова. Поскольку в этот момент ds=0, то ds:si образуют полный адрес. |
9. Передаёт управление по адресу 1000:0000. |
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì |
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ |
ïî-ïðåæíåìó íåò. |
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err. |
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå |
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé |
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîã áû |
êàê-íèáóäü îáðàáîòàòü âòîðè÷íûé çàãðóç÷èê. |
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80, |
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà, |
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà). |
Óñòàíàâëèâàåò bx='12', åñëè òèï ôàéëîâîé ñèñòåìû - FAT12, è |
bx='16' â ñëó÷àå FAT16. Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî |
âûçîâà. Ïîñêîëüêó â ýòîò ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ. |
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:(7C00-8), bp=7C00: пара ss:bp при работе с остальным |
кодом должна указывать на 0:7C00, а -8 берётся от того, что |
инициализирующий код бутсектора уже поместил в стек 2 двойных слова, |
и они должны сохраняться в неизменности. |
2. Разбирает переданные параметры, выясняет, какое действие запрошено, |
и вызывает нужную вспомогательную процедуру. |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:(7C00-8), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -8 áåð¸òñÿ îò òîãî, ÷òî |
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 2 äâîéíûõ ñëîâà, |
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû, âûÿñíÿåò, êàêîå äåéñòâèå çàïðîøåíî, |
è âûçûâàåò íóæíóþ âñïîìîãàòåëüíóþ ïðîöåäóðó. |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры kordldr.f1x. |
Процедура получения следующего кластера в FAT (get_next_cluster): |
1. Вспоминает разрядность FAT, вычисленную ранее. |
Для FAT12: |
2. Устанавливает ds = 0x6000 - сегмент, куда ранее была считана |
вся таблица FAT. |
3. Подсчитывает si = (кластер) + (кластер)/2 - смещение в этом сегменте |
слова, задающего следующий кластер. Загружает слово по этому адресу. |
4. Если кластер имеет нечётный номер, то соответствующий ему элемент |
располагается в старших 12 битах слова, и слово нужно сдвинуть вправо |
на 4 бита; в противном случае - в младших 12 битах, и делать ничего не |
надо. |
5. Выделяет из получившегося слова 12 бит. Сравнивает их с пределом 0xFF7: |
номера нормальных кластеров меньше, и флаг CF устанавливается; |
специальные значения EOF и BadClus сбрасывают флаг CF. |
Для FAT16: |
2. Вычисляет адрес памяти, предназначенной для соответствующего сектора данных |
в таблице FAT. |
3. Если сектор ещё не загружен, то загружает его. |
4. Вычисляет смещение данных для конкретного кластера относительно начала |
сектора. |
5. Загружает слово в ax из адреса, вычисленному на шагах 1 и 3. |
6. Сравнивает его с пределом 0xFFF7: номера нормальных кластеров меньше, и флаг |
CF устанавливается; специальные значения EOF и BadClus сбрасывают CF. |
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f1x. |
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster): |
1. Âñïîìèíàåò ðàçðÿäíîñòü FAT, âû÷èñëåííóþ ðàíåå. |
Äëÿ FAT12: |
2. Óñòàíàâëèâàåò ds = 0x6000 - ñåãìåíò, êóäà ðàíåå áûëà ñ÷èòàíà |
âñÿ òàáëèöà FAT. |
3. Ïîäñ÷èòûâàåò si = (êëàñòåð) + (êëàñòåð)/2 - ñìåùåíèå â ýòîì ñåãìåíòå |
ñëîâà, çàäàþùåãî ñëåäóþùèé êëàñòåð. Çàãðóæàåò ñëîâî ïî ýòîìó àäðåñó. |
4. Åñëè êëàñòåð èìååò íå÷¸òíûé íîìåð, òî ñîîòâåòñòâóþùèé åìó ýëåìåíò |
ðàñïîëàãàåòñÿ â ñòàðøèõ 12 áèòàõ ñëîâà, è ñëîâî íóæíî ñäâèíóòü âïðàâî |
íà 4 áèòà; â ïðîòèâíîì ñëó÷àå - â ìëàäøèõ 12 áèòàõ, è äåëàòü íè÷åãî íå |
íàäî. |
5. Âûäåëÿåò èç ïîëó÷èâøåãîñÿ ñëîâà 12 áèò. Ñðàâíèâàåò èõ ñ ïðåäåëîì 0xFF7: |
íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã CF óñòàíàâëèâàåòñÿ; |
ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò ôëàã CF. |
Äëÿ FAT16: |
2. Âû÷èñëÿåò àäðåñ ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ ñîîòâåòñòâóþùåãî ñåêòîðà äàííûõ |
â òàáëèöå FAT. |
3. Åñëè ñåêòîð åù¸ íå çàãðóæåí, òî çàãðóæàåò åãî. |
4. Âû÷èñëÿåò ñìåùåíèå äàííûõ äëÿ êîíêðåòíîãî êëàñòåðà îòíîñèòåëüíî íà÷àëà |
ñåêòîðà. |
5. Çàãðóæàåò ñëîâî â ax èç àäðåñà, âû÷èñëåííîìó íà øàãàõ 1 è 3. |
6. Ñðàâíèâàåò åãî ñ ïðåäåëîì 0xFFF7: íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã |
CF óñòàíàâëèâàåòñÿ; ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò CF. |
Процедура загрузки файла (load_file): |
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. |
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты |
разделяются символом '/') в FAT-формат 8+3. Если это невозможно |
(больше 8 символов в имени, больше 3 символов в расширении или |
больше одной точки), возвращается с ошибкой. |
3. Ищет элемент с таким именем в текущей рассматриваемой папке. Для корневой |
папки используется процедура из бутсектора. Для остальных папок: |
a) Проверяет, есть ли такая папка в кэше некорневых папок. |
(Идентификация папок осуществляется по номеру начального кластера.) |
Если такой папки ещё нет, добавляет её в кэш; если тот переполняется, |
выкидывает папку, к которой дольше всего не было обращений. (Для |
каждого элемента кэша хранится метка от 0 до (размер кэша)-1, |
определяющая его номер при сортировке по давности последнего обращения. |
При обращении к какому-то элементу его метка становится нулевой, |
а те метки, которые меньше старого значения, увеличиваются на единицу.) |
б) Просматривает в поисках запрошенного имени все элементы из кэша, |
используя процедуру из бутсектора. Если обнаруживает искомый элемент, |
переходит к шагу 4. Если обнаруживает конец папки, возвращается из |
процедуры с ошибкой. |
в) В цикле считывает папку посекторно. При этом пропускает начальные |
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый |
прочитанный сектор копирует в кэш, если там ещё остаётся место, |
и просматривает в нём все элементы. Работает, пока не случится одно из |
трёх событий: найден искомый элемент; кончились кластеры (судя по |
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце |
(первый байт нулевой). В двух последних случаях возвращается с ошибкой. |
4. Проверяет тип найденного элемента (файл/папка): последний элемент в |
запрошенном имени должен быть файлом, все промежуточные - папками. |
Если текущий компонент имени - промежуточный, продвигает текущую |
рассматриваемую папку и возвращается к пункту 2. |
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный |
при вызове буфер последовательными вызовами функции бутсектора; |
при этом если несколько кластеров файла расположены на диске |
последовательно, то их чтение объединяется в одну операцию. |
Следит за тем, чтобы не превысить указанный при вызове процедуры |
лимит числа секторов для чтения. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4. |
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû |
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî |
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè |
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé. |
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. Äëÿ êîðíåâîé |
ïàïêè èñïîëüçóåòñÿ ïðîöåäóðà èç áóòñåêòîðà. Äëÿ îñòàëüíûõ ïàïîê: |
a) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå íåêîðíåâûõ ïàïîê. |
(Èäåíòèôèêàöèÿ ïàïîê îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) |
Åñëè òàêîé ïàïêè åù¸ íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, |
âûêèäûâàåò ïàïêó, ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ |
êàæäîãî ýëåìåíòà êýøà õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, |
îïðåäåëÿþùàÿ åãî íîìåð ïðè ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. |
Ïðè îáðàùåíèè ê êàêîìó-òî ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, |
à òå ìåòêè, êîòîðûå ìåíüøå ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.) |
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà, |
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò, |
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç |
ïðîöåäóðû ñ îøèáêîé. |
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå |
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé |
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî, |
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç |
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî |
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå |
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé. |
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â |
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè. |
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ |
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2. |
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé |
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà; |
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå |
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ. |
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû |
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ. |
Процедура продолжения загрузки файла (continue_load_file): встроена |
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее |
сохранённые из load_file) и продолжает шаг 5. |
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà |
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå |
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5. |
/kernel/trunk/bootloader/extended_primary_loader/fat32/bootsect.txt |
---|
24,310 → 24,310 |
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
;***************************************************************************** |
Читай между строк - там никогда не бывает опечаток. |
×èòàé ìåæäó ñòðîê - òàì íèêîãäà íå áûâàåò îïå÷àòîê. |
Бутсектор для FAT32-тома на носителе с размером сектора 0x200 = 512 байт. |
Áóòñåêòîð äëÿ FAT32-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò. |
===================================================================== |
Есть две версии в зависимости от того, поддерживает ли носитель LBA, |
выбор осуществляется установкой константы use_lba в первой строке исходника. |
Требования для работы: |
1) Сам бутсектор, первая копия FAT и все используемые файлы |
должны быть читабельны. (Если дело происходит на носителе с разбиением на |
разделы и загрузочный код в MBR достаточно умный, то читабельности резервной |
копии бутсектора (сектор номер 6 на томе) достаточно вместо читабельности |
самого бутсектора). |
2) Минимальный процессор - 80386. |
3) В системе должно быть как минимум 584K свободной базовой памяти. |
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA, |
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà. |
Òðåáîâàíèÿ äëÿ ðàáîòû: |
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû |
äîëæíû áûòü ÷èòàáåëüíû. (Åñëè äåëî ïðîèñõîäèò íà íîñèòåëå ñ ðàçáèåíèåì íà |
ðàçäåëû è çàãðóçî÷íûé êîä â MBR äîñòàòî÷íî óìíûé, òî ÷èòàáåëüíîñòè ðåçåðâíîé |
êîïèè áóòñåêòîðà (ñåêòîð íîìåð 6 íà òîìå) äîñòàòî÷íî âìåñòî ÷èòàáåëüíîñòè |
ñàìîãî áóòñåêòîðà). |
2) Ìèíèìàëüíûé ïðîöåññîð - 80386. |
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 584K ñâîáîäíîé áàçîâîé ïàìÿòè. |
===================================================================== |
Документация в тему (ссылки проверялись на валидность 15.05.2008): |
официальная спецификация FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
в формате PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
русский перевод: http://wasm.ru/docs/11/fatgen103-rus.zip |
официальная спецификация расширения EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
то же, версия 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
описание функций BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
официальная спецификация Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 15.05.2008): |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx |
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf |
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf |
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf |
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html |
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf |
===================================================================== |
Схема используемой памяти: |
...-7C00 стек |
7C00-7E00 код бутсектора |
7E00-8200 вспомогательный файл загрузчика (kordldr.f32) |
8400-8C00 информация о кэше для таблицы FAT: 100h входов по 8 |
байт: 4 байта (две ссылки - вперёд и назад) для |
организации L2-списка всех прочитанных секторов в |
порядке возрастания последнего времени использования |
+ 4 байта для номера сектора; при переполнении кэша |
выкидывается элемент из головы списка, то есть тот, |
к которому дольше всех не было обращений |
60000-80000 кэш для таблицы FAT (100h секторов) |
80000-90000 текущий кластер текущей рассматриваемой папки |
90000-... кэш для содержимого папок (каждой папке отводится |
2000h байт = 100h входов, одновременно в кэше |
может находиться не более 8 папок; |
точный размер определяется размером доступной |
физической памяти - как правило, непосредственно |
перед A0000 размещается EBDA, Extended BIOS Data Area) |
Ñõåìà èñïîëüçóåìîé ïàìÿòè: |
...-7C00 ñòåê |
7C00-7E00 êîä áóòñåêòîðà |
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f32) |
8400-8C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèöû FAT: 100h âõîäîâ ïî 8 |
áàéò: 4 áàéòà (äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ |
îðãàíèçàöèè L2-ñïèñêà âñåõ ïðî÷èòàííûõ ñåêòîðîâ â |
ïîðÿäêå âîçðàñòàíèÿ ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ |
+ 4 áàéòà äëÿ íîìåðà ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà |
âûêèäûâàåòñÿ ýëåìåíò èç ãîëîâû ñïèñêà, òî åñòü òîò, |
ê êîòîðîìó äîëüøå âñåõ íå áûëî îáðàùåíèé |
60000-80000 êýø äëÿ òàáëèöû FAT (100h ñåêòîðîâ) |
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè |
90000-... êýø äëÿ ñîäåðæèìîãî ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ |
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå |
ìîæåò íàõîäèòüñÿ íå áîëåå 8 ïàïîê; |
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé |
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî |
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area) |
===================================================================== |
Основной процесс загрузки. |
Точка входа (start): получает управление от BIOS при загрузке, при этом |
dl содержит идентификатор диска, с которого идёт загрузка |
1. Настраивает стек ss:sp = 0:7C00 (стек располагается непосредственно перед |
кодом), сегмент данных ds = 0, и устанавливает ss:bp на начало |
бутсектора (в дальнейшем данные будут адресоваться через [bp+N] - |
это освобождает ds и экономит на размере кода). Сохраняет в стеке |
идентификатор загрузочного диска для последующего обращения |
через byte [bp-2]. |
2. LBA-версия: проверяет, поддерживает ли носитель LBA, вызовом функции 41h |
прерывания 13h. Если нет, переходит на код обработки ошибок с |
сообщением об отсутствии LBA. |
CHS-версия: определяет геометрию носителя вызовом функции 8 прерывания 13h и |
записывает полученные данные поверх BPB. Если вызов завершился ошибкой, |
предполагает уже существующие данные корректными. |
3. Вычисляет начало данных FAT-тома, сохраняет его в стек для последующего |
обращения через dword [bp-10]. В процессе вычисления узнаёт начало |
первой FAT, сохраняет и его в стек для последующего обращения через |
Îñíîâíîé ïðîöåññ çàãðóçêè. |
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì |
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà |
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä |
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî |
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] - |
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). Ñîõðàíÿåò â ñòåêå |
èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà äëÿ ïîñëåäóþùåãî îáðàùåíèÿ |
÷åðåç byte [bp-2]. |
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h |
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ |
ñîîáùåíèåì îá îòñóòñòâèè LBA. |
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è |
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé, |
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè. |
3. Âû÷èñëÿåò íà÷àëî äàííûõ FAT-òîìà, ñîõðàíÿåò åãî â ñòåê äëÿ ïîñëåäóþùåãî |
îáðàùåíèÿ ÷åðåç dword [bp-10].  ïðîöåññå âû÷èñëåíèÿ óçíà¸ò íà÷àëî |
ïåðâîé FAT, ñîõðàíÿåò è åãî â ñòåê äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç |
dword [bp-6]. |
4. (Заканчивая тему параметров в стеке) Помещает в стек dword-значение -1 |
для последующего обращения через dword [bp-14] - инициализация |
переменной, содержащей текущий сектор, находящийся в кэше FAT |
(-1 не является валидным значением для номера сектора FAT). |
5. Ищет в корневой папке элемент kordldr.f32. Если не находит - переходит на |
код обработки ошибок с сообщением о ненайденном загрузчике. |
Замечание: на этом этапе загрузки искать можно только в корневой |
папке и только имена, заданные в формате файловой системе FAT |
(8+3 - 8 байт на имя, 3 байта на расширение, все буквы должны |
быть заглавными, при необходимости имя и расширение дополняются |
пробелами, разделяющей точки нет, завершающего нуля нет). |
6. Загружает первый кластер файла kordldr.f32 по адресу 0:7E00 и передаёт |
ему управление. При этом в регистре eax оказывается абсолютный |
номер первого сектора kordldr.f32, а в cx - число считанных секторов |
(равное размеру кластера). |
4. (Çàêàí÷èâàÿ òåìó ïàðàìåòðîâ â ñòåêå) Ïîìåùàåò â ñòåê dword-çíà÷åíèå -1 |
äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç dword [bp-14] - èíèöèàëèçàöèÿ |
ïåðåìåííîé, ñîäåðæàùåé òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT |
(-1 íå ÿâëÿåòñÿ âàëèäíûì çíà÷åíèåì äëÿ íîìåðà ñåêòîðà FAT). |
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f32. Åñëè íå íàõîäèò - ïåðåõîäèò íà |
êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î íåíàéäåííîì çàãðóç÷èêå. |
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé |
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT |
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû |
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ |
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò). |
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f32 ïî àäðåñó 0:7E00 è ïåðåäà¸ò |
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðå eax îêàçûâàåòñÿ àáñîëþòíûé |
íîìåð ïåðâîãî ñåêòîðà kordldr.f32, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ |
(ðàâíîå ðàçìåðó êëàñòåðà). |
Вспомогательные процедуры бутсектора. |
Код обработки ошибок (err): |
1. Выводит строку с сообщением об ошибке. |
2. Выводит строку "Press any key...". |
3. Ждёт нажатия any key. |
4. Вызывает int 18h, давая шанс BIOSу попытаться загрузиться откуда-нибудь ещё. |
5. Для подстраховки зацикливается. |
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà. |
Êîä îáðàáîòêè îøèáîê (err): |
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå. |
2. Âûâîäèò ñòðîêó "Press any key...". |
3. Æä¸ò íàæàòèÿ any key. |
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸. |
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ. |
Процедура чтения кластера (read_cluster): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ êëàñòåðà (read_cluster): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = номер кластера |
на выходе: ecx = число прочитанных секторов (размер кластера), |
es:bx указывает на конец буфера, в который были прочитаны данные, |
eax и старшие слова других 32-битных регистров разрушаются |
Загружает в ecx размер кластера, перекодирует номер кластера в номер сектора |
и переходит к следующей процедуре. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = íîìåð êëàñòåðà |
íà âûõîäå: ecx = ÷èñëî ïðî÷èòàííûõ ñåêòîðîâ (ðàçìåð êëàñòåðà), |
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå, |
eax è ñòàðøèå ñëîâà äðóãèõ 32-áèòíûõ ðåãèñòðîâ ðàçðóøàþòñÿ |
Çàãðóæàåò â ecx ðàçìåð êëàñòåðà, ïåðåêîäèðóåò íîìåð êëàñòåðà â íîìåð ñåêòîðà |
è ïåðåõîäèò ê ñëåäóþùåé ïðîöåäóðå. |
Процедура чтения секторов (read_sectors32 и read_sectors2): |
на входе должно быть установлено: |
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors32 è read_sectors2): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
es:bx = указатель на начало буфера, куда будут прочитаны данные |
eax = стартовый сектор (относительно начала логического диска |
для read_sectors32, относительно начала данных |
для read_sectors2) |
cx = число секторов (должно быть больше нуля) |
на выходе: es:bx указывает на конец буфера, в который были прочитаны данные |
старшие слова 32-битных регистров могут разрушиться |
0. Если вызывается read_sectors2, она переводит указанный ей номер сектора |
в номер относительно начала логического диска, прибавляя номер сектора |
начала данных, хранящийся в стеке как [bp-10]. |
1. Переводит стартовый сектор (отсчитываемый от начала тома) в сектор на |
устройстве, прибавляя значение соответствующего поля из BPB. |
2. В цикле (шаги 3-6) читает секторы, следит за тем, чтобы на каждой итерации |
CHS-версия: все читаемые секторы были на одной дорожке. |
LBA-версия: число читаемых секторов не превосходило 7Fh (требование |
спецификации EDD BIOS). |
CHS-версия: |
3. Переводит абсолютный номер сектора в CHS-систему: сектор рассчитывается как |
единица плюс остаток от деления абсолютного номера на число секторов |
на дорожке; дорожка рассчитывается как остаток от деления частного, |
полученного на предыдущем шаге, на число дорожек, а цилиндр - как |
частное от этого же деления. Если число секторов для чтения больше, |
чем число секторов до конца дорожки, уменьшает число секторов для |
чтения. |
4. Формирует данные для вызова int 13h (ah=2 - чтение, al=число секторов, |
dh=головка, (младшие 6 бит cl)=сектор, |
(старшие 2 бита cl и весь ch)=дорожка, dl=диск, es:bx->буфер). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, выполняет сброс диска |
и повторяет попытку чтения, всего делается не более трёх попыток |
(несколько попыток нужно в случае дискеты для гарантии того, что |
мотор раскрутился). Если все три раза происходит ошибка чтения, |
переходит на код обработки ошибок с сообщением "Read error". |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
LBA-версия: |
3. Если число секторов для чтения больше 7Fh, уменьшает его (для текущей |
итерации) до 7Fh. |
4. Формирует в стеке пакет для int 13h (кладёт все нужные данные командами |
push, причём в обратном порядке: стек - структура LIFO, и данные в |
стеке хранятся в обратном порядке по отношению к тому, как их туда |
клали). |
5. Вызывает BIOS. Если BIOS рапортует об ошибке, переходит на код обработки |
ошибок с сообщением "Read error". Очищает стек от пакета, |
сформированного на предыдущем шаге. |
6. В соответствии с числом прочитанных на текущей итерации секторов |
корректирует текущий сектор, число оставшихся секторов и указатель на |
буфер (в паре es:bx корректируется es). Если всё прочитано, заканчивает |
работу, иначе возвращается на шаг 3. |
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå |
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà |
äëÿ read_sectors32, îòíîñèòåëüíî íà÷àëà äàííûõ |
äëÿ read_sectors2) |
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ) |
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå |
ñòàðøèå ñëîâà 32-áèòíûõ ðåãèñòðîâ ìîãóò ðàçðóøèòüñÿ |
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà |
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà |
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-10]. |
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà |
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB. |
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè |
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå. |
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå |
ñïåöèôèêàöèè EDD BIOS). |
CHS-âåðñèÿ: |
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê |
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ |
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî, |
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê |
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå, |
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ |
÷òåíèÿ. |
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ, |
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð, |
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà |
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê |
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî |
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ, |
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error". |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
LBA-âåðñèÿ: |
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé |
èòåðàöèè) äî 7Fh. |
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè |
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â |
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà |
êëàëè). |
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè |
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà, |
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå. |
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ |
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà |
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò |
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3. |
Процедура поиска элемента в папке (lookup_in_dir): |
на входе должно быть установлено: |
Ïðîöåäóðà ïîèñêà ýëåìåíòà â ïàïêå (lookup_in_dir): |
íà âõîäå äîëæíî áûòü óñòàíîâëåíî: |
ss:bp = 0:7C00 |
ds:si = указатель на имя файла в формате FAT (см. выше) |
eax = начальный кластер папки |
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå) |
eax = íà÷àëüíûé êëàñòåð ïàïêè |
bx = 0 |
на выходе: флаг CF определяет, удалось ли найти файл; если удалось, то |
CF сброшен и es:di указывает на элемент папки |
В цикле считывает кластеры папки и ищет запрошенный элемент в прочитанных |
данных. Для чтения кластера использует уже описанную процедуру read_clusters, |
для продвижения по цепочке кластеров - описанную далее процедуру |
get_next_clusters. Данные читаются в область памяти, начинающуюся с адреса |
8000:0000, при этом первые 2000h байт из данных папки (может быть, меньше, |
если чтение прервётся раньше) не перекрываются последующими чтениями |
(это будет использовано позднее, в системе кэширования из kordldr.f32). |
Выход осуществляется в любом из следующих случаев: найден запрошенный элемент; |
кончились элементы в папке (первый байт очередного элемента нулевой); |
кончились данные папки в соответствии с цепочкой кластеров из FAT. |
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî |
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè |
 öèêëå ñ÷èòûâàåò êëàñòåðû ïàïêè è èùåò çàïðîøåííûé ýëåìåíò â ïðî÷èòàííûõ |
äàííûõ. Äëÿ ÷òåíèÿ êëàñòåðà èñïîëüçóåò óæå îïèñàííóþ ïðîöåäóðó read_clusters, |
äëÿ ïðîäâèæåíèÿ ïî öåïî÷êå êëàñòåðîâ - îïèñàííóþ äàëåå ïðîöåäóðó |
get_next_clusters. Äàííûå ÷èòàþòñÿ â îáëàñòü ïàìÿòè, íà÷èíàþùóþñÿ ñ àäðåñà |
8000:0000, ïðè ýòîì ïåðâûå 2000h áàéò èç äàííûõ ïàïêè (ìîæåò áûòü, ìåíüøå, |
åñëè ÷òåíèå ïðåðâ¸òñÿ ðàíüøå) íå ïåðåêðûâàþòñÿ ïîñëåäóþùèìè ÷òåíèÿìè |
(ýòî áóäåò èñïîëüçîâàíî ïîçäíåå, â ñèñòåìå êýøèðîâàíèÿ èç kordldr.f32). |
Âûõîä îñóùåñòâëÿåòñÿ â ëþáîì èç ñëåäóþùèõ ñëó÷àåâ: íàéäåí çàïðîøåííûé ýëåìåíò; |
êîí÷èëèñü ýëåìåíòû â ïàïêå (ïåðâûé áàéò î÷åðåäíîãî ýëåìåíòà íóëåâîé); |
êîí÷èëèñü äàííûå ïàïêè â ñîîòâåòñòâèè ñ öåïî÷êîé êëàñòåðîâ èç FAT. |
Процедура вывода на экран ASCIIZ-строки (out_string): |
на входе: ds:si -> строка |
В цикле, пока не достигнут завершающий ноль, вызывает функцию int 10h/ah=0Eh. |
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string): |
íà âõîäå: ds:si -> ñòðîêà |
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh. |
===================================================================== |
Работа вспомогательного загрузчика kordldr.f32: |
1. Определяет, был ли он загружен CHS- или LBA-версией бутсектора. |
В зависимости от этого устанавливает смещения используемых процедур |
бутсектора. Критерий проверки: в CHS-версии по адресу err находится |
байт 0xE8 (машинная команда call), в LBA-версии по тому же адресу |
находится байт 0x14, а адрес процедуры err другой. |
2. Узнаёт размер свободной базовой памяти (т.е. свободного непрерывного куска |
адресов памяти, начинающегося с 0) вызовом int 12h. В соответствии с |
ним вычисляет число элементов в кэше папок. Хотя бы для одного элемента |
место должно быть, отсюда ограничение в 592 Kb (94000h байт). |
Замечание: этот размер не может превосходить 0A0000h байт и |
на практике оказывается немного (на 1-2 килобайта) меньшим из-за |
наличия дополнительной области данных BIOS "вверху" базовой памяти. |
3. Инициализирует кэширование папок. Бутсектор уже загрузил какую-то часть |
данных корневой папки; копирует загруженные данные в кэш и запоминает, |
что в кэше есть корневая папка. |
4. Инициализирует кэширование FAT. Бутсектор имеет дело с FAT в том и только |
том случае, когда ему приходится загружать данные корневой папки, |
не поместившиеся в один кластер. В этом случае в памяти присутствует |
один сектор FAT (если было несколько обращений - последний из |
использованных). |
5. Если кластер равен сектору, то бутсектор загрузил только часть файла |
kordldr.f32, и загрузчик подгружает вторую свою часть, используя |
значения регистров на входе в kordldr.f32. |
6. Загружает вторичный загрузчик kord/loader по адресу 1000:0000. Если файл не |
найден, или оказался папкой, или оказался слишком большим, то переходит |
на код обработки ошибок из бутсектора с сообщением |
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f32: |
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà. |
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð |
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: â CHS-âåðñèè ïî àäðåñó err íàõîäèòñÿ |
áàéò 0xE8 (ìàøèííàÿ êîìàíäà call), â LBA-âåðñèè ïî òîìó æå àäðåñó |
íàõîäèòñÿ áàéò 0x14, à àäðåñ ïðîöåäóðû err äðóãîé. |
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà |
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ |
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà |
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò). |
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è |
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà |
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè. |
3. Èíèöèàëèçèðóåò êýøèðîâàíèå ïàïîê. Áóòñåêòîð óæå çàãðóçèë êàêóþ-òî ÷àñòü |
äàííûõ êîðíåâîé ïàïêè; êîïèðóåò çàãðóæåííûå äàííûå â êýø è çàïîìèíàåò, |
÷òî â êýøå åñòü êîðíåâàÿ ïàïêà. |
4. Èíèöèàëèçèðóåò êýøèðîâàíèå FAT. Áóòñåêòîð èìååò äåëî ñ FAT â òîì è òîëüêî |
òîì ñëó÷àå, êîãäà åìó ïðèõîäèòñÿ çàãðóæàòü äàííûå êîðíåâîé ïàïêè, |
íå ïîìåñòèâøèåñÿ â îäèí êëàñòåð.  ýòîì ñëó÷àå â ïàìÿòè ïðèñóòñòâóåò |
îäèí ñåêòîð FAT (åñëè áûëî íåñêîëüêî îáðàùåíèé - ïîñëåäíèé èç |
èñïîëüçîâàííûõ). |
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà |
kordldr.f32, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ |
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f32. |
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå |
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò |
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì |
"Fatal error: cannot load the secondary loader". |
Замечание: на этом этапе имя файла уже можно указывать вместе с путём |
и в формате ASCIIZ, хотя поддержки длинных имён и неанглийских символов |
по-прежнему нет. |
7. Изменяет код обработки ошибок бутсектора на переход на метку hooked_err. |
Это нужно, чтобы последующие обращения к коду бутсектора в случае |
ошибок чтения не выводил соответствующее сообщение с последующей |
перезагрузкой, а рапортовал об ошибке чтения, которую могло бы |
как-нибудь обработать ядро. |
8. Если загрузочный диск имеет идентификатор меньше 0x80, |
то устанавливает al='f' ("floppy"), ah=идентификатор диска, |
иначе al='h' ("hard"), ah=идентификатор диска-0x80 (номер диска). |
(Говорите, дискеток с FAT32 не бывает? В чём-то Вы правы... но |
уверены ли Вы, что нет загрузочных устройств, подобных дискетам, |
но большего размера, и для которых BIOS-идентификатор меньше 0x80?) |
Устанавливает bx='32' (тип файловой системы - FAT32). |
Устанавливает si=смещение функции обратного вызова. Поскольку в этот |
момент ds=0, то ds:si образуют полный адрес. |
9. Передаёт управление по адресу 1000:0000. |
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì |
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ |
ïî-ïðåæíåìó íåò. |
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err. |
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå |
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé |
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîãëî áû |
êàê-íèáóäü îáðàáîòàòü ÿäðî. |
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80, |
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà, |
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà). |
(Ãîâîðèòå, äèñêåòîê ñ FAT32 íå áûâàåò?  ÷¸ì-òî Âû ïðàâû... íî |
óâåðåíû ëè Âû, ÷òî íåò çàãðóçî÷íûõ óñòðîéñòâ, ïîäîáíûõ äèñêåòàì, |
íî áîëüøåãî ðàçìåðà, è äëÿ êîòîðûõ BIOS-èäåíòèôèêàòîð ìåíüøå 0x80?) |
Óñòàíàâëèâàåò bx='32' (òèï ôàéëîâîé ñèñòåìû - FAT32). |
Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî âûçîâà. Ïîñêîëüêó â ýòîò |
ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ. |
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000. |
Функция обратного вызова для вторичного загрузчика: |
предоставляет возможность чтения файла. |
Вход и выход описаны в спецификации на загрузчик. |
1. Сохраняет стек вызывающего кода и устанавливает свой стек: |
ss:sp = 0:(7C00-10), bp=7C00: пара ss:bp при работе с остальным |
кодом должна указывать на 0:7C00, а -10 берётся от того, что |
инициализирующий код бутсектора уже поместил в стек 10 байт параметров, |
и они должны сохраняться в неизменности. (Значение [ebp-14], |
"текущий сектор, находящийся в кэше FAT", не используется после |
инициализации кэширования в kordldr.f32.) |
2. Разбирает переданные параметры и вызывает нужную из вспомогательных |
процедур (загрузки файла либо продолжения загрузки файла). |
3. Восстанавливает стек вызывающего кода и возвращает управление. |
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà: |
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà. |
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê. |
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê: |
ss:sp = 0:(7C00-10), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì |
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -10 áåð¸òñÿ îò òîãî, ÷òî |
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 10 áàéò ïàðàìåòðîâ, |
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. (Çíà÷åíèå [ebp-14], |
"òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT", íå èñïîëüçóåòñÿ ïîñëå |
èíèöèàëèçàöèè êýøèðîâàíèÿ â kordldr.f32.) |
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò íóæíóþ èç âñïîìîãàòåëüíûõ |
ïðîöåäóð (çàãðóçêè ôàéëà ëèáî ïðîäîëæåíèÿ çàãðóçêè ôàéëà). |
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå. |
Вспомогательные процедуры kordldr.f32. |
Процедура получения следующего кластера в FAT (get_next_cluster): |
1. Вычисляет номер сектора в FAT, в котором находится запрошенный элемент. |
(В секторе 0x200 байт, каждый вход занимает 4 байта.) |
2. Проверяет, есть ли сектор в кэше. Если есть, пропускает шаги 3 и 4. |
3. Если нет, то в кэш нужно вставить новый элемент. Если кэш ещё не заполнен, |
выделяет очередной элемент в конце кэша. Если заполнен, удаляет |
самый старый элемент (тот, к которому дольше всего не было обращений); |
для того, чтобы отслеживать порядок элементов по времени последнего |
обращения, все (выделенные) элементы кэша связаны в двусвязный список, |
в котором первым элементом является самый старый, а ссылки вперёд |
указывают на следующий по времени последнего обращения. |
4. Читает соответствующий сектор FAT с диска. |
5. Корректирует список: текущий обрабатываемый элемент удаляется с той позиции, |
где он находится, и добавляется в конец. (В случае со свежедобавленными |
в кэш элементами удаления не делается, поскольку их в списке ещё нет.) |
6. Считывает нужный вход в FAT, сбрасывая старшие 4 бита. |
7. Сравнивает прочитанное значение с пределом: если оно строго меньше |
0x0FFFFFF7, то оно задаёт номер следующего кластера в цепочке; |
в противном случае цепочка закончилась. |
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f32. |
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster): |
1. Âû÷èñëÿåò íîìåð ñåêòîðà â FAT, â êîòîðîì íàõîäèòñÿ çàïðîøåííûé ýëåìåíò. |
(Â ñåêòîðå 0x200 áàéò, êàæäûé âõîä çàíèìàåò 4 áàéòà.) |
2. Ïðîâåðÿåò, åñòü ëè ñåêòîð â êýøå. Åñëè åñòü, ïðîïóñêàåò øàãè 3 è 4. |
3. Åñëè íåò, òî â êýø íóæíî âñòàâèòü íîâûé ýëåìåíò. Åñëè êýø åù¸ íå çàïîëíåí, |
âûäåëÿåò î÷åðåäíîé ýëåìåíò â êîíöå êýøà. Åñëè çàïîëíåí, óäàëÿåò |
ñàìûé ñòàðûé ýëåìåíò (òîò, ê êîòîðîìó äîëüøå âñåãî íå áûëî îáðàùåíèé); |
äëÿ òîãî, ÷òîáû îòñëåæèâàòü ïîðÿäîê ýëåìåíòîâ ïî âðåìåíè ïîñëåäíåãî |
îáðàùåíèÿ, âñå (âûäåëåííûå) ýëåìåíòû êýøà ñâÿçàíû â äâóñâÿçíûé ñïèñîê, |
â êîòîðîì ïåðâûì ýëåìåíòîì ÿâëÿåòñÿ ñàìûé ñòàðûé, à ññûëêè âïåð¸ä |
óêàçûâàþò íà ñëåäóþùèé ïî âðåìåíè ïîñëåäíåãî îáðàùåíèÿ. |
4. ×èòàåò ñîîòâåòñòâóþùèé ñåêòîð FAT ñ äèñêà. |
5. Êîððåêòèðóåò ñïèñîê: òåêóùèé îáðàáàòûâàåìûé ýëåìåíò óäàëÿåòñÿ ñ òîé ïîçèöèè, |
ãäå îí íàõîäèòñÿ, è äîáàâëÿåòñÿ â êîíåö. ( ñëó÷àå ñî ñâåæåäîáàâëåííûìè |
â êýø ýëåìåíòàìè óäàëåíèÿ íå äåëàåòñÿ, ïîñêîëüêó èõ â ñïèñêå åù¸ íåò.) |
6. Ñ÷èòûâàåò íóæíûé âõîä â FAT, ñáðàñûâàÿ ñòàðøèå 4 áèòà. |
7. Ñðàâíèâàåò ïðî÷èòàííîå çíà÷åíèå ñ ïðåäåëîì: åñëè îíî ñòðîãî ìåíüøå |
0x0FFFFFF7, òî îíî çàäà¸ò íîìåð ñëåäóþùåãî êëàñòåðà â öåïî÷êå; |
â ïðîòèâíîì ñëó÷àå öåïî÷êà çàêîí÷èëàñü. |
Процедура загрузки файла (load_file): |
1. Текущая рассматриваемая папка - корневая. В цикле выполняет шаги 2-4. |
2. Конвертирует имя текущего рассматриваемого компонента имени (компоненты |
разделяются символом '/') в FAT-формат 8+3. Если это невозможно |
(больше 8 символов в имени, больше 3 символов в расширении или |
больше одной точки), возвращается с ошибкой. |
3. Ищет элемент с таким именем в текущей рассматриваемой папке. |
а) Проверяет, есть ли такая папка в кэше папок. (Идентификация папок |
осуществляется по номеру начального кластера.) Если такой папки ещё |
нет, добавляет её в кэш; если тот переполняется, выкидывает папку, |
к которой дольше всего не было обращений. (Для каждого элемента кэша |
хранится метка от 0 до (размер кэша)-1, определяющая его номер при |
сортировке по давности последнего обращения. При обращении к какому-то |
элементу его метка становится нулевой, а те метки, которые меньше |
старого значения, увеличиваются на единицу.) |
б) Просматривает в поисках запрошенного имени все элементы из кэша, |
используя процедуру из бутсектора. Если обнаруживает искомый элемент, |
переходит к шагу 4. Если обнаруживает конец папки, возвращается из |
процедуры с ошибкой. |
в) В цикле считывает папку посекторно. При этом пропускает начальные |
секторы, которые уже находятся в кэше и уже были просмотрены. Каждый |
прочитанный сектор копирует в кэш, если там ещё остаётся место, |
и просматривает в нём все элементы. Работает, пока не случится одно из |
трёх событий: найден искомый элемент; кончились кластеры (судя по |
цепочке кластеров в FAT); очередной элемент папки сигнализирует о конце |
(первый байт нулевой). В двух последних случаях возвращается с ошибкой. |
4. Проверяет тип найденного элемента (файл/папка): последний элемент в |
запрошенном имени должен быть файлом, все промежуточные - папками. |
Если текущий компонент имени - промежуточный, продвигает текущую |
рассматриваемую папку и возвращается к пункту 2. |
5. Проходит по цепочке кластеров в FAT и считывает все кластеры в указанный |
при вызове буфер последовательными вызовами функции бутсектора; |
при этом если несколько кластеров файла расположены на диске |
последовательно, то их чтение объединяется в одну операцию. |
Следит за тем, чтобы не превысить указанный при вызове процедуры |
лимит числа секторов для чтения. |
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file): |
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4. |
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû |
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî |
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè |
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé. |
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. |
à) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå ïàïîê. (Èäåíòèôèêàöèÿ ïàïîê |
îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) Åñëè òàêîé ïàïêè åù¸ |
íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, âûêèäûâàåò ïàïêó, |
ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ êàæäîãî ýëåìåíòà êýøà |
õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, îïðåäåëÿþùàÿ åãî íîìåð ïðè |
ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. Ïðè îáðàùåíèè ê êàêîìó-òî |
ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, à òå ìåòêè, êîòîðûå ìåíüøå |
ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.) |
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà, |
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò, |
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç |
ïðîöåäóðû ñ îøèáêîé. |
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå |
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé |
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî, |
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç |
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî |
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå |
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé. |
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â |
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè. |
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ |
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2. |
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé |
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà; |
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå |
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ. |
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû |
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ. |
Процедура продолжения загрузки файла (continue_load_file): встроена |
внутрь шага 5 load_file; загружает в регистры нужные значения (ранее |
сохранённые из load_file) и продолжает шаг 5. |
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà |
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå |
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5. |
/kernel/trunk/init.inc |
---|
310,7 → 310,7 |
test al, al |
jnz .PCI_BIOS32_not_found |
; здесь создаются дискрипторы для PCI BIOS |
; çäåñü ñîçäàþòñÿ äèñêðèïòîðû äëÿ PCI BIOS |
add ebx, OS_BASE |
dec ecx |
334,7 → 334,7 |
mov [(pci_bios_entry-OS_BASE)], edx |
; jmp .end |
.PCI_BIOS32_not_found: |
; здесь должна заполнятся pci_emu_dat |
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat |
.BIOS32_not_found: |
.end: |
ret |
/kernel/trunk/data16.inc |
---|
13,9 → 13,9 |
preboot_bootlog db 0 |
boot_drive db 0 |
bx_from_load: |
dw 'r1' ; структура для хранения параметров- откуда гашрузились, берется ниже из bx ; {SPraid}[13.03.2007] |
; a,b,c,d - винчестеры, r - рам диск |
; # диска... символ, а не байт. '1', а не 1 |
dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007] |
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê |
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1 |
align 4 |
old_ints_h: |
/kernel/trunk/readme-ext-loader.txt |
---|
1,52 → 1,52 |
При компиляции ядра можно задать - например, в lang.inc, - дополнительный |
параметр extended_primary_loader=1; он переключает ядро на альтернативный |
способ загрузки. Загрузка несовместима |
с основой версией ядра; требуется специальный первичный загрузчик, существующие |
собраны в папке bootloader/extended_primary_loader. |
Есть варианты загрузки с FAT12/FAT16/FAT32/ISO, |
есть вариант загрузчика, встраивающегося в загрузку Windows. Встраивание |
в GRUB аналогично описанному для основного способа загрузки - |
последним загрузчиком в цепочке |
при этом оказывается тот, который установлен в образе дискеты FAT12. |
Ïðè êîìïèëÿöèè ÿäðà ìîæíî çàäàòü - íàïðèìåð, â lang.inc, - äîïîëíèòåëüíûé |
ïàðàìåòð extended_primary_loader=1; îí ïåðåêëþ÷àåò ÿäðî íà àëüòåðíàòèâíûé |
ñïîñîá çàãðóçêè. Çàãðóçêà íåñîâìåñòèìà |
ñ îñíîâîé âåðñèåé ÿäðà; òðåáóåòñÿ ñïåöèàëüíûé ïåðâè÷íûé çàãðóç÷èê, ñóùåñòâóþùèå |
ñîáðàíû â ïàïêå bootloader/extended_primary_loader. |
Åñòü âàðèàíòû çàãðóçêè ñ FAT12/FAT16/FAT32/ISO, |
åñòü âàðèàíò çàãðóç÷èêà, âñòðàèâàþùåãîñÿ â çàãðóçêó Windows. Âñòðàèâàíèå |
â GRUB àíàëîãè÷íî îïèñàííîìó äëÿ îñíîâíîãî ñïîñîáà çàãðóçêè - |
ïîñëåäíèì çàãðóç÷èêîì â öåïî÷êå |
ïðè ýòîì îêàçûâàåòñÿ òîò, êîòîðûé óñòàíîâëåí â îáðàçå äèñêåòû FAT12. |
При загрузке поддерживается опрос параметров из файла config.ini, |
но не поддерживается сохранение выбранных параметров. Файл config.ini |
ищется рядом с первичным загрузчиком, как и ядро kernel.mnt; в случае |
загрузчика с дискеты эти файлы располагаются на самой дискете, |
в случае других загрузчиков - рядом с первичным загрузчиком вне образа. |
Ïðè çàãðóçêå ïîääåðæèâàåòñÿ îïðîñ ïàðàìåòðîâ èç ôàéëà config.ini, |
íî íå ïîääåðæèâàåòñÿ ñîõðàíåíèå âûáðàííûõ ïàðàìåòðîâ. Ôàéë config.ini |
èùåòñÿ ðÿäîì ñ ïåðâè÷íûì çàãðóç÷èêîì, êàê è ÿäðî kernel.mnt; â ñëó÷àå |
çàãðóç÷èêà ñ äèñêåòû ýòè ôàéëû ðàñïîëàãàþòñÿ íà ñàìîé äèñêåòå, |
â ñëó÷àå äðóãèõ çàãðóç÷èêîâ - ðÿäîì ñ ïåðâè÷íûì çàãðóç÷èêîì âíå îáðàçà. |
Если config.ini не найден, используются умолчальные значения. Если |
config.ini найден, то он разбивается на строчки, строчки должны иметь |
вид <параметр>=<значение>, перед параметром и вокруг знака равенства |
могут быть пробелы, всё, что идёт в строке после значения, игнорируется. |
Параметры чувствительны к регистру символов. |
Строки, не имеющие такого вида, а также строки, в которых параметр неизвестен, |
а также строки, в которых значение недопустимо, игнорируются. |
Åñëè config.ini íå íàéäåí, èñïîëüçóþòñÿ óìîë÷àëüíûå çíà÷åíèÿ. Åñëè |
config.ini íàéäåí, òî îí ðàçáèâàåòñÿ íà ñòðî÷êè, ñòðî÷êè äîëæíû èìåòü |
âèä <ïàðàìåòð>=<çíà÷åíèå>, ïåðåä ïàðàìåòðîì è âîêðóã çíàêà ðàâåíñòâà |
ìîãóò áûòü ïðîáåëû, âñ¸, ÷òî èä¸ò â ñòðîêå ïîñëå çíà÷åíèÿ, èãíîðèðóåòñÿ. |
Ïàðàìåòðû ÷óâñòâèòåëüíû ê ðåãèñòðó ñèìâîëîâ. |
Ñòðîêè, íå èìåþùèå òàêîãî âèäà, à òàêæå ñòðîêè, â êîòîðûõ ïàðàìåòð íåèçâåñòåí, |
à òàêæå ñòðîêè, â êîòîðûõ çíà÷åíèå íåäîïóñòèìî, èãíîðèðóþòñÿ. |
Все числа должны быть целыми неотрицательными, записанными в десятичной |
системе счисления. Булевские значения кодируются следующим образом: |
0=off=no соответствует выключенному параметру, 1=on=yes - включённому. |
Âñå ÷èñëà äîëæíû áûòü öåëûìè íåîòðèöàòåëüíûìè, çàïèñàííûìè â äåñÿòè÷íîé |
ñèñòåìå ñ÷èñëåíèÿ. Áóëåâñêèå çíà÷åíèÿ êîäèðóþòñÿ ñëåäóþùèì îáðàçîì: |
0=off=no ñîîòâåòñòâóåò âûêëþ÷åííîìó ïàðàìåòðó, 1=on=yes - âêëþ÷¸ííîìó. |
Известные параметры: |
Èçâåñòíûå ïàðàìåòðû: |
timeout=<число секунд> задаёт время ожидания в экране выбора параметров. |
Если таймаут больше 9, используется значение 9. Значение по умолчанию 5. |
timeout=<÷èñëî ñåêóíä> çàäà¸ò âðåìÿ îæèäàíèÿ â ýêðàíå âûáîðà ïàðàìåòðîâ. |
Åñëè òàéìàóò áîëüøå 9, èñïîëüçóåòñÿ çíà÷åíèå 9. Çíà÷åíèå ïî óìîë÷àíèþ 5. |
resolution=<ширина>*<высота> или <ширина>x<высота> задаёт желаемое |
разрешение графического режима. Если такого графического режима, |
устраивающего систему, не найдено, параметр игнорируется. По умолчанию |
пробуются последовательно разрешения 1024*768, 800*600, 640*480. |
resolution=<øèðèíà>*<âûñîòà> èëè <øèðèíà>x<âûñîòà> çàäà¸ò æåëàåìîå |
ðàçðåøåíèå ãðàôè÷åñêîãî ðåæèìà. Åñëè òàêîãî ãðàôè÷åñêîãî ðåæèìà, |
óñòðàèâàþùåãî ñèñòåìó, íå íàéäåíî, ïàðàìåòð èãíîðèðóåòñÿ. Ïî óìîë÷àíèþ |
ïðîáóþòñÿ ïîñëåäîâàòåëüíî ðàçðåøåíèÿ 1024*768, 800*600, 640*480. |
vbemode=<номер видеорежима VBE> задаёт желаемый графический режим. |
Если такой режим не существует или не устраивает систему, параметр |
игнорируется. Параметр более приоритетен, чем resolution. Умолчального |
значения нет. |
vbemode=<íîìåð âèäåîðåæèìà VBE> çàäà¸ò æåëàåìûé ãðàôè÷åñêèé ðåæèì. |
Åñëè òàêîé ðåæèì íå ñóùåñòâóåò èëè íå óñòðàèâàåò ñèñòåìó, ïàðàìåòð |
èãíîðèðóåòñÿ. Ïàðàìåòð áîëåå ïðèîðèòåòåí, ÷åì resolution. Óìîë÷àëüíîãî |
çíà÷åíèÿ íåò. |
vrr=<включить VRR> - булевский параметр. Умолчальное значение 0. |
vrr=<âêëþ÷èòü VRR> - áóëåâñêèé ïàðàìåòð. Óìîë÷àëüíîå çíà÷åíèå 0. |
biosdisks=<включить доступ к дискам через BIOS> - булевский параметр. |
Умолчальное значение 1. |
biosdisks=<âêëþ÷èòü äîñòóï ê äèñêàì ÷åðåç BIOS> - áóëåâñêèé ïàðàìåòð. |
Óìîë÷àëüíîå çíà÷åíèå 1. |
imgfrom=<источник рамдиска>. 1 - грузить дискету, 2 - грузить файл |
kolibri.img, находящийся рядом с первичным загрузчиком. Умолчальное |
значение 1 при загрузке с дискеты и 2 в противном случае. |
imgfrom=<èñòî÷íèê ðàìäèñêà>. 1 - ãðóçèòü äèñêåòó, 2 - ãðóçèòü ôàéë |
kolibri.img, íàõîäÿùèéñÿ ðÿäîì ñ ïåðâè÷íûì çàãðóç÷èêîì. Óìîë÷àëüíîå |
çíà÷åíèå 1 ïðè çàãðóçêå ñ äèñêåòû è 2 â ïðîòèâíîì ñëó÷àå. |