From 32b4fcb9ab1aa04aae1bd8a2ef06e109fc9a6509 Mon Sep 17 00:00:00 2001 From: CleverMouse Date: Mon, 27 May 2013 22:16:00 +0000 Subject: [PATCH] recode all kernel sources to UTF-8; binary still uses single-byte encoding and isn't changed at all git-svn-id: svn://kolibrios.org@3539 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/blkdev/cd_drv.inc | 492 +- kernel/trunk/blkdev/disk_cache.inc | 2 +- kernel/trunk/blkdev/fdc.inc | 6 +- kernel/trunk/blkdev/flp_drv.inc | 310 +- kernel/trunk/blkdev/hd_drv.inc | 14 +- kernel/trunk/blkdev/ide_cache.inc | 2 +- kernel/trunk/blkdev/rd.inc | 18 +- kernel/trunk/boot/bootcode.inc | 12 +- kernel/trunk/boot/booten.inc | 10 +- kernel/trunk/boot/bootet.inc | 108 +- kernel/trunk/boot/bootge.inc | 10 +- kernel/trunk/boot/bootru.inc | 108 +- kernel/trunk/boot/bootsp.inc | 110 +- kernel/trunk/boot/bootvesa.inc | 4 +- kernel/trunk/boot/et.inc | 2 +- kernel/trunk/boot/ru.inc | 6 +- .../after_win/kordldr.win.txt | 688 +- .../extended_primary_loader/cdfs/bootsect.txt | 726 +- .../fat1x/bootsect.txt | 608 +- .../fat32/bootsect.txt | 552 +- kernel/trunk/bootloader/readme | 24 +- kernel/trunk/const.inc | 2 +- kernel/trunk/core/conf_lib-sp.inc | 18 +- kernel/trunk/core/conf_lib.inc | 4 +- kernel/trunk/core/memory.inc | 42 +- kernel/trunk/core/sched.inc | 4 +- kernel/trunk/core/sys32-sp.inc | 6 +- kernel/trunk/core/sys32.inc | 43 +- kernel/trunk/core/syscall.inc | 4 +- kernel/trunk/core/v86.inc | 6 +- kernel/trunk/data16.inc | 6 +- kernel/trunk/data32.inc | 72 +- kernel/trunk/data32sp.inc | 70 +- kernel/trunk/detect/dev_fd.inc | 6 +- kernel/trunk/detect/dev_hdcd.inc | 262 +- kernel/trunk/detect/sear_par.inc | 6 +- kernel/trunk/docs/loader_doc.txt | 46 +- kernel/trunk/docs/sysfuncr.txt | 7816 ++++++++--------- kernel/trunk/docs/sysfuncs.txt | 10 +- kernel/trunk/drivers/apm.asm | 2 +- kernel/trunk/drivers/com_mouse.asm | 76 +- kernel/trunk/drivers/emu10k1x.asm | 2 +- kernel/trunk/drivers/ensoniq.asm | 2 +- kernel/trunk/drivers/fm801.asm | 2 +- kernel/trunk/drivers/intelac97.asm | 2 +- kernel/trunk/drivers/sis.asm | 2 +- kernel/trunk/drivers/vt823x.asm | 2 +- kernel/trunk/fs/fat12.inc | 36 +- kernel/trunk/fs/fs.inc | 18 +- kernel/trunk/fs/iso9660.inc | 146 +- kernel/trunk/fs/part_set.inc | 12 +- kernel/trunk/gui/event.inc | 144 +- kernel/trunk/init.inc | 4 +- kernel/trunk/kernel.asm | 9 +- kernel/trunk/kernelsp.inc | 6 +- kernel/trunk/readme-ext-loader.txt | 84 +- .../sec_loader/trunk/boot/PrimaryLoader.txt | 116 +- .../trunk/boot/after_win/kordldr.win.txt | 688 +- .../sec_loader/trunk/boot/cdfs/bootsect.txt | 726 +- .../sec_loader/trunk/boot/fat1x/bootsect.txt | 608 +- .../sec_loader/trunk/boot/fat32/bootsect.txt | 552 +- kernel/trunk/sec_loader/trunk/debug_msg.inc | 2 +- kernel/trunk/sec_loader/trunk/loader.asm | 54 +- kernel/trunk/sec_loader/trunk/loader.lst | 2 +- kernel/trunk/sec_loader/trunk/parse.inc | 28 +- kernel/trunk/sec_loader/trunk/parse_any.inc | 88 +- kernel/trunk/sec_loader/trunk/parse_dat.inc | 2 +- .../trunk/sec_loader/trunk/parse_def_sect.inc | 652 +- kernel/trunk/sec_loader/trunk/parse_err.inc | 4 +- .../trunk/sec_loader/trunk/parse_loader.inc | 68 +- kernel/trunk/sec_loader/trunk/sl_equ.inc | 58 +- kernel/trunk/sec_loader/trunk/sl_proc.inc | 82 +- kernel/trunk/sec_loader/trunk/startos.ini | 12 +- kernel/trunk/video/vga.inc | 4 +- 74 files changed, 8258 insertions(+), 8272 deletions(-) diff --git a/kernel/trunk/blkdev/cd_drv.inc b/kernel/trunk/blkdev/cd_drv.inc index b1359e07e4..e3dba90a7e 100644 --- a/kernel/trunk/blkdev/cd_drv.inc +++ b/kernel/trunk/blkdev/cd_drv.inc @@ -9,21 +9,21 @@ $Revision$ ;********************************************************** -; D (ATAPI) +; Непосредственная работа с устройством СD (ATAPI) ;********************************************************** -; -; , Mario79, +; Автор части исходного текста Кулаков Владимир Геннадьевич +; Адаптация, доработка и разработка Mario79, -; +; Максимальное количество повторений операции чтения MaxRetr equ 10 -; -; ( ) +; Предельное время ожидания готовности к приему команды +; (в тиках) BSYWaitTime equ 1000 ;2 NoTickWaitTime equ 0xfffff CDBlockSize equ 2048 ;******************************************** -;* * -;* * +;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * +;* Многократное повторение чтения при сбоях * ;******************************************** ReadCDWRetr: ;----------------------------------------------------------- @@ -85,34 +85,34 @@ ReadCDWRetr: 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 @@ ReadCDWRetr_1: 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 @@ ReadCDWRetr_1: jz @@NextRetr jmp .wait @@: -; 2,5 +; Задержка на 2,5 секунды ; mov EAX,[timer_ticks] ; add EAX,50 ;250 ;@@Wait: @@ -161,66 +161,66 @@ ReadCDWRetr_1: 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 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 ; 17h + add DX, 7 ;порт 1х7h mov ecx, NoTickWaitTime @@WaitDevice0: cmp [timer_ticks_enable], 0 @@ -231,21 +231,21 @@ SendPacketDatCommand: 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 @@ SendPacketDatCommand: mov AX, [PacketCommand+10] out DX, AX sti -; +; Ожидание готовности данных mov DX, [ATABasePortAddr] - add DX, 7 ; 17h + add DX, 7 ;порт 1х7h mov ecx, NoTickWaitTime @@WaitDevice1: cmp [timer_ticks_enable], 0 @@ -274,40 +274,40 @@ SendPacketDatCommand: 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 @@ SendPacketDatCommand: ;*********************************************** -;* 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 @@ SendPacketNoDatCommand: 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 ; 17h + 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 @@ SendPacketNoDatCommand: ; sti cmp [ignore_CD_eject_wait], 1 je @@clear_DEC -; +; Ожидание подтверждения приема команды mov DX, [ATABasePortAddr] - add DX, 7 ; 17h + 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 @@ SendPacketNoDatCommand: 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 @@ SendCommandToHDD_1: 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 @@ SendCommandToHDD_1: 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 @@ SendCommandToHDD_1: @@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,37 +597,37 @@ WaitUnitReady: 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 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 @@ prevent_medium_removal: 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 @@ allow_medium_removal: 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 @@ ATAPI_IDE3_lock db 0 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 diff --git a/kernel/trunk/blkdev/disk_cache.inc b/kernel/trunk/blkdev/disk_cache.inc index c8766f8927..ea7702d22c 100644 --- a/kernel/trunk/blkdev/disk_cache.inc +++ b/kernel/trunk/blkdev/disk_cache.inc @@ -397,7 +397,7 @@ saved_esi_pos = 16+12 ; size of local variables + size of registers before esi 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 diff --git a/kernel/trunk/blkdev/fdc.inc b/kernel/trunk/blkdev/fdc.inc index 8b087c81a5..1e3476f281 100644 --- a/kernel/trunk/blkdev/fdc.inc +++ b/kernel/trunk/blkdev/fdc.inc @@ -37,9 +37,9 @@ save_image: 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: diff --git a/kernel/trunk/blkdev/flp_drv.inc b/kernel/trunk/blkdev/flp_drv.inc index bfb69972f6..e07b7742ca 100644 --- a/kernel/trunk/blkdev/flp_drv.inc +++ b/kernel/trunk/blkdev/flp_drv.inc @@ -9,12 +9,12 @@ $Revision$ ;********************************************************** -; +; Непосредственная работа с контроллером гибкого диска ;********************************************************** -; . -; 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 @@ give_back_application_data_1: 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 @@ take_data_from_application_1: 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_C DB ? 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 @@ Init_FDC_DMA: 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 @@ FDCDataOutput: 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,45 +182,45 @@ FDCDataInput: ret ;********************************************* -;* * +;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * ;********************************************* FDCInterrupt: -; +; Установить флаг прерывани mov [FDD_IntFlag], 1 ret ;****************************************** -;* * -;* * +;* УСТАНОВИТЬ НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЙ * +;* НГМД * ;****************************************** SetUserInterrupts: mov [fdc_irq_func], FDCInterrupt 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 @@ WaitFDCInterrupt: ret ;********************************* -;* "A:" * +;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * ;********************************* FDDMotorON: pusha @@ -237,11 +237,11 @@ FDDMotorON: 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 @@ FDDMotorON_B: 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 @@ fdd_motor_on: ret ;***************************************** -;* * +;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * ;***************************************** save_timer_fdd_motor: mov eax, [timer_ticks] @@ -282,7 +282,7 @@ save_timer_fdd_motor: ret ;***************************************** -;* * +;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * ;***************************************** proc check_fdd_motor_status_has_work? cmp [flp_status], 0 @@ -318,7 +318,7 @@ end_check_fdd_motor_status: ret ;********************************** -;* * +;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * ;********************************** FDDMotorOFF: push AX @@ -332,35 +332,35 @@ FDDMotorOFF_1: 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,54 +371,54 @@ RecalibrateFDD: 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 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 @@ SeekTrack: 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 @@ ReadSector: 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 @@ ReadSector: 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 @@ ReadSectWithRetr: 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 @@ ReadSectWithRetr: 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 @@ WriteSector: 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 @@ WriteSector: 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 @@ WriteSectWithRetr: 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 @@ WriteSectWithRetr: ret ;********************************************* -;* * +;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * ;********************************************* GetStatusInfo: push AX diff --git a/kernel/trunk/blkdev/hd_drv.inc b/kernel/trunk/blkdev/hd_drv.inc index 5a906b46d1..f472966b7e 100644 --- a/kernel/trunk/blkdev/hd_drv.inc +++ b/kernel/trunk/blkdev/hd_drv.inc @@ -109,28 +109,28 @@ hd_read_pio: 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 diff --git a/kernel/trunk/blkdev/ide_cache.inc b/kernel/trunk/blkdev/ide_cache.inc index 6bd21aa377..0a4f920a30 100644 --- a/kernel/trunk/blkdev/ide_cache.inc +++ b/kernel/trunk/blkdev/ide_cache.inc @@ -52,7 +52,7 @@ write_cache_more: cmp [dma_hdd], 1 jnz .nodma @@: -; ꥤ塞 楯窨 ᫥⥫ ᥪ஢ 饭 +; Объединяем запись цепочки последовательных секторов в одно обращение к диску cmp ecx, 1 jz .nonext cmp dword [esi+8+4], 2 diff --git a/kernel/trunk/blkdev/rd.inc b/kernel/trunk/blkdev/rd.inc index 5e565174d3..e67f65757e 100644 --- a/kernel/trunk/blkdev/rd.inc +++ b/kernel/trunk/blkdev/rd.inc @@ -346,10 +346,10 @@ uni2ansi_str: mov al, '_' jmp .doit .yo1: - mov al, '' + mov al, 0xF0 ; 'Ё' jmp .doit .yo2: - mov al, '' + mov al, 0xF1 ; 'ё' jmp .doit .rus1: ; 0x410-0x43F -> 0x80-0xAF @@ -389,9 +389,9 @@ ansi2uni_char: ; 0xF0 -> 0x401 ; 0xF1 -> 0x451 @@: - cmp al, '' + cmp al, 0xF0 ; 'Ё' jz .yo1 - cmp al, '' + cmp al, 0xF1 ; 'ё' jz .yo2 .unk: mov al, '_' ; ah=0 @@ -411,16 +411,16 @@ char_toupper: jb .ret cmp al, 'z' jbe .az - cmp al, '' + cmp al, 0xF1 ; 'ё' jz .yo1 - cmp al, '' + cmp al, 0xA0 ; 'а' jb .ret - cmp al, '' + cmp al, 0xE0 ; 'р' jb .rus1 - cmp al, '' + cmp al, 0xEF ; 'я' ja .ret ; 0xE0-0xEF -> 0x90-0x9F - sub al, ''-'' + sub al, 0xE0-0x90 .ret: ret .rus1: diff --git a/kernel/trunk/boot/bootcode.inc b/kernel/trunk/boot/bootcode.inc index d7eecba2b5..c4a2ac9ca3 100644 --- a/kernel/trunk/boot/bootcode.inc +++ b/kernel/trunk/boot/bootcode.inc @@ -428,7 +428,7 @@ sayerr: .nopci: ; \end{Mario79} - mov al, 0xf6 ; , + mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование out 0x60, al xor cx, cx wait_loop: ; variant 2 @@ -847,21 +847,21 @@ end if 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, '' + mov cl, 0xE3 ; 'у' in cp866 jz @f - mov cl, '' + mov cl, 0xEB ; 'ы' in cp866 @@: mov [time_str+9], cl else if lang eq et cmp al, 1 ja @f - mov [time_str+9], ' ' - mov [time_str+10], ' ' + mov byte [time_str+9], ' ' + mov byte [time_str+10], ' ' @@: else if lang eq sp ; esperar 5/4/3/2 segundos, 1 segundo diff --git a/kernel/trunk/boot/booten.inc b/kernel/trunk/boot/booten.inc index c3d203a305..bf7c8611d9 100644 --- a/kernel/trunk/boot/booten.inc +++ b/kernel/trunk/boot/booten.inc @@ -89,11 +89,11 @@ save_quest db "Remember current settings? [y/n]: ",0 loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 end if -_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 +_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 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 diff --git a/kernel/trunk/boot/bootet.inc b/kernel/trunk/boot/bootet.inc index 4968fb60a9..ff2119bbf6 100644 --- a/kernel/trunk/boot/bootet.inc +++ b/kernel/trunk/boot/bootet.inc @@ -15,87 +15,87 @@ $Revision$ d80x25_bottom: - db 186,' KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI' - db 'ITA ',186 - db 186,' Naha faili COPYING detailid ' - db ' ',186 + latin1 '║ KolibriOS pohineb MenuetOS ja kaasas IGASUGUSE GARANTI' + latin1 'ITA ║' + latin1 '║ Naha faili COPYING detailid ' + latin1 ' ║' line_full_bottom d80x25_bottom_num = 3 -msg_apm db " APM x.x ", 0 -novesa db "Ekraan: EGA/CGA",13,10,0 -s_vesa db "Vesa versioon: " +msg_apm: latin1 " APM x.x ", 0 +novesa: latin1 "Ekraan: EGA/CGA",13,10,0 +s_vesa: latin1 "Vesa versioon: " .ver db "?.?",13,10,0 -gr_mode db "Vali videomode: ",13,10,0 +gr_mode: latin1 "Vali videomode: ",13,10,0 -ask_bd db "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0 +ask_bd: latin1 "Lisa kettad nahtavaks BIOS reziim V86? [1-jah, 2-no]: ",0 if defined extended_primary_loader -bdev db "Paigalda mluketas [1-diskett; 2-kolibri.img]: ",0 +bdev: latin1 "Paigalda mäluketas [1-diskett; 2-kolibri.img]: ",0 else -bdev db "Paigalda mluketas [1-diskett; 2-C:\kolibri.img (FAT32);" - db 13,10,186," " - db "3-kasuta eellaaditud mluketast kerneli restardist;" - db 13,10,186," " - db "4-loo thi pilt]: ",0 +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 end if -prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 +prnotfnd: latin1 "Fataalne - Videoreziimi ei leitud.",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 ebannestus.",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 +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 boot_dev db 0 ; 0=floppy, 1=hd -start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jtkamiseks",13,10,0 -time_msg db " vi oota " -time_str db " 5 sekundit" - db " automaatseks jtkamiseks",13,10,0 -current_cfg_msg db "Praegused seaded:",13,10,0 -curvideo_msg db " [a] Videoreziim: ",0 +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 -mode0 db "320x200, EGA/CGA 256 vrvi",0 -mode9 db "640x480, VGA 16 vrvi",0 +mode0: latin1 "320x200, EGA/CGA 256 värvi",0 +mode9: latin1 "640x480, VGA 16 värvi",0 -usebd_msg db " [b] Lisa kettad nahtavaks BIOS:",0 -on_msg db " sees",13,10,0 -off_msg db " vljas",13,10,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 -preboot_device_msg db " [c] Disketi kujutis: ",0 +preboot_device_msg:latin1 " [c] Disketi kujutis: ",0 if defined extended_primary_loader preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 db "reaalne diskett",13,10,0 -pdm2 db "kolibri.img",13,10,0 +pdm1: latin1 "reaalne diskett",13,10,0 +pdm2: latin1 "kolibri.img",13,10,0 else preboot_device_msgs dw 0,pdm1,pdm2,pdm3 -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 thi pilt",13,10,0 +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 end if -loading_msg db "Laadin KolibriOS...",0 +loading_msg:latin1 "Laadin KolibriOS...",0 if ~ defined extended_primary_loader -save_quest db "Jta meelde praegused seaded? [y/n]: ",0 -loader_block_error db "Alglaaduri andmed vigased, ei saa jtkata. Peatatud.",0 +save_quest:latin1 "Jäta meelde praegused seaded? [y/n]: ",0 +loader_block_error:latin1 "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 end if -_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 +_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 -remark1 db "Vaikimisi maaratud vaartused on valitud mugavuse enamikes, kuid mitte koik.",0 -remark2 db "Kui susteem ei kaivitu, proovige lulitada kirje [b].",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 remarks dw remark1, remark2 num_remarks = 2 diff --git a/kernel/trunk/boot/bootge.inc b/kernel/trunk/boot/bootge.inc index 2c6ac20f0a..db2ed3154a 100644 --- a/kernel/trunk/boot/bootge.inc +++ b/kernel/trunk/boot/bootge.inc @@ -89,11 +89,11 @@ save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 end if -_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 +_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 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 diff --git a/kernel/trunk/boot/bootru.inc b/kernel/trunk/boot/bootru.inc index 2298824833..fa7082caba 100644 --- a/kernel/trunk/boot/bootru.inc +++ b/kernel/trunk/boot/bootru.inc @@ -15,87 +15,83 @@ $Revision$ d80x25_bottom: - db 186,' KolibriOS ᭮ MenuetOS ' - db ' A. ',186 - db 186,' ஡ ᬮ 䠩 COPYING.TXT ' - db ' ',186 + cp866 '║ KolibriOS основана на MenuetOS и НЕ ПРЕДОСТАВЛЯЕТ НИКАКИХ ГАРAНТИЙ. ║' + cp866 '║ Подробнее смотрите в файле COPYING.TXT ║' line_full_bottom d80x25_bottom_num = 3 -msg_apm db " APM x.x ", 0 -novesa db ": EGA/CGA",13,10,0 -s_vesa db " VESA: " - .ver db "?.?",13,10,0 +msg_apm: cp866 " APM x.x ", 0 +novesa: cp866 "Видеокарта: EGA/CGA",13,10,0 +s_vesa: cp866 "Версия VESA: " + .ver db "?.?",13,10,0 -gr_mode db "롥 ०: ",13,10,0 +gr_mode: cp866 "Выберите видеорежим: ",13,10,0 -ask_bd db " ᪨, १ BIOS ० V86? [1-, 2-]: ",0 +ask_bd: cp866 "Добавить диски, видимые через BIOS в режиме V86? [1-да, 2-нет]: ",0 if defined extended_primary_loader -bdev db "㧨 ࠧ [1-᪥; 2-kolibri.img 㧪]: ",0 +bdev: cp866 "Загрузить образ из [1-дискета; 2-kolibri.img из папки загрузки]: ",0 else -bdev db "㧨 ࠧ [1-᪥; 2-C:\kolibri.img (FAT32);" - db 13,10,186," " - db "3-ᯮ짮 㦥 㦥 ࠧ;" - db 13,10,186," " - db "4-ᮧ ࠧ]: ",0 +bdev: cp866 "Загрузить образ из [1-дискета; 2-C:\kolibri.img (FAT32);",13,10 + cp866 "║ 3-использовать уже загруженный образ;",13,10 + cp866 "║ 4-создать чистый образ]: ",0 end if -prnotfnd db "訡 - ० .",0 +prnotfnd: cp866 "Ошибка - Видеорежим не найден.",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 +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 -mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0 -mode9 db "640x480, VGA 16 梥⮢",13,10,0 +mode0: cp866 "320x200, EGA/CGA 256 цветов",13,10,0 +mode9: cp866 "640x480, VGA 16 цветов",13,10,0 -usebd_msg db " [b] ᪨, १ BIOS:",0 -on_msg db " ",13,10,0 -off_msg db " 몫",13,10,0 +usebd_msg:cp866 " [b] Добавить диски, видимые через BIOS:",0 +on_msg: cp866 " вкл",13,10,0 +off_msg: cp866 " выкл",13,10,0 -preboot_device_msg db " [c] ࠧ ᪥: ",0 +preboot_device_msg:cp866 " [c] Образ дискеты: ",0 if defined extended_primary_loader preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 db " ᪥",13,10,0 -pdm2 db "kolibri.img 㧪",13,10,0 +pdm1: cp866 "настоящая дискета",13,10,0 +pdm2: cp866 "kolibri.img из папки загрузки",13,10,0 else preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4 -pdm1 db " ᪥",13,10,0 -pdm2 db "C:\kolibri.img (FAT32)",13,10,0 -pdm3 db "ᯮ짮 㦥 㦥 ࠧ",13,10,0 -pdm4 db "ᮧ ࠧ",13,10,0 +pdm1: cp866 "настоящая дискета",13,10,0 +pdm2: cp866 "C:\kolibri.img (FAT32)",13,10,0 +pdm3: cp866 "использовать уже загруженный образ",13,10,0 +pdm4: cp866 "создать чистый образ",13,10,0 end if -loading_msg db " 㧪 KolibriOS...",0 +loading_msg:cp866 "Идёт загрузка KolibriOS...",0 if ~ defined extended_primary_loader ; saving not supported in this case -save_quest db " ⥪騥 ன? [y/n]: ",0 -loader_block_error db "訡 砫쭮 稪, த .",0 +save_quest:cp866 "Запомнить текущие настройки? [y/n]: ",0 +loader_block_error:cp866 "Ошибка в данных начального загрузчика, продолжение невозможно.",0 end if -_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 +_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 -remark1 db "祭 㬮砭 ࠭ 㤮⢠ 設⢠, .",0 -remark2 db "᫨ 㧨 ⥬, ஡ ⪫ 㭪 [b].",0 +remark1:cp866 "Значения по умолчанию выбраны для удобства большинства, но не всех.",0 +remark2:cp866 "Если у Вас не грузится система, попробуйте отключить пункт [b].",0 remarks dw remark1, remark2 num_remarks = 2 diff --git a/kernel/trunk/boot/bootsp.inc b/kernel/trunk/boot/bootsp.inc index 0360e11d32..f9d30d741a 100644 --- a/kernel/trunk/boot/bootsp.inc +++ b/kernel/trunk/boot/bootsp.inc @@ -11,93 +11,93 @@ ; ;====================================================================== -; Para modificar ste archivo es necesario abrirlo con codificacin CP850 +; Para modificar éste archivo es necesario abrirlo con codificación CP850 $Revision: 2455 $ d80x25_bottom: - db 186,' KolibriOS est basado en MenuetOS y viene ABSOLUTAMENTE ' - db 'SIN GARANTA ',186 - db 186,' Lee el archivo COPYING por ms detalles ' - db ' ',186 + cp850 '║ KolibriOS está basado en MenuetOS y viene ABSOLUTAMENTE ' + cp850 'SIN GARANTíA ║' + cp850 '║ Lee el archivo COPYING por más detalles ' + cp850 ' ║' line_full_bottom d80x25_bottom_num = 3 -msg_apm db " APM x.x ", 0 -novesa db "Monitor: EGA/CGA",13,10,0 -s_vesa db "Versin de VESA: " +msg_apm: cp850 " APM x.x ", 0 +novesa: cp850 "Monitor: EGA/CGA",13,10,0 +s_vesa: cp850 "Versión de VESA: " .ver db "?.?",13,10,0 -gr_mode db "Selecciona un modo de video: ",13,10,0 +gr_mode: cp850 "Selecciona un modo de video: ",13,10,0 -ask_bd db "Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0 +ask_bd: cp850 "¿Agregar discos visibles por el BIOS emulados en modo V86? [1-si, 2-no]: ",0 if defined extended_primary_loader -bdev db "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0 +bdev: cp850 "Cargar unidad ram desde [1-disquete; 2-kolibri.img]: ",0 else -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 ncleo;" - db 13,10,186," " - db "4-crear imagen vaca]: ",0 +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 end if -prnotfnd db "Fatal - Modo de video no encontrado.",0 +prnotfnd: cp850 "Fatal - Modo de video no encontrado.",0 -not386 db "Fatal - CPU 386+ requerido.",0 -fatalsel db "Fatal - Modo de grficos 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 +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 boot_dev db 0 ; 0=floppy, 1=hd -start_msg db "Presiona [abcd] para cambiar la configuracin, [Enter] para continuar",13,10,0 -time_msg db " o espera " -time_str db " 5 segundos" - db " para que inicie automticamente",13,10,0 -current_cfg_msg db "Configuracin actual:",13,10,0 -curvideo_msg db " [a] Modo de video: ",0 +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 -mode0 db "320x200, EGA/CGA 256 colores",13,10,0 -mode9 db "640x480, VGA 16 colores",13,10,0 +mode0: cp850 "320x200, EGA/CGA 256 colores",13,10,0 +mode9: cp850 "640x480, VGA 16 colores",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 +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 -preboot_device_msg db " [c] Imagen de disquete: ",0 +preboot_device_msg:cp850 " [c] Imagen de disquete: ",0 if defined extended_primary_loader preboot_device_msgs dw 0,pdm1,pdm2,0 -pdm1 db "disquete real",13,10,0 -pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm1: cp850 "disquete real",13,10,0 +pdm2: cp850 "C:\kolibri.img (FAT32)",13,10,0 else preboot_device_msgs dw 0,pdm1,pdm2,pdm3 -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 vaca",13,10,0 +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 end if -loading_msg db "Cargando KolibriOS...",0 +loading_msg:cp850 "Cargando KolibriOS...",0 if ~ defined extended_primary_loader -save_quest db "Recordar configuracin actual? [s/n]: ",0 -loader_block_error db "Bootloader invlido, no puedo continuar. Detenido.",0 +save_quest:cp850 "¿Recordar configuración actual? [s/n]: ",0 +loader_block_error:cp850 "Bootloader inválido, no puedo continuar. Detenido.",0 end if -_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 +_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 -remark1 db "Los valores por defecto puede que no funcionen en algunas configuraciones.",0 -remark2 db "Si el sistema no inicia, prueba deshabilitar la opcin [b].",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 remarks dw remark1, remark2 num_remarks = 2 diff --git a/kernel/trunk/boot/bootvesa.inc b/kernel/trunk/boot/bootvesa.inc index 6dec8b493d..b25a080c79 100644 --- a/kernel/trunk/boot/bootvesa.inc +++ b/kernel/trunk/boot/bootvesa.inc @@ -78,7 +78,7 @@ virtual at $A000 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 @@ calc_vmodes_table: 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 diff --git a/kernel/trunk/boot/et.inc b/kernel/trunk/boot/et.inc index 66fd5f611e..5a9d1cde1c 100644 --- a/kernel/trunk/boot/et.inc +++ b/kernel/trunk/boot/et.inc @@ -9,7 +9,7 @@ $Revision$ ; Full ASCII code font -; only and added +; only õ and ä added ; Kaitz ET_FNT: fontfile file "ETFONT.FNT" diff --git a/kernel/trunk/boot/ru.inc b/kernel/trunk/boot/ru.inc index dbc7493ec7..4896e2c491 100644 --- a/kernel/trunk/boot/ru.inc +++ b/kernel/trunk/boot/ru.inc @@ -11,9 +11,9 @@ $Revision$ ; 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 diff --git a/kernel/trunk/bootloader/extended_primary_loader/after_win/kordldr.win.txt b/kernel/trunk/bootloader/extended_primary_loader/after_win/kordldr.win.txt index 703c5a447c..3affd3f39e 100644 --- a/kernel/trunk/bootloader/extended_primary_loader/after_win/kordldr.win.txt +++ b/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. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/trunk/bootloader/extended_primary_loader/cdfs/bootsect.txt b/kernel/trunk/bootloader/extended_primary_loader/cdfs/bootsect.txt index 969c52bba5..7fedad1772 100644 --- a/kernel/trunk/bootloader/extended_primary_loader/cdfs/bootsect.txt +++ b/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. Если же нет, то считываются все сектора, кроме последнего, после чего + последний сектор считывается отдельно во временную область, и уже + оттуда нужная часть данных копируется в буфер. diff --git a/kernel/trunk/bootloader/extended_primary_loader/fat1x/bootsect.txt b/kernel/trunk/bootloader/extended_primary_loader/fat1x/bootsect.txt index 26a9621e1a..c0449aa693 100644 --- a/kernel/trunk/bootloader/extended_primary_loader/fat1x/bootsect.txt +++ b/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. diff --git a/kernel/trunk/bootloader/extended_primary_loader/fat32/bootsect.txt b/kernel/trunk/bootloader/extended_primary_loader/fat32/bootsect.txt index 858b52a8bc..caabcb33f9 100644 --- a/kernel/trunk/bootloader/extended_primary_loader/fat32/bootsect.txt +++ b/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. diff --git a/kernel/trunk/bootloader/readme b/kernel/trunk/bootloader/readme index 14d1c6f1d5..b68c8bac03 100644 --- a/kernel/trunk/bootloader/readme +++ b/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 --------------------------------------------------------------------- diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index a54426e37a..f420bd388a 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -330,7 +330,7 @@ new_app_base equ 0; 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) diff --git a/kernel/trunk/core/conf_lib-sp.inc b/kernel/trunk/core/conf_lib-sp.inc index cf2abd211b..7dd26edb98 100644 --- a/kernel/trunk/core/conf_lib-sp.inc +++ b/kernel/trunk/core/conf_lib-sp.inc @@ -1,11 +1,11 @@ -; ste archivo debe ser editado con codificacin CP866 +; Éste archivo debe ser editado con codificación CP866 -ugui_mouse_speed db 'velocidad del ratn',0 -ugui_mouse_delay db 'demora del ratn',0 +ugui_mouse_speed:cp850 'velocidad del ratón',0 +ugui_mouse_delay:cp850 'demora del ratón',0 -udev db 'disp',0 -unet db 'red',0 -unet_active db 'activa',0 -unet_addr db 'direc',0 -unet_mask db 'msc',0 -unet_gate db 'puer',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 diff --git a/kernel/trunk/core/conf_lib.inc b/kernel/trunk/core/conf_lib.inc index 0b63e88ecb..be70368261 100644 --- a/kernel/trunk/core/conf_lib.inc +++ b/kernel/trunk/core/conf_lib.inc @@ -164,7 +164,7 @@ endp proc strtoint_dec stdcall,strs pushad xor edx, edx - ; + ; поиск конца mov esi, [strs] @@: lodsb @@ -180,7 +180,7 @@ proc strtoint_dec stdcall,strs dec ebx or ebx, ebx jz @f - imul ecx, ecx, 10; 冷 + imul ecx, ecx, 10; порядок jmp @b @@: diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 171d09227e..1ea2898728 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -631,21 +631,21 @@ proc page_fault_handler 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,21 +661,21 @@ end if .user_space: test eax, PG_MAP - jnz .err_access ; - ; ? + jnz .err_access ;Страница присутствует + ;Ошибка доступа ? shr ebx, 12 mov ecx, ebx 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 @@ end if .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 diff --git a/kernel/trunk/core/sched.inc b/kernel/trunk/core/sched.inc index 02d6e98baf..0467a7d9fc 100644 --- a/kernel/trunk/core/sched.inc +++ b/kernel/trunk/core/sched.inc @@ -99,8 +99,8 @@ updatecputimes: 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: diff --git a/kernel/trunk/core/sys32-sp.inc b/kernel/trunk/core/sys32-sp.inc index b086b5d746..fa555a1f18 100644 --- a/kernel/trunk/core/sys32-sp.inc +++ b/kernel/trunk/core/sys32-sp.inc @@ -1,4 +1,4 @@ -; ste archivo debe ser editado con codificacin CP866 +; Éste archivo debe ser editado con codificación CP866 - msg_sel_ker db "ncleo", 0 - msg_sel_app db "aplicacin", 0 + msg_sel_ker: cp850 "núcleo", 0 + msg_sel_app: cp850 "aplicación", 0 diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 94b2a465b0..045290e37b 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -61,7 +61,7 @@ iglobal 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 @@ uglobal 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 @@ exc_c: ; 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 @@ unlock_application_table: 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,17 +685,6 @@ terminate: ; terminate application 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 diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index 327cfdb847..b80930b298 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -29,7 +29,7 @@ cross_order: align 32 sysenter_entry: - ; + ; Настраиваем стек mov esp, [ss:tss._esp0] sti push ebp ; save app esp + 4 @@ -47,7 +47,7 @@ sysenter_entry: 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 diff --git a/kernel/trunk/core/v86.inc b/kernel/trunk/core/v86.inc index 82b8a21f85..c6b4b3e41c 100644 --- a/kernel/trunk/core/v86.inc +++ b/kernel/trunk/core/v86.inc @@ -178,7 +178,7 @@ v86_set_page: ; 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 @@ v86_exc_c: 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] diff --git a/kernel/trunk/data16.inc b/kernel/trunk/data16.inc index 585a8f7666..190e4a966f 100644 --- a/kernel/trunk/data16.inc +++ b/kernel/trunk/data16.inc @@ -13,9 +13,9 @@ preboot_lfb db 0 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: diff --git a/kernel/trunk/data32.inc b/kernel/trunk/data32.inc index 661bbd7af0..4795d3e942 100644 --- a/kernel/trunk/data32.inc +++ b/kernel/trunk/data32.inc @@ -49,43 +49,43 @@ keymap_alt: if lang eq ru - 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_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_APIC_found db 'APIC 祭', 0 - boot_APIC_nfound db 'APIC ', 0 + boot_APIC_found: cp866 'APIC включен', 0 + boot_APIC_nfound: cp866 'APIC не найден', 0 if preboot_blogesc - boot_tasking db ' ⮢ ᪠, ESC ',0 + boot_tasking: cp866 'Все готово для запуска, нажмитре ESC для старта',0 end if else if lang eq sp include 'data32sp.inc' @@ -159,7 +159,7 @@ read_firstapp db '/sys/' firstapp db 'LAUNCHER',0 notifyapp db '@notify',0 if lang eq ru -ud_user_message db '訡: ন ',0 +ud_user_message: cp866 'Ошибка: неподдерживаемая инструкция процессора',0 else if ~ lang eq sp ud_user_message db 'Error: unsupported processor instruction',0 end if diff --git a/kernel/trunk/data32sp.inc b/kernel/trunk/data32sp.inc index 716033f4d2..dda02fff98 100644 --- a/kernel/trunk/data32sp.inc +++ b/kernel/trunk/data32sp.inc @@ -1,40 +1,40 @@ - 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 libreras (.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 ratn',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 aplicacin',0 - boot_mtrr db 'Configurando MTRR',0 + 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_APIC_found db 'APIC habilitado', 0 - boot_APIC_nfound db 'APIC no encontrado', 0 + boot_APIC_found: cp850 'APIC habilitado', 0 + boot_APIC_nfound: cp850 'APIC no encontrado', 0 if preboot_blogesc - boot_tasking db 'Todo configurado - presiona ESC para iniciar',0 + boot_tasking: cp850 'Todo configurado - presiona ESC para iniciar',0 end if -msg_version db 'versin incompatible del controlador',13,10,0 -msg_www db 'por favor, visita www.kolibrios.org',13,10,0 +msg_version: cp850 'versión incompatible del controlador',13,10,0 +msg_www: cp850 'por favor, visita www.kolibrios.org',13,10,0 -ud_user_message db 'Error: instruccin no soportada por el procesador',0 +ud_user_message:cp850 'Error: instrucción no soportada por el procesador',0 diff --git a/kernel/trunk/detect/dev_fd.inc b/kernel/trunk/detect/dev_fd.inc index b55b3670c7..c8dbdd38d7 100644 --- a/kernel/trunk/detect/dev_fd.inc +++ b/kernel/trunk/detect/dev_fd.inc @@ -9,9 +9,9 @@ $Revision$ ;*************************************************** -; -; FDD -; Mario79 +; предварительная очистка области таблицы +; поиск и занесение в таблицу приводов FDD +; автор Mario79 ;*************************************************** xor eax, eax mov edi, DRIVE_DATA diff --git a/kernel/trunk/detect/dev_hdcd.inc b/kernel/trunk/detect/dev_hdcd.inc index b8a3a5f6b2..9284c95869 100644 --- a/kernel/trunk/detect/dev_hdcd.inc +++ b/kernel/trunk/detect/dev_hdcd.inc @@ -9,13 +9,13 @@ $Revision$ ;****************************************************** -; HDD CD -; . -; Mario79 +; поиск приводов HDD и CD +; автор исходного текста Кулаков Владимир Геннадьевич. +; адаптация и доработка Mario79 ;****************************************************** ;**************************************************** -;* HDD CD * +;* ПОИСК HDD и CD * ;**************************************************** FindHDD: mov [ChannelNumber], 1 @@ -71,54 +71,54 @@ FindHDD_3: 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 @@ ReadHDD_ID: 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 @@ SendCommandToHDD: 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 @@ SendCommandToHDD: 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 @@ ReadCD_ID: 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 ; 17h + 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 @@ ReadCD_ID: 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 @@ DeviceReset: ret @@Err4_2: mov [DevErrorCode], 4 -; +; Записать код ошибки ret EndFindHDD: diff --git a/kernel/trunk/detect/sear_par.inc b/kernel/trunk/detect/sear_par.inc index b240ce2580..ec790899d2 100644 --- a/kernel/trunk/detect/sear_par.inc +++ b/kernel/trunk/detect/sear_par.inc @@ -9,9 +9,9 @@ $Revision$ ;**************************************************** -; HDD -; -; Mario79 +; поиск логических дисков на обнаруженных HDD +; и занесение данных в область таблицы +; автор Mario79 ;**************************************************** mov [transfer_adress], DRIVE_DATA+0xa search_partitions_ide0: diff --git a/kernel/trunk/docs/loader_doc.txt b/kernel/trunk/docs/loader_doc.txt index 3134c98ec7..ac46890d6a 100644 --- a/kernel/trunk/docs/loader_doc.txt +++ b/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/ diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 2fbf0fcd83..ac50580ef1 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/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 @@ dword- * 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 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); * +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 = слишком много процессов diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index 20671c3348..5cf7c72dbd 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -2923,9 +2923,9 @@ Remarks: * 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) ebx=-1; + not less than 14, function returns eax=5 (not found) and ebx=-1; * size of ramdisk root folder is 14 blocks, - 0x1C00=7168 ; but function returns ebx=0 + 0x1C00=7168 bytes; 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 @@ Remarks: 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 - 11 18). + subfunction 11 of function 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 @@ Message codes: * in addition dword-image of the register DR6 is given: * bits 0-3: condition of the corresponding breakpoint (set by subfunction 9) is satisfied - * 14: exception has occured because of the trace mode + * bit 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 @@ Parameters: Format of the information structure: * +0: dword: 7 = subfunction number * +4: dword: flags field: - * 0: start process as debugged + * bit 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) diff --git a/kernel/trunk/drivers/apm.asm b/kernel/trunk/drivers/apm.asm index fcc0f19b59..23e1686a61 100644 --- a/kernel/trunk/drivers/apm.asm +++ b/kernel/trunk/drivers/apm.asm @@ -297,7 +297,7 @@ free_ports: ret -; +; ДАННЫЕ ПРОГРАММЫ title db '',0 flags dw 0 diff --git a/kernel/trunk/drivers/com_mouse.asm b/kernel/trunk/drivers/com_mouse.asm index c4943ab93e..5d4c66b2cb 100644 --- a/kernel/trunk/drivers/com_mouse.asm +++ b/kernel/trunk/drivers/com_mouse.asm @@ -174,68 +174,68 @@ endp 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,41 +257,41 @@ irq_handler: ; 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 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 @@ irq_handler: 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 @@ irq_handler: 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 @@ irq_handler: jmp .EndMouseInterrupt .Error: -; -; , +; Произошел сбой в порядке передачи информации от +; мыши, обнулить счетчик байтов пакета данных mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 .EndMouseInterrupt: @@ -340,9 +340,9 @@ irq_handler: align 4 struc COM_MOUSE_DATA { -; +; Номер принимаемого от мыши байта .MouseByteNumber db ? -; , +; Трехбайтовая структура данных, передаваемая мышью .FirstByte db ? .SecondByte db ? .ThirdByte db ? diff --git a/kernel/trunk/drivers/emu10k1x.asm b/kernel/trunk/drivers/emu10k1x.asm index 9b2e52b4c6..8d934067fe 100644 --- a/kernel/trunk/drivers/emu10k1x.asm +++ b/kernel/trunk/drivers/emu10k1x.asm @@ -19,7 +19,7 @@ IRQ_REMAP equ 0 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 diff --git a/kernel/trunk/drivers/ensoniq.asm b/kernel/trunk/drivers/ensoniq.asm index 82e20359d1..4de9600215 100644 --- a/kernel/trunk/drivers/ensoniq.asm +++ b/kernel/trunk/drivers/ensoniq.asm @@ -17,7 +17,7 @@ include 'imports.inc' 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 diff --git a/kernel/trunk/drivers/fm801.asm b/kernel/trunk/drivers/fm801.asm index 1de7366a3e..4316425bf4 100644 --- a/kernel/trunk/drivers/fm801.asm +++ b/kernel/trunk/drivers/fm801.asm @@ -17,7 +17,7 @@ API_VERSION equ 0x01000100 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 diff --git a/kernel/trunk/drivers/intelac97.asm b/kernel/trunk/drivers/intelac97.asm index 989ad00618..c68770186b 100644 --- a/kernel/trunk/drivers/intelac97.asm +++ b/kernel/trunk/drivers/intelac97.asm @@ -21,7 +21,7 @@ IRQ_REMAP equ 0 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 diff --git a/kernel/trunk/drivers/sis.asm b/kernel/trunk/drivers/sis.asm index df64bf2c9c..4a72d0e08a 100644 --- a/kernel/trunk/drivers/sis.asm +++ b/kernel/trunk/drivers/sis.asm @@ -21,7 +21,7 @@ IRQ_REMAP equ 0 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 diff --git a/kernel/trunk/drivers/vt823x.asm b/kernel/trunk/drivers/vt823x.asm index 2ae2210887..e58a67fa32 100644 --- a/kernel/trunk/drivers/vt823x.asm +++ b/kernel/trunk/drivers/vt823x.asm @@ -19,7 +19,7 @@ IRQ_REMAP equ 0 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 diff --git a/kernel/trunk/fs/fat12.inc b/kernel/trunk/fs/fat12.inc index 7aabfe83fb..8d46af49af 100644 --- a/kernel/trunk/fs/fat12.inc +++ b/kernel/trunk/fs/fat12.inc @@ -119,9 +119,9 @@ frfl6_1: 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 @@ read_flp_root: 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 @@ read_flp_fat: 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 @@ calculatefatchain_flp: 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 @@ save_flp_root: 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 @@ save_flp_fat: 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: diff --git a/kernel/trunk/fs/fs.inc b/kernel/trunk/fs/fs.inc index 9a941bd0ee..0a88cb7fe8 100644 --- a/kernel/trunk/fs/fs.inc +++ b/kernel/trunk/fs/fs.inc @@ -441,7 +441,7 @@ hd_err_return: 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 @@ expand_pathz: ;* output eax - number ;******************************************* StringToNumber: -; -; : -; EDI - . 0Dh -; : -; CF - : -; 0 - ; -; 1 - -; CF=0, AX - . +; ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД +; Вход: +; EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh +; Выход: +; CF - индикатор ошибок: +; 0 - ошибок нет; +; 1 - ошибка +; Если CF=0, то AX - число. push bx push cx diff --git a/kernel/trunk/fs/iso9660.inc b/kernel/trunk/fs/iso9660.inc index dc5475dce2..eed566e280 100644 --- a/kernel/trunk/fs/iso9660.inc +++ b/kernel/trunk/fs/iso9660.inc @@ -137,7 +137,7 @@ fs_CdRead: .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 @@ fs_CdRead: 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 @@ fs_CdRead: .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 @@ fs_CdReadFolder: .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 @@ fs_CdReadFolder: 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 @@ fs_CdReadFolder: .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 @@ fs_CdReadFolder: 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 @@ fs_CdReadFolder: 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 @@ fs_CdReadFolder: 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 @@ cd_get_parameters_of_file_1: inc eax mov [edi+4], eax @@: -; +; получаем размер файла в байтах xor eax, eax mov [edi+32+4], eax mov eax, [ebp-23] @@ -503,21 +503,21 @@ cd_find_lfn: ; 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 jne .access_denied call prevent_medium_removal -; +; тестовое чтение mov [CDSectorAddress], dword 16 mov [CDDataBuf_pointer], CDDataBuf call ReadCDWRetr;_1 cmp [DevErrorCode], 0 jne .access_denied -; +; вычисление последней сессии call WaitUnitReady cmp [DevErrorCode], 0 jne .access_denied @@ -539,37 +539,37 @@ cd_find_lfn: 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 @@ cd_find_lfn: 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 @@ cd_get_name: 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 @@ cd_compare_name: 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 @@ cd_compare_name: 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 @@ char_todown: jb .ret cmp al, 'Z' jbe .az - cmp al, '' + cmp al, 0x80 ; 'А' jb .ret - cmp al, '' + cmp al, 0x90 ; 'Р' jb .rus1 - cmp al, '' + cmp al, 0x9F ; 'Я' ja .ret ; 0x90-0x9F -> 0xE0-0xEF - add al, ''-'' + add al, 0xE0-0x90 .ret: ret .rus1: @@ -744,10 +744,10 @@ uni2ansi_char: mov al, '_' jmp .doit .yo1: - mov al, '' + mov al, 0xF0 ; 'Ё' in cp866 jmp .doit .yo2: - mov al, '' + mov al, 0xF1 ; 'ё' in cp866 jmp .doit .rus1: ; 0x410-0x43F -> 0x80-0xAF diff --git a/kernel/trunk/fs/part_set.inc b/kernel/trunk/fs/part_set.inc index 3c1aa8b686..620768ed65 100644 --- a/kernel/trunk/fs/part_set.inc +++ b/kernel/trunk/fs/part_set.inc @@ -77,10 +77,10 @@ ext2_data: .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 @@ test_primary_partition_3: ;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 @@ hd_and_partition_ok: ; 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 diff --git a/kernel/trunk/gui/event.inc b/kernel/trunk/gui/event.inc index 3ae3a60bf2..e426645614 100644 --- a/kernel/trunk/gui/event.inc +++ b/kernel/trunk/gui/event.inc @@ -21,8 +21,8 @@ align 4 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 @@ init_events: ;; used from kernel.asm 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 @@ align 4 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 @@ align 4 .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 @@ create_event: ;; EXPORT use 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 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,22 +142,22 @@ NotDummyTest: ;; INTERNAL use (not returned push edi ;-------------------------------------- align 4 -.small: ; -... +.small: ; криво как-то... pop edi pushfd cli 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 @@ clear_event: ;; EXPORT use 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 @@ Wait_events: 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 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 @@ wait_event_timeout: 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 @@ wait_finish: 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 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 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 ;-------------------------------------- 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 ;----------------------------------------------------------------------------- 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 @@ sys_wait_event_timeout: ;; f23 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 @@ get_event_for_app: ;; used from f10,f11,f23 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) diff --git a/kernel/trunk/init.inc b/kernel/trunk/init.inc index 754f67b2e4..dcc1667b11 100644 --- a/kernel/trunk/init.inc +++ b/kernel/trunk/init.inc @@ -310,7 +310,7 @@ init_BIOS32: test al, al jnz .PCI_BIOS32_not_found - ; PCI BIOS + ; здесь создаются дискрипторы для PCI BIOS add ebx, OS_BASE dec ecx @@ -334,7 +334,7 @@ init_BIOS32: mov [(pci_bios_entry-OS_BASE)], edx ; jmp .end .PCI_BIOS32_not_found: - ; pci_emu_dat + ; здесь должна заполнятся pci_emu_dat .BIOS32_not_found: .end: ret diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 14320598db..27952a0954 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -84,6 +84,7 @@ debug_direct_print equ 0 include "proc32.inc" include "kglobals.inc" include "lang.inc" +include "encoding.inc" include "const.inc" max_processes equ 255 @@ -494,9 +495,9 @@ no_mode_0x12: ; !!!! It`s dirty hack, fix it !!! ; Bits of EDX : - ; Bit 3116 During the SYSRET instruction, this field is copied into the CS register + ; Bit 31–16 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 150 During the SYSCALL instruction, this field is copied into the CS register + ; Bit 15–0 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 @@ -3337,8 +3338,8 @@ sys_sheduler: ;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 diff --git a/kernel/trunk/kernelsp.inc b/kernel/trunk/kernelsp.inc index 750017a4a0..1b8dccefa4 100644 --- a/kernel/trunk/kernelsp.inc +++ b/kernel/trunk/kernelsp.inc @@ -1,4 +1,4 @@ -; ste archivo debe ser editado con codificacin CP866 +; Éste archivo debe ser editado con codificación CP866 -version db 'Kolibri OS versin 0.7.7.0+ ',13,10,13,10,0 -diff16 "fin del cdigo del kernel",0,$ +version: cp850 'Kolibri OS versión 0.7.7.0+ ',13,10,13,10,0 +diff16 "fin del código del kernel",0,$ diff --git a/kernel/trunk/readme-ext-loader.txt b/kernel/trunk/readme-ext-loader.txt index 986703dd4e..ccfe7fc629 100644 --- a/kernel/trunk/readme-ext-loader.txt +++ b/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 в противном случае. diff --git a/kernel/trunk/sec_loader/trunk/boot/PrimaryLoader.txt b/kernel/trunk/sec_loader/trunk/boot/PrimaryLoader.txt index 510f243099..eddd3f1633 100644 --- a/kernel/trunk/sec_loader/trunk/boot/PrimaryLoader.txt +++ b/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 не будут модифицированы ядром. diff --git a/kernel/trunk/sec_loader/trunk/boot/after_win/kordldr.win.txt b/kernel/trunk/sec_loader/trunk/boot/after_win/kordldr.win.txt index 703c5a447c..3affd3f39e 100644 --- a/kernel/trunk/sec_loader/trunk/boot/after_win/kordldr.win.txt +++ b/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. Добавляет сектор в конец списка (самый новый вход). diff --git a/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.txt b/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.txt index 969c52bba5..7fedad1772 100644 --- a/kernel/trunk/sec_loader/trunk/boot/cdfs/bootsect.txt +++ b/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. Если же нет, то считываются все сектора, кроме последнего, после чего + последний сектор считывается отдельно во временную область, и уже + оттуда нужная часть данных копируется в буфер. diff --git a/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.txt b/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.txt index 26a9621e1a..c0449aa693 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat1x/bootsect.txt +++ b/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. diff --git a/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.txt b/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.txt index 858b52a8bc..caabcb33f9 100644 --- a/kernel/trunk/sec_loader/trunk/boot/fat32/bootsect.txt +++ b/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. diff --git a/kernel/trunk/sec_loader/trunk/debug_msg.inc b/kernel/trunk/sec_loader/trunk/debug_msg.inc index 5a8a0ac415..c9d0ee99d0 100644 --- a/kernel/trunk/sec_loader/trunk/debug_msg.inc +++ b/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 diff --git a/kernel/trunk/sec_loader/trunk/loader.asm b/kernel/trunk/sec_loader/trunk/loader.asm index 81e5544380..3d216a627b 100644 --- a/kernel/trunk/sec_loader/trunk/loader.asm +++ b/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_any.inc' 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 @@ start: 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 @@ start: 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 @@ cpugood: ; 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 @@ table_15_87: 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 @@ struc FAT_32_entry ;Byte Directory Entry Structure } -; , .... +;Тут будут распологатсья данные, которые затруднительно распологать в стековой области.... ;;; ;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 diff --git a/kernel/trunk/sec_loader/trunk/loader.lst b/kernel/trunk/sec_loader/trunk/loader.lst index 3984e145d6..3abcde5d68 100644 --- a/kernel/trunk/sec_loader/trunk/loader.lst +++ b/kernel/trunk/sec_loader/trunk/loader.lst @@ -905,7 +905,7 @@ flat assembler version 1.68 (65535 kilobytes memory) 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 diff --git a/kernel/trunk/sec_loader/trunk/parse.inc b/kernel/trunk/sec_loader/trunk/parse.inc index d23784b8e7..762b404443 100644 --- a/kernel/trunk/sec_loader/trunk/parse.inc +++ b/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,23 +63,23 @@ parse_start: .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 cmp al, '[' jz .parse_loader jmp .start -;////// loader +;////// проверка на наличее секции loader use_parse_loader ;pause if DEBUG xor ax, ax int 16h end if -;////// , , +;////// вывод графического экрана, выбор, секции под дефолту use_any_sec -; .. +;парсинг выбраной или дефолтной секции т.е. разбор параметров выполнение сценария use_parse_def_sect ;////////////////// diff --git a/kernel/trunk/sec_loader/trunk/parse_any.inc b/kernel/trunk/sec_loader/trunk/parse_any.inc index d51a60c9d0..a1b18aa0fb 100644 --- a/kernel/trunk/sec_loader/trunk/parse_any.inc +++ b/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 @@ color_sym_yellow equ 14 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 @@ end if test ax, ax jz .parse_run_only -; . +;отобразим полный список всех найденых секций. if DEBUG pusha mov si, show_all_sect @@ -70,7 +70,7 @@ if DEBUG popa end if ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - mov al, 0xf6 ; , + mov al, 0xf6 ; Сброс клавиатуры, разрешить сканирование out 0x60, al xor cx, cx .wait_loop: ; variant 2 @@ -102,7 +102,7 @@ end if 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 @@ end if pop dword [es:8*4] sti -; +;процедура формирования буфера для скролинга секций ;if DEBUG ; pusha ; mov ax,point_default @@ -130,20 +130,20 @@ end if ; 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_descript ; 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 @@ show_timer_message 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 @@ clear_timer_msg @@: 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 @@ clear_timer_msg 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 @@ clear_timer_msg .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 @@ clear_timer_msg -; . +; тут мы будем парсить только дефолтную секцию и выполнять ее ничего не предлагая пользователю из диалогов. .parse_run_only: if DEBUG pusha @@ -286,7 +286,7 @@ end if macro show_bl_sc { ;;;;;;;;;;;;;;; -; +;очистим экран и выведем меню ; draw frames xor ax, ax if DEBUG @@ -324,7 +324,7 @@ end if ;;;;;;;;;;;;;;;;;;;;;;; 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 @@ macro get_frame_buffer 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 @@ macro get_frame_buffer .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 @@ macro get_frame_buffer .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 @@ macro get_frame_buffer .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 get_frame_buffer macro show_act_cursor { -; +;отображение курсора по умолчанию lea si, point_to_hframe mov di, 962-160 mov ax, point_default @@ -554,7 +554,7 @@ end if } macro show_descript -; , +;Этот макрос показывает краткое описание, если оно есть у секции в пункте ;Section description { local .start_p_sh_d @@ -568,14 +568,14 @@ local .show_mess_prev_eq 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 @@ local .show_mess_prev_eq 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 @@ local .show_mess_prev_eq repe scasb ;cut ' ' inc cx dec di -;;;;;;;;;;;;;;;;;;;;di , . -; 37 . -; .. -;es:di - , ds:si +;;;;;;;;;;;;;;;;;;;;di указывает на строчку, которую нам нужно выводить. +;строчка будет выводиться блоками по 37 символов. +;настроим куда будем выводить т.е. начало +;es:di - указывают на строчку из которой мы берем символ, ds:si куда будем выводить push di pop si diff --git a/kernel/trunk/sec_loader/trunk/parse_dat.inc b/kernel/trunk/sec_loader/trunk/parse_dat.inc index 51ff9eca94..3d0d9a1f47 100644 --- a/kernel/trunk/sec_loader/trunk/parse_dat.inc +++ b/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' diff --git a/kernel/trunk/sec_loader/trunk/parse_def_sect.inc b/kernel/trunk/sec_loader/trunk/parse_def_sect.inc index 6bdb692095..bf4f1389c3 100644 --- a/kernel/trunk/sec_loader/trunk/parse_def_sect.inc +++ b/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 @@ ATTR_ARCHIVE equ 0x20 -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 @@ macro use_parse_def_sect 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 @@ local .found_end_str 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 @@ local .found_end_str 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 @@ local .found_end_str inc di dec cx jnz @b -;;;not found , +;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки .found_end_str: push word [es:di] @@ -189,7 +189,7 @@ local .found_end_str } macro use_RamdiskFS -; , + . +; формирование рам диска, + обработка всего связанного. { if DEBUG local ._not_memory_in_sys @@ -200,19 +200,19 @@ local ._not_memory_in_sys 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 .rest_value_loop_RS 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 @@ local ._end_parse_RS 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 @@ local ._end_parse_RS 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 @@ local ._end_parse_RS 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 @@ local ._end_parse_RS .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 @@ end if macro use_free_memory { local _support_function_use_free_memory -; , 1 . -; 088 015 -; , 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,17 +380,17 @@ macro show_ERRORS } -macro get_type_FS ; RFS. +macro get_type_FS ;получить и создать образ для заданной RFS. { mov di, point_default ;restore value mov cx, save_cx_d .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 @@ macro get_type_FS ; 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 @@ macro get_type_FS ; 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 @@ macro get_type_FS ; repe cmpsb jnz .krfs_cmp ;is not compare -make_FAT_RamFS ; +make_FAT_RamFS ;сделать if DEBUG pusha @@ -464,7 +464,7 @@ end if .end_get_FRS_ERROR_1: -; - :( +;сообщение об ошибке - данный участок кода не был корректно обработан :( or show_errors_sect, show_error_1 jmp ._end_parse_FRS .end_get_FRS_ERROR_2: @@ -486,55 +486,55 @@ macro make_FAT_RamFS 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 ;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 @@ use_RamdiskCluster ; .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 @@ use_RamdiskCluster ; 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 @@ use_RamdiskCluster ; 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 @@ use_RamdiskCluster ; dec eax cdq idiv edi -;FATSz = eax, edx +;FATSz = сейчас частное в eax, а остаток в edx mov word [fat12_buffer.BPB_FATSz16], ax @@ -619,7 +619,7 @@ use_RamdiskCluster ; .fat12: ;fat12 if DEBUG -; , c FS=fat12 +; выведем в отладке, что собираемся делать образ диска c FS=fat12 pushad mov si, start_making_FAT12_msg call printplain @@ -628,8 +628,8 @@ end if -; 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 @@ end if 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 .. 02600 -; ) 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,18 +715,18 @@ end if macro use_RamdiskSector { -; FS +;для некоторых FS будет игнорироваться mov di, point_default ;restore value mov cx, save_cx_d .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 @@ macro use_RamdiskSector 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 @@ macro use_RamdiskSector 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 @@ end if macro use_RamdiskCluster { -; FS +;для некоторых FS будет игнорироваться ; push es ; push di mov di, point_default ;restore value @@ -820,10 +820,10 @@ macro use_RamdiskCluster .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 @@ macro use_RamdiskCluster 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 @@ macro use_RamdiskCluster 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 @@ end if } macro use_Loader_Image -; 1 . -; 1.44 +;предназначен для загрузки образов выше 1 Мб. +;первоначальная версия загружает образ дискеты 1.44 мб { local .start_p_LI local .exit @@ -902,14 +902,14 @@ local .rest_value_loop 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 @@ local .found_end_str 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 @@ local .found_end_str 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 @@ local .found_end_str 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 @@ local .found_end_str jnz .error_LM -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 64 1 . +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; забрасывание блока в 64 кб выше 1 мб. mov si, table_15_87 push es push ds @@ -1027,7 +1027,7 @@ local .found_end_str macro name_in_root_fat -;, +;макрос, который записывает информацию о загруженном файле в корневую фат таблицу { } @@ -1036,9 +1036,9 @@ macro name_in_root_fat macro use_RamdiskFile { -; callback -; , .. -; 087 int 0x15 - 64 1 +;загрузка файлов с использование callback сервиса первичного загрузчика +;используется только для загрузки необходимых и небольших файлов, т.к. достаточно медленно работает +;для загрузки использует 0х87 функцию int 0x15 прерывания - загрузка блоков данных до 64 кб выше 1 мб local .start_loop local ._end local .rest_value_loop @@ -1046,14 +1046,14 @@ local .error 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 @@ local .error 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 @@ local .error 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,14 +1115,14 @@ local .error ;@@: mov point_to_dest_file_name, di inc di -; +;проверка индивидуальности имени файла check_name_file ;/restore di - point and cx -size section mov di, save_di_RAMDISK mov cx, save_cx_RAMDISK test al, al - jnz .start_loop ; al =0, . + jnz .start_loop ;если в al значение не =0, то такое имя уже существует в системе. @@ -1132,13 +1132,13 @@ check_name_file 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 @@ end if 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 @@ end if -; -; 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 @@ move_file_up @@: -; +;тут организован цикл по загрузке файлов в корневую директорию mov di, save_di_RAMDISK mov cx, save_cx_RAMDISK if DEBUG @@ -1278,7 +1278,7 @@ end if jmp .start_loop ._end: -; 1- +;перенесем за 1-ый мб фат и рут дир move_up_fat_and_root_d @@ -1286,7 +1286,7 @@ move_up_fat_and_root_d -; +;загрузка блока ; mov ah,0x87 ; mov cx, ;size in byte @@ -1296,8 +1296,8 @@ move_up_fat_and_root_d } -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 @@ macro use_BPB_RAM ; 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 @@ if DEBUG end if } macro first_create_fat_table -; 3 fat , , 0 -; . +;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение +;для смещения в корневой таблице. { mov al, byte [fat12_buffer.BPB_Media] @@ -1361,12 +1361,12 @@ if DEBUG 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,30 +1390,30 @@ end if } macro register_file_in_fat -; Fat -; 12, )) -; fat/ +;макрос регистрации файла в файловой структуре Fat +;пока поддерживается только фат12, пока )) +;вычисление смежных кластеров и занесение инфы в fat/ { local .step2 local .step3 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 @@ end if -;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 @@ end if 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 @@ end if 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 @@ end if 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,25 +1543,25 @@ end if 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 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 mov si, dest_name_fat mov cx, 11 -; +;запишем в структуру имя @@: mov al, byte [es:di] inc di @@ -1585,7 +1585,7 @@ END IF - add point_to_free_root, 32 ; . + add point_to_free_root, 32 ;увелицим смещение до следующего значения. pop es } @@ -1595,8 +1595,8 @@ END IF 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 @@ macro get_firstDataSector 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 @@ macro get_firstDataSector if DEBUG pushad - mov ax, firstDataSect ; + mov ax, firstDataSect ;первый сектор данных mov cx, 0x0a mov di, firstDataSect_msg call decode @@ -1629,7 +1629,7 @@ if DEBUG 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 @@ if DEBUG 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 @@ end if } 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 @@ end if loop @b ;.succesfuly: -;, :( +;печально, такое имя уже имеется :( or ax, -1 jmp .exit @@ -1799,9 +1799,9 @@ end if 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_s 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 @@ local .st5 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 @@ local .st5 cmp al, 0x60 jbe .st2_l - xor al, 0x20; + xor al, 0x20;сделаем заглавные буквы .st2_l: mov byte [si], al inc di @@ -1909,7 +1909,7 @@ local .st5 xor ax, ax jmp @f -;;;;;;;; , +;;;;;;;;файл закончился, и нужно внести в конец пробелы .st4_s: mov al, ' ' .st4: @@ -1941,32 +1941,32 @@ end if } 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 movzx ebx, word [fat12_buffer.BPB_BytsPerSec] movzx edx, byte [fat12_buffer.BPB_SecPerClus] - imul bx, dx ; + imul bx, dx ;получим размер кластера push ebx ;save bx imul eax, ebx -; shl eax,9 ; 512 +; shl eax,9 ;умножим на 512 if DEBUG pushad @@ -2002,25 +2002,25 @@ end if @@: - 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 ; 08000 + sub save_file_size, ecx ;отнимим +; jmp .st1 ;получим 0х8000 -; +;корректировка значения должна быть выполенена на размер кластера .correct_on_byte: -;/ +;/узнаем размер кластера pop eax ;restore size of claster push ecx @@: @@ -2040,9 +2040,9 @@ end if 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 @@ end if macro move_up_fat_and_root_d -;, 1 +;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию { local .st1 @@ -2077,20 +2077,20 @@ local .st1 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 diff --git a/kernel/trunk/sec_loader/trunk/parse_err.inc b/kernel/trunk/sec_loader/trunk/parse_err.inc index d1c9a8436d..b8c940eb4a 100644 --- a/kernel/trunk/sec_loader/trunk/parse_err.inc +++ b/kernel/trunk/sec_loader/trunk/parse_err.inc @@ -30,7 +30,7 @@ error: 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 @@ error: 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 diff --git a/kernel/trunk/sec_loader/trunk/parse_loader.inc b/kernel/trunk/sec_loader/trunk/parse_loader.inc index 540b4ab8d1..a23fa61781 100644 --- a/kernel/trunk/sec_loader/trunk/parse_loader.inc +++ b/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 - '[' 0a -;cx - - +;блок макросов по обработке секции [loader] +;входные данные: +;es:di - указатель на секцию начинающиюся с '[' встечающиюся после 0хa +;cx - счетчик кол-во байт для проверке в кадре ; macro use_parse_loader { @@ -35,16 +35,16 @@ macro use_parse_loader ;////////////////// ;/ parse [loader] ;////////////////// - mov bx, cx ;c + mov bx, cx ;cохраним в регистры значения счетчика и указателя mov ax, di ; mov word [bp-4],.start ;is alredy set, see up 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 @@ end if 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 @@ end if ;//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 @@ end if 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 @@ end if 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 @@ end if 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 @@ end if 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 @@ end if 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 @@ end if ; 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 @@ end if 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 @@ end if .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 @@ end if 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 @@ end if jmp .start_d .correct_exit: - pop cx ; + pop cx ;восстановим значение счетчика pop di @@ -272,7 +272,7 @@ end if 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 @@ end if inc cx dec di ;get timeout value -;2 a .. 0 99 +;2 знакa может быть обработано т.е. значение от 0 до 99 секунд push cx xor bx, bx mov cx, 2 diff --git a/kernel/trunk/sec_loader/trunk/sl_equ.inc b/kernel/trunk/sec_loader/trunk/sl_equ.inc index a8e42bfa23..44abf2a06f 100644 --- a/kernel/trunk/sec_loader/trunk/sl_equ.inc +++ b/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_RS equ 0x2 ;found RS value 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 @@ point_to_eframe equ word [bp-56] ;point on point frame -; 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, -; , .. 01000:0000 +;данные которые используются при обработке секции, т.е. после нажатия Enter, уже не возможно вернуться в первоначальный экран +;для возврата, необходимо перезапустить полностью код т.е. стартовать с 0х1000:0000 diff --git a/kernel/trunk/sec_loader/trunk/sl_proc.inc b/kernel/trunk/sec_loader/trunk/sl_proc.inc index 7e718a572c..202fc32598 100644 --- a/kernel/trunk/sec_loader/trunk/sl_proc.inc +++ b/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_yellow equ 14 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 @@ show_name_section: dec di -; )) +;все вырезали и все готово для вывода имени секции )) push es pop ds @@ -249,52 +249,52 @@ end if pop si ret -.not_name_sec_fb: ; - +.not_name_sec_fb: ;нет имени в названии секции - значит так и скажем об этом push cs pop ds mov di, default_section_name 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 @@ find_before_sect: 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 @@ find_before_sect: 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 @@ find_next_sect: 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 @@ find_next_sect: -; -; +;настроили указатель на дефаулт секцию +;будем искать вниз .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 @@ find_next_sect: ;;;;;;;;;;;;;;;;;;;;;;;;;; ;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 @@ end if pop ax ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; +;установка таймера и отображение счетчика времени gettime: mov ah, 0 int 1Ah @@ -462,13 +462,13 @@ newtimer: 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 @@ newtimer: 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 diff --git a/kernel/trunk/sec_loader/trunk/startos.ini b/kernel/trunk/sec_loader/trunk/startos.ini index cb9c409e2d..9de8796b09 100644 --- a/kernel/trunk/sec_loader/trunk/startos.ini +++ b/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" diff --git a/kernel/trunk/video/vga.inc b/kernel/trunk/video/vga.inc index a776a9b54c..4b3117f7b3 100644 --- a/kernel/trunk/video/vga.inc +++ b/kernel/trunk/video/vga.inc @@ -403,7 +403,7 @@ align 4 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 @@ VGA_draw_bar_1: 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