diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/cd_drv.inc b/kernel/tags/kolibri0.6.0.0/blkdev/cd_drv.inc new file mode 100644 index 0000000000..36b5b5feb1 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/cd_drv.inc @@ -0,0 +1,546 @@ +;********************************************************** +; Непосредственная работа с устройством СD (ATAPI) +;********************************************************** +; Автор исходного текста Кулаков Владимир Геннадьевич. +; Адаптация и доработка Mario79 + +; Процедура для полного считывания всех +; данных из сектора компакт-диска +; Автор текста программы Кулаков Владимир Геннадьевич. + + +; Максимальное количество повторений операции чтения +MaxRetr equ 3 +; Предельное время ожидания готовности к приему команды +; (в тиках) +BSYWaitTime equ 1000 ;2 + +;************************************************* +;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * +;* Считываются данные пользователя, информация * +;* субканала и контрольная информация * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* CDSectorAddress - адрес считываемого сектора. * +;* Данные считывается в массив CDDataBuf. * +;************************************************* +ReadCD: + pusha +; Задать размер сектора + mov [CDBlockSize],2048 ;2352 +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать пакетную команду для считывания +; сектора данных + ; Задать код команды Read CD + mov [PacketCommand],byte 0x28 ;0xBE + ; Задать адрес сектора + mov AX,word [CDSectorAddress+2] + xchg AL,AH + mov word [PacketCommand+2],AX + mov AX,word [CDSectorAddress] + xchg AL,AH + mov word [PacketCommand+4],AX +; mov eax,[CDSectorAddress] +; mov [PacketCommand+2],eax + ; Задать количество считываемых секторов + mov [PacketCommand+8],byte 1 + ; Задать считывание данных в полном объеме +; mov [PacketCommand+9],byte 0xF8 +; Подать команду + call SendPacketDatCommand +; call test_mario79 + popa + ret + +;******************************************** +;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * +;* Многократное повторение чтения при сбоях * +;******************************************** +ReadCDWRetr: + pusha +; Цикл, пока команда не выполнена успешно или не +; исчерпано количество попыток + mov ECX,MaxRetr +@@NextRetr: +; Подать команду + call ReadCD + cmp [DevErrorCode],0 + je @@End_4 +; Задержка на 2,5 секунды + mov EAX,[timer_ticks] + add EAX,250 ;50 +@@Wait: + call change_task + cmp EAX,[timer_ticks] + ja @@Wait + loop @@NextRetr +; call test_mario79 +; Сообщение об ошибке +; mov SI,offset ErrS +; call FatalError +@@End_4: + popa + ret + + +; Универсальные процедуры, обеспечивающие выполнение +; пакетных команд в режиме PIO +; +; Автор текста программы Кулаков Владимир Геннадьевич. + +; Максимально допустимое время ожидания реакции +; устройства на пакетную команду (в тиках) +MaxCDWaitTime equ 1000 ;200 ;10 секунд + +; Область памяти для формирования пакетной команды +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 + +;**************************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * +;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет; * +;* CDBlockSize - размер принимаемого блока данных. * +;**************************************************** +SendPacketDatCommand: + pushad +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать ATA-команду передачи пакетной команды + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + ; Загрузить размер передаваемого блока + mov AX,[CDBlockSize] + mov [ATACylinder],AX + mov [ATAHead],0 + mov [ATACommand],0A0h + call SendCommandToHDD_1 +; call test_mario79 + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End_8 ;закончить, сохранив код ошибки + +; Ожидание готовности дисковода к приему +; пакетной команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice0: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,BSYWaitTime + ja @@Err1_1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice0 + test AL,1 ;состояние сигнала ERR + jnz @@Err6 + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice0 +; Послать пакетную команду + cli + mov DX,[ATABasePortAddr] + mov AX,[PacketCommand] + out DX,AX + mov AX,[PacketCommand+2] + out DX,AX + mov AX,[PacketCommand+4] + out DX,AX + mov AX,[PacketCommand+6] + out DX,AX + mov AX,[PacketCommand+8] + out DX,AX + mov AX,[PacketCommand+10] + out DX,AX + sti +; Ожидание готовности данных + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice1: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,MaxCDWaitTime + ja @@Err1_1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_temp + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice1 + cli +; Принять блок данных от контроллера + mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf + ; Загрузить адрес регистра данных контроллера + mov DX,[ATABasePortAddr] ;порт 1x0h + ; Загрузить в счетчик размер блока в байтах + mov CX,[CDBlockSize] + ; Вычислить размер блока в 16-разрядных словах + shr CX,1 ;разделить размер блока на 2 + ; Принять блок данных + cld + rep insw + sti + ; Успешное завершение приема данных + jmp @@End_8 + +; Записать код ошибки +@@Err1_1: + mov [DevErrorCode],1 + jmp @@End_8 +@@Err6_temp: + mov [DevErrorCode],7 + jmp @@End_8 +@@Err6: + mov [DevErrorCode],6 + +@@End_8: + popad + ret + + + +;*********************************************** +;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * +;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * +;* Входные параметры передаются через * +;* глобальные перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале; * +;* PacketCommand - 12-байтный командный пакет. * +;*********************************************** +SendPacketNoDatCommand: + pushad +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать ATA-команду передачи пакетной команды + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + mov [ATACylinder],0 + mov [ATAHead],0 + mov [ATACommand],0A0h + call SendCommandToHDD_1 + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End_9 ;закончить, сохранив код ошибки +; Ожидание готовности дисковода к приему +; пакетной команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice0_1: + call change_task + ; Проверить время ожидания + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,BSYWaitTime + ja @@Err1_3 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice0_1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_1 + test AL,08h ;состояние сигнала DRQ + jz @@WaitDevice0_1 +; Послать пакетную команду +; cli + mov DX,[ATABasePortAddr] + mov AX,word [PacketCommand] + out DX,AX + mov AX,word [PacketCommand+2] + out DX,AX + mov AX,word [PacketCommand+4] + out DX,AX + mov AX,word [PacketCommand+6] + out DX,AX + mov AX,word [PacketCommand+8] + out DX,AX + mov AX,word [PacketCommand+10] + out DX,AX +; sti +; Ожидание подтверждения приема команды + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h +@@WaitDevice1_1: + call change_task + ; Проверить время выполнения команды + mov EAX,[timer_ticks] + sub EAX,[TickCounter_1] + cmp EAX,MaxCDWaitTime + ja @@Err1_3 ;ошибка тайм-аута + ; Ожидать освобождения устройства + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitDevice1_1 + test AL,1 ;состояние сигнала ERR + jnz @@Err6_1 + test AL,40h ;состояние сигнала DRDY + jz @@WaitDevice1_1 + jmp @@End_9 + +; Записать код ошибки +@@Err1_3: + mov [DevErrorCode],1 + jmp @@End_9 +@@Err6_1: + mov [DevErrorCode],6 +@@End_9: + popad + ret + +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска (0 или 1); * +;* ATAFeatures - "особенности"; * +;* ATASectorCount - количество секторов; * +;* ATASectorNumber - номер начального сектора; * +;* ATACylinder - номер начального цилиндра; * +;* ATAHead - номер начальной головки; * +;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * +;* ATACommand - код команды. * +;* После успешного выполнения функции: * +;* в ATABasePortAddr - базовый адрес HDD; * +;* в DevErrorCode - ноль. * +;* При возникновении ошибки в DevErrorCode будет * +;* возвращен код ошибки. * +;**************************************************** +SendCommandToHDD_1: + pushad +; Проверить значение кода режима + 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 к приему команды + ; Выбрать нужный диск + mov DX,[ATABasePortAddr] + add DX,6 ;адрес регистра головок + mov AL,[DiskNumber] + cmp AL,1 ;проверить номера диска + ja @@Err4_4 + shl AL,4 + or AL,10100000b + out DX,AL + ; Ожидать, пока диск не будет готов + inc DX +; mov ecx,0xfff + mov eax,[timer_ticks] + mov [TickCounter_1],eax +@@WaitHDReady_2: + call change_task + ; Проверить время ожидания +; dec ecx +; cmp ecx,0 +; je @@Err1 + mov eax,[timer_ticks] + sub eax,[TickCounter_1] + cmp eax,BSYWaitTime ;300 ;ожидать 3 сек. + ja @@Err1_4 ;ошибка тайм-аута + ; Прочитать регистр состояния + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady_2 + ; Проверить состояние сигнала DRQ + test AL,08h + jnz @@WaitHDReady_2 +; Загрузить команду в регистры контроллера + cli + mov DX,[ATABasePortAddr] + inc DX ;регистр "особенностей" + mov AL,[ATAFeatures] + out DX,AL + inc DX ;счетчик секторов + mov AL,[ATASectorCount] + out DX,AL + inc DX ;регистр номера сектора + mov AL,[ATASectorNumber] + out DX,AL + inc DX ;номер цилиндра (младший байт) + mov AX,[ATACylinder] + out DX,AL + inc DX ;номер цилиндра (старший байт) + mov AL,AH + out DX,AL + inc DX ;номер головки/номер диска + mov AL,[DiskNumber] + shl AL,4 + cmp [ATAHead],0Fh ;проверить номер головки + ja @@Err5_4 + or AL,[ATAHead] + or AL,10100000b + mov AH,[ATAAddressMode] + shl AH,6 + or AL,AH + out DX,AL +; Послать команду + mov AL,[ATACommand] + inc DX ;регистр команд + out DX,AL + sti +; Сбросить признак ошибки + mov [DevErrorCode],0 + jmp @@End_10 +; Записать код ошибки +@@Err1_4: + mov [DevErrorCode],1 + jmp @@End_10 +@@Err2_4: + mov [DevErrorCode],2 + jmp @@End_10 +@@Err3_4: + mov [DevErrorCode],3 + jmp @@End_10 +@@Err4_4: + mov [DevErrorCode],4 + jmp @@End_10 +@@Err5_4: + mov [DevErrorCode],5 +; Завершение работы программы +@@End_10: + sti + popad + ret + +;************************************************* +;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +WaitUnitReady: + pusha +; Запомнить время начала операции + mov EAX,[timer_ticks] + mov [WURStartTime],EAX +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду TEST UNIT READY + mov [PacketCommand],word 00h +; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА +@@SendCommand: + ; Подать команду проверки готовности + call SendPacketNoDatCommand + call change_task + ; Проверить код ошибки + cmp [DevErrorCode],0 + je @@End_11 + ; Проверить время ожидания готовности + mov EAX,[timer_ticks] + sub EAX,[WURStartTime] + cmp EAX,MaxCDWaitTime + jb @@SendCommand + ; Ошибка тайм-аута + mov [DevErrorCode],1 +@@End_11: + popa + ret + + +;************************************************* +;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +LoadMedium: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду START/STOP UNIT + ; Задать код команды + mov [PacketCommand],word 1Bh + ; Задать операцию загрузки носителя + mov [PacketCommand+4],word 00000011b +; Подать команду + call SendPacketNoDatCommand + popa + ret + +;************************************************* +;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +UnloadMedium: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Сформировать команду START/STOP UNIT + ; Задать код команды + mov [PacketCommand],word 1Bh + ; Задать операцию извлечения носителя + mov [PacketCommand+4],word 00000010b +; Подать команду + call SendPacketNoDatCommand + popa + ret + +;************************************************* +;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;************************************************* +ReadCapacity: + pusha +; Очистить буфер пакетной команды + call clear_packet_buffer +; Задать размер буфера в байтах + mov [CDBlockSize],8 +; Сформировать команду READ CAPACITY + mov [PacketCommand],word 25h +; Подать команду + call SendPacketDatCommand + popa + ret + +clear_packet_buffer: +; Очистить буфер пакетной команды + mov [PacketCommand],dword 0 + mov [PacketCommand+4],dword 0 + mov [PacketCommand+8],dword 0 + ret + diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/cdrom.inc b/kernel/tags/kolibri0.6.0.0/blkdev/cdrom.inc new file mode 100644 index 0000000000..1b6b256d3c --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/cdrom.inc @@ -0,0 +1,261 @@ +sys_cd_audio: + + cmp word [cdbase],word 0 + jnz @f + mov eax,1 + ret + @@: + + ; eax=1 cdplay at ebx 0x00FFSSMM + ; eax=2 get tracklist size of ecx to [ebx] + ; eax=3 stop/pause playing + + cmp eax,1 + jnz nocdp + call sys_cdplay + ret + nocdp: + + cmp eax,2 + jnz nocdtl + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add ebx,[edi] + call sys_cdtracklist + ret + nocdtl: + + cmp eax,3 + jnz nocdpause + call sys_cdpause + ret + nocdpause: + + mov eax,0xffffff01 + ret + + + +sys_cd_atapi_command: + + pushad + + mov dx,word [cdbase] + add dx,6 + mov ax,word [cdid] + out dx,al + mov esi,10 + call delay_ms + mov dx,word [cdbase] + add dx,7 + in al,dx + and al,0x80 + cmp al,0 + jnz res + jmp cdl6 + res: + mov dx,word [cdbase] + add dx,7 + mov al,0x8 + out dx,al + mov dx,word [cdbase] + add dx,0x206 + mov al,0xe + out dx,al + mov esi,1 + call delay_ms + mov dx,word [cdbase] + add dx,0x206 + mov al,0x8 + out dx,al + mov esi,30 + call delay_ms + xor cx,cx + cdl5: + inc cx + cmp cx,10 + jz cdl6 + mov dx,word [cdbase] + add dx,7 + in al,dx + and al,0x88 + cmp al,0x00 + jz cdl5 + mov esi,100 + call delay_ms + jmp cdl5 + cdl6: + mov dx,word [cdbase] + add dx,4 + mov al,0 + out dx,al + mov dx,word [cdbase] + add dx,5 + mov al,0 + out dx,al + mov dx,word [cdbase] + add dx,7 + mov al,0xec + out dx,al + mov esi,5 + call delay_ms + mov dx,word [cdbase] + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,0 + out dx,al + add dx,1 + mov al,128 + out dx,al + add dx,2 + mov al,0xa0 + out dx,al + xor cx,cx + mov dx,word [cdbase] + add dx,7 + cdl1: + inc cx + cmp cx,100 + jz cdl2 + in al,dx + and ax,0x88 + cmp al,0x8 + jz cdl2 + mov esi,2 + call delay_ms + jmp cdl1 + cdl2: + + popad + ret + + +sys_cdplay: + + mov ax,5 + push ax + push ebx + cdplay: + call sys_cd_atapi_command + cli + mov dx,word [cdbase] + mov ax,0x0047 + out dx,ax + mov al,1 + mov ah,[esp+0] ; min xx + out dx,ax + mov ax,[esp+1] ; fr sec + out dx,ax + mov ax,256+99 + out dx,ax + mov ax,0x0001 + out dx,ax + mov ax,0x0000 + out dx,ax + mov esi,10 + call delay_ms + sti + add dx,7 + in al,dx + test al,1 + jz cdplayok + mov ax,[esp+4] + dec ax + mov [esp+4],ax + cmp ax,0 + jz cdplayfail + jmp cdplay + cdplayfail: + cdplayok: + pop ebx + pop ax + xor eax, eax + ret + + +sys_cdtracklist: + + push ebx + tcdplay: + call sys_cd_atapi_command + mov dx,word [cdbase] + mov ax,0x43+2*256 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,0x0 + out dx,ax + mov ax,200 + out dx,ax + mov ax,0x0 + out dx,ax + in al,dx + mov cx,1000 + mov dx,word [cdbase] + add dx,7 + cld + cdtrnwewait: + mov esi,10 + call delay_ms + in al,dx + and al,128 + cmp al,0 + jz cdtrl1 + loop cdtrnwewait + cdtrl1: + ; read the result + mov ecx,[esp+0] + mov dx,word [cdbase] + cdtrread: + add dx,7 + in al,dx + and al,8 + cmp al,8 + jnz cdtrdone + sub dx,7 + in ax,dx + mov [ecx],ax + add ecx,2 + jmp cdtrread + cdtrdone: + pop ecx + xor eax, eax + ret + + +sys_cdpause: + + call sys_cd_atapi_command + + mov dx,word [cdbase] + mov ax,0x004B + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + mov ax,0 + out dx,ax + + mov esi,10 + call delay_ms + add dx,7 + in al,dx + + xor eax, eax + ret + diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/fdc.inc b/kernel/tags/kolibri0.6.0.0/blkdev/fdc.inc new file mode 100644 index 0000000000..6b4e438d32 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/fdc.inc @@ -0,0 +1,73 @@ +iglobal + ;function pointers. + fdc_irq_func dd fdc_null +endg + +uglobal + dmasize db 0x0 + dmamode db 0x0 +endg + +fdc_init: ;start with clean tracks. + mov edi,0xD201 + mov al,0 + mov ecx,160 + rep stosb +ret + +fdc_filesave: ;ebx: cluster to be saved. + pusha ;returns immediately. does not trigger a write. + mov eax,ebx + add eax,31 + mov bl,18 + div bl + mov ah,0 + add eax,0xD201 + mov [eax],byte 1 ;This track is now dirty. + popa +ret + +fdc_irq: + call [fdc_irq_func] +fdc_null: +ret + +save_image: + call reserve_flp + call restorefatchain + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_save_image + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],1 ; Сектор + mov esi,0x100000 + call SeekTrack +save_image_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr +; call WriteSector + cmp [FDC_Status],0 + jne unnecessary_save_image + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne save_image_1 + mov [FDD_Sector],1 + inc [FDD_Head] + cmp [FDD_Head],2 + jne save_image_1 + mov [FDD_Head],0 + inc [FDD_Track] + call SeekTrack + cmp [FDD_Track],80 + jne save_image_1 +unnecessary_save_image: + mov [fdc_irq_func],fdc_null + popa + mov [flp_status],0 + ret + diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/flp_drv.inc b/kernel/tags/kolibri0.6.0.0/blkdev/flp_drv.inc new file mode 100644 index 0000000000..c969d7a877 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/flp_drv.inc @@ -0,0 +1,615 @@ +;********************************************************** +; Непосредственная работа с контроллером гибкого диска +;********************************************************** +; Автор исходного текста Кулаков Владимир Геннадьевич. +; Адаптация и доработка Mario79 + +give_back_application_data: ; переслать приложению + mov edi,[0x3010] + mov edi,[edi+TASKDATA.mem_start] + add edi,ecx +give_back_application_data_1: + mov esi,0xD000 ;FDD_DataBuffer ;0x40000 + xor ecx,ecx + mov cx,128 + cld + rep movsd + ret + +take_data_from_application: ; взять из приложения + mov esi,[0x3010] + mov esi,[esi+TASKDATA.mem_start] + add esi,ecx +take_data_from_application_1: + mov edi,0xD000 ;FDD_DataBuffer ;0x40000 + xor ecx,ecx + mov cx,128 + cld + 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 ;сектор не найден + +; Максимальные значения координат сектора (заданные +; значения соответствуют параметрам стандартного +; трехдюймового гибкого диска объемом 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 ? +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 + mov al,0 + out 0x0c,al ; reset the flip-flop to a known state. + mov al,6 ; mask channel 2 so we can reprogram it. + out 0x0a,al + mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy + out 0x0b,al + mov al,0 + out 0x0c,al ; reset the flip-flop to a known state. + mov eax,0xD000 + out 0x04,al ; set the channel 2 starting address to 0 + shr eax,8 + out 0x04,al + shr eax,8 + out 0x81,al + mov al,0 + out 0x0c, al ; reset flip-flop + mov al, 0xff ;set count (actual size -1) + out 0x5, al + mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) + out 0x5,al + mov al,2 + out 0xa,al + popad + ret + +;*********************************** +;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC * +;* Параметры: * +;* AL - выводимый байт. * +;*********************************** +FDCDataOutput: +; pusha + push eax ecx edx + mov AH,AL ;запомнить байт в AH +; Сбросить переменную состояния контроллера + mov [FDC_Status],FDC_Normal +; Проверить готовность контроллера к приему данных + mov DX,3F4h ;(порт состояния FDC) + mov ecx, 0x10000 ;установить счетчик тайм-аута +@@TestRS: + 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 + out DX,AL +@@End_5: +; popa + pop edx ecx eax + ret + +;****************************************** +;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC * +;* Процедура не имеет входных параметров. * +;* Выходные данные: * +;* AL - считанный байт. * +;****************************************** +FDCDataInput: + push ECX + push DX +; Сбросить переменную состояния контроллера + mov [FDC_Status],FDC_Normal +; Проверить готовность контроллера к передаче данных + mov DX,3F4h ;(порт состояния FDC) + xor CX,CX ;установить счетчик тайм-аута +@@TestRS_1: + 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 +@@End_6: pop DX + pop ECX + 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 ;прерывание произошло + call change_task + mov eax,[timer_ticks] + sub eax,[TickCounter] + cmp eax,50 ;25 ;5 ;ожидать 5 тиков + jb @@TestRS_2 +; jl @@TestRS_2 +; Ошибка тайм-аута + mov [FDC_Status],FDC_TimeOut +; mov [flp_status],0 +@@End_7: popa + ret + +;********************************* +;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * +;********************************* +FDDMotorON: + pusha +; cmp [fdd_motor_status],1 +; je fdd_motor_on + mov al,[flp_number] + cmp [fdd_motor_status],al + je fdd_motor_on +; Произвести сброс контроллера НГМД + mov DX,3F2h ;порт управления двигателями + mov AL,0 + out DX,AL +; Выбрать и включить мотор дисковода + cmp [flp_number],1 + jne FDDMotorON_B +; call FDDMotorOFF_B + mov AL,1Ch ; Floppy A + jmp FDDMotorON_1 +FDDMotorON_B: +; call FDDMotorOFF_A + mov AL,2Dh ; Floppy B +FDDMotorON_1: + out DX,AL +; Обнулить счетчик тиков + mov eax,[timer_ticks] + mov [TickCounter],eax +; Ожидать 0,5 с +@@dT: + call change_task + mov eax,[timer_ticks] + sub eax,[TickCounter] + cmp eax,50 ;10 + jb @@dT + cmp [flp_number],1 + jne fdd_motor_on_B + mov [fdd_motor_status],1 + jmp fdd_motor_on +fdd_motor_on_B: + mov [fdd_motor_status],2 +fdd_motor_on: + call save_timer_fdd_motor + popa + ret + +;***************************************** +;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * +;***************************************** +save_timer_fdd_motor: + mov eax,[timer_ticks] + mov [timer_fdd_motor],eax + ret + +;***************************************** +;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * +;***************************************** +check_fdd_motor_status: + cmp [fdd_motor_status],0 + je end_check_fdd_motor_status_1 + mov eax,[timer_ticks] + sub eax,[timer_fdd_motor] + cmp eax,500 + jb end_check_fdd_motor_status + call FDDMotorOFF + mov [fdd_motor_status],0 +end_check_fdd_motor_status_1: + mov [flp_status],0 +end_check_fdd_motor_status: + ret + +;********************************** +;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * +;********************************** +FDDMotorOFF: + push AX + push DX + cmp [flp_number],1 + jne FDDMotorOFF_1 + call FDDMotorOFF_A + jmp FDDMotorOFF_2 +FDDMotorOFF_1: + call FDDMotorOFF_B +FDDMotorOFF_2: + pop DX + pop AX + ; сброс флагов кеширования в связи с устареванием информации + mov [root_read],0 + mov [flp_fat],0 + ret + +FDDMotorOFF_A: + mov DX,3F2h ;порт управления двигателями + mov AL,0Ch ; Floppy A + out DX,AL + ret + +FDDMotorOFF_B: + mov DX,3F2h ;порт управления двигателями + mov AL,5h ; Floppy B + out DX,AL + ret + +;******************************* +;* РЕКАЛИБРОВКА ДИСКОВОДА "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 +; mov [flp_status],0 +;no_fdc_status_error: + call save_timer_fdd_motor + popa + ret + +;***************************************************** +;* ПОИСК ДОРОЖКИ * +;* Параметры передаются через глобальные переменные: * +;* 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: ; Трек не найден + mov [FDC_Status],FDC_TrackNotFound +; mov [flp_status],0 +@@Exit: + call save_timer_fdd_motor + popa + ret + +;******************************************************* +;* ЧТЕНИЕ СЕКТОРА ДАННЫХ * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции чтения * +;* содержимое сектора будет занесено в FDD_DataBuffer. * +;******************************************************* +ReadSector: + pushad + call save_timer_fdd_motor +; Установить скорость передачи 500 Кбайт/с + mov AX,0 + mov DX,03F7h + out DX,AL +; Инициализировать канал прямого доступа к памяти + mov [dmamode],0x46 + call Init_FDC_DMA +; Подать команду "Чтение данных" + mov AL,0E6h ;чтение в мультитрековом режиме + call FDCDataOutput + mov AL,[FDD_Head] + shl AL,2 + call FDCDataOutput + mov AL,[FDD_Track] + call FDCDataOutput + mov AL,[FDD_Head] + call FDCDataOutput + mov AL,[FDD_Sector] + call FDCDataOutput + mov AL,2 ;код размера сектора (512 байт) + call FDCDataOutput + mov AL,18 ;+1; 3Fh ;число секторов на дорожке + call FDCDataOutput + mov AL,1Bh ;значение GPL + call FDCDataOutput + 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 + mov [FDC_Status],FDC_Normal + jmp @@Exit_1 +@@Err_1: mov [FDC_Status],FDC_SectorNotFound +; mov [flp_status],0 +@@Exit_1: + call save_timer_fdd_motor + popad + ret + +;******************************************************* +;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * +;* Параметры передаются через глобальные переменные: * +;* 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 + cmp [FDC_Status],0 + je @@Exit_2 + cmp [FDC_Status],1 + je @@Err_3 + ; Троекратное повторение чтения + inc [ReadRepCounter] + cmp [ReadRepCounter],3 + jb @@ReadSector_1 + ; Троекратное повторение рекалибровки + call RecalibrateFDD + call SeekTrack + inc [RecalRepCounter] + cmp [RecalRepCounter],3 + jb @@TryAgain +; mov [flp_status],0 +@@Exit_2: + popa + ret +@@Err_3: + mov [flp_status],0 + popa + ret + +;******************************************************* +;* ЗАПИСЬ СЕКТОРА ДАННЫХ * +;* Параметры передаются через глобальные переменные: * +;* FDD_Track - номер дорожки (0-79); * +;* FDD_Head - номер головки (0-1); * +;* FDD_Sector - номер сектора (1-18). * +;* Результат операции заносится в FDC_Status. * +;* В случае успешного выполнения операции записи * +;* содержимое FDD_DataBuffer будет занесено в сектор. * +;******************************************************* +WriteSector: + pushad + call save_timer_fdd_motor +; Установить скорость передачи 500 Кбайт/с + mov AX,0 + mov DX,03F7h + out DX,AL +; Инициализировать канал прямого доступа к памяти + mov [dmamode],0x4A + call Init_FDC_DMA +; Подать команду "Запись данных" + mov AL,0xC5 ;0x45 ;запись в мультитрековом режиме + call FDCDataOutput + mov AL,[FDD_Head] + shl AL,2 + call FDCDataOutput + mov AL,[FDD_Track] + call FDCDataOutput + mov AL,[FDD_Head] + call FDCDataOutput + mov AL,[FDD_Sector] + call FDCDataOutput + mov AL,2 ;код размера сектора (512 байт) + call FDCDataOutput + mov AL,18; 3Fh ;число секторов на дорожке + call FDCDataOutput + mov AL,1Bh ;значение GPL + call FDCDataOutput + 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 + mov [FDC_Status],FDC_Normal + jmp @@Exit_3 +@@Err_2: mov [FDC_Status],FDC_SectorNotFound +@@Exit_3: + call save_timer_fdd_motor + popad + ret + +;******************************************************* +;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * +;* Параметры передаются через глобальные переменные: * +;* 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 + cmp [FDC_Status],0 + je @@Exit_4 + cmp [FDC_Status],1 + je @@Err_4 + ; Троекратное повторение чтения + inc [ReadRepCounter] + cmp [ReadRepCounter],3 + jb @@WriteSector_1 + ; Троекратное повторение рекалибровки + call RecalibrateFDD + call SeekTrack + inc [RecalRepCounter] + cmp [RecalRepCounter],3 + jb @@TryAgain_1 +@@Exit_4: + popa + ret +@@Err_4: + mov [flp_status],0 + popa + ret + +;********************************************* +;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * +;********************************************* +GetStatusInfo: + push AX + call FDCDataInput + mov [FDC_ST0],AL + call FDCDataInput + mov [FDC_ST1],AL + call FDCDataInput + mov [FDC_ST2],AL + call FDCDataInput + mov [FDC_C],AL + call FDCDataInput + mov [FDC_H],AL + call FDCDataInput + mov [FDC_R],AL + call FDCDataInput + mov [FDC_N],AL + pop AX + ret + diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/rd.inc b/kernel/tags/kolibri0.6.0.0/blkdev/rd.inc new file mode 100644 index 0000000000..0a9f876440 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/rd.inc @@ -0,0 +1,2292 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; RAMDISK functions ;; +;; (C) 2004 Ville Turjanmaa, License: GPL ;; +;; Addings by M.Lisovin ;; +;; LFN support by diamond ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; calculate fat chain + +calculatefatchain: + + pushad + + mov esi,0x100000+512 + mov edi,0x280000 + + fcnew: + mov eax,dword [esi] + mov ebx,dword [esi+4] + mov ecx,dword [esi+8] + mov edx,ecx + shr edx,4 ;8 ok + shr dx,4 ;7 ok + xor ch,ch + shld ecx,ebx,20 ;6 ok + shr cx,4 ;5 ok + shld ebx,eax,12 + and ebx,0x0fffffff ;4 ok + shr bx,4 ;3 ok + shl eax,4 + and eax,0x0fffffff ;2 ok + shr ax,4 ;1 ok + mov dword [edi],eax + mov dword [edi+4],ebx + mov dword [edi+8],ecx + mov dword [edi+12],edx + add edi,16 + add esi,12 + + cmp edi,0x280000+2856*2 ;2849 clusters + jnz fcnew + + popad + ret + + +restorefatchain: ; restore fat chain + + pushad + + mov esi,0x280000 + mov edi,0x100000+512 + + fcnew2: + mov eax,dword [esi] + mov ebx,dword [esi+4] + shl ax,4 + shl eax,4 + shl bx,4 + shr ebx,4 + shrd eax,ebx,8 + shr ebx,8 + mov dword [edi],eax + mov word [edi+4],bx + add edi,6 + add esi,8 + + cmp edi,0x100000+512+4278 ;4274 bytes - all used FAT + jb fcnew2 + + mov esi,0x100000+512 ; duplicate fat chain + mov edi,0x100000+512+0x1200 + mov ecx,1069 ;4274/4 + cld + rep movsd + + popad + ret + + +ramdisk_free_space: +;--------------------------------------------- +; +; returns free space in edi +; rewr.by Mihasik +;--------------------------------------------- + + push eax ebx ecx + + mov edi,0x280000 ;start of FAT + xor ax,ax ;Free cluster=0x0000 in FAT + xor ebx,ebx ;counter + mov ecx,2849 ;2849 clusters + cld + rdfs1: + repne scasw + jnz rdfs2 ;if last cluster not 0 + inc ebx + test ecx, ecx + jnz rdfs1 + rdfs2: + shl ebx,9 ;free clusters*512 + mov edi,ebx + + pop ecx ebx eax + ret + + +expand_filename: +;--------------------------------------------- +; +; exapand filename with '.' to 11 character +; eax - pointer to filename +;--------------------------------------------- + + push esi edi ebx + + mov edi,esp ; check for '.' in the name + add edi,12+8 + + mov esi,eax + + mov eax,edi + mov [eax+0],dword ' ' + mov [eax+4],dword ' ' + mov [eax+8],dword ' ' + + flr1: + + cmp [esi],byte '.' + jne flr2 + mov edi,eax + add edi,7 + jmp flr3 + + flr2: + + mov bl,[esi] + mov [edi],bl + + flr3: + + inc esi + inc edi + + mov ebx,eax + add ebx,11 + + cmp edi,ebx + jbe flr1 + + pop ebx edi esi + ret + +fileread: +;---------------------------------------------------------------- +; +; fileread - sys floppy +; +; eax points to filename 11 chars +; ebx first wanted block ; 1+ ; if 0 then set to 1 +; ecx number of blocks to read ; 1+ ; if 0 then set to 1 +; edx mem location to return data +; esi length of filename 12*X 0=root +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- + test ebx,ebx ;if ebx=0 - set to 1 + jnz frfl5 + inc ebx + frfl5: + test ecx,ecx ;if ecx=0 - set to 1 + jnz frfl6 + inc ecx + frfl6: + test esi,esi ; return ramdisk root + jnz fr_noroot ;if not root + cmp ebx,14 ;14 clusters=root dir + ja oorr + cmp ecx,14 + ja oorr + jmp fr_do + oorr: + mov eax,5 ;out of root range (fnf) + xor ebx,ebx + dec ebx ;0xffffffff + ret + + fr_do: ;reading rootdir + mov edi,edx + dec ebx + push edx + mov edx,ecx + add edx,ebx + cmp edx,15 ;ebx+ecx=14+1 + pushf + jbe fr_do1 + sub edx,14 + sub ecx,edx + fr_do1: + shl ebx,9 + mov esi,0x100000+512*19 + add esi,ebx + shl ecx,7 + cld + rep movsd + popf + pop edx + jae fr_do2 + xor eax,eax ; ok read + xor ebx,ebx + ret + fr_do2: ;if last cluster + mov eax,6 ;end of file + xor ebx,ebx + ret + + fr_noroot: + + sub esp,32 + call expand_filename + + dec ebx + + push eax + + push eax ebx ecx edx esi edi + call rd_findfile + je fifound + add esp,32+28 ;if file not found + ret + + fifound: + + mov ebx,[edi-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + add edi,0xf + movzx eax,word [edi] + mov edi,eax ;edi=cluster + + frnew: + + add eax,31 ;bootsector+2*fat+filenames + shl eax,9 ;*512 + add eax,0x100000 ;image base + mov ebx,[esp+8] + mov ecx,512 ;[esp+4] + + cmp [esp+16],dword 0 ; wanted cluster ? + jne frfl7 + call memmove + add [esp+8],dword 512 + dec dword [esp+12] ; last wanted cluster ? + je frnoread + jmp frfl8 + frfl7: + dec dword [esp+16] + frfl8: + movzx eax,word [edi*2+0x280000] ; find next cluster from FAT + mov edi,eax + cmp edi,4095 ;eof - cluster + jz frnoread2 + + cmp [esp+24],dword 512 ;eof - size + jb frnoread + sub [esp+24],dword 512 + + jmp frnew + + frnoread2: + + cmp [esp+16],dword 0 ; eof without read ? + je frnoread + + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + mov eax,6 ; end of file + ret + + frnoread: + + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + xor eax,eax ;read ok + ret + +filedelete: +;-------------------------------------------- +; +; filedelete - sys floppy +; in: +; eax - pointer to filename 11 chars +; +; out: +; eax - 0 = successful, 5 = file not found +; +;-------------------------------------------- + + sub esp,32 + call expand_filename + + push eax ebx ecx edx esi edi + + call rd_findfile + je fifoundd + pop edi esi edx ecx ebx eax ;file not found + add esp,32 + mov eax,5 + ret + + fifoundd: + + mov [edi-11],byte 0xE5 ;mark filename deleted + add edi,0xf + movzx eax,word [edi] + mov edi,eax ;edi = cluster + + frnewd: + + shl edi,1 ;find next cluster from FAT + add edi,0x280000 + movzx eax,word [edi] + mov [edi],word 0x0 ;clear fat chain cluster + mov edi,eax + cmp edi,dword 0xff8 ;last cluster ? + jb frnewd + + pop edi esi edx ecx ebx eax + add esp,32 + xor eax,eax ; file found + ret + + + +filesave: +;---------------------------------------------------------- +; +; filesave - sys floppy +; +; eax points to filename 11 chars +; +; eax ; pointer to file name +; ebx ; buffer +; ecx ; count to write in bytes +; edx ; 0 create new , 1 append +; +;----------------------------------------------------------- + + sub esp,32 + call expand_filename + test edx,edx + jnz fsdel + pusha + call filedelete + popa + + fsdel: + + call ramdisk_free_space + cmp ecx,edi + jbe rd_do_save + add esp,32 + mov eax,8 ;disk full + ret + + rd_do_save: + + push eax ebx ecx edx esi edi + + mov edi,0x100000+512*18+512 ;Point at directory + mov edx,224 +1 + ; find an empty spot for filename in the root dir + l20ds: + dec edx + jz frnoreadds + l21ds: + cmp [edi],byte 0xE5 + jz fifoundds + cmp [edi],byte 0x0 + jz fifoundds + add edi,32 ; Advance to next entry + jmp l20ds + fifoundds: + + push edi ; move the filename to root dir + mov esi,[esp+4+20] + mov ecx,11 + cld + rep movsb + pop edi + mov edx,edi + add edx,11+0xf ; edx <- cluster save position + mov ebx,[esp+12] ; save file size + mov [edi+28],ebx + mov [edi+11],byte 0x20 ; attribute +; Ivan Poddubny 11/12/2003: +call get_date_for_file ; from FAT32.INC +mov [edi+24],ax ; date +call get_time_for_file ; from FAT32.INC +mov [edi+22],ax ; time +; End + mov edi,0x280000 ;pointer to first cluster + mov ecx,2849 + cld + frnewds: + xor ax,ax + repne scasw + mov ebx,2848 + sub ebx,ecx + mov [edx],bx ; save next cluster pos. to prev cl. + mov edx,edi ; next save pos abs mem add + dec edx + dec edx + call fdc_filesave + pusha ; move save to floppy cluster + add ebx,31 + shl ebx,9 + add ebx,0x100000 + mov eax,[esp+32+16] + mov ecx,512 + call memmove + popa + + mov eax,[esp+12] + cmp eax,512 + jbe flnsa + sub eax,512 + mov [esp+12],eax + add dword [esp+16], 512 + jmp frnewds + + flnsa: + mov [edi-2],word 4095 ; mark end of file - last cluster + + frnoreadds: + + pop edi esi edx ecx ebx eax + add esp,32 + +; pusha +; cli +; call fdc_commitfile +; sti +; popa + + xor eax,eax ;ok write + ret + + rd_findfile: + ;by Mihasik + ;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx + + mov edi,0x100000+512*18+512 ;Point at directory + cld + rd_newsearch: + mov esi,eax + mov ecx,11 + rep cmpsb + je rd_ff + add cl,21 + add edi,ecx + cmp edi,0x100000+512*33 + jb rd_newsearch + mov eax,5 ;if file not found - eax=5 + xor ebx,ebx + dec ebx ;ebx=0xffffffff and zf=0 + rd_ff: + ret + +; \begin{diamond} + +uni2ansi_str: +; convert UNICODE zero-terminated string to ASCII-string (codepage 866) +; in: esi->source, edi->buffer (may be esi=edi) +; destroys: eax,esi,edi + lodsw + test ax, ax + jz .done + cmp ax, 0x80 + jb .ascii + cmp ax, 0x401 + jz .yo1 + cmp ax, 0x451 + jz .yo2 + cmp ax, 0x410 + jb .unk + cmp ax, 0x440 + jb .rus1 + cmp ax, 0x450 + jb .rus2 +.unk: + mov al, '_' + jmp .doit +.yo1: + mov al, 'р' + jmp .doit +.yo2: + mov al, 'с' + jmp .doit +.rus1: +; 0x410-0x43F -> 0x80-0xAF + add al, 0x70 + jmp .doit +.rus2: +; 0x440-0x44F -> 0xE0-0xEF + add al, 0xA0 +.ascii: +.doit: + stosb + jmp uni2ansi_str +.done: + mov byte [edi], 0 + ret + +ansi2uni_char: +; convert ANSI character in al to UNICODE character in ax, using cp866 encoding + mov ah, 0 +; 0x00-0x7F - trivial map + cmp al, 0x80 + jb .ret +; 0x80-0xAF -> 0x410-0x43F + cmp al, 0xB0 + jae @f + add ax, 0x410-0x80 +.ret: + ret +@@: +; 0xE0-0xEF -> 0x440-0x44F + cmp al, 0xE0 + jb .unk + cmp al, 0xF0 + jae @f + add ax, 0x440-0xE0 + ret +; 0xF0 -> 0x401 +; 0xF1 -> 0x451 +@@: + cmp al, 'р' + jz .yo1 + cmp al, 'с' + jz .yo2 +.unk: + mov al, '_' ; ah=0 + ret +.yo1: + mov ax, 0x401 + ret +.yo2: + mov ax, 0x451 + ret + +char_toupper: +; convert character to uppercase, using cp866 encoding +; in: al=symbol +; out: al=converted symbol + cmp al, 'a' + jb .ret + cmp al, 'z' + jbe .az + cmp al, ' ' + jb .ret + cmp al, 'а' + jb .rus1 + cmp al, 'п' + ja .ret +; 0xE0-0xEF -> 0x90-0x9F + sub al, 'а'-'ђ' +.ret: + ret +.rus1: +; 0xA0-0xAF -> 0x80-0x8F +.az: + and al, not 0x20 + ret + +fat_get_name: +; in: edi->FAT entry +; out: CF=1 - no valid entry +; else CF=0 and ebp->ASCIIZ-name +; (maximum length of filename is 255 (wide) symbols without trailing 0, +; but implementation requires buffer 261 words) +; destroys eax + cmp byte [edi], 0 + jz .no + cmp byte [edi], 0xE5 + jnz @f +.no: + stc + ret +@@: + cmp byte [edi+11], 0xF + jz .longname + push ecx + mov ecx, 8 + push edi ebp ecx + test byte [ebp-4], 1 + jnz .unicode_short +@@: + mov al, [edi] + inc edi + mov [ebp], al + inc ebp + loop @b + pop ecx +@@: + cmp byte [ebp-1], ' ' + jnz @f + dec ebp + loop @b +@@: + mov byte [ebp], '.' + inc ebp + mov ecx, 3 + push ecx +@@: + mov al, [edi] + inc edi + mov [ebp], al + inc ebp + loop @b + pop ecx +@@: + cmp byte [ebp-1], ' ' + jnz @f + dec ebp + loop @b + dec ebp +@@: + and byte [ebp], 0 ; CF=0 + pop ebp edi ecx + ret +.unicode_short: +@@: + mov al, [edi] + inc edi + call ansi2uni_char + mov [ebp], ax + inc ebp + inc ebp + loop @b + pop ecx +@@: + cmp word [ebp-2], ' ' + jnz @f + dec ebp + dec ebp + loop @b +@@: + mov word [ebp], '.' + inc ebp + inc ebp + mov ecx, 3 + push ecx +@@: + mov al, [edi] + inc edi + call ansi2uni_char + mov [ebp], ax + inc ebp + inc ebp + loop @b + pop ecx +@@: + cmp word [ebp-2], ' ' + jnz @f + dec ebp + dec ebp + loop @b + dec ebp + dec ebp +@@: + and word [ebp], 0 ; CF=0 + pop ebp edi ecx + ret +.longname: +; LFN + mov al, byte [edi] + and eax, 0x3F + dec eax + cmp al, 20 + jae .no ; ignore invalid entries + mov word [ebp+260*2], 0 ; force null-terminating for orphans + imul eax, 13*2 + add ebp, eax + test byte [edi], 0x40 + jz @f + mov word [ebp+13*2], 0 +@@: + push eax +; now copy name from edi to ebp ... + mov eax, [edi+1] + mov [ebp], eax ; symbols 1,2 + mov eax, [edi+5] + mov [ebp+4], eax ; 3,4 + mov eax, [edi+9] + mov [ebp+8], ax ; 5 + mov eax, [edi+14] + mov [ebp+10], eax ; 6,7 + mov eax, [edi+18] + mov [ebp+14], eax ; 8,9 + mov eax, [edi+22] + mov [ebp+18], eax ; 10,11 + mov eax, [edi+28] + mov [ebp+22], eax ; 12,13 +; ... done + pop eax + sub ebp, eax + test eax, eax + jz @f +; if this is not first entry, more processing required + stc + ret +@@: +; if this is first entry: + test byte [ebp-4], 1 + jnz .ret +; buffer at ebp contains UNICODE name, convert it to ANSI + push esi edi + mov esi, ebp + mov edi, ebp + call uni2ansi_str + pop edi esi +.ret: + clc + ret + +fat_compare_name: +; compares ASCIIZ-names, case-insensitive (cp866 encoding) +; in: esi->name, ebp->name +; out: if names match: ZF=1 and esi->next component of name +; else: ZF=0, esi is not changed +; destroys eax + push ebp esi +.loop: + mov al, [ebp] + inc ebp + call char_toupper + push eax + lodsb + call char_toupper + cmp al, [esp] + jnz .done + pop eax + test al, al + jnz .loop + dec esi + pop eax + pop ebp + xor eax, eax ; set ZF flag + ret +.done: + cmp al, '/' + jnz @f + cmp byte [esp], 0 + jnz @f + mov [esp+4], esi +@@: + pop eax + pop esi ebp + ret + +fat_time_to_bdfe: +; in: eax=FAT time +; out: eax=BDFE time + push ecx edx + mov ecx, eax + mov edx, eax + shr eax, 11 + shl eax, 16 ; hours + and edx, 0x1F + add edx, edx + mov al, dl ; seconds + shr ecx, 5 + and ecx, 0x3F + mov ah, cl ; minutes + pop edx ecx + ret + +fat_date_to_bdfe: + push ecx edx + mov ecx, eax + mov edx, eax + shr eax, 9 + add ax, 1980 + shl eax, 16 ; year + and edx, 0x1F + mov al, dl ; day + shr ecx, 5 + and ecx, 0xF + mov ah, cl ; month + pop edx ecx + ret + +bdfe_to_fat_time: + push edx + mov edx, eax + shr eax, 16 + and dh, 0x3F + shl eax, 6 + or al, dh + shr dl, 1 + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + +bdfe_to_fat_date: + push edx + mov edx, eax + shr eax, 16 + sub ax, 1980 + and dh, 0xF + shl eax, 4 + or al, dh + and dl, 0x1F + shl eax, 5 + or al, dl + pop edx + ret + +fat_entry_to_bdfe: +; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi +; destroys eax + mov eax, [ebp-4] + mov [esi+4], eax ; ASCII/UNICODE name +fat_entry_to_bdfe2: + movzx eax, byte [edi+11] + mov [esi], eax ; attributes + movzx eax, word [edi+14] + call fat_time_to_bdfe + mov [esi+8], eax ; creation time + movzx eax, word [edi+16] + call fat_date_to_bdfe + mov [esi+12], eax ; creation date + and dword [esi+16], 0 ; last access time is not supported on FAT + movzx eax, word [edi+18] + call fat_date_to_bdfe + mov [esi+20], eax ; last access date + movzx eax, word [edi+22] + call fat_time_to_bdfe + mov [esi+24], eax ; last write time + movzx eax, word [edi+24] + call fat_date_to_bdfe + mov [esi+28], eax ; last write date + mov eax, [edi+28] + mov [esi+32], eax ; file size (low dword) + xor eax, eax + mov [esi+36], eax ; file size (high dword) + test ebp, ebp + jz .ret + push ecx edi + lea edi, [esi+40] + mov esi, ebp + test byte [esi-4], 1 + jz .ansi + mov ecx, 260/2 + rep movsd + mov [edi-2], ax +@@: + mov esi, edi + pop edi ecx +.ret: + ret +.ansi: + mov ecx, 264/4 + rep movsd + mov [edi-1], al + jmp @b + +bdfe_to_fat_entry: +; convert BDFE at edx to FAT entry at edi +; destroys eax +; attributes byte + test byte [edi+11], 8 ; volume label? + jnz @f + mov al, [edx] + and al, 0x27 + and byte [edi+11], 0x10 + or byte [edi+11], al +@@: + mov eax, [edx+8] + call bdfe_to_fat_time + mov [edi+14], ax ; creation time + mov eax, [edx+12] + call bdfe_to_fat_date + mov [edi+16], ax ; creation date + mov eax, [edx+20] + call bdfe_to_fat_date + mov [edi+18], ax ; last access date + mov eax, [edx+24] + call bdfe_to_fat_time + mov [edi+22], ax ; last write time + mov eax, [edx+28] + call bdfe_to_fat_date + mov [edi+24], ax ; last write date + ret + +ramdisk_root_first: + mov edi, 0x100000+512*19 + clc + ret +ramdisk_root_next: + add edi, 0x20 + cmp edi, 0x100000+512*33 + cmc + ret + +ramdisk_root_extend_dir: + stc + ret + +ramdisk_notroot_next: + add edi, 0x20 + test edi, 0x1FF + jz ramdisk_notroot_next_sector + ret ; CF=0 +ramdisk_notroot_next_sector: + push ecx + mov ecx, [eax] + mov ecx, [ecx*2+0x280000] + and ecx, 0xFFF + cmp ecx, 2849 + jae ramdisk_notroot_first.err2 + mov [eax], ecx + pop ecx +ramdisk_notroot_first: + mov eax, [eax] + cmp eax, 2 + jb .err + cmp eax, 2849 + jae .err + shl eax, 9 + lea edi, [eax+(31 shl 9)+0x100000] + clc + ret +.err2: + pop ecx +.err: + stc + ret +ramdisk_notroot_next_write: + test edi, 0x1FF + jz ramdisk_notroot_next_sector +ramdisk_root_next_write: + ret + +ramdisk_notroot_extend_dir: + pusha + xor eax, eax + mov edi, 0x280000 + mov ecx, 2849 + repnz scasw + jnz .notfound + mov word [edi-2], 0xFFF + sub edi, 0x280000 + shr edi, 1 + dec edi + mov eax, [esp+28] + mov ecx, [eax] + mov [0x280000+ecx*2], di + mov [eax], edi + shl edi, 9 + add edi, (31 shl 9)+0x100000 + mov [esp], edi + xor eax, eax + mov ecx, 128 + rep stosd + popa + clc + ret +.notfound: + popa + stc + ret + +rd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and edi->direntry + push esi edi + push 0 + push ramdisk_root_first + push ramdisk_root_next +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found + test byte [edi+11], 10h + jz .notfound + movzx eax, word [edi+26] + mov [esp+8], eax + mov dword [esp+4], ramdisk_notroot_first + mov dword [esp], ramdisk_notroot_next + jmp .loop +.notfound: + add esp, 12 + pop edi esi + stc + ret +.found: + mov eax, [esp+8] + add esp, 16 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskRead - LFN variant for reading sys floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskRead: + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 ; EOF +@@: + movzx edi, word [edi+26] ; cluster +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + lea eax, [edi+31] ; bootsector+2*fat+filenames + shl eax, 9 ; *512 + add eax, 0x100000 ; image base +; now eax points to data of cluster + sub ebx, 512 + jae .skip + lea eax, [eax+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx +.skip: + movzx edi, word [edi*2+0x280000] ; find next cluster from FAT + jmp .new +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder +; +; esi points to filename; only root is folder on ramdisk +; ebx pointer to structure 32-bit number = first wanted block +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskReadFolder: + push edi + cmp byte [esi], 0 + jz .root + call rd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + movzx eax, word [edi+26] + add eax, 31 + push 0 + jmp .doit +.root: + mov eax, 19 + push 14 +.doit: + push esi ecx ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + mov byte [edx], 1 ; version + pop ecx eax + mov esi, edi ; esi points to block of data of folder entry (BDFE) +.main_loop: + mov edi, eax + shl edi, 9 + add edi, 0x100000 + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + test edi, 0x1FF + jnz .do_bdfe + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x280000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 +@@: + mov edi, eax + shl edi, 9 + add edi, 0x100000 + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec ebx + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + test edi, 0x1FF + jnz .l1 + pop eax + inc eax + dec byte [esp+262*2+16] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x280000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+16], 0 +@@: + jmp .main_loop +.done: + add esp, 262*2+4 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx esi edi edi + ret + +iglobal +label fat_legal_chars byte +; 0 = not allowed +; 1 = allowed only in long names +; 3 = allowed + times 32 db 0 +; ! " # $ % & ' ( ) * + , - . / + db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 +; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 +; @ A B C D E F G H I J K L M N O + db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 +; P Q R S T U V W X Y Z [ \ ] ^ _ + db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 +; ` a b c d e f g h i j k l m n o + db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 +; p q r s t u v w x y z { | } ~ + db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 +endg + +fat_name_is_legal: +; in: esi->(long) name +; out: CF set <=> legal +; destroys eax + push esi + xor eax, eax +@@: + lodsb + test al, al + jz .done + cmp al, 80h + jae .big + test [fat_legal_chars+eax], 1 + jnz @b +.err: + pop esi + clc + ret +.big: +; 0x80-0xAF, 0xE0-0xEF + cmp al, 0xB0 + jb @b + cmp al, 0xE0 + jb .err + cmp al, 0xF0 + jb @b + jmp .err +.done: + sub esi, [esp] + cmp esi, 257 + pop esi + ret + +fat_next_short_name: +; in: edi->8+3 name +; out: name corrected +; CF=1 <=> error + pushad + mov ecx, 8 + mov al, '~' + std + push edi + add edi, 7 + repnz scasb + pop edi + cld + jz .tilde +; tilde is not found, insert "~1" at end + add edi, 6 + cmp word [edi], ' ' + jnz .insert_tilde +@@: dec edi + cmp byte [edi], ' ' + jz @b + inc edi +.insert_tilde: + mov word [edi], '~1' + popad +; clc ; CF already cleared + ret +.tilde: + push edi + add edi, 7 + xor ecx, ecx +@@: +; after tilde may be only digits and trailing spaces + cmp byte [edi], '~' + jz .break + cmp byte [edi], ' ' + jz .space + cmp byte [edi], '9' + jnz .found + dec edi + jmp @b +.space: + dec edi + inc ecx + jmp @b +.found: + inc byte [edi] +.succ: + pop edi + popad + clc + ret +.break: + jecxz .noplace + inc edi + mov al, '1' +@@: + xchg al, [edi] + inc edi + cmp al, ' ' + mov al, '0' + jnz @b + jmp .succ +.noplace: + dec edi + cmp edi, [esp] + jz .err + add dword [esp], 8 + mov word [edi], '~1' + inc edi + inc edi +@@: + mov byte [edi], '0' + inc edi + cmp edi, [esp] + jb @b + pop edi + popad + ;clc ; automatically + ret +.err: + pop edi + popad + stc + ret + +fat_gen_short_name: +; in: esi->long name +; edi->buffer (8+3=11 chars) +; out: buffer filled + pushad + mov eax, ' ' + push edi + stosd + stosd + stosd + pop edi + xor eax, eax + push 8 + pop ebx + lea ecx, [edi+8] +.loop: + lodsb + test al, al + jz .done + call char_toupper + cmp al, ' ' + jz .space + cmp al, 80h + ja .big + test [fat_legal_chars+eax], 2 + jnz .symbol +.inv_symbol: + mov al, '_' + or bh, 1 +.symbol: + cmp al, '.' + jz .dot +.normal_symbol: + dec bl + jns .store + mov bl, 0 +.space: + or bh, 1 + jmp .loop +.store: + stosb + jmp .loop +.big: + cmp al, 0xB0 + jb .normal_symbol + cmp al, 0xE0 + jb .inv_symbol + cmp al, 0xF0 + jb .normal_symbol + jmp .inv_symbol +.dot: + test bh, 2 + jz .firstdot + pop ebx + add ebx, edi + sub ebx, ecx + push ebx + cmp edi, ecx + jbe .skip +@@: + dec edi + mov al, ' ' + xchg al, [edi] + dec ebx + mov [ebx], al + cmp edi, ecx + ja @b +.skip: + mov bh, 3 + jmp @f +.firstdot: + cmp bl, 8 + jz .space + push edi + or bh, 2 +@@: + mov edi, ecx + mov bl, 3 + jmp .loop +.done: + test bh, 2 + jz @f + pop edi +@@: + lea edi, [ecx-8] + test bh, 1 + jz @f + call fat_next_short_name +@@: + popad + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskRewrite - LFN variant for writing sys floppy +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +@@: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret + +fs_RamdiskRewrite: + cmp byte [esi], 0 + jz @b + pushad + xor ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + push ramdisk_root_extend_dir + push ramdisk_root_next_write + push ebp + push ramdisk_root_first + push ramdisk_root_next + jmp .common1 +.noroot: +; check existence + mov byte [ebp], 0 + call rd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + movzx ebp, word [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 + cmp ebp, 2849 + jae .ret1 + push ramdisk_notroot_extend_dir + push ramdisk_notroot_next_write + push ebp + push ramdisk_notroot_first + push ramdisk_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 20 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xchg ax, word [edi+26] ; start cluster + test eax, eax + jz .done1 +@@: + cmp eax, 0xFF8 + jae .done1 + lea edi, [0x280000 + eax*2] ; position in FAT + xor eax, eax + xchg ax, [edi] + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 20 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+20 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+12+8+12+8] + mov [eax], ebp + call dword [eax-4] + pop eax +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+12+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + push eax + lea eax, [esp+12+8+12+8] + call dword [eax+8] ; extend directory + pop eax + jnc .scan_dir + add esp, 8+8+12+20 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+8+8+12+8] + mov [esp+4], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+8] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+8] +; edi points to last entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call .read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call .read_symbols + xor eax, eax + stosw + mov cl, 2 + call .read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+4] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + and word [edi+20], 0 ; high word of cluster + and word [edi+26], 0 ; low word of cluster - to be filled + and dword [edi+28], 0 ; file size - to be filled +.doit: + push edx + push ecx + push edi + add edi, 26 ; edi points to low word of cluster + push edi + jecxz .done + mov ecx, 2849 + mov edi, 0x280000 +.write_loop: +; allocate new cluster + xor eax, eax + repnz scasw + jnz .disk_full2 + dec edi + dec edi + lea eax, [edi-0x280000] + shr eax, 1 ; eax = cluster + mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp] + stosw + pop edi + push edi + inc ecx +; write data + shl eax, 9 + add eax, 0x100000+31*512 + mov ebx, edx + xchg eax, ebx + push ecx + mov ecx, 512 + cmp dword [esp+12], ecx + jae @f + mov ecx, [esp+12] +@@: + call memmove + add edx, ecx + sub [esp+12], ecx + pop ecx + jnz .write_loop +.done: + mov ebx, edx + pop edi edi ecx edx + sub ebx, edx + mov [edi+28], ebx + add esp, 20 + mov [esp+16], ebx + popad + xor eax, eax + ret +.disk_full2: + mov ebx, edx + pop edi edi ecx edx + sub ebx, edx + mov [edi+28], ebx + add esp, 20 + mov [esp+16], ebx + popad + push ERROR_DISK_FULL + pop eax + ret + +.read_symbol: + or ax, -1 + test esi, esi + jz .retFFFF + lodsb + test al, al + jnz ansi2uni_char + xor eax, eax + xor esi, esi +.retFFFF: + ret + +.read_symbols: + call .read_symbol + stosw + loop .read_symbols + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskWrite - LFN variant for writing to sys floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +@@: + push ERROR_ACCESS_DENIED +fs_RamdiskWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_RamdiskWrite: + cmp byte [esi], 0 + jz @b + pushad + call rd_find_lfn + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; must not be directory + test byte [edi+11], 10h + jz @f + popad + push ERROR_ACCESS_DENIED + jmp .ret0 +@@: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + call fat_update_datetime + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push 0 ; return value=0 + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call ramdisk_extend_file + jnc .length_ok +; ramdisk_extend_file can return two error codes: FAT table error or disk full. +; First case is fatal error, in second case we may write some data + mov [esp], eax + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + mov [esp+28], eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + pop eax + mov [esp+28], eax ; eax=return value + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret + movzx edi, word [edi+26] ; starting cluster +.write_loop: + sub ebx, 0x200 + jae .next_cluster + push ecx + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov eax, edi + shl eax, 9 + add eax, 0x100000+31*512+0x200 + sub eax, ebx + mov ebx, eax + mov eax, edx + call memmove + xor ebx, ebx + add edx, ecx + sub [esp], ecx + pop ecx + jz .ret +.next_cluster: + movzx edi, word [edi*2+0x280000] + jmp .write_loop + +ramdisk_extend_file.zero_size: + xor eax, eax + jmp ramdisk_extend_file.start_extend + +; extends file on ramdisk to given size, new data area is filled by 0 +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) +ramdisk_extend_file: + push ecx +; find the last cluster of file + movzx eax, word [edi+26] ; first cluster + mov ecx, [edi+28] + jecxz .zero_size +@@: + sub ecx, 0x200 + jbe @f + mov eax, [eax*2+0x280000] + and eax, 0xFFF + jz .fat_err + cmp eax, 0xFF8 + jb @b +.fat_err: + pop ecx + push ERROR_FAT_TABLE + pop eax + stc + ret +@@: + push eax + mov eax, [eax*2+0x280000] + and eax, 0xFFF + cmp eax, 0xFF8 + pop eax + jb .fat_err +; set length to full number of sectors and make sure that last sector is zero-padded + sub [edi+28], ecx + push eax edi + mov edi, eax + shl edi, 9 + lea edi, [edi+0x100000+31*512+0x200+ecx] + neg ecx + xor eax, eax + rep stosb + pop edi eax +.start_extend: + pop ecx +; now do extend + push edx esi + mov esi, 0x280000+2*2 ; start scan from cluster 2 + mov edx, 2847 ; number of clusters to scan +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new sector + push ecx + mov ecx, edx + push edi + mov edi, esi + jecxz .disk_full + push eax + xor eax, eax + repnz scasw + pop eax + jnz .disk_full + mov word [edi-2], 0xFFF + mov esi, edi + mov edx, ecx + sub edi, 0x280000 + shr edi, 1 + dec edi ; now edi=new cluster + test eax, eax + jz .first_cluster + mov [0x280000+eax*2], di + jmp @f +.first_cluster: + pop eax ; eax->direntry + push eax + mov [eax+26], di +@@: + push edi + shl edi, 9 + add edi, 0x100000+31*512 + xor eax, eax + mov ecx, 512/4 + rep stosd + pop eax ; eax=new cluster + pop edi ; edi->direntry + pop ecx ; ecx=required size + add dword [edi+28], 0x200 + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop esi edx + xor eax, eax ; CF=0 + ret +.disk_full: + pop edi ecx + pop esi edx + stc + push ERROR_DISK_FULL + pop eax + ret + +fat_update_datetime: + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskSetFileEnd - set end of file on ramdisk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskSetFileEnd: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop edi + xor eax, eax + ret +.expand: + push ecx + mov ecx, eax + call ramdisk_extend_file + pop ecx + pop edi + ret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x280000+ecx*2] + jmp @b +@@: +; zero data at the end of last sector + push ecx + mov edi, ecx + shl edi, 9 + lea edi, [edi+0x100000+31*512+eax+0x200] + mov ecx, eax + neg ecx + xor eax, eax + rep stosb + pop ecx +; terminate FAT chain + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x280000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + pop ecx + pop edi + xor eax, eax + ret + +fs_RamdiskGetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn +fs_GetFileInfo_finish: + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push esi ebp + xor ebp, ebp + mov esi, edx + and dword [esi+4], 0 + call fat_entry_to_bdfe2 + pop ebp esi + pop edi + xor eax, eax + ret + +fs_RamdiskSetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call rd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + call bdfe_to_fat_entry + pop edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_RamdiskExecute - LFN variant for executing on sys floppy +; +; esi points to ramdisk filename (e.g. 'launcher') +; ebp points to full filename (e.g. '/rd/1/launcher') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_RamdiskExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_RamdiskExecute.flags - second entry +; +; esi points to ramdisk filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call rd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov edx, [eax+4] ; cluster + lea esi, [edx+31] + shl esi, 9 + add esi, 0x100000 + mov ecx, 512/4 + rep movsd + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov dx, [edx*2+0x280000] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.6.0.0/blkdev/rdsave.inc b/kernel/tags/kolibri0.6.0.0/blkdev/rdsave.inc new file mode 100644 index 0000000000..8fe849c5f3 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/blkdev/rdsave.inc @@ -0,0 +1,25 @@ +sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) + cmp ebx,1 + jnz img_save_hd_1 + mov edx,bootpath ; path = '/KOLIBRI ' + jmp img_save_hd_3 + img_save_hd_1: + cmp ebx,2 + jnz img_save_hd_2 + mov edx,bootpath2 ; path = 0 (root dir) + jmp img_save_hd_3 + img_save_hd_2: + cmp ebx,3 + jnz exit_for_anyone + mov edx,[0x3010] + mov edx,[edx+TASKDATA.mem_start] + add edx,ecx + img_save_hd_3: + call reserve_hd1 + call restorefatchain ; restore FAT !!! + mov eax,image_save + mov ebx,1440*1024 ; size 1440 Kb + mov ecx,0x100000 ; address of image + call file_write + mov [esp+36],eax + ret diff --git a/kernel/tags/kolibri0.6.0.0/boot/bootcode.inc b/kernel/tags/kolibri0.6.0.0/boot/bootcode.inc new file mode 100644 index 0000000000..5321288ce5 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/bootcode.inc @@ -0,0 +1,1259 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; BOOTCODE.INC ;; +;; ;; +;; KolibriOS 16-bit loader, ;; +;; based on bootcode for MenuetOS ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;========================================================================== +; +; 16 BIT FUNCTIONS +; +;========================================================================== + +putchar: +; in: al=character + mov ah, 0Eh + mov bh, 0 + int 10h + ret + +print: +; in: si->string + mov al, 186 + call putchar + mov al, ' ' + call putchar + +printplain: +; in: si->string + pusha + lodsb +@@: + call putchar + lodsb + cmp al, 0 + jnz @b + popa + ret + +; Now int 16 is used for keyboard support. +; This is shorter, simpler and more reliable. +if 0 +getkey: push ecx + push edx + add ebx,0x0101 + xor eax,eax + + gk1: + in al,0x60 + mov cl,al + gk0: + in al,0x60 + cmp al,cl + je gk0 + cmp ax,11 + jg gk0 + gk0_1: + mov cl,al + +; add al,47 +; mov [ds:keyinbs-0x10000],al +; mov si,keyinbs-0x10000 +; call printplain + + gk12: + in al,0x60 + cmp al,cl + je gk12 + cmp ax,240 + jne gk13 + mov al,cl + jmp gk14 + gk13: + add cl,128 + cmp al,cl + jne gk1 + sub al,128 + gk14: + + movzx edx,bl + cmp eax,edx + jb gk1 + movzx edx,bh + cmp eax,edx + jg gk1 + test ebx,0x010000 + jnz gk3 + mov cx,0x1000 + mov dx,cx + add eax,47 + mov cx,ax + cmp cx,58 + jb gk_nozero + sub cx,10 + gk_nozero: + mov [ds:keyin-0x10000],cl + mov si,keyin-0x10000 + call printplain + gk3: + sub eax,48 + pop edx + pop ecx + ret +end if + +getkey: +; get number in range [bl,bh] (bl,bh in ['0'..'9']) +; in: bx=range +; out: ax=digit (1..9, 10 for 0) + mov ah, 0 + int 16h + cmp al, bl + jb getkey + cmp al, bh + ja getkey + push ax + call putchar + pop ax + and ax, 0Fh + jnz @f + mov al, 10 +@@: + ret + +setcursor: +; in: dl=column, dh=row + mov ah, 2 + mov bh, 0 + int 10h + ret + +macro _setcursor row,column +{ + mov dx, row*256 + column + call setcursor +} + +pagetable_set: +;eax - physical address +;es:di - page table +;ecx - number of pages to map + or al, 7 +@@: + stosd + add eax, 1000h + loop @b + ret + +boot_read_floppy: + push si + xor si, si + mov ah, 2 ; read +@@: + push ax + int 0x13 + pop ax + jnc @f + inc si + cmp si, 10 + jb @b + mov si, badsect-0x10000 +sayerr_plain: + call printplain + jmp $ +@@: + pop si + ret + +; 16-bit data +; videomodes table + org $+0x10000 +gr_table: + dw 0x112+0100000000000000b , 640 , 480 ; 1 + dw 0x115+0100000000000000b , 800 , 600 ; 2 + dw 0x118+0100000000000000b , 1024 , 768 ; 3 + dw 0x11B+0100000000000000b , 1280 , 1024 ; 4 + dw 0x112 , 640 , 480 ; 5 + dw 0x115 , 800 , 600 ; 6 + dw 0x118 , 1024 , 768 ; 7 + dw 0x11B , 1280 ,1024 ; 8 + dw 0x13, 640, 480 ; 9 + dw 0x12, 640, 480 ; 0 + +; table for move to extended memory (int 15h, ah=87h) + movedesc: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + + db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + org $-0x10000 + +;========================================================================= +; +; 16 BIT CODE +; +;========================================================================= + + +start_of_code: + cld +; \begin{diamond}[02.12.2005] + cmp ax, 'KL' + jnz @f + mov word [cs:cfgmanager.loader_block-0x10000], si + mov word [cs:cfgmanager.loader_block+2-0x10000], ds +@@: +; \end{diamond}[02.12.2005] + +; set up stack + mov ax, 3000h + mov ss, ax + mov sp, 0EC00h +; set up segment registers + push cs + pop ds + push cs + pop es + +; set videomode + mov ax, 3 + int 0x10 + +if lang eq ru + ; Load & set russian VGA font (RU.INC) + mov bp,RU_FNT1-10000h ; RU_FNT1 - First part + mov bx,1000h ; 768 bytes + mov cx,30h ; 48 symbols + mov dx,80h ; 128 - position of first symbol + mov ax,1100h + int 10h + + mov bp,RU_FNT2-10000h ; RU_FNT2 -Second part + mov bx,1000h ; 512 bytes + mov cx,20h ; 32 symbols + mov dx,0E0h ; 224 - position of first symbol + mov ax,1100h + int 10h + ; End set VGA russian font +end if + +; draw frames + push 0xb800 + pop es + xor di, di +; mov si,d80x25-0x10000 +; mov cx,80*25 +; mov ah,1*16+15 +; dfl1: +; lodsb +; stosw +; loop dfl1 + mov ah, 1*16+15 +; draw top + mov si, d80x25_top - 0x10000 + mov cx, d80x25_top_num * 80 +@@: + lodsb + stosw + loop @b +; draw spaces + mov si, space_msg - 0x10000 + mov cx, 25 - d80x25_top_num - d80x25_bottom_num +dfl1: + push cx + push si + mov cx, 80 +@@: + lodsb + stosw + loop @b + pop si + pop cx + loop dfl1 +; draw bottom + mov si, d80x25_bottom - 0x10000 + mov cx, d80x25_bottom_num * 80 +@@: + lodsb + stosw + loop @b + + mov byte [space_msg-0x10000+80], 0 ; now space_msg is null terminated + + _setcursor d80x25_top_num,0 + + +; TEST FOR 386+ + + mov bx, 0x4000 + pushf + pop ax + mov dx,ax + xor ax,bx + push ax + popf + pushf + pop ax + and ax,bx + and dx,bx + cmp ax,dx + jnz cpugood + mov si,not386-0x10000 +sayerr: + call print + jmp $ + cpugood: + +; set up esp + movzx esp, sp + +; FLUSH 8042 KEYBOARD CONTROLLER + +;// mike.dld [ + ; mov al,0xED + ; out 0x60,al + ; or cx,-1 + ; @@: + ; in al,0x64 + ; test al,2 + ; jz @f + ; loop @b + ; @@: + ; mov al,0 + ; out 0x60,al + ; or cx,-1 + ; @@: + ; in al,0x64 + ; test al,2 + ; jz @f + ; loop @b + ; @@: +;// mike.dld ] + +; mov ecx,10000 +; fl1: +; in al,0x64 +; loop fl1 +; test al,1 +; jz fl2 +; in al,0x60 +; jmp fl1 +; fl2: + +;**************************************************************** +; The function is modified Mario79 +;***************************************************************** +; wait_kbd: ; variant 1 +; mov cx,2500h ;задержка порядка 10 мсек +; test_kbd: +; in al,64h ;читаем состояние клавиатуры +; test al,2 ;проверка бита готовности +; loopnz test_kbd + + mov al,0xf6 ; Сброс клавиатуры, разрешить сканирование + out 0x60,al + xor cx,cx +wait_loop: ; variant 2 +; reading state of port of 8042 controller + in al,64h + and al,00000010b ; ready flag +; wait until 8042 controller is ready + loopnz wait_loop + +; --------------- APM --------------------- + push 0 + pop es + mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found) + mov ax, 0x5300 + xor bx, bx + int 0x15 + jc apm_end ; APM not found + test cx, 2 + jz apm_end ; APM 32-bit protected-mode interface not supported + mov [es : 0x9044], ax ; Save APM Version + mov [es : 0x9046], cx ; Save APM flags + + ; Write APM ver ---- + and ax, 0xf0f + add ax, '00' + mov si, msg_apm - 0x10000 + mov [si + 5], ah + mov [si + 7], al + _setcursor 0, 3 + call printplain + _setcursor d80x25_top_num,0 + ; ------------------ + + mov ax, 0x5304 ; Disconnect interface + xor bx, bx + int 0x15 + mov ax, 0x5303 ; Connect 32 bit mode interface + xor bx, bx + int 0x15 + ; init selectors + movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment + shl eax, 4 + mov [apm_code_32 - 0x10000 + 2], ax + shr eax, 16 + mov [apm_code_32 - 0x10000 + 4], al + movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment + shl ecx, 4 + mov [apm_code_16 - 0x10000 + 2], cx + shr ecx, 16 + mov [apm_code_16 - 0x10000 + 4], cl + movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment + shl edx, 4 + mov [apm_data_16 - 0x10000 + 2], dx + shr edx, 16 + mov [apm_data_16 - 0x10000 + 4], dl + mov [es : 0x9040], ebx ; offset of APM entry point +apm_end: +; ----------------------------------------- + +; DISPLAY VESA INFORMATION + + push 0 + pop es + mov ax,0x4f00 + mov di,0xa000 + int 0x10 + cmp ax,0x004f + mov si, novesa-0x10000 + jnz @f + mov ax,[es:di+4] + add ax,'0'*256+'0' + mov si,vervesa-0x10000 + mov [si+vervesa_off], ah + mov [si+vervesa_off+2], al +@@: call print + +; \begin{diamond}[30.11.2005] +cfgmanager: +; settings: +; a) preboot_graph = graphical mode +; preboot_gprobe = probe this mode? +; b) preboot_mtrr = use hardware acceleration? +; c) preboot_vrrm = use VRR? +; d) preboot_device = from what boot? + mov di, preboot_graph-0x10000 +; check bootloader block + cmp [.loader_block-0x10000], -1 + jz .noloaderblock + les bx, [.loader_block-0x10000] + cmp byte [es:bx], 1 + mov si, loader_block_error-0x10000 + jnz sayerr + test byte [es:bx+1], 1 + jz @f +; image in memory present + cmp [di+preboot_device-preboot_graph], 0 + jnz @f + mov [di+preboot_device-preboot_graph], 3 +@@: +.noloaderblock: +; determine default settings + mov [.bSettingsChanged-0x10000], 0 + cmp byte [di], 0 + jnz .preboot_gr_end + mov [di+preboot_gprobe-preboot_graph], 0 + mov al, [vervesa+vervesa_off-0x10000] + cmp al, 'x' + jz .novesa + cmp al, '1' + jz .vesa12 + mov [di+preboot_gprobe-preboot_graph], 2 + mov al, 3 + jmp @f +.vesa12: + mov al, 7 + jmp @f +.novesa: + mov al, 10 +@@: + mov [di], al +.preboot_gr_end: + cmp [di+preboot_mtrr-preboot_graph], 1 + adc [di+preboot_mtrr-preboot_graph], 0 + cmp [di+preboot_vrrm-preboot_graph], 1 + adc [di+preboot_vrrm-preboot_graph], 0 + cmp [di+preboot_device-preboot_graph], 1 + adc [di+preboot_device-preboot_graph], 0 +; notify user + mov si, linef-0x10000 + call print + mov si, start_msg-0x10000 + call print + mov si, time_msg-0x10000 + call print +; get start time + call .gettime + mov [.starttime-0x10000], eax + mov word [.timer-0x10000], .newtimer + mov word [.timer-0x10000+2], cs +.printcfg: + _setcursor 9,0 + mov si, current_cfg_msg-0x10000 + call print + mov si, curvideo_msg-0x10000 + call print + mov al, [preboot_graph-0x10000] + cmp al, 8 + ja .pnovesa + mov dl, al + and eax, 3 + mov si, [modes_msg-0x10000+eax*2] + call printplain + mov si, modevesa20-0x10000 + cmp dl, 4 + jbe @f + mov si, modevesa12-0x10000 +@@: + call printplain + cmp dl, 4 + ja .x + mov si, probeno_msg-0x10000 + cmp [preboot_gprobe-0x10000], 2 + jnz @f + mov si, probeok_msg-0x10000 +@@: + call printplain +.x: + jmp .c +.pnovesa: + cmp al, 9 + mov si, mode9-0x10000 + jz @b + mov si, mode10-0x10000 + jmp @b +.c: + mov si, linef-0x10000 + call printplain + mov si, mtrr_msg-0x10000 + cmp [preboot_mtrr-0x10000], 1 + call .say_on_off + mov si, vrrm_msg-0x10000 + cmp [preboot_vrrm-0x10000], 1 + call .say_on_off + mov si, preboot_device_msg-0x10000 + call print + mov al, [preboot_device-0x10000] + and eax, 3 + mov si, [preboot_device_msgs-0x10000+eax*2] + call printplain +.wait: + _setcursor 25,0 ; out of screen +; set timer interrupt handler + cli + push 0 + pop es + mov eax, [es:8*4] + mov [.oldtimer-0x10000], eax + mov eax, [.timer-0x10000] + mov [es:8*4], eax + sti +; wait for keypressed + mov ah, 0 + int 16h + push ax +; restore timer interrupt + push 0 + pop es + mov eax, [.oldtimer-0x10000] + mov [es:8*4], eax + mov [.timer-0x10000], eax + _setcursor 7,0 + mov si, space_msg-0x10000 + call printplain + pop ax +; switch on key + cmp al, 13 + jz .continue + or al, 20h + cmp al, 'a' + jz .change_a + cmp al, 'b' + jz .change_b + cmp al, 'c' + jz .change_c + cmp al, 'd' + jnz .wait + _setcursor 15,0 + mov si,bdev-0x10000 + call print + mov bx,'13' + call getkey + mov [preboot_device-0x10000], al + _setcursor 13,0 +.d: + mov [.bSettingsChanged-0x10000], 1 + mov si, space_msg-0x10000 + call printplain + _setcursor 15,0 + mov cx, 6 +@@: + call printplain + loop @b + jmp .printcfg +.change_a: + _setcursor 15,0 + mov si, gr_mode-0x10000 + call printplain + mov bx, '09' + call getkey + mov [preboot_graph-0x10000], al + cmp al, 4 + ja @f + mov si, probetext-0x10000 + call printplain + mov bx, '12' + call getkey + mov [preboot_gprobe-0x10000], al +@@: + _setcursor 10,0 + jmp .d +.change_b: + _setcursor 15,0 + mov si, gr_acc-0x10000 + call print + mov bx, '12' + call getkey + mov [preboot_mtrr-0x10000], al + _setcursor 11,0 + jmp .d +.change_c: + _setcursor 15,0 + mov si, vrrmprint-0x10000 + call print + mov bx, '12' + call getkey + mov [preboot_vrrm-0x10000], al + _setcursor 12,0 + jmp .d +.say_on_off: + pushf + call print + mov si, on_msg-0x10000 + popf + jz @f + mov si, off_msg-0x10000 +@@: call printplain + ret +; novesa and vervesa strings are not used at the moment of executing this code +virtual at novesa +.oldtimer dd ? +.starttime dd ? +.bSettingsChanged db ? +.timer dd ? +end virtual + org $+0x10000 +.loader_block dd -1 + org $-0x10000 +.gettime: + mov ah, 0 + int 1Ah + xchg ax, cx + shl eax, 10h + xchg ax, dx + ret +.newtimer: + push ds + push cs + pop ds + pushf + call [.oldtimer-0x10000] + pushad + call .gettime + sub eax, [.starttime-0x10000] + sub ax, 18*5 + jae .timergo + neg ax + add ax, 18-1 + mov bx, 18 + xor dx, dx + div bx +if lang eq ru +; Ї®¤®¦¤ЁвҐ 5 ᥪ㭤, 4/3/2 ᥪ㭤л, 1 ᥪ㭤г + cmp al, 5 + mov cl, ' ' + jae @f + cmp al, 1 + mov cl, 'г' + jz @f + mov cl, 'л' +@@: mov [time_str+9-0x10000], cl +else +; wait 5/4/3/2 seconds, 1 second + cmp al, 1 + mov cl, 's' + ja @f + mov cl, ' ' +@@: mov [time_str+9-0x10000], cl +end if + add al, '0' + mov [time_str+1-0x10000], al + mov si, time_msg-0x10000 + _setcursor 7,0 + call print + _setcursor 25,0 + popad + pop ds + iret +.timergo: + push 0 + pop es + mov eax, [.oldtimer-0x10000] + mov [es:8*4], eax + mov sp, 0EC00h +.continue: + sti + _setcursor 6,0 + mov si, space_msg-0x10000 + call printplain + call printplain + _setcursor 6,0 + mov si, loading_msg-0x10000 + call print + _setcursor 15,0 + cmp [.bSettingsChanged-0x10000], 0 + jz .load + cmp [.loader_block-0x10000], -1 + jz .load + les bx, [.loader_block-0x10000] + mov eax, [es:bx+3] + push ds + pop es + test eax, eax + jz .load + push eax + mov si, save_quest-0x10000 + call print +.waityn: + mov ah, 0 + int 16h + or al, 20h + cmp al, 'n' + jz .loadc + cmp al, 'y' + jnz .waityn + call putchar + mov byte [space_msg-0x10000+80], 186 + pop eax + push cs + push .cont + push eax + retf +.loadc: + pop eax +.cont: + push cs + pop ds + mov si, space_msg-0x10000 + mov byte [si+80], 0 + _setcursor 15,0 + call printplain + _setcursor 15,0 +.load: +; \end{diamond}[02.12.2005] + +; ASK GRAPHICS MODE + + movzx ax, [preboot_graph-0x10000] + push 0 + pop es +; address is gr_table+6*(ax-1)-0x10000 + add ax, ax + lea si, [gr_table-0x10000 + eax + eax*2 - 6] + mov bx,[si+0] + mov cx,[si+2] + mov dx,[si+4] + cmp al, 9*2 + mov al, 32 ; BPP + jb @f + mov [es:0x9000], al + mov dword [es:0x9018], 0x800000 + @@: + mov [es:0x9008],bx + mov [es:0x900A],cx + mov [es:0x900C],dx + test bh, bh + jz nov + +; USE DEFAULTS OR PROBE + +; bx - mode : cx - x size : dx - y size + cmp [preboot_gprobe-0x10000], 1 + jz noprobe + + mov bx,0x100 + newprobe: + inc bx + cmp bx,0x17f + mov si,prnotfnd-0x10000 + jz sayerr + + probemore: + push cx + mov ax,0x4f01 + mov cx,bx + and cx,0xfff + mov di,0xa000 + int 0x10 + pop cx + + test byte [es:di], 80h ; lfb? + jz newprobe + cmp [es:di+0x12], cx ; x size? + jnz newprobe + cmp [es:di+0x14], dx ; y size? + jnz newprobe + cmp byte [es:di+0x19], 32 ;24 + jb newprobe + +; add bx,0100000000000000b + or bh, 40h + mov [es:0x9008],bx + + noprobe: + + +; FIND VESA 2.0 LFB & BPP + + mov ax,0x4f01 + mov cx,bx + and cx,0xfff + mov di,0xa000 + int 0x10 + ; LFB + mov eax,[es:di+0x28] + mov [es:0x9018],eax + ; ---- vbe voodoo + BytesPerScanLine equ 0x10 + mov ax, [es:di+BytesPerScanLine] + mov [es:0x9001],ax + ; BPP + mov al,byte [es:di+0x19] + mov [es:0x9000],al + nov: + cmp al,24 + mov si,bt24-0x10000 + jz bppl + cmp al,32 + mov si,bt32-0x10000 + jz bppl + mov si,btns-0x10000 + jmp sayerr + bppl: + call print + + +; FIND VESA 1.2 PM BANK SWITCH ADDRESS + + push es + mov ax,0x4f0A + xor bx, bx + int 0x10 + xor eax,eax + mov ax,es + shl eax,4 + movzx ebx,di + add eax,ebx + mov bx,[es:di] + add eax,ebx + pop es + mov [es:0x9014],eax + + +; GRAPHICS ACCELERATION + + mov al, [preboot_mtrr-0x10000] + mov [es:0x901C],al + +; VRR_M USE + + mov al,[preboot_vrrm-0x10000] + mov [es:0x9030],al + + +; MEMORY MODEL + +; movzx eax,byte [es:preboot_memory-0x10000] +; cmp eax,0 +; jne pre_mem +;;;;;;;;;;;;;;;;;;;;;;;;; +; mario79 - memory size ; +;;;;;;;;;;;;;;;;;;;;;;;;; +; mov ax,0E801h +;;; xor bx,bx ; thanks to Alexei for bugfix [18.07.2004] +; xor cx, cx +; xor dx, dx +; int 0x15 +; movzx ebx, dx ;bx +; movzx eax, cx ;ax +; shl ebx,6 ; перевод в килобайты (x64) +; add eax,ebx +; add eax, 1000h ;440h +; cmp eax,40000h ; 256? +; jge mem_256_z +; cmp eax,20000h ; 128? +; jge mem_128_z +; cmp eax,10000h ; 64? +; jge mem_64_z +; cmp eax,8000h ; 32? +; jge mem_32_z +; jmp mem_16_z +; +;mem_256_z: mov si,memokz256-0x10000 +; call printplain +; mov eax,5 +; jmp pre_mem +;mem_128_z: mov si,memokz128-0x10000 +; call printplain +; mov eax,4 +; jmp pre_mem +;mem_64_z: mov si,memokz64-0x10000 +; call printplain +; mov eax,3 +; jmp pre_mem +;mem_32_z: mov si,memokz32-0x10000 +; call printplain +; mov eax,2 +; jmp pre_mem +;mem_16_z: mov si,memokz16-0x10000 +; call printplain +; mov eax,1 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; pre_mem: +; push word 0x0000 +; pop es +; mov [es:0x9030],al +; push word 0x1000 +; pop es +; mov si,linef-0x10000 +; call printplain + + + + +; DIRECT WRITE TO LFB, PAGING DISABLED + +; movzx eax,byte [es:preboot_lfb-0x10000] +; mov eax,1 ; paging disabled +; cmp eax,0 +; jne pre_lfb +; mov si,gr_direct-0x10000 +; call printplain +; mov ebx,'12' +; call getkey +; pre_lfb: +; push word 0x0000 +; pop es +; mov [es:0x901E],al +; mov ax,0x1000 +; mov es,ax +; mov si,linef-0x10000 +; call printplain + mov [es:0x901E],byte 1 + + + +; BOOT DEVICE + + mov al, [preboot_device-0x10000] + dec al + mov [boot_dev-0x10000],al + +; READ DISKETTE TO MEMORY + +; cmp [boot_dev-0x10000],0 + jne no_sys_on_floppy + mov si,diskload-0x10000 + call print + xor ax, ax ; reset drive + xor dx, dx + int 0x13 +; now load floppy image to memory +; at first load boot sector and first FAT table + mov cx, 0x0001 ; startcyl,startsector + xor dx, dx ; starthead,drive + mov al, 1+9 ; no of sectors to read + mov bx, 0xB000 ; es:bx -> data area + call boot_read_floppy +; and copy them to extended memory + mov si, movedesc-0x10000 + mov [si+8*2+3], bh + push es + push ds + pop es + mov cx, 256*10 + mov ah, 0x87 + int 0x15 + test ah, ah + jz @f +sayerr_floppy: + mov dx, 0x3f2 + mov al, 0 + out dx, al + mov si, memmovefailed-0x10000 + jmp sayerr_plain +@@: + add dword [si+8*3+2], 512*10 +; copy FAT to second copy + mov byte [si+8*2+3], 0xB2 + mov cx, 256*9 + mov ah, 0x87 + int 0x15 + pop es + test ah, ah + jnz sayerr_floppy + add dword [si+8*3+2], 512*9 +; calculate total number of sectors to read + mov ax, 1+9+14 ; boot+FAT+root + mov di, 0xB203 +.calc_loop: + test word [es:di], 0xFFF + jz @f + inc ax +@@: + test word [es:di+1], 0xFFF0 + jz @f + inc ax +@@: + add di, 3 + cmp di, 0xB200+1440*3 + jb .calc_loop + push ax + mov bp, 1+9 ; already read sectors +; now read rest + mov byte [si+8*2+3], 0xA0 + mov di, 2-14 ; absolute sector-31 + mov cx, 0x0002 ; cylinder=0, sector=2 + mov dx, 0x0100 ; head=1, disk=0 +.read_loop: +; determine whether sector must be read + cmp di, 2 + jl .read + mov bx, di + shr bx, 1 + jnc .even + test word [es:bx+di+0xB200], 0xFFF0 + jmp @f +.even: + test word [es:bx+di+0xB200], 0xFFF +@@: + jz .skip +.read: + mov bx, 0xA000 + mov al, 1 ; 1 sector + call boot_read_floppy + inc bp + push es + push ds + pop es + pusha + mov cx, 256 + mov ah, 0x87 + int 0x15 + test ah, ah + popa + pop es + jnz sayerr_floppy +.skip: + add dword [si+8*3+2], 512 + inc cx + cmp cl, 19 + jnz @f + mov cl, 1 + inc dh + cmp dh, 2 + jnz @f + mov dh, 0 + inc ch +@@: + pop ax + push ax + pusha +; draw percentage +; total sectors: ax +; read sectors: bp + xchg ax, bp + mov cx, 100 + mul cx + div bp + aam + xchg al, ah + add ax, '00' + mov si, pros-0x10000 + cmp [si], ax + jz @f + mov [si], ax + call printplain +@@: + popa + inc di + cmp di, 2880-31 + jnz .read_loop + +; mov cx, 0x0001 ; startcyl,startsector +; xor dx, dx ; starthead,drive +; push word 80*2 ; read no of sect +; reads: +; pusha +; xor si,si +; newread: +; mov bx,0xa000 ; es:bx -> data area +; mov ax,0x0200+18 ; read, no of sectors to read +; int 0x13 +; test ah, ah +; jz goodread +; inc si +; cmp si,10 +; jnz newread +; mov si,badsect-0x10000 +;sayerr_plain: +; call printplain +; jmp $ +; goodread: +; ; move -> 1mb +; mov si,movedesc-0x10000 +; push es +; push ds +; pop es +; mov cx,256*18 +; mov ah,0x87 +; int 0x15 +; pop es +; +; test ah,ah ; was the move successfull ? +; je goodmove +; mov dx,0x3f2 ; floppy motor off +; mov al,0 +; out dx,al +; mov si,memmovefailed-0x10000 +; jmp sayerr_plain +; goodmove: +; +; add dword [movedesc-0x10000+0x18+2], 512*18 +; popa +; inc dh +; cmp dh,2 +; jnz bb2 +; mov dh,0 +; inc ch +; pusha ; print prosentage +; mov si,pros-0x10000 +; shr ch, 2 +; mov al, '5' +; test ch, 1 +; jnz @f +; mov al, '0' +;@@: +; mov [si+1], al +; shr ch, 1 +; add ch, '0' +; mov [si], ch +; call printplain +; popa +; bb2: +; pop ax +; dec ax +; push ax +; jnz reads +; readdone: +; pop ax + mov si,backspace2-0x10000 + call printplain + mov si,okt-0x10000 + call printplain + no_sys_on_floppy: + xor ax, ax ; reset drive + xor dx, dx + int 0x13 + mov dx,0x3f2 ; floppy motor off + mov al,0 + out dx,al + + push es +; PAGE TABLE + + push dword [es:0x9018] + + map_mem equ 64 ; amount of memory to map + + push 0x6000 + pop es ; es:di = 6000:0 + xor di,di + mov cx,256*map_mem ; Map (mapmem) M +; initialize as identity mapping + xor eax, eax + call pagetable_set + + +; 4 KB PAGE DIRECTORY + + push 0x7F00 + pop es ; es:di = 7F00:0 + xor di, di + mov cx, 64 / 4 + mov eax, 0x60007 ; for 0 M + call pagetable_set + xor si,si + mov di,second_base_address shr 20 + mov cx,64/2 + rep movs word [es:di], [es:si] + + mov eax, 0x7F000 +8+16 ; Page directory and enable caches + mov cr3, eax + +; SET GRAPHICS + + pop es + mov ax,[es:0x9008] ; vga & 320x200 + mov bx, ax + cmp ax,0x13 + je setgr + cmp ax,0x12 + je setgr + mov ax,0x4f02 ; Vesa + setgr: + int 0x10 + test ah,ah + mov si, fatalsel-0x10000 + jnz sayerr +; set mode 0x12 graphics registers: + cmp bx,0x12 + jne gmok2 + + mov al,0x05 + mov dx,0x03ce + push dx + out dx,al ; select GDC mode register + mov al,0x02 + inc dx + out dx,al ; set write mode 2 + + mov al,0x02 + mov dx,0x03c4 + out dx,al ; select VGA sequencer map mask register + mov al,0x0f + inc dx + out dx,al ; set mask for all planes 0-3 + + mov al,0x08 + pop dx + out dx,al ; select GDC bit mask register + ; for writes to 0x03cf + + gmok2: + push ds + pop es diff --git a/kernel/tags/kolibri0.6.0.0/boot/booteng.inc b/kernel/tags/kolibri0.6.0.0/boot/booteng.inc new file mode 100644 index 0000000000..f55132f3e8 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/booteng.inc @@ -0,0 +1,134 @@ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +macro line_full_top { + db 201 + times 78 db 205 + db 187 +} +macro line_full_bottom { + db 200 + times 78 db 205 + db 188 +} +macro line_half { + db 186,' ' + times 76 db 0xc4 + db ' ',186 +} +macro line_space { + db 186 + times 78 db 32 + db 186 +} +d80x25_top: + line_full_top +space_msg: line_space +verstr: +; line_space +; version string + db 186,32 + repeat 78 + load a byte from version+%-1 + if a = 13 + break + end if + db a + end repeat + repeat 78 - ($-verstr) + db ' ' + end repeat + db 32,186 + line_half +d80x25_top_num = 4 +d80x25_bottom: + db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' + db 'NO WARRANTY ',186 + db 186,' See file COPYING for details ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Display: EGA/CGA",13,10,0 +vervesa db "Version of Vesa: Vesa x.x",13,10,0 +vervesa_off=22 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 Colors: [9] 320x200, " + db "VGA 16 Colors: [0] 640x480",13,10 + db 186," Select mode: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",13,10,0 +vrrmprint db "Apply VRR? (picture frequency greater than 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0 +;askmouse db " Mouse at:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Select port [1-3]: ",0 +;no_com1 db 13,10,186, " No COM1 mouse",0 +;no_com2 db 13,10,186, " No COM2 mouse",0 +gr_acc db "Vesa 2.0+ : MTRR graphics acceleration " + db "[1-yes/2-no] ? ",0 +;gr_direct db 186," Use direct LFB writing? " +; db "[1-yes/2-no] ? ",0 +;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Load ramdisk from [1-floppy; 2-C:\menuet.img (FAT32);" + db 13,10,186," " + db "3-use preloaded ram-image from kernel restart]: ",0 +probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, " + db "2-probe bios (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fatal - Videomode not found.",0 +;modena db "Fatal - VBE 0x112+ required.",0 +not386 db "Fatal - CPU 386+ required.",0 +btns db "Fatal - Can't determine color depth.",0 +fatalsel db "Fatal - Graphics mode not supported by hardware.",0 +badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loading diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0 +time_msg db " or wait " +time_str db " 5 seconds" + db " before automatical continuation",13,10,0 +current_cfg_msg db "Current settings:",13,10,0 +curvideo_msg db " [a] Videomode: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +modevesa20 db " with LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 colors",0 +mode10 db "640x480, VGA 16 colors",0 +probeno_msg db " (standard mode)",0 +probeok_msg db " (check nonstandard modes)",0 +mtrr_msg db " [b] Use MTRR for graphics acceleration:",0 +on_msg db " on",13,10,0 +off_msg db " off",13,10,0 +vrrm_msg db " [c] Use VRR:",0 +preboot_device_msg db " [d] Floppy image: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +pdm1 db "real floppy",13,10,0 +pdm2 db "C:\menuet.img (FAT32)",13,10,0 +pdm3 db "use already loaded image",13,10,0 +loading_msg db "Loading KolibriOS...",0 +save_quest db "Remember current settings? [y/n]: ",0 +loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 diff --git a/kernel/tags/kolibri0.6.0.0/boot/bootge.inc b/kernel/tags/kolibri0.6.0.0/boot/bootge.inc new file mode 100644 index 0000000000..e2427dd7c5 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/bootge.inc @@ -0,0 +1,139 @@ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +macro line_full_top { + db 201 + times 78 db 205 + db 187 +} +macro line_full_bottom { + db 200 + times 78 db 205 + db 188 +} +macro line_half { + db 186,' ' + times 76 db 0xc4 + db ' ',186 +} +macro line_space { + db 186 + times 78 db 32 + db 186 +} +d80x25_top: + line_full_top +space_msg: line_space +verstr: +; line_space +; version string + db 186,32 + repeat 78 + load a byte from version+%-1 + if a = 13 + break + end if + db a + end repeat + repeat 78 - ($-verstr) + db ' ' + end repeat + db 32,186 + line_half +d80x25_top_num = 4 +d80x25_bottom: +; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' +; db 'NO WARRANTY ',186 +; db 186,' See file COPYING for details ' +; db ' ',186 + + db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' + db ' Garantie vertrieben ',186 + db 186,' Details stehen in der Datei COPYING ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "Anzeige: EGA/CGA ",13,10,0 +vervesa db "Vesa-Version: Vesa ",13,10,0 +vervesa_off=22 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 Farben: [9] 320x200, " + db "VGA 16 Farben: [0] 640x480",13,10 + db 186," Waehle Modus: ",0 +bt24 db "Bits Per Pixel: 24",13,10,0 +bt32 db "Bits Per Pixel: 32",13,10,0 +vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" + db " only for transfers:",13,10 + db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 +;askmouse db " Maus angeschlossen an:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Waehle Port [1-3]: ",0 +;no_com1 db 13,10,186, " Keine COM1 Maus",0 +;no_com2 db 13,10,186, " Keine COM2 Maus",0 +gr_acc db "Vesa 2.0+ : MTRR Grafikbeschleunigung " + db "[1-ja/2-nein] ? ",0 +;gr_direct db 186," Benutze direct LFB? " +; db "[1-ja/2-nein] ? ",0 +;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 +;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 +bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\menuet.img (FAT32);" + db 13,10,186," " + db "3-benutze ein bereits geladenes Kernel image]: ",0 +probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, " + db "2-BIOS Test (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "Fatal - Videomodus nicht gefunden.",0 +;modena db "Fatal - VBE 0x112+ required.",0 +not386 db "Fatal - CPU 386+ benoetigt.",0 +btns db "Fatal - konnte Farbtiefe nicht erkennen.",0 +fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0 +badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0 +memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Lade Diskette: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0 +time_msg db " oder warte " +time_str db " 5 Sekunden" + db " bis zum automatischen Start",13,10,0 +current_cfg_msg db "Aktuelle Einstellungen:",13,10,0 +curvideo_msg db " [a] Videomodus: ",0 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +modevesa20 db " mit LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 colors",0 +mode10 db "640x480, VGA 16 colors",0 +probeno_msg db " (Standard Modus)",0 +probeok_msg db " (teste nicht-standard Modi)",0 +mtrr_msg db " [b] Nutze MTRR fuer Graphibeschleunigung:",0 +on_msg db " an",13,10,0 +off_msg db " aus",13,10,0 +vrrm_msg db " [c] Nutze VRR:",0 +preboot_device_msg db " [d] Diskettenimage: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +pdm1 db "Echte Diskette",13,10,0 +pdm2 db "C:\menuet.img (FAT32)",13,10,0 +pdm3 db "Nutze bereits geladenes Image",13,10,0 +loading_msg db "Lade KolibriOS...",0 +save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 +loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 diff --git a/kernel/tags/kolibri0.6.0.0/boot/bootru.inc b/kernel/tags/kolibri0.6.0.0/boot/bootru.inc new file mode 100644 index 0000000000..b5256c93d4 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/bootru.inc @@ -0,0 +1,134 @@ +;====================================================================== +; +; BOOT DATA +; +;====================================================================== + +macro line_full_top { + db 201 + times 78 db 205 + db 187 +} +macro line_full_bottom { + db 200 + times 78 db 205 + db 188 +} +macro line_half { + db 186,' ' + times 76 db 0xc4 + db ' ',186 +} +macro line_space { + db 186 + times 78 db 32 + db 186 +} +d80x25_top: + line_full_top +space_msg: line_space +verstr: +; line_space +; version string + db 186,32 + repeat 78 + load a byte from version+%-1 + if a = 13 + break + end if + db a + end repeat + repeat 78 - ($-verstr) + db ' ' + end repeat + db 32,186 + line_half +d80x25_top_num = 4 +d80x25_bottom: + db 186,' Kolibri OS ®б­®ў ­  ­  Menuet OS Ё ­Ґ ЇаҐ¤®бв ў«пҐв ' + db '­ЁЄ ЄЁе Ј аa­вЁ©. ',186 + db 186,' Џ®¤а®Ў­ҐҐ ᬮваЁвҐ д ©« GNU.TXT ' + db ' ',186 + line_full_bottom +d80x25_bottom_num = 3 + +novesa db "‚Ё¤Ґ®Є ав : EGA/CGA",13,10,0 +vervesa db "‚ҐабЁп VESA: Vesa x.x",13,10,0 +vervesa_off=19 +msg_apm db " APM x.x ", 0 +gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " + db "[3] 1024x768, [4] 1280x1024",13,10 + db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " + db "[7] 1024x768, [8] 1280x1024",13,10 + db 186," EGA/CGA 256 –ўҐв®ў: [9] 320x200, " + db "VGA 16 –ўҐв®ў: [0] 640x480",13,10 + db 186," ‚лЎҐаЁвҐ ўЁ¤Ґ®аҐ¦Ё¬: ",0 +bt24 db "ѓ«гЎЁ­  梥в : 24",13,10,0 +bt32 db "ѓ«гЎЁ­  梥в : 32",13,10,0 +vrrmprint db "€бЇ®«м§®ў вм VRR? (з бв®в  Є ¤а®ў ўлиҐ 60 ѓж" + db " в®«мЄ® ¤«п ЇҐаҐе®¤®ў:",13,10 + db 186," 1024*768>800*600 Ё 800*600>640*480) [1-¤ , 2-­Ґв]: ",0 +;askmouse db "Њлим:" ; 186, " " +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " ‚лЎҐаЁвҐ Ї®ав [1-3]: ",0 +;no_com1 db 13,10,186," No COM1 mouse",0 +;no_com2 db 13,10,186," No COM2 mouse",0 +gr_acc db "Vesa 2.0+: ‚Є«озЁвм MTRR ¤«п г᪮७Ёп Ја дЁЄЁ? " + db "[1-¤ /2-­Ґв]: ",0 +;gr_direct db 186," €бЇ®«м§®ў вм «Ё­Ґ©­л© ўЁ¤Ґ®ЎгдҐа? " +; db "[1-¤ /2-­Ґв]: ",0 +;mem_model db 13,10,186," ЋЎк+¬ Ї ¬пвЁ [1-16 Mb / 2-32 Mb / " +; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0 +;bootlog db 13,10,186," Џа®б¬®ваҐвм ¦га­ « § Јаг§ЄЁ? [1-­Ґв/2-¤ ]: ",0 +bdev db "‡ Јаг§Ёвм ®Ўа § Ё§ [1-¤ЁбЄҐв ; 2-C:\menuet.img (FAT32);" + db 13,10,186," " + db "3-ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §]: ",0 +probetext db 13,10,13,10,186," ‘в ­¤ ав­л© ўЁ¤Ґ®аҐ¦Ё¬? [1-¤ , " + db "2-Їа®ўҐаЁвм ¤агЈЁҐ (Vesa 3.0)]: ",0 +;memokz256 db 13,10,186," RAM 256 Mb",0 +;memokz128 db 13,10,186," RAM 128 Mb",0 +;memokz64 db 13,10,186," RAM 64 Mb",0 +;memokz32 db 13,10,186," RAM 32 Mb",0 +;memokz16 db 13,10,186," RAM 16 Mb",0 +prnotfnd db "ЋиЁЎЄ  - ‚Ё¤Ґ®аҐ¦Ё¬ ­Ґ ­ ©¤Ґ­.",0 +;modena db "ЋиЁЎЄ  - ’ॡгҐвбп Ї®¤¤Ґа¦Є  VBE 0x112+.",0 +not386 db "ЋиЁЎЄ  - ’ॡгҐвбп Їа®жҐбб®а 386+.",0 +btns db "ЋиЁЎЄ  - ЌҐ ¬®Јг ®ЇаҐ¤Ґ«Ёвм Ј«гЎЁ­г 梥в .",0 +fatalsel 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 +mode1 db "640x480",0 +mode2 db "800x600",0 +mode3 db "1024x768",0 +mode4 db "1280x1024",0 +modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 +modevesa20 db " б LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 梥⮢",0 +mode10 db "640x480, VGA 16 梥⮢",0 +probeno_msg db " (бв ­¤ ав­л© ўЁ¤Ґ®аҐ¦Ё¬)",0 +probeok_msg db " (Їа®ўҐаЁвм ­Ґбв ­¤ ав­лҐ ०Ё¬л)",0 +mtrr_msg db " [b] €бЇ®«м§®ў ­ЁҐ MTRR ¤«п г᪮७Ёп Ја дЁЄЁ:",0 +on_msg db " ўЄ«",13,10,0 +off_msg db " ўлЄ«",13,10,0 +vrrm_msg db " [c] €бЇ®«м§®ў ­ЁҐ VRR:",0 +preboot_device_msg db " [d] ЋЎа § ¤ЁбЄҐвл: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +pdm1 db "­ бв®пй п ¤ЁбЄҐв ",13,10,0 +pdm2 db "C:\menuet.img (FAT32)",13,10,0 +pdm3 db "ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §",13,10,0 +loading_msg db "€¤св § Јаг§Є  KolibriOS...",0 +save_quest db "‡ Ї®¬­Ёвм ⥪гйЁҐ ­ бва®©ЄЁ? [y/n]: ",0 +loader_block_error db "ЋиЁЎЄ  ў ¤ ­­ле ­ з «м­®Ј® § Јаг§зЁЄ , Їа®¤®«¦Ґ­ЁҐ ­Ґў®§¬®¦­®.",0 diff --git a/kernel/tags/kolibri0.6.0.0/boot/preboot.inc b/kernel/tags/kolibri0.6.0.0/boot/preboot.inc new file mode 100644 index 0000000000..d38c76a597 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/preboot.inc @@ -0,0 +1,26 @@ +display_modechg db 0 ; display mode change for text, yes/no (0 or 2) + ; + ; !! Important note !! + ; + ; Must be set to 2, to avoid two screenmode + ; changes within a very short period of time. + +display_atboot db 0 ; show boot screen messages ( 2-no ) + +preboot_graph db 0 ; graph mode +preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes) +preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no) +;;preboot_mouse db 0 ; mouse port (1-PS2, 2-COM1, 3-COM2) +preboot_mtrr db 0 ; mtrr acceleration (1-yes, 2-no) +preboot_device db 0 ; boot device + ; (1-floppy 2-harddisk 3-kernel restart) +;;preboot_memory db 0 ; amount of memory + ; (1-16Mb;2-32Mb;3-64Mb;4-128Mb;5-256Mb) + ; !!!! 0 - autodetect !!!! +preboot_blogesc db 1 ; start immediately after bootlog + + if $>10200h +ERROR: prebooting parameters must fit in first sector!!! + end if +hdsysimage db 'MENUET IMG' ; load from +image_save db 'MENUET IMG' ; save to diff --git a/kernel/tags/kolibri0.6.0.0/boot/rdload.inc b/kernel/tags/kolibri0.6.0.0/boot/rdload.inc new file mode 100644 index 0000000000..cc98ec19ce --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/rdload.inc @@ -0,0 +1,95 @@ +; READ RAMDISK IMAGE FROM HD + + cmp [boot_dev],1 + jne no_sys_on_hd + + test [0x40001],byte 0x40 + jz position_2 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + mov [fat32part],0 + position_1_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [0x40002] + cmp [fat32part],eax + jle position_1_1 + position_2: + test [0x40001],byte 0x10 + jz position_3 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + mov [fat32part],0 + position_2_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [0x40003] + cmp eax,[fat32part] + jle position_2_1 + position_3: + test [0x40001],byte 0x4 + jz position_4 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + mov [fat32part],0 + position_3_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [0x40004] + cmp eax,[fat32part] + jle position_3_1 + position_4: + test [0x40001],byte 0x1 + jz no_sys_on_hd + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 + mov [fat32part],0 + position_4_1: + inc [fat32part] + call search_and_read_image + cmp [image_retrieved],1 + je yes_sys_on_hd + movzx eax,byte [0x40005] + cmp eax,[fat32part] + jle position_4_1 + jmp yes_sys_on_hd + + search_and_read_image: +; mov [0xfe10],dword 0 ; entries in hd cache + call set_FAT32_variables + mov edx, bootpath + call read_image + test eax, eax + jz image_present + mov edx, bootpath2 + call read_image + test eax, eax + jz image_present + ret + image_present: + mov [image_retrieved],1 + ret + +read_image: + mov eax, hdsysimage + mov ebx, 1474560/512 + mov ecx, 0x100000 + mov esi, 0 + mov edi, 12 + call file_read + ret + +image_retrieved db 0 +counter_of_partitions db 0 +no_sys_on_hd: +yes_sys_on_hd: diff --git a/kernel/tags/kolibri0.6.0.0/boot/ru.inc b/kernel/tags/kolibri0.6.0.0/boot/ru.inc new file mode 100644 index 0000000000..68ef06107a --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/ru.inc @@ -0,0 +1,92 @@ +; Generated by RUFNT.EXE +; By BadBugsKiller (C) +; Modifyed by BadBugsKiller 12.01.2004 17:45 +; Шрифт уменьшен в размере и теперь состоит из 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 + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 + +RU_FNT2: + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 + + db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 + db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 + db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 + db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/boot/shutdown.inc b/kernel/tags/kolibri0.6.0.0/boot/shutdown.inc new file mode 100644 index 0000000000..5c54dd5ea7 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/boot/shutdown.inc @@ -0,0 +1,532 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Shutdown for Menuet +;; +;; Distributed under General Public License +;; See file COPYING for details. +;; Copyright 2003 Ville Turjanmaa +;; + + +system_shutdown: ; shut down the system + + push 3 ; stop playing cd + pop eax + call sys_cd_audio + cld + + mov al,[0x2f0000+0x9030] + cmp al,1 + jl no_shutdown_parameter + cmp al,4 + jle yes_shutdown_param + no_shutdown_parameter: + +; movzx ecx,word [0x2f0000+0x900A] +; movzx esi,word [0x2f0000+0x900C] +; imul ecx,esi ;[0xfe04] +;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen +; push ecx +; mov esi,[0xfe80] +; cmp esi,32*0x100000 +; jbe no_darken_screen +; mov edi,16*0x100000 +; push esi edi +; sdnewpix: +; lodsd +; shr eax,1 +; and eax,0x7f7f7f7f +; stosd +; loop sdnewpix +; pop ecx +; pop esi edi +; rep movsd +; no_darken_screen: + +; read shutdown code: +; 1) display shutdown "window" + + mov eax,[0xfe00] + shr eax,1 + lea esi,[eax+220] ; x end + sub eax,220 ; x start + + mov ebx,[0xfe04] + shr ebx,1 + mov [shutdownpos],ebx + lea ebp,[ebx+105] ; y end + sub ebx,120 ; y start + + xor edi,edi + inc edi ; force putpixel & dtext + mov ecx,0x0000ff + +; vertical loop begin + sdnewpix1: + push eax ; save x start + +; horizontal loop begin + sdnewpix2: + + call [putpixel] + + inc eax + cmp eax,esi + jnz sdnewpix2 +; horizontal loop end + + dec ecx ; color + pop eax ; restore x start + + inc ebx ; advance y pos + cmp ebx,ebp + jnz sdnewpix1 +; vertical loop end + +; 2) display text strings +; a) version + mov eax,[0xfe00] + shr eax,1 + shl eax,16 + mov ax,word [shutdownpos] + push eax + sub eax,(220-27)*10000h + 105 + mov ebx,0xffff00 + mov ecx,version + push 34 + pop edx + call dtext + +; b) variants + add eax,105+33 + push 6 + pop esi +; mov ebx,0xffffff + mov bl,0xFF + mov ecx,shutdowntext + mov dl,40 + newsdt: + call dtext + add eax,10 + add ecx,edx + dec esi + jnz newsdt + +; 3) load & display rose.txt + mov eax,rosef ; load rose.txt + xor ebx,ebx + push 2 + pop ecx + mov edx,0x90000 + push edx + push 12 + pop esi + push edi ; may be destroyed + call fileread + pop edi + + pop ecx + inc ecx ; do not display stars from rose.txt + pop eax + add eax,20*10000h - 110 + + mov ebx,0x00ff00 + push 27 + pop edx + + nrl: + call dtext +; sub ebx,0x050000 + ror ebx, 16 + sub bl, 0x05 + ror ebx, 16 + add eax,8 + add ecx,31 + cmp cx,word 0x0001+25*31 + jnz nrl + + call checkVga_N13 + + yes_shutdown_param: + cli + + mov eax,kernel ; load kernel.mnt to 0x8000:0 + push 12 + pop esi + xor ebx,ebx + or ecx,-1 + mov edx,0x80000 + call fileread + + mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0 + mov edi,0x40000 + mov ecx,1000 + rep movsb + + mov eax,0x2F0000 ; restore 0x0 - 0xffff + xor ebx,ebx + mov ecx,0x10000 + call memmove + + call restorefatchain + + mov word [0x467+0],pr_mode_exit-0x10000 + mov word [0x467+2],0x1000 + + mov al,0x0F + out 0x70,al + mov al,0x05 + out 0x71,al + + mov al,0xFE + out 0x64,al + hlt + +use16 + +pr_mode_exit: +org $-0x10000 + +; setup stack + mov ax, 3000h + mov ss, ax + mov esp, 0EC00h +; setup ds + push cs + pop ds + + lidt [old_ints_h-0x10000] +;remap IRQs + mov al,0x11 + out 0x20,al + call rdelay + out 0xA0,al + call rdelay + + mov al,0x08 + out 0x21,al + call rdelay + mov al,0x70 + out 0xA1,al + call rdelay + + mov al,0x04 + out 0x21,al + call rdelay + mov al,0x02 + out 0xA1,al + call rdelay + + mov al,0x01 + out 0x21,al + call rdelay + out 0xA1,al + call rdelay + + mov al,0 + out 0x21,al + call rdelay + out 0xA1,al + sti + + temp_3456: + xor ax,ax + mov es,ax + mov al,byte [es:0x9030] + cmp al,1 + jl nbw + cmp al,4 + jle nbw32 + + nbw: + in al,0x60 + call pause_key + cmp al,6 + jae nbw + mov bl,al + nbw2: + in al,0x60 + call pause_key + cmp al,bl + je nbw2 + cmp al,240 ;ax,240 + jne nbw31 + mov al,bl + dec ax + jmp nbw32 + nbw31: + add bl,128 + cmp al,bl + jne nbw + sub al,129 + + nbw32: + + dec ax ; 1 = write floppy + js nbw + jnz no_floppy_write + call floppy_write + jmp temp_3456 ;nbw + no_floppy_write: + + dec ax ; 2 = power off + jnz no_apm_off + call APM_PowerOff + jmp $ + no_apm_off: + + dec ax ; 3 = reboot + jnz restart_kernel ; 4 = restart kernel + push 0x40 + pop ds + mov word[0x0072],0x1234 + jmp 0xF000:0xFFF0 + + pause_key: + mov cx,100 + pause_key_1: + loop pause_key_1 + ret +org $+0x10000 +old_ints_h: + dw 0x400 + dd 0 + dw 0 +org $-0x10000 + +rdelay: + ret + +iglobal + kernel db 'KERNEL MNT' +; shutdown_parameter db 0 +endg + +restart_kernel: + + mov ax,0x0003 ; set text mode for screen + int 0x10 + + jmp 0x4000:0000 + + +restart_kernel_4000: + cli + +; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0 +; +; new_kernel_block_move: +; +; mov ebx,0 +; +; new_kernel_byte_move: +; +; mov ax,di +; add ax,0x7000 +; mov es,ax +; mov dl,[es:bx] +; mov es,di +; mov [es:bx],dl +; +; inc ebx +; cmp ebx,65536 +; jbe new_kernel_byte_move +; +; add di,0x1000 +; cmp di,0x2000 +; jbe new_kernel_block_move + push ds + pop es + mov cx, 0x8000 + push cx + mov ds, cx + xor si, si + xor di, di + rep movsw + push 0x9000 + pop ds + push 0x2000 + pop es + pop cx + rep movsw + + wbinvd ; write and invalidate cache + +; mov ax,0x1000 +; mov es,ax +; mov ax,0x3000 +; mov ss,ax +; mov sp,0xec00 +; restore timer + mov al, 00110100b + out 43h, al + jcxz $+2 + mov al, 0xFF + out 40h, al + jcxz $+2 + out 40h, al + jcxz $+2 + sti + +; bootloader interface + push 0x1000 + pop ds + mov si, .bootloader_block;-0x10000 + mov ax, 'KL' + jmp 0x1000:0000 + +.bootloader_block: + db 1 ; version + dw 1 ; floppy image is in memory + dd 0 ; cannot save parameters + +APM_PowerOff: + mov ax, 5304h + xor bx, bx + int 15h +;!!!!!!!!!!!!!!!!!!!!!!!! +mov ax,0x5300 +xor bx,bx +int 0x15 +push ax + +mov ax,0x5301 +xor bx,bx +int 0x15 + +mov ax,0x5308 +mov bx,1 +mov cx,bx +int 0x15 + +mov ax,0x530E +xor bx,bx +pop cx +int 0x15 + +mov ax,0x530D +mov bx,1 +mov cx,bx +int 0x15 + +mov ax,0x530F +mov bx,1 +mov cx,bx +int 0x15 + +mov ax,0x5307 +mov bx,1 +mov cx,3 +int 0x15 +;!!!!!!!!!!!!!!!!!!!!!!!! +fwwritedone: + ret +org $+0x10000 +flm db 0 +org $-0x10000 + +floppy_write: ; write diskette image to physical floppy + + cmp [flm-0x10000],byte 1 + je fwwritedone + mov [flm-0x10000],byte 1 + + xor ax, ax ; reset drive + xor dx, dx + int 0x13 + + mov cx,0x0001 ; startcyl,startsector +; mov dx,0x0000 ; starthead,drive + xor dx, dx + mov ax, 80*2 ; read no of sect + + fwwrites: + push ax + + ; move 1mb+ -> 0:a000 + + pusha + mov si,fwmovedesc -0x10000 + mov cx,256*18 + mov ah,0x87 + push ds + pop es + int 0x15 + add dword [fwmovedesc-0x10000+0x12], 512*18 + popa + + xor si,si + mov es,si + fwnewwrite: + mov bx,0xa000 ; es:bx -> data area + mov ax,0x0300+18 ; read, no of sectors to read + int 0x13 + + test ah, ah + jz fwgoodwrite + + inc si + cmp si,10 + jnz fwnewwrite + +; can't access diskette - return + pop ax + ret + + fwgoodwrite: + inc dh + cmp dh,2 + jnz fwbb2 + mov dh,0 + inc ch + fwbb2: + pop ax + dec ax + jnz fwwrites + ret +org $+0x10000 + fwmovedesc: + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 + db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 + db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 +org $-0x10000 +use32 +org $+0x10000 +uglobal + shutdownpos dd 0x0 +endg + +iglobal +if lang eq en +shutdowntext: + db "IT'S SAFE TO POWER OFF COMPUTER OR " + db ' ' + db '1) SAVE RAMDISK TO FLOPPY ' + db '2) APM - POWEROFF ' + db '3) REBOOT ' + db '4) RESTART KERNEL ' +else if lang eq ru +shutdowntext: + db "ЃҐ§®Ї б­®Ґ ўлЄ«о祭ЁҐ Є®¬ЇмовҐа  Ё«Ё " + db ' ' + db '1) ‘®еа ­Ёвм а ¬¤ЁбЄ ­  ¤ЁбЄҐвг ' + db '2) APM - ўлЄ«о祭ЁҐ ЇЁв ­Ёп ' + db '3) ЏҐаҐ§ Јаг§Є  бЁб⥬л ' + db '4) ђҐбв ав п¤а  Ё§ Ћ‡“ ' +else +shutdowntext: + db "SIE KOENNEN DEN COMPUTER NUN AUSSCHALTEN" + db ' ' + db '1) RAMDISK AUF DISK SPEICHERN ' + db '2) APM - AUSSCHALTEN ' + db '3) NEUSTARTEN ' + db '4) KERNEL NEU STARTEN ' +end if +rosef: + db 'ROSE TXT' +endg diff --git a/kernel/tags/kolibri0.6.0.0/build_en.bat b/kernel/tags/kolibri0.6.0.0/build_en.bat new file mode 100644 index 0000000000..2a911504f5 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/build_en.bat @@ -0,0 +1,4 @@ +@erase lang.inc +@echo lang fix en >lang.inc +@fasm kernel.asm kernel.mnt +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/build_ge.bat b/kernel/tags/kolibri0.6.0.0/build_ge.bat new file mode 100644 index 0000000000..15951e4d4d --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/build_ge.bat @@ -0,0 +1,4 @@ +@erase lang.inc +@echo lang fix ge >lang.inc +@fasm kernel.asm kernel.mnt +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/build_ru.bat b/kernel/tags/kolibri0.6.0.0/build_ru.bat new file mode 100644 index 0000000000..fdea9bebf6 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/build_ru.bat @@ -0,0 +1,4 @@ +@erase lang.inc +@echo lang fix ru >lang.inc +@fasm kernel.asm kernel.mnt +@pause \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/bus/pci/pci16.inc b/kernel/tags/kolibri0.6.0.0/bus/pci/pci16.inc new file mode 100644 index 0000000000..c229148529 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/bus/pci/pci16.inc @@ -0,0 +1,46 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; PCI16.INC ;; +;; ;; +;; 16 bit PCI driver code ;; +;; ;; +;; Version 0.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +init_pci_16: + + pushad + + xor ax,ax + mov es,ax + mov byte [es:0x9020],1 ;default mechanism:1 + mov ax,0xb101 + int 0x1a + or ah,ah + jnz pci16skip + + mov [es:0x9021],cl ;last PCI bus in system + mov [es:0x9022],bx + mov [es:0x9024],edi + +; we have a PCI BIOS, so check which configuration mechanism(s) +; it supports +; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) + test al,1 + jnz pci16skip + test al,2 + jz pci16skip + mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 + +pci16skip: + + mov ax,0x1000 + mov es,ax + + popad \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/bus/pci/pci32.inc b/kernel/tags/kolibri0.6.0.0/bus/pci/pci32.inc new file mode 100644 index 0000000000..c224880fe7 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/bus/pci/pci32.inc @@ -0,0 +1,358 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; PCI32.INC ;; +;; ;; +;; 32 bit PCI driver code ;; +;; ;; +;; Version 0.2 December 21st, 2002 ;; +;; ;; +;; Author: Victor Prodan, victorprodan@yahoo.com ;; +;; Credits: ;; +;; Ralf Brown ;; +;; Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;*************************************************************************** +; Function +; pci_api: +; +; Description +; entry point for system PCI calls +;*************************************************************************** + +align 4 + +pci_api: + + cmp [pci_access_enabled],1 + jne no_pci_access_for_applications + + or al,al + jnz pci_fn_1 + ; PCI function 0: get pci version (AH.AL) + movzx eax,word [0x2F0000+0x9022] + ret + +pci_fn_1: + cmp al,1 + jnz pci_fn_2 + + ; PCI function 1: get last bus in AL + mov al,[0x2F0000+0x9021] + ret + +pci_fn_2: + cmp al,2 + jne pci_fn_3 + ; PCI function 2: get pci access mechanism + mov al,[0x2F0000+0x9020] + ret +pci_fn_3: + + cmp al,4 + jz pci_read_reg ;byte + cmp al,5 + jz pci_read_reg ;word + cmp al,6 + jz pci_read_reg ;dword + + cmp al,8 + jz pci_write_reg ;byte + cmp al,9 + jz pci_write_reg ;word + cmp al,10 + jz pci_write_reg ;dword + + no_pci_access_for_applications: + + mov eax,-1 + + ret + +;*************************************************************************** +; Function +; pci_make_config_cmd +; +; Description +; creates a command dword for use with the PCI bus +; bus # in ah +; device+func in bh (dddddfff) +; register in bl +; +; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) +;*************************************************************************** + +align 4 + +pci_make_config_cmd: + shl eax,8 ; move bus to bits 16-23 + mov ax,bx ; combine all + and eax,0xffffff + or eax,0x80000000 + ret + +;*************************************************************************** +; Function +; pci_read_reg: +; +; Description +; read a register from the PCI config space into EAX/AX/AL +; IN: ah=bus,device+func=bh,register address=bl +; number of bytes to read (1,2,4) coded into AL, bits 0-1 +;*************************************************************************** + +align 4 + +pci_read_reg: + cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? + je pci_read_reg_2 + + ; mechanism 1 + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + call pci_make_config_cmd + mov ebx,eax + ; get current state + mov dx,0xcf8 + in eax, dx + push eax + ; set up addressing to config data + mov eax,ebx + and al,0xfc ; make address dword-aligned + out dx,eax + ; get requested DWORD of config data + mov dl,0xfc + and bl,3 + or dl,bl ; add to port address first 2 bits of register address + + or esi,esi + jz pci_read_byte1 + cmp esi,1 + jz pci_read_word1 + cmp esi,2 + jz pci_read_dword1 + jmp pci_fin_read1 + +pci_read_byte1: + in al,dx + jmp pci_fin_read1 +pci_read_word1: + in ax,dx + jmp pci_fin_read1 +pci_read_dword1: + in eax,dx + jmp pci_fin_read1 +pci_fin_read1: + ; restore configuration control + xchg eax,[esp] + mov dx,0xcf8 + out dx,eax + + pop eax + pop esi + ret +pci_read_reg_2: + + test bh,128 ;mech#2 only supports 16 devices per bus + jnz pci_read_reg_err + + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + push eax + ;store current state of config space + mov dx,0xcf8 + in al,dx + mov ah,al + mov dl,0xfa + in al,dx + + xchg eax,[esp] + ; out 0xcfa,bus + mov al,ah + out dx,al + ; out 0xcf8,0x80 + mov dl,0xf8 + mov al,0x80 + out dx,al + ; compute addr + shr bh,3 ; func is ignored in mechanism 2 + or bh,0xc0 + mov dx,bx + + or esi,esi + jz pci_read_byte2 + cmp esi,1 + jz pci_read_word2 + cmp esi,2 + jz pci_read_dword2 + jmp pci_fin_read2 + +pci_read_byte2: + in al,dx + jmp pci_fin_read2 +pci_read_word2: + in ax,dx + jmp pci_fin_read2 +pci_read_dword2: + in eax,dx +; jmp pci_fin_read2 +pci_fin_read2: + + ; restore configuration space + xchg eax,[esp] + mov dx,0xcfa + out dx,al + mov dl,0xf8 + mov al,ah + out dx,al + + pop eax + pop esi + ret + +pci_read_reg_err: + xor eax,eax + dec eax + ret + + +;*************************************************************************** +; Function +; pci_write_reg: +; +; Description +; write a register from ECX/CX/CL into the PCI config space +; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, +; value to write in ecx +; number of bytes to write (1,2,4) coded into AL, bits 0-1 +;*************************************************************************** + +align 4 + +pci_write_reg: + cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? + je pci_write_reg_2 + + ; mechanism 1 + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + call pci_make_config_cmd + mov ebx,eax + ; get current state into ecx + mov dx,0xcf8 + in eax, dx + push eax + ; set up addressing to config data + mov eax,ebx + and al,0xfc ; make address dword-aligned + out dx,eax + ; write DWORD of config data + mov dl,0xfc + and bl,3 + or dl,bl + mov eax,ecx + + or esi,esi + jz pci_write_byte1 + cmp esi,1 + jz pci_write_word1 + cmp esi,2 + jz pci_write_dword1 + jmp pci_fin_write1 + +pci_write_byte1: + out dx,al + jmp pci_fin_write1 +pci_write_word1: + out dx,ax + jmp pci_fin_write1 +pci_write_dword1: + out dx,eax + jmp pci_fin_write1 +pci_fin_write1: + + ; restore configuration control + pop eax + mov dl,0xf8 + out dx,eax + + xor eax,eax + pop esi + + ret +pci_write_reg_2: + + test bh,128 ;mech#2 only supports 16 devices per bus + jnz pci_write_reg_err + + + push esi ; save register size into ESI + mov esi,eax + and esi,3 + + push eax + ;store current state of config space + mov dx,0xcf8 + in al,dx + mov ah,al + mov dl,0xfa + in al,dx + xchg eax,[esp] + ; out 0xcfa,bus + mov al,ah + out dx,al + ; out 0xcf8,0x80 + mov dl,0xf8 + mov al,0x80 + out dx,al + ; compute addr + shr bh,3 ; func is ignored in mechanism 2 + or bh,0xc0 + mov dx,bx + ; write register + mov eax,ecx + + or esi,esi + jz pci_write_byte2 + cmp esi,1 + jz pci_write_word2 + cmp esi,2 + jz pci_write_dword2 + jmp pci_fin_write2 + +pci_write_byte2: + out dx,al + jmp pci_fin_write2 +pci_write_word2: + out dx,ax + jmp pci_fin_write2 +pci_write_dword2: + out dx,eax + jmp pci_fin_write2 +pci_fin_write2: + ; restore configuration space + pop eax + mov dx,0xcfa + out dx,al + mov dl,0xf8 + mov al,ah + out dx,al + + xor eax,eax + pop esi + ret + +pci_write_reg_err: + xor eax,eax + dec eax + ret diff --git a/kernel/tags/kolibri0.6.0.0/core/debug.inc b/kernel/tags/kolibri0.6.0.0/core/debug.inc new file mode 100644 index 0000000000..d8d1c02c93 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/debug.inc @@ -0,0 +1,499 @@ +; diamond, 2006 +sys_debug_services: + cmp eax, 9 + ja @f + jmp dword [sys_debug_services_table+eax*4] +@@: ret +sys_debug_services_table: + dd debug_set_event_data + dd debug_getcontext + dd debug_setcontext + dd debug_detach + dd debug_suspend + dd debug_resume + dd debug_read_process_memory + dd debug_write_process_memory + dd debug_terminate + dd debug_set_drx + +debug_set_event_data: +; in: ebx = pointer +; destroys eax + mov eax, [0x3000] + shl eax, 8 + mov [eax+0x80000+APPDATA.dbg_event_mem], ebx + ret + +get_debuggee_slot: +; in: ebx=PID +; out: CF=1 if error +; CF=0 and eax=slot*0x20 if ok +; out: interrupts disabled + cli + mov eax, ebx + call pid_to_slot + test eax, eax + jz .ret_bad + shl eax, 5 + push ebx + mov ebx, [0x3000] + cmp [0x80000+eax*8+APPDATA.debugger_slot], ebx + pop ebx + jnz .ret_bad +; clc ; automatically + ret +.ret_bad: + stc + ret + +debug_detach: +; in: ebx=pid +; destroys eax,ebx + call get_debuggee_slot + jc .ret + and dword [eax*8+0x80000+APPDATA.debugger_slot], 0 + call do_resume +.ret: + sti + ret + +debug_terminate: +; in: ebx=pid + call get_debuggee_slot + jc debug_detach.ret + mov ebx, eax + shr ebx, 5 + push 2 + pop eax + jmp sys_system + +debug_suspend: +; in: ebx=pid +; destroys eax,ebx + call get_debuggee_slot + jc .ret + mov bl, [0x3000+eax+TASKDATA.state] ; process state + test bl, bl + jz .1 + cmp bl, 5 + jnz .ret + mov bl, 2 +.2: mov [0x3000+eax+TASKDATA.state], bl +.ret: + sti + ret +.1: + inc ebx + jmp .2 + +do_resume: + mov bl, [0x3000+eax+TASKDATA.state] + cmp bl, 1 + jz .1 + cmp bl, 2 + jnz .ret + mov bl, 5 +.2: mov [0x3000+eax+TASKDATA.state], bl +.ret: ret +.1: dec ebx + jmp .2 + +debug_resume: +; in: ebx=pid +; destroys eax,ebx + call get_debuggee_slot + jc .ret + call do_resume +.ret: sti + ret + +debug_getcontext: +; in: +; ebx=pid +; ecx=sizeof(CONTEXT) +; edx->CONTEXT +; destroys eax,ecx,edx,esi,edi + cmp ecx, 28h + jnz .ret + add edx, std_application_base_address + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .ret + imul eax, tss_step/32 + add eax, tss_data + mov edi, edx + cmp [l.cs - tss_sceleton + eax], app_code + jnz .ring0 + lea esi, [l.eip - tss_sceleton + eax] + shr ecx, 2 + rep movsd + jmp .ret +.ring0: +; note that following code assumes that all interrupt/exception handlers +; saves ring-3 context by push ds es, pushad in this order + mov esi, [l.esp0 - tss_sceleton + eax] +; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad + sub esi, 8+12+8+20h + lodsd + mov [edi+24h], eax + lodsd + mov [edi+20h], eax + lodsd + mov [edi+1Ch], eax + lodsd + lodsd + mov [edi+14h], eax + lodsd + mov [edi+10h], eax + lodsd + mov [edi+0Ch], eax + lodsd + mov [edi+8], eax + add esi, 8 + lodsd + mov [edi], eax + lodsd + lodsd + mov [edi+4], eax + lodsd + mov [edi+18h], eax +.ret: + sti + ret + +debug_setcontext: +; in: +; ebx=pid +; ecx=sizeof(CONTEXT) +; edx->CONTEXT +; destroys eax,ecx,edx,esi,edi + cmp ecx, 28h + jnz .ret + add edx, std_application_base_address + push ebx + mov ebx, edx + call check_region + pop ebx + dec eax + jnz .ret + call get_debuggee_slot + jc .stiret + imul eax, tss_step/32 + add eax, tss_data + mov esi, edx + cmp [l.cs - tss_sceleton + eax], app_code + jnz .ring0 + lea edi, [l.eip - tss_sceleton + eax] + shr ecx, 2 + rep movsd + jmp .stiret +.ring0: + mov edi, [l.esp0 - tss_sceleton + eax] + sub edi, 8+12+8+20h + mov eax, [esi+24h] + stosd + mov eax, [esi+20h] + stosd + mov eax, [esi+1Ch] + stosd + scasd + mov eax, [esi+14h] + stosd + mov eax, [esi+10h] + stosd + mov eax, [esi+0Ch] + stosd + mov eax, [esi+8] + stosd + add edi, 8 + mov eax, [esi] + stosd + scasd + mov eax, [esi+4] + stosd + mov eax, [esi+18h] + stosd +.stiret: + sti +.ret: + ret + +debug_set_drx: + call get_debuggee_slot + jc .errret + mov ebp, eax + lea eax, [eax*8+0x80000+APPDATA.dbg_regs] +; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 +; [eax+10]=dr7 + add edx, std_application_base_address + jc .errret + cmp cl, 3 + ja .errret + mov ebx, dr7 + shr ebx, cl + shr ebx, cl + test ebx, 2 ; bit 1+2*index = G0..G3, global break enable + jnz .errret2 + test ch, ch + jns .new +; clear breakpoint + movzx ecx, cl + add ecx, ecx + and dword [eax+ecx*2], 0 ; clear DR + btr dword [eax+10h], ecx ; clear L bit + test byte [eax+10h], 55h + jnz .okret + imul eax, ebp, tss_step/32 + and byte [eax + tss_data + l.trap - tss_sceleton], not 1 +.okret: + and dword [esp+36], 0 + sti + ret +.errret: + sti + mov dword [esp+36], 1 + ret +.errret2: + sti + mov dword [esp+36], 2 + ret +.new: +; add new breakpoint +; cl=index; ch=flags; edx=address + test ch, 0xF0 + jnz .errret + mov bl, ch + and bl, 3 + cmp bl, 2 + jz .errret + mov bl, ch + shr bl, 2 + cmp bl, 2 + jz .errret + test dl, bl + jnz .errret + or byte [eax+10h+1], 3 ; set GE and LE flags + movzx ebx, ch + movzx ecx, cl + add ecx, ecx + bts dword [eax+10h], ecx ; set L flag + add ecx, ecx + mov [eax+ecx], edx ; set DR + shl ebx, cl + mov edx, 0xF + shl edx, cl + not edx + and [eax+10h+2], dx + or [eax+10h+2], bx ; set R/W and LEN fields + imul eax, ebp, tss_step/32 + or byte [eax + tss_data + l.trap - tss_sceleton], 1 + jmp .okret + +debug_read_process_memory: +; in: +; ebx=pid +; ecx=length +; esi->buffer in debugger +; edx=address in debuggee +; out: [esp+36]=sizeof(read) +; destroys all + add esi, std_application_base_address + push ebx + mov ebx, esi + call check_region + pop ebx + dec eax + jnz .err + call get_debuggee_slot + jc .err + shr eax, 5 + mov ebx, esi + call read_process_memory + sti + mov dword [esp+36], eax + ret +.err: + or dword [esp+36], -1 + ret + +debug_write_process_memory: +; in: +; ebx=pid +; ecx=length +; esi->buffer in debugger +; edx=address in debuggee +; out: [esp+36]=sizeof(write) +; destroys all + add esi, std_application_base_address + push ebx + mov ebx, esi + call check_region + pop ebx + dec eax + jnz debug_read_process_memory.err + call get_debuggee_slot + jc debug_read_process_memory.err + shr eax, 5 + mov ebx, esi + call write_process_memory + sti + mov [esp+36], eax + ret + +debugger_notify: +; in: eax=debugger slot +; ecx=size of debug message +; [esp+4]..[esp+4+ecx]=message +; interrupts must be disabled! +; destroys all general registers +; interrupts remain disabled + xchg ebp, eax + mov edi, [timer_ticks] + add edi, 500 ; 5 sec timeout +.1: + mov eax, ebp + shl eax, 8 + mov edx, [0x80000+eax+APPDATA.dbg_event_mem] + test edx, edx + jz .ret +; read buffer header + push ecx + push eax + push eax + mov eax, ebp + mov ebx, esp + mov ecx, 8 + call read_process_memory + cmp eax, ecx + jz @f + add esp, 12 + jmp .ret +@@: + cmp dword [ebx], 0 + jg @f +.2: + pop ecx + pop ecx + pop ecx + cmp dword [0x3000], 1 + jnz .notos + cmp [timer_ticks], edi + jae .ret +.notos: + sti + call change_task + cli + jmp .1 +@@: + mov ecx, [ebx+8] + add ecx, [ebx+4] + cmp ecx, [ebx] + ja .2 +; advance buffer position + push ecx + mov ecx, 4 + sub ebx, ecx + mov eax, ebp + add edx, ecx + call write_process_memory + pop eax +; write message + mov eax, ebp + add edx, ecx + add edx, [ebx+8] + add ebx, 20 + pop ecx + pop ecx + pop ecx + call write_process_memory +; new debug event + mov eax, ebp + shl eax, 8 + or byte [0x80000+eax+APPDATA.event_mask+1], 1 ; set flag 100h +.ret: + ret + +debug_exc: +; int 1 = #DB + save_ring3_context + cld + mov ax, os_data + mov ds, ax + mov es, ax + mov eax, dr6 + test ax, ax + jns @f +; this is exception from task switch +; set DRx registers for task and continue + mov eax, [0x3000] + shl eax, 8 + add eax, 0x80000+APPDATA.dbg_regs + mov ecx, [eax+0] + mov dr0, ecx + mov ecx, [eax+4] + mov dr1, ecx + mov ecx, [eax+8] + mov dr2, ecx + mov ecx, [eax+0Ch] + mov dr3, ecx + xor ecx, ecx + mov dr6, ecx + mov ecx, [eax+10h] + mov dr7, ecx + restore_ring3_context + iretd +@@: + push eax + xor eax, eax + mov dr6, eax +; test if debugging + cli + mov eax, [0x3000] + shl eax, 8 + mov eax, [0x80000+eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + add esp, 28h+4 + mov [error_interrupt], 1 + call show_error_parameters + mov edx, [0x3010] + mov byte [edx+TASKDATA.state], 4 + jmp change_task +.debug: +; we are debugged process, notify debugger and suspend ourself +; eax=debugger PID + pop edx + mov ebx, dr7 + mov cl, not 1 +.l1: + test bl, 1 + jnz @f + and dl, cl +@@: + shr ebx, 2 + add cl, cl + inc ecx + cmp cl, not 10h + jnz .l1 + push edx ; DR6 image + mov ecx, [0x3010] + push dword [ecx+TASKDATA.pid] ; PID + push 12 + pop ecx + push 3 ; 3 = debug exception + call debugger_notify + pop ecx + pop ecx + pop ecx + mov edx, [0x3010] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task + restore_ring3_context + iretd diff --git a/kernel/tags/kolibri0.6.0.0/core/mem.inc b/kernel/tags/kolibri0.6.0.0/core/mem.inc new file mode 100644 index 0000000000..16aed7c3cf --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/mem.inc @@ -0,0 +1,469 @@ +if ~defined mem_inc +mem_inc_fix: +mem_inc fix mem_inc_fix +;include "memmanag.inc" +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;High-level memory management in MenuetOS. +;;It uses memory manager in memmanager.inc +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +second_base_address=0xC0000000 +std_application_base_address=0x10000000 +general_page_table_ dd 0 +general_page_table=general_page_table_+second_base_address +;----------------------------------------------------------------------------- +create_general_page_table: +;input +; none +;output +; none +;Procedure create general page directory and write +;it address to [general_page_table]. + pushad + mov eax,1 ;alloc 1 page + mov ebx,general_page_table ;write address to [general_page_table] + call MEM_Alloc_Pages ;allocate page directory + mov eax,[general_page_table] + call MEM_Get_Linear_Address ;eax - linear address of page directory + mov edi,eax + mov ebx,eax ;copy address of page directory to safe place + xor eax,eax + mov ecx,4096/4 + cld + rep stosd ;clear page directory + + mov eax,4 + mov edx,eax + call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region + cmp eax,edx + jnz $ ;hang if not enough memory + +;fill page tables + xor esi,esi + mov ebp,7 + +.loop: +;esi - number of page in page directory +;ebp - current page address +;ebx - linear address of page directory + mov eax,[ebx+4*esi] + add dword [ebx+4*esi],7 ;add flags to address of page table + call MEM_Get_Linear_Address +;eax - linear address of page table + mov ecx,4096/4 +;ecx (counter) - number of pages in page table +;current address=4Mb*esi + +.loop1: + mov [eax],ebp ;write page address (with flags) in page table + add eax,4 + add ebp,4096 ;size of page=4096 bytes + loop .loop1 + + inc esi ;next page directory entry + cmp esi,edx + jnz .loop + +;map region 0x80000000-0x807fffff to LFB + mov eax,2 ;size of the region is 4Mb so only 1 page table needed + mov edx,ebx ;ebx still contains linear address of the page directory + add ebx,0x800 + call MEM_Alloc_Pages ;alloc page table for the region + mov eax,[ebx] + add dword [ebx],7 ;add flags + call MEM_Get_Linear_Address ;get linear address of the page table + mov ecx,4096/4 ;number of pages in page table + mov edi,[0xfe80] + add edi,7 +.loop3: +;eax - linear address of page table +;edi - current linear address with flags + mov [eax],edi + add eax,4 + add edi,4096 + loop .loop3 + mov eax,[ebx+4] + call MEM_Get_Linear_Address + add dword [ebx+4],7 + mov ecx,4096/4 +.loop31: + mov [eax],edi + add eax,4 + add edi,4096 + loop .loop31 + +;map region 0xC0000000-* to 0x0-* + mov esi,edx ;esi=linear address of the page directory + lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00) + mov ecx,4 + rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block + mov eax,[0xfe8c] ;eax=memory size + add eax,0x3fffff + shr eax,22 + mov esi,eax ;calculate number of entries in page directory + sub esi,4 ;subtract entries for first 16Mb. + mov ebp,0x1000000+7 ;start physical address with flags + +;mapping memory higher than 16Mb +.loop4: +;esi (counter) - number of entries in page directory +;edi - address of entry + test esi,esi + jle .loop4end + call MEM_Alloc_Page ;alloc page table for entry in page directory + mov [edi],eax + add dword [edi],7 ;write physical address of page table in page directory + add edi,4 ;move entry pointer + call MEM_Get_Linear_Address + mov ecx,eax + xor edx,edx + +.loop5: +;ecx - linear address of page table +;edx - index of page in page table +;ebp - current mapped physical address with flags + mov [ecx+4*edx],ebp ;write address of page in page table + add ebp,0x1000 ;move to next page + inc edx + cmp edx,4096/4 + jl .loop5 + + dec esi + jmp .loop4 +.loop4end: + +.set_cr3: +;set value of cr3 register to the address of page directory + mov eax,[general_page_table] + add eax,8+16 ;add flags + mov cr3,eax ;now we have full access paging + + popad + ret +;----------------------------------------------------------------------------- +simple_clone_cr3_table: +;Parameters: +; eax - physical address of cr3 table (page directory) +;result: +; eax - physical address of clone of cr3 table. +;Function copy only page directory. + push ecx + push edx + push esi + push edi + call MEM_Get_Linear_Address +;eax - linear address of cr3 table + mov esi,eax + call MEM_Alloc_Page + test eax,eax + jz .failed +;eax - physical address of new page diretory + mov edx,eax + call MEM_Get_Linear_Address + mov edi,eax + mov ecx,4096/4 + cld +;esi - address of old page directory +;edi - address of new page directory + rep movsd ;copy page directory + mov eax,edx +.failed: + pop edi + pop esi + pop edx + pop ecx + ret + +;----------------------------------------------------------------------------- +create_app_cr3_table: +;Parameters: +; eax - slot of process (index in 0x3000 table) +;result: +; eax - physical address of table. +;This function create page directory for new process and +;write it physical address to offset 0xB8 of extended +;process information. + push ebx + + mov ebx,eax + mov eax,[general_page_table] + call simple_clone_cr3_table ;clone general page table + shl ebx,8 + mov [second_base_address+0x80000+ebx+APPDATA.dir_table],eax ;save address of page directory + + pop ebx + ret +;----------------------------------------------------------------------------- +get_cr3_table: +;Input: +; eax - slot of process +;result: +; eax - physical address of page directory + shl eax,8 ;size of process extended information=256 bytes + mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] + ret +;----------------------------------------------------------------------------- +dispose_app_cr3_table: +;Input: +; eax - slot of process +;result: +; none +;This procedure frees page directory, +;page tables and all memory of process. + pushad + mov ebp,eax +;ebp = process slot in the procedure. + shl eax,8 + mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table] + mov ebx,eax +;ebx = physical address of page directory + call MEM_Get_Linear_Address + mov edi,eax +;edi = linear address of page directory + mov eax,[edi+(std_application_base_address shr 20)] + and eax,not (4096-1) + call MEM_Get_Linear_Address + mov esi,eax +;esi = linear address of first page table + +;search threads +; mov ecx,0x200 + xor edx,edx + mov eax,0x2 + +.loop: +;eax = current slot of process + mov ecx,eax + shl ecx,5 + cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 ;if process running? + jz .next ;skip empty slots + shl ecx,3 + cmp [second_base_address+0x80000+ecx+APPDATA.dir_table],ebx ;compare page directory addresses + jnz .next + inc edx ;thread found +.next: + inc eax + cmp eax,[0x3004] ;exit loop if we look through all processes + jle .loop + +;edx = number of threads +;our process is zombi so it isn't counted + cmp edx,1 + jg .threadsexists +;if there isn't threads then clear memory. + add edi,std_application_base_address shr 20 + +.loop1: +;edi = linear address of current directory entry +;esi = linear address of current page table + test esi,esi + jz .loop1end + xor ecx,ecx + +.loop2: +;ecx = index of page + mov eax,[esi+4*ecx] + test eax,eax + jz .loopend ;skip empty entries + and eax,not (4096-1) ;clear flags + push ecx + call MEM_Free_Page ;free page + pop ecx +.loopend: + inc ecx + cmp ecx,1024 ;there are 1024 pages in page table + jl .loop2 + + mov eax,esi + call MEM_Free_Page_Linear ;free page table +.loop1end: + add edi,4 ;move to next directory entry + mov eax,[edi] + and eax,not (4096-1) + call MEM_Get_Linear_Address + mov esi,eax ;calculate linear address of new page table + test edi,0x800 + jz .loop1 ;test if we at 0x80000000 address? + + and edi,not (4096-1) ;clear offset of page directory entry + mov eax,edi + call MEM_Free_Page_Linear ;free page directory + popad + ret + +.threadsexists: ;do nothing + popad ;last thread will free memory + ret +;----------------------------------------------------------------------------- +mem_alloc_specified_region: +;eax - linear directory address +;ebx - start address (aligned to 4096 bytes) +;ecx - size in pages +;result: +; eax=1 - ok +; eax=0 - failed +;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval. + pushad + mov ebp,ebx ;save start address for recoil + mov esi,eax +.gen_loop: +;esi = linear directory address +;ebx = current address +;ecx = remaining size in pages + mov edx,ebx + shr edx,22 + mov edi,[esi+4*edx] ;find directory entry for current address + test edi,edi + jnz .table_exists ;check if page table allocated + call MEM_Alloc_Page ;alloc page table + test eax,eax + jz .failed + mov [esi+4*edx],eax + add dword [esi+4*edx],7 ;write it address with flags + call MEM_Get_Linear_Address + call mem_fill_page ;clear page table + jmp .table_linear +.table_exists: +;calculate linear address of page table + mov eax,edi + and eax,not (4096-1) ;clear flags + call MEM_Get_Linear_Address +.table_linear: +;eax = linear address of page table + mov edx,ebx + shr edx,12 + and edx,(1024-1) ;calculate index in page table + mov edi,eax + +.loop: +;edi = linear address of page table +;edx = current page table index +;ecx = remaining size in pages +;ebx = current address + test ecx,ecx + jle .endloop1 ;all requested pages allocated + + call MEM_Alloc_Page ;alloc new page + test eax,eax + jz .failed + mov [edi+4*edx],eax + add dword [edi+4*edx],7 ;write it address with flags + call MEM_Get_Linear_Address + call mem_fill_page ;clear new page +;go to next page table entry + dec ecx + add ebx,4096 + inc edx + test edx,(1024-1) + jnz .loop + + jmp .gen_loop + +.endloop1: + popad + mov eax,1 ;ok + ret + +.failed: +;calculate data for recoil + sub ebx,ebp + shr ebx,12 + mov ecx,ebx ;calculate number of allocated pages + mov eax,esi ;restore linear address of page directory + mov ebx,ebp ;restore initial address + call mem_free_specified_region ;free all allocated pages + popad + xor eax,eax ;fail + ret +;----------------------------------------------------------------------------- +mem_fill_page: +;Input: +; eax - address +;result: +; none +;set to zero 4096 bytes at eax address. + push ecx + push edi + mov edi,eax + mov ecx,4096/4 + xor eax,eax + rep stosd + lea eax,[edi-4096] + pop edi + pop ecx + ret +;----------------------------------------------------------------------------- +mem_free_specified_region: +;eax - linear page directory address +;ebx - start address (aligned to 4096 bytes) +;ecx - size in pages +;result - none +;Free pages in [ebx;ebx+4096*ecx) region. + pushad + mov esi,eax + xor ebp,ebp + +.gen_loop: +;esi = linear page directory address +;ebx = current address +;ecx = remaining pages +;ebp = 0 for first page table +; 1 otherwise + mov edx,ebx + shr edx,22 + mov eax,[esi+4*edx] ;find directory entry for current address + and eax,not (4096-1) + test eax,eax + jnz .table_exists +;skip absent page tables + mov edx,ebx + shr edx,12 + and edx,(1024-1) ;edx - index of current page + add ebx,1 shl 22 + add ecx,edx + and ebx,not ((1 shl 22)-1) + mov ebp,1 ;set flag + sub ecx,1024 ;ecx=ecx-(1024-edx) + jg .gen_loop + popad + ret +.table_exists: + call MEM_Get_Linear_Address +;eax - linear address of table + mov edx,ebx + shr edx,12 + and edx,(1024-1) ;edx - index of current page + mov edi,eax + +.loop: +;edi = linear address of page table entry +;edx = index of page table entry +;ecx = remaining pages + test ecx,ecx + jle .endloop1 + + mov eax,[edi+4*edx] + and eax,not (4096-1) + call MEM_Free_Page ;free page + mov dword [edi+4*edx],0 ;and clear page table entry + dec ecx + inc edx + cmp edx,1024 + jl .loop + + test ebp,ebp + jz .first_page + mov eax,edi + call MEM_Free_Page_Linear ;free page table + mov edx,ebx + shr edx,22 + mov dword [esi+4*edx],0 ;and clear page directory entry +.first_page: + add ebx,1 shl 22 + and ebx,not ((1 shl 22)-1) ;calculate new current address + mov ebp,1 ;set flag + jmp .gen_loop + +.endloop1: + popad + ret +end if diff --git a/kernel/tags/kolibri0.6.0.0/core/memmanag.inc b/kernel/tags/kolibri0.6.0.0/core/memmanag.inc new file mode 100644 index 0000000000..7055213ac1 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/memmanag.inc @@ -0,0 +1,833 @@ +if ~defined memmanager_inc +memmanager_inc_fix: +memmanager_inc fix memmanager_inc_fix +;for testing in applications +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Memory allocator for MenuetOS kernel +;; Andrey Halyavin, halyavin@land.ru 2005 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; heap block structure - +;; you can handle several ranges of +;; pages simultaneosly. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +.heap_linear_address equ 0 +.heap_block_size equ 4 +.heap_physical_address equ 8 +.heap_reserved equ 12 +.heap_block_info equ 16 +max_heaps equ 8 +.range_info equ 36 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; memory manager data +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +uglobal + MEM_heap_block rd .heap_block_info*max_heaps/4 + MEM_heap_count rd 1 + MEM_cli_count rd 1 + MEM_cli_prev rd 1 + MEM_FreeSpace rd 1 +; MEM_AllSpace rd 1 +endg +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Init +;;Initialize memory manager structures. +;;Must be called first. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MEM_Init: + push eax + xor eax,eax + mov [MEM_cli_prev],eax ;init value = 0 + dec eax + mov [MEM_cli_count],eax ;init value = -1 + pop eax + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Heap_Lock +;;Wait until all operations with heap will be finished. +;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations +;;with heap are forbidden. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MEM_Heap_Lock: + pushfd + cli + inc dword [MEM_cli_count] + jz MEM_Heap_First_Lock + add esp,4 + ret +MEM_Heap_First_Lock: ;save interrupt flag + shr dword [esp],9 + and dword [esp],1 + pop dword [MEM_cli_prev] + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Heap_UnLock +;;After this routine operations with heap are allowed. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MEM_Heap_UnLock: + dec dword [MEM_cli_count] + js MEM_Heap_UnLock_last + ret +MEM_Heap_UnLock_last: + cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag + jz MEM_Heap_UnLock_No_sti + sti +MEM_Heap_UnLock_No_sti: + ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Add_Heap +;;Add new range to memory manager. +;;eax - linear address +;;ebx - size in pages +;;ecx - physical address +;;Result: +;; eax=1 - success +;; eax=0 - failed +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MEM_Add_Heap: + push edx + call MEM_Heap_Lock + mov edx,[MEM_heap_count] + cmp edx,max_heaps + jz MEM_Add_Heap_Error + inc dword [MEM_heap_count] + shl edx,4 + mov [MEM_heap_block+edx+.heap_linear_address],eax + mov [MEM_heap_block+edx+.heap_block_size],ebx + shl dword [MEM_heap_block+edx+.heap_block_size],12 + mov [MEM_heap_block+edx+.heap_physical_address],ecx + lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table + and edx,0xFFFFF000 + + push edi + mov edi,edx + shr edi,12 + sub edi,ebx ;edi=-free space + sub [MEM_FreeSpace],edi +; sub [MEM_AllSpace],edi + + mov [eax],eax + add [eax],edx ;first 4 bytes - pointer to first free page +;clean page info area + lea edi,[eax+4] + mov ecx,edx + shr ecx,2 + push eax + xor eax,eax + rep stosd + pop eax + pop edi +;create free pages list. + mov ecx,[eax] + shl ebx,12 + add eax,ebx ;eax - address after block +MEM_Add_Heap_loop: + add ecx,4096 + mov [ecx-4096],ecx ;set forward pointer + cmp ecx,eax + jnz MEM_Add_Heap_loop + mov dword [ecx-4096],0 ;set end of list +MEM_Add_Heap_ret: + call MEM_Heap_UnLock + pop edx + ret +MEM_Add_Heap_Error: + xor eax,eax + jmp MEM_Add_Heap_ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Get_Physical_Address +;;Translate linear address to physical address +;;Parameters: +;; eax - linear address +;;Result: +;; eax - physical address +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Get_Physical_Address +MEM_Get_Physical_Address: + push ecx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Get_Physical_Address_loop: + sub eax,[MEM_heap_block+ecx+.heap_linear_address] + jl MEM_Get_Physical_Address_next + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jge MEM_Get_Physical_Address_next + add eax,[MEM_heap_block+ecx+.heap_physical_address] + jmp MEM_Get_Physical_Address_loopend +MEM_Get_Physical_Address_next: + add eax,[MEM_heap_block+ecx+.heap_linear_address] + sub ecx,16 + jns MEM_Get_Physical_Address_loop + xor eax,eax ;address not found +MEM_Get_Physical_Address_loopend: + call MEM_Heap_UnLock + pop ecx + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Get_Linear_Address +;;Translate physical address to linear address. +;;Parameters: +;; eax - physical address +;;Result: +;; eax - linear address +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Get_Linear_Address +MEM_Get_Linear_Address: + push ecx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Get_Linear_Address_loop: + sub eax,[MEM_heap_block+ecx+.heap_physical_address] + jl MEM_Get_Linear_Address_Next + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jge MEM_Get_Linear_Address_Next + add eax,[MEM_heap_block+ecx+.heap_linear_address] + call MEM_Heap_UnLock + pop ecx + ret +MEM_Get_Linear_Address_Next: + add eax,[MEM_heap_block+ecx+.heap_physical_address] + sub ecx,16 + jns MEM_Get_Linear_Address_loop + call MEM_Heap_UnLock + pop ecx + xor eax,eax ;address not found + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Alloc_Page +;;Allocate and add reference to page +;;Result: +;; eax<>0 - physical address of page +;; eax=0 - not enough memory +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Alloc_Page +MEM_Alloc_Page: + push ecx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Alloc_Page_loop: + push ecx + mov ecx,[MEM_heap_block+ecx+.heap_linear_address] + cmp dword [ecx],0 + jz MEM_Alloc_Page_loopend + mov eax,[ecx] + push dword [eax] + pop dword [ecx] + sub eax,ecx + push eax + shr eax,10 + mov word [ecx+.range_info+eax],1 + pop eax + pop ecx + add eax,[MEM_heap_block+ecx+.heap_physical_address] + dec [MEM_FreeSpace] + jmp MEM_Alloc_Page_ret +MEM_Alloc_Page_loopend: + pop ecx + sub ecx,16 + jns MEM_Alloc_Page_loop + xor eax,eax +MEM_Alloc_Page_ret: + call MEM_Heap_UnLock + pop ecx + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Alloc_Page_Linear +;;Allocate and add reference to page +;;Result: +;; eax<>0 - linear address of page +;; eax=0 - not enough memory +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Alloc_Page_Linear +MEM_Alloc_Page_Linear: + push ecx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Alloc_Page_Linear_loop: + push ecx + mov ecx,[MEM_heap_block+ecx+.heap_linear_address] + cmp dword [ecx],0 + jz MEM_Alloc_Page_Linear_loopend + mov eax,[ecx] + push dword [eax] + pop dword [ecx] + push eax + sub eax,ecx + shr eax,10 + mov word [ecx+.range_info+eax],1 + pop eax + pop ecx + dec [MEM_FreeSpace] + jmp MEM_Alloc_Page_Linear_ret +MEM_Alloc_Page_Linear_loopend: + pop ecx + sub ecx,16 + jns MEM_Alloc_Page_Linear_loop + xor eax,eax +MEM_Alloc_Page_Linear_ret: + call MEM_Heap_UnLock + pop ecx + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Free_Page +;;Remove reference and free page if number of +;;references is equal to 0 +;;Parameters: +;; eax - physical address of page +;;Result: +;; eax - 1 success +;; eax - 0 failed +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if (used MEM_Free_Page) | (used MEM_Free_Page_Linear) +MEM_Free_Page: + test eax,eax + jz MEM_Free_Page_Zero + test eax,0xFFF + jnz MEM_Free_Page_Not_Aligned + push ebx + push ecx + push edx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Free_Page_Heap_loop: + sub eax,[MEM_heap_block+ecx+.heap_physical_address] + js MEM_Free_Page_Heap_loopnext + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jl MEM_Free_Page_Heap_loopend +MEM_Free_Page_Heap_loopnext: + add eax,[MEM_heap_block+ecx+.heap_physical_address] + sub ecx,16 + jns MEM_Free_Page_Heap_loop + xor eax,eax + inc eax + jmp MEM_Free_Page_ret +MEM_Free_Page_Heap_loopend: + mov ecx,[MEM_heap_block+ecx+.heap_linear_address] + mov ebx,eax + add eax,ecx + shr ebx,10 + mov edx,[ecx+.range_info+ebx] + test edx,0x80000000 + jnz MEM_Free_Page_Bucket + test dx,dx + jz MEM_Free_Page_Error + dec word [ecx+.range_info+ebx] + jnz MEM_Free_Page_OK +MEM_Free_Page_Bucket: + push dword [ecx] + mov [ecx],eax + pop dword [eax] + mov dword [ecx+.range_info+ebx],0 + inc [MEM_FreeSpace] +MEM_Free_Page_OK: + mov eax,1 +MEM_Free_Page_ret: + call MEM_Heap_UnLock + pop edx + pop ecx + pop ebx + ret +MEM_Free_Page_Error: + xor eax,eax + jmp MEM_Free_Page_ret +MEM_Free_Page_Zero: + inc eax + ret +MEM_Free_Page_Not_Aligned: + xor eax,eax + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Free_Page_Linear +;;Remove reference and free page if number of +;;references is equal to 0 +;;Parameters: +;; eax - linear address of page +;;Result: +;; eax - 1 success +;; eax - 0 failed +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Free_Page_Linear +MEM_Free_Page_Linear: + test eax,eax + jz MEM_Free_Page_Zero + test eax,0xFFF + jnz MEM_Free_Page_Not_Aligned + push ebx + push ecx + push edx + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 + +MEM_Free_Page_Linear_Heap_loop: + sub eax,[MEM_heap_block+ecx+.heap_linear_address] + js MEM_Free_Page_Linear_Heap_loopnext + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jl MEM_Free_Page_Heap_loopend +MEM_Free_Page_Linear_Heap_loopnext: + add eax,[MEM_heap_block+ecx+.heap_linear_address] + sub ecx,16 + jns MEM_Free_Page_Linear_Heap_loop + xor eax,eax + inc eax + jmp MEM_Free_Page_ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Alloc_Pages +;;Allocates set of pages. +;;Parameters: +;; eax - number of pages +;; ebx - buffer for physical addresses +;;Result: +;; eax - number of allocated pages +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Alloc_Pages +MEM_Alloc_Pages: + push eax + push ebx + push ecx + mov ecx,eax + test ecx,ecx + jz MEM_Alloc_Pages_ret +MEM_Alloc_Pages_loop: + call MEM_Alloc_Page + test eax,eax + jz MEM_Alloc_Pages_ret + mov [ebx],eax + add ebx,4 + dec ecx + jnz MEM_Alloc_Pages_loop +MEM_Alloc_Pages_ret: + sub [esp+8],ecx + pop ecx + pop ebx + pop eax + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Alloc_Pages_Linear +;;Allocates set of pages. +;;Parameters: +;; eax - number of pages +;; ebx - buffer for linear addresses +;;Result: +;; eax - number of allocated pages +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Alloc_Pages_Linear +MEM_Alloc_Pages_Linear: + push eax + push ebx + push ecx + mov ecx,eax + test ecx,ecx + jz MEM_Alloc_Pages_Linear_ret +MEM_Alloc_Pages_Linear_loop: + call MEM_Alloc_Page_Linear + test eax,eax + jz MEM_Alloc_Pages_Linear_ret + mov [ebx],eax + add ebx,4 + dec ecx + jnz MEM_Alloc_Pages_Linear_loop +MEM_Alloc_Pages_Linear_ret: + sub [esp+8],ecx + pop ecx + pop ebx + pop eax + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Free_Pages +;;Parameters: +;; eax - number of pages +;; ebx - array of addresses +;;Result: +;; eax=1 - succcess +;; eax=0 - failed +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Free_Pages +MEM_Free_Pages: + push ebx + push ecx + mov ecx,eax + test ecx,ecx + jz MEM_Free_Pages_ret +MEM_Free_Pages_loop: + mov eax,[ebx] + call MEM_Free_Page + add ebx,4 + test eax,eax + jz MEM_Free_Pages_ret + dec ecx + jnz MEM_Free_Pages_loop +MEM_Free_Pages_ret: + pop ecx + pop ebx + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Free_Pages_Linear +;;Parameters: +;; eax - number of pages +;; ebx - array of addresses +;;Result: +;; eax=1 - succcess +;; eax=0 - failed +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Free_Pages_Linear +MEM_Free_Pages_Linear: + push ebx + push ecx + mov ecx,eax + test ecx,ecx + jz MEM_Free_Pages_Linear_ret +MEM_Free_Pages_Linear_loop: + mov eax,[ebx] + call MEM_Free_Page_Linear + add ebx,4 + test eax,eax + jz MEM_Free_Pages_Linear_ret + dec ecx + jnz MEM_Free_Pages_Linear_loop +MEM_Free_Pages_Linear_ret: + pop ecx + pop ebx + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Get_Heap_Number +;;Calculate number of heap which pointer belongs to. +;;Parameter: +;; eax - address +;;Result: +;; ecx - number of heap*16. +;; eax=0 if address not found. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Get_Heap_Number +MEM_Get_Heap_Number: + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Get_Heap_loop: + sub eax,[MEM_heap_block+ecx+.heap_physical_address] + jl MEM_Get_Heap_loopnext + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jl MEM_Get_Heap_loopend +MEM_Get_Heap_loopnext: + add eax,[MEM_heap_block+ecx+.heap_physical_address] + sub ecx,16 + jns MEM_Get_Heap_loop + call MEM_Heap_UnLock + xor eax,eax + ret +MEM_Get_Heap_loopend: + add eax,[MEM_heap_block+ecx+.heap_physical_address] + call MEM_Heap_UnLock + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Get_Heap_Number_Linear +;;Calculate number of heap which pointer belongs to. +;;Parameter: +;; eax - address +;;Result: +;; ecx - number of heap*16. +;; eax=0 if address not found. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +if used MEM_Get_Heap_Number_Linear +MEM_Get_Heap_Number_Linear: + call MEM_Heap_Lock + mov ecx,[MEM_heap_count] + dec ecx + shl ecx,4 +MEM_Get_Heap_Linear_loop: + sub eax,[MEM_heap_block+ecx+.heap_linear_address] + jl MEM_Get_Heap_Linear_loopnext + cmp eax,[MEM_heap_block+ecx+.heap_block_size] + jl MEM_Get_Heap_Linear_loopend +MEM_Get_Heap_Linear_loopnext: + add eax,[MEM_heap_block+ecx+.heap_linear_address] + sub ecx,16 + jns MEM_Get_Heap_Linear_loop + call MEM_Heap_UnLock + xor eax,eax + ret +MEM_Get_Heap_Linear_loopend: + add eax,[MEM_heap_block+ecx+.heap_linear_address] + call MEM_Heap_UnLock + ret +end if +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;MEM_Alloc +;;Allocate small region. +;;Parameters: +;; eax - size (00 - ok +; 0 - failed. +;This function find least empty slot. +;It doesn't increase [0x3004]! + mov eax,0x3000+second_base_address + push ebx + mov ebx,[0x3004] + inc ebx + shl ebx,5 + add ebx,eax ;ebx - address of process information for (last+1) slot +.newprocessplace: +;eax = address of process information for current slot + cmp eax,ebx + jz .endnewprocessplace ;empty slot after high boundary + add eax,0x20 + cmp word [eax+TASKDATA.state],9 ;check process state, 9 means that process slot is empty + jnz .newprocessplace +.endnewprocessplace: + mov ebx,eax + sub eax,0x3000+second_base_address + shr eax,5 ;calculate slot index + cmp eax,256 + jge .failed ;it should be <256 + mov word [ebx+TASKDATA.state],9 ;set process state to 9 (for slot after hight boundary) + mov [new_process_place],eax ;save process slot + pop ebx + ret +.failed: + xor eax,eax + pop ebx + ret +;----------------------------------------------------------------------------- +safe_sti: + cmp byte [0xe000], 1 + jne @f + sti + @@:ret + +;----------------------------------------------------------------------------- +new_sys_threads: +;eax=1 - create thread +; ebx=thread start +; ecx=thread stack value +;result: +; eax=pid + xor edx,edx ; flags=0 + pushad + + cmp eax,1 + jnz .ret ;other subfunctions + mov esi,new_process_loading + call sys_msg_board_str +;lock application_table_status mutex +.table_status: + cli + cmp [application_table_status],0 + je .stf + sti + call change_task + jmp .table_status +.stf: + call set_application_table_status +;find free process slot + + call find_new_process_place + test eax,eax + jz .failed + +;set parameters for thread + xor eax,eax + mov [app_i_param],eax + mov [app_i_icon],eax + mov [app_start],ebx + mov [app_esp],ecx + + mov esi,[0x3000] + shl esi,8 + add esi,0x80000+APPDATA.app_name + mov ebx,esi ;ebx=esi - pointer to extended information about current thread + + mov edi,[new_process_place] + shl edi,8 + add edi,0x80000 + lea edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread + mov ecx,256/4 + rep stosd ;clean extended information about new thread + mov edi,edx + mov ecx,11 + rep movsb ;copy process name + mov eax,[ebx+APPDATA.mem_size] + mov [app_mem],eax ;set memory size + mov eax,[ebx+APPDATA.dir_table] + mov dword [edx-APPDATA.app_name+APPDATA.dir_table],eax ;copy page directory +; mov eax,[new_process_place] +; mov ebx,[0x3000] +; call addreference_app_cr3_table + + push 0 ;no parameters + call fs_execute.add_app_parameters ;start thread + mov [esp+28],eax + popad + ret + +.failed: + sti + popad + mov eax,-1 + ret +.ret: + popad + ret +;----------------------------------------------------------------------------- +new_mem_resize: +;input: +; ebx - new size +;result: +; [esp+36]:=0 - normal +; [esp+36]:=1 - error +;This function set new application memory size. + mov esi,ebx ;save new size + add ebx,4095 + and ebx,not (4096-1) ;round up size + mov ecx,[0x3000] + shl ecx,8 + mov edx,[0x80000 + APPDATA.mem_size +ecx] + add edx,4095 + and edx,not (4096-1) ;old size + mov eax,[0x80000 + APPDATA.dir_table+ecx] + call MEM_Get_Linear_Address +;eax - linear address of page directory + call MEM_Heap_Lock ;guarantee that two threads willn't + ;change memory size simultaneously + cmp ebx,edx +; mov esi,ebx ;save new size + jg .expand + +.free: + sub edx,ebx + jz .unlock ;do nothing + mov ecx,edx + shr ecx,12 + add ebx,std_application_base_address + call mem_free_specified_region ;free unnecessary pages + jmp .unlock + +.expand: + sub ebx,edx + mov ecx,ebx + shr ecx,12 + mov ebx,edx + add ebx,std_application_base_address + call mem_alloc_specified_region ;alloc necessary pages + test eax,eax + jz .failed ;not enough memory + +.unlock: + mov ebx,esi + mov eax,[0x3000] + shl eax,8 + mov [eax+0x80000 + APPDATA.mem_size],ebx ;write new memory size +;search threads and update +;application memory size infomation + mov ecx,[eax+0x80000 + APPDATA.dir_table] + mov eax,2 + +.search_threads: +;eax = current slot +;ebx = new memory size +;ecx = page directory + cmp eax,[0x3004] + jg .search_threads_end + mov edx,eax + shl edx,5 + cmp word [0x3000+edx+TASKDATA.state],9 ;if slot empty? + jz .search_threads_next + shl edx,3 + cmp [edx+0x80000+APPDATA.dir_table],ecx ;if it is our thread? + jnz .search_threads_next + mov [edx+0x80000+APPDATA.mem_size],ebx ;update memory size +.search_threads_next: + inc eax + jmp .search_threads +.search_threads_end: + + call MEM_Heap_UnLock + mov dword [esp+36],0 + ret + +.failed: + call MEM_Heap_UnLock + mov dword [esp+36],1 + ret +;----------------------------------------------------------------------------- +pid_to_slot: +;Input: +; eax - pid of process +;Output: +; eax - slot of process or 0 if process don't exists +;Search process by PID. + push ebx + push ecx + mov ebx,[0x3004] + shl ebx,5 + mov ecx,2*32 + +.loop: +;ecx=offset of current process info entry +;ebx=maximum permitted offset + cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 + jz .endloop ;skip empty slots + cmp [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID + jz .pid_found +.endloop: + add ecx,32 + cmp ecx,ebx + jle .loop + + pop ecx + pop ebx + xor eax,eax + ret + +.pid_found: + shr ecx,5 + mov eax,ecx ;convert offset to index of slot + pop ecx + pop ebx + ret +;----------------------------------------------------------------------------- +is_new_process: +;Input: +; eax - process slot +;Output: +; eax=1 - it is new process +; eax=0 - it is old process +; shl eax,5 +; mov eax,[second_base_address+0x3000+eax+0x10] +; cmp eax,std_application_base_address ;check base address of application +; jz .new_process +; xor eax,eax +; ret + +;.new_process: + mov eax,1 + ret +;----------------------------------------------------------------------------- +write_process_memory: +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes written + pushad + shl eax,8 + mov eax,[0x80000+eax+APPDATA.dir_table] + call MEM_Get_Linear_Address + mov ebp,eax +;ebp=linear address of page directory of other process. + add edx,std_application_base_address ;convert to linear address + test ecx,ecx + jle .ret + +.write_loop: +;ebx = current buffer address +;ecx>0 = current size +;edx = current address in other process +;ebp = linear address of page directory + + call MEM_Heap_Lock ;cli + mov esi,edx + shr esi,22 + mov eax,[ebp+4*esi] ;find page directory entry + and eax,not (4096-1) ;clear flags + test eax,eax + jz .page_not_found + call MEM_Get_Linear_Address ;calculate linear address of page table + test eax,eax + jz .page_not_found + mov esi,edx + shr esi,12 + and esi,1023 + mov eax,[eax+4*esi] ;find page table entry + and eax,not (4096-1) + test eax,eax + jz .page_not_found + call MEM_Get_Linear_Address ;calculate linear address of page + test eax,eax + jz .page_not_found + mov edi,eax + call MEM_Add_Reference_Linear;guarantee that page willn't disappear + call MEM_Heap_UnLock ;sti + + mov esi,edx + and esi,4095 + add edi,esi ;add offset in page +;edi = linear address corresponding edx in other process + sub esi,4096 + neg esi ;esi - number of remaining bytes in page + cmp esi,ecx + jl .min_ecx + mov esi,ecx +.min_ecx: ;esi=min(ecx,esi) - number of bytes to write + sub ecx,esi + push ecx + mov ecx,esi ;ecx - number of bytes to write + mov esi,ebx ;esi - source, edi - destination + add edx,ecx ;move pointer in address space of other process + push edi + +;move ecx bytes + test ecx,3 + jnz .not_aligned + shr ecx,2 + rep movsd + jmp .next_iter +.not_aligned: + rep movsb +.next_iter: + + pop eax + and eax,not (4096-1) ;eax - linear address of current page + call MEM_Free_Page_Linear ;free reference + mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it. + pop ecx ;restore number of remaining bytes + test ecx,ecx + jnz .write_loop +.ret: + popad + mov eax,ecx + ret + +.page_not_found: + call MEM_Heap_UnLock ;error has appeared in critical region + sub ecx,[esp+24] ;[esp+24]<-->ecx + neg ecx ;ecx=number_of_written_bytes + mov [esp+28],ecx ;[esp+28]<-->eax + popad + ret +;----------------------------------------------------------------------------- +syscall_test: +;for testing memory manager from applications. + mov edx,ecx + mov ecx,ebx + call trans_address + mov ebx,eax + mov eax,[0x3000] + call read_process_memory + ret +;----------------------------------------------------------------------------- +read_process_memory: +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes read. + pushad + shl eax,8 + mov eax,[0x80000+eax+APPDATA.dir_table] + call MEM_Get_Linear_Address + mov ebp,eax + add edx,std_application_base_address +.read_loop: +;ebx = current buffer address +;ecx>0 = current size +;edx = current address in other process +;ebp = linear address of page directory + + call MEM_Heap_Lock ;cli + mov esi,edx + shr esi,22 + mov eax,[ebp+4*esi] ;find page directory entry + and eax,not (4096-1) + test eax,eax + jz .page_not_found + call MEM_Get_Linear_Address + test eax,eax + jz .page_not_found + mov esi,edx + shr esi,12 + and esi,1023 + mov eax,[eax+4*esi] ;find page table entry + and eax,not (4096-1) + test eax,eax + jz .page_not_found + call MEM_Get_Linear_Address ;calculate linear address of page + test eax,eax + jz .page_not_found + mov esi,eax + call MEM_Add_Reference_Linear;guarantee that page willn't disappear + call MEM_Heap_UnLock ;sti + + mov edi,edx + and edi,4095 + add esi,edi ;add offset in page +;esi = linear address corresponding edx in other process + sub edi,4096 + neg edi + +;edi=min(edi,ecx) - number of bytes to copy + cmp edi,ecx + jl .min_ecx + mov edi,ecx +.min_ecx: + + sub ecx,edi ;update size of remaining bytes + add edx,edi ;update current pointer in other address space. + push ecx + mov ecx,edi ;ecx - number of bytes to read + mov edi,ebx ;esi - source, edi - destination + push esi +;move ecx bytes + test ecx,3 + jnz .not_aligned + shr ecx,2 + rep movsd + jmp .next_iter +.not_aligned: + rep movsb +.next_iter: + pop eax + and eax,not (4096-1) ;eax - linear address of current page + call MEM_Free_Page_Linear ;free reference + mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it. + pop ecx ;restore number of remaining bytes + test ecx,ecx + jnz .read_loop + + popad + mov eax,ecx + ret + +.page_not_found: + call MEM_Heap_UnLock ;error has appeared in critical region + sub ecx,[esp+24] ;[esp+24]<-->ecx + neg ecx ;ecx=number_of_read_bytes + mov [esp+28],ecx ;[esp+28]<-->eax + popad + ret +;----------------------------------------------------------------------------- +check_region: +;input: +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + mov eax,[0x3000] + jmp check_process_region +;----------------------------------------------------------------------------- +check_process_region: +;input: +; eax - slot +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + test ecx,ecx + jle .ok + shl eax,5 + cmp word [0x3000+eax+TASKDATA.state],0 + jnz .failed + shl eax,3 + mov eax,[0x80000+eax+APPDATA.dir_table] + test eax,eax + jz .failed + call MEM_Get_Linear_Address + push ebx + push ecx + push edx + mov edx,ebx + and edx,not (4096-1) + sub ebx,edx + add ecx,ebx + mov ebx,edx + add ecx,(4096-1) + and ecx,not (4096-1) +.loop: +;eax - linear address of page directory +;ebx - current page +;ecx - current size + mov edx,ebx + shr edx,22 + mov edx,[eax+4*edx] + and edx,not (4096-1) + test edx,edx + jz .failed1 + push eax + mov eax,edx + call MEM_Get_Linear_Address + mov edx,ebx + shr edx,12 + and edx,(1024-1) + mov eax,[eax+4*edx] + and eax,not (4096-1) + test eax,eax + pop eax + jz .failed1 + add ebx,4096 + sub ecx,4096 + jg .loop + pop edx + pop ecx + pop ebx +.ok: + mov eax,1 + ret + +.failed1: + pop edx + pop ecx + pop ebx +.failed: + xor eax,eax + ret +;----------------------------------------------------------------------------- +new_sys_ipc: +;input: +; eax=1 - set ipc buffer area +; ebx=address of buffer +; ecx=size of buffer +; eax=2 - send message +; ebx=PID +; ecx=address of message +; edx=size of message + cmp eax,1 + jnz .no_ipc_def +;set ipc buffer area + mov edi,[0x3000] + shl edi,8 + add edi,0x80000 + cli + mov [edi+APPDATA.ipc_start],ebx ;set fields in extended information area + mov [edi+APPDATA.ipc_size],ecx + sti + mov [esp+36],dword 0 ;success + ret + +.no_ipc_def: + cmp eax,2 + jnz .no_ipc_send +;send message + cli +;obtain slot from PID + mov eax,ebx + call pid_to_slot + test eax,eax + jz .no_pid + mov ebp,eax +;ebp = slot of other process + shl eax,8 + mov edi,[eax+0x80000+APPDATA.ipc_start] ;is ipc area defined? + test edi,edi + jz .no_ipc_area + mov esi,[eax+0x80000+APPDATA.ipc_size] ;esi - size of buffer + push dword -1 ;temp variable for read_process_memory + mov ebx,esp + push ecx + push edx + mov ecx,4 ;read 4 bytes + mov eax,ebp + mov edx,edi ;from beginning of buffer. + call read_process_memory + mov eax,[esp+8] + test eax,eax + jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now + add edx,4 ;move to next 4 bytes + mov eax,ebp + call read_process_memory ;read size of occupied space in buffer + sub esi,8 + sub esi,[esp] + sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size) + js .buffer_overflow ;esi<0 - not enough memory in buffer + mov esi,[esp+8] ;previous offset + add dword [esp+8],8 + mov edi,[esp] + add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4] + mov eax,ebp + call write_process_memory + add edx,esi + sub edx,4 ;move to beginning of place for our message + mov eax,[second_base_address+0x3010] + mov eax,[eax+TASKDATA.pid] ;eax - our PID + mov [esp+8],eax + mov eax,ebp + call write_process_memory ;write PID + mov ebx,esp ;address of size of message + mov eax,ebp + add edx,4 + call write_process_memory ;write size of message + add edx,4 + pop ecx ;ecx - size of message + pop eax + call trans_address + mov ebx,eax ;ebx - linear address of message + add esp,4 ;pop temporary variable + mov eax,ebp + call write_process_memory ;write message + sti +;awake other process + shl ebp,8 + mov eax,ebp + or [eax+0x80000+APPDATA.event_mask],dword 0x40 + + cmp dword [check_idle_semaphore],20 + jge .ipc_no_cis + mov dword [check_idle_semaphore],5 +.ipc_no_cis: + mov dword [esp+36],0 + ret +.no_ipc_send: + mov dword [esp+36],-1 + ret +.no_pid: + sti + mov dword [esp+36],4 + ret +.no_ipc_area: + sti + mov dword [esp+36],1 + ret +.ipc_blocked: + sti + add esp,12 + mov dword [esp+36],2 + ret +.buffer_overflow: + sti + add esp,12 + mov dword [esp+36],3 + ret +;----------------------------------------------------------------------------- +trans_address: +;Input +; eax - application address +;Output +; eax - linear address for kernel + add eax,std_application_base_address + ret +;----------------------------------------------------------------------------- + +; \begin{diamond} + include 'debug.inc' + +fs_execute: +; ebx - cmdline +; edx - flags +; ebp - full filename +; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it + pushad +; check filename length - with terminating NULL must be no more than 1024 symbols + mov edi, ebp + mov ecx, 1024 + xor eax, eax + repnz scasb + jz @f + popad + mov eax, -ERROR_FILE_NOT_FOUND + ret +@@: + + mov esi, new_process_loading + call sys_msg_board_str ; write message to message board + +; lock application_table_status mutex +.table_status: + cli + cmp [application_table_status], 0 + jz .stf + sti + call change_task + jmp .table_status +.stf: + call set_application_table_status + push ebx ; save command line pointer for add_app_parameters + + call find_new_process_place ; find new process slot + call safe_sti + test eax, eax + mov ecx, -0x20 ; too many processes + jz .failed + +; write application name + push edi + mov ecx, edi + sub ecx, ebp + mov [appl_path], ebp + mov [appl_path_size], ecx + dec edi + std + mov al, '/' + repnz scasb + cld + jnz @f + inc edi +@@: + inc edi +; now edi points to name without path + mov esi, edi + mov ecx, 8 ; 8 chars for name + mov edi, [new_process_place] + shl edi, cl + add edi, 0x80000+APPDATA.app_name +.copy_process_name_loop: + lodsb + cmp al, '.' + jz .copy_process_name_done + test al, al + jz .copy_process_name_done + stosb + loop .copy_process_name_loop +.copy_process_name_done: + mov al, ' ' + rep stosb + pop eax + mov cl, 3 ; 3 chars for extension + dec esi +@@: + dec eax + cmp eax, esi + jbe .copy_process_ext_done + cmp byte [eax], '.' + jnz @b + lea esi, [eax+1] +.copy_process_ext_loop: + lodsb + test al, al + jz .copy_process_ext_done + stosb + loop .copy_process_ext_loop +.copy_process_ext_done: + mov al, ' ' + rep stosb + +; read header + lea eax, [esp+8+36] + mov edi, 0x90000 + call dword [eax-4] + mov ecx, eax + neg ecx + jnz .cleanfailed +; check menuet signature + mov ecx, -0x1F + cmp dword [0x90000], 'MENU' + jnz .cleanfailed + cmp word [0x90004], 'ET' + jnz .cleanfailed + call get_app_params + mov ecx, -0x1F + jc .cleanfailed +; sanity check - because we will load all file, +; file size must be not greater than memory size + mov eax, [esp+8+36] + cmp [app_mem], eax + jb .cleanfailed + + mov eax, [new_process_place] + inc ecx ; -0x1E = no memory + call create_app_cr3_table + test eax, eax + jz .cleanfailed_mem + + call MEM_Get_Linear_Address + + mov ebx, std_application_base_address + mov ecx, [app_mem] + add ecx, 4095 + shr ecx, 12 + mov edx, eax ; edx - linear address of page directory + call mem_alloc_specified_region + mov ecx, -0x1E ; no memory + test eax, eax + jz .cleanfailed_mem1 + + add edx, std_application_base_address shr 20 + mov eax, [edx] + and eax, not 4095 + call MEM_Get_Linear_Address + push edx ; save pointer to first page table + mov edx, eax +; read file +; first block is already read to 0x90000 + mov eax, [edx] + and eax, not 0xFFF + call MEM_Get_Linear_Address + mov esi, 0x90000 + mov edi, eax + mov ecx, 512/4 + rep movsd + sub edi, eax +.loop1: +; [esp] = pointer to current page directory entry +; edx = pointer to current page table +; edi = offset in page + mov eax, [edx] + and eax, not 0xFFF + call MEM_Get_Linear_Address + push edi + add edi, eax + lea eax, [esp+8+36+8] + call dword [eax-4] + pop edi + test eax, eax + jnz .endloop1 + add edi, 512 ; new offset + cmp edi, 4096 + jb .loop1 + xor edi, edi + add edx, 4 ; go to next page + test edx, 4096-1 + jnz .loop1 + pop eax + add eax, 4 ; go to next directory entry + push eax + mov eax, [eax] + and eax, not 0xFFF + call MEM_Get_Linear_Address + mov edx, eax + jmp .loop1 +.endloop1: + pop edx + cmp eax, 6 + jnz .cleanfailed_mem2 + call .add_app_parameters + mov [esp+28], eax + popad + ret + +.cleanfailed_mem2: +; file read error; free all allocated mem + mov ecx, eax + neg ecx + mov eax, [new_process_place] + call dispose_app_cr3_table + jmp .cleanfailed +.cleanfailed_mem1: +; there is mem for directory entry, but there is no mem for pages +; so free directory entry + mov eax, [new_process_place] + shl eax, 8 + mov eax, [0x80000+eax+0xB8] + call MEM_Free_Page +.cleanfailed_mem: +; there is no mem for directory entry, display message + mov esi, start_not_enough_memory + call sys_msg_board_str +.cleanfailed: + push ecx +; clean process name, this avoid problems with @panel + mov edi, [new_process_place] + shl edi, 8 + add edi, 0x80000+APPDATA.app_name + mov ecx, 11 + mov al, ' ' + rep stosb + pop eax +.failed: + pop ebx + mov [esp+28], eax + popad + mov [application_table_status], 0 + call safe_sti + ret +; \end{diamond} +.add_app_parameters: +;input: +; [esp] - pointer to parameters +; [esp+4]-[esp+36] pushad registers. +;result +; eax - pid of new process +; or zero if failed + cli + mov ebx,[new_process_place] + cmp ebx,[0x3004] + jle .noinc + inc dword [0x3004] ;update number of processes +.noinc: + +; mov ebx,[new_process_place] +;set 0x8c field of extended information about process +;(size of application memory) + shl ebx,8 + mov eax,[app_mem] + mov [second_base_address+0x80000+APPDATA.mem_size+ebx],eax +;set 0x10 field of information about process +;(application base address) +; mov ebx,[new_process_place] +; shl ebx,5 + shr ebx,3 + mov dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address + +;add command line parameters +.add_command_line: + mov edx,[app_i_param] + test edx,edx + jz .no_command_line ;application don't need parameters + mov eax,[esp+4] + test eax,eax + jz .no_command_line ;no parameters specified +;calculate parameter length + mov esi,eax + xor ecx,ecx + inc ecx ; include terminating null +.command_line_len: + cmp byte [esi],0 + jz .command_line_len_end + inc esi + inc ecx + cmp ecx,256 + jl .command_line_len + +.command_line_len_end: +;ecx - parameter length +;edx - address of parameters in new process address space + mov ebx,eax ;ebx - address of parameters in our address space + mov eax,[new_process_place] + call write_process_memory ;copy parameters to new process address space + +.no_command_line: +;****************************************************************** + mov edx,[app_i_icon] + test edx,edx + jz .no_command_line_1 ;application don't need path of file + mov ebx,[appl_path] + mov ecx,[appl_path_size] + mov eax,[new_process_place] + call write_process_memory ;copy path of file to new process address space +.no_command_line_1: +;****************************************************************** + mov ebx,[new_process_place] + mov eax,ebx + shl ebx,5 + mov [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL + mov [ebx+window_data+WDATA.fl_redraw],1 + add ebx,0x3000 ;ebx - pointer to information about process + mov [ebx+TASKDATA.wnd_number],al ;set window number on screen = process slot + + mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) + + inc dword [process_number] + mov eax,[process_number] + mov [ebx+TASKDATA.pid],eax ;set PID + + mov ecx,ebx + add ecx,draw_data-0x3000 ;ecx - pointer to draw data +;set draw data to full screen + mov [ecx+RECT.left],dword 0 + mov [ecx+RECT.top],dword 0 + mov eax,[0xfe00] + mov [ecx+RECT.right],eax + mov eax,[0xfe04] + mov [ecx+RECT.bottom],eax +;set cr3 register in TSS of application + mov ecx,[new_process_place] + shl ecx,8 + mov eax,[0x80000+APPDATA.dir_table+ecx] + add eax,8+16 ;add flags + mov [l.cr3],eax + + mov eax,[app_start] + mov [l.eip],eax ;set eip in TSS + mov eax,[app_esp] + mov [l.esp],eax ;set stack in TSS + +;gdt + ;mov ebx,[new_process_place] + ;shl ebx,3 + mov ax,app_code ;ax - selector of code segment + ;add ax,bx + mov [l.cs],ax + mov ax,app_data + ;add ax,bx ;ax - selector of data segment + mov [l.ss],ax + mov [l.ds],ax + mov [l.es],ax + mov [l.fs],ax + mov ax,graph_data ;ax - selector of graphic segment + mov [l.gs],ax + mov [l.io],word 128 + mov [l.eflags],dword 0x11202 + mov [l.ss0],os_data + mov ebx,[new_process_place] + shl ebx,12 + add ebx,sysint_stack_data+4096 + mov [l.esp0],ebx + +;copy tss to it place + mov eax,tss_sceleton + mov ebx,[new_process_place] + imul ebx,tss_step + add ebx,tss_data ;ebx - address of application TSS + mov ecx,120 + call memmove + +;Add IO access table - bit array of permitted ports + or eax,-1 + mov edi,[new_process_place] + imul edi,tss_step + add edi,tss_data+128 + mov ecx,2048 + cld + rep stosd ;full access to 2048*8=16384 ports + + mov ecx,ebx ;ecx - address of application TSS + mov edi,[new_process_place] + shl edi,3 +;set TSS descriptor + mov [edi+gdts+tss0+0],word tss_step ;limit (size) + mov [edi+gdts+tss0+2],cx ;part of offset + mov eax,ecx + shr eax,16 + mov [edi+gdts+tss0+4],al ;part of offset + mov [edi+gdts+tss0+7],ah ;part of offset + mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags + + +;flush keyboard and buttons queue + mov [0xf400],byte 0 + mov [0xf500],byte 0 + + mov edi,[new_process_place] + shl edi,5 + add edi,window_data + mov ebx,[new_process_place] + movzx esi,word [0xC000+ebx*2] + lea esi,[0xC400+esi*2] + call windowactivate ;gui initialization + + mov ebx,[new_process_place] + shl ebx,5 +; set if debuggee + test byte [esp+28], 1 + jz .no_debug + mov [0x3000+ebx+TASKDATA.state], 1 ; set process state - suspended + mov eax, [0x3000] + mov [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current + jmp .debug +.no_debug: + mov [0x3000+ebx+TASKDATA.state], 0 ; set process state - running +.debug: + + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + +; add esp,4 ;pop pointer to parameters +; popad + mov eax,[process_number] ;set result + mov [application_table_status],0 ;unlock application_table_status mutex + call safe_sti + ret 4 + +end if diff --git a/kernel/tags/kolibri0.6.0.0/core/physmem.inc b/kernel/tags/kolibri0.6.0.0/core/physmem.inc new file mode 100644 index 0000000000..90d08ab294 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/physmem.inc @@ -0,0 +1,220 @@ +virtual at 0 +physical_mem_block: + .start rd 1 + .size rd 1 + .flags rd 1 ;0-free, pid-used. +.sizeof: +end virtual +max_physical_mem_blocks = 24 +uglobal + num_physical_mem_blocks rd 1 + physical_mem_blocks rd 3*max_physical_mem_blocks +endg +Init_Physical_Memory_Manager: + pushad + mov edi,physical_mem_blocks + mov ecx,3*max_physical_mem_blocks + xor eax,eax + cld + rep stosd + mov dword [num_physical_mem_blocks],2 + mov [physical_mem_blocks+physical_mem_block.start],0x60000 + mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb + mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000 + mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb + popad + ret +Insert_Block: +;input: +; eax - handle +;output: +; none + push eax ecx esi edi + sub eax,[num_physical_mem_blocks] + neg eax + mov edi,physical_mem_block.sizeof + imul eax,edi + shr eax,2 + mov ecx,eax + mov esi,[num_physical_mem_blocks] + imul esi,edi + add esi,physical_mem_blocks + lea edi,[esi+physical_mem_block.sizeof] + std + rep movsd + pop edi esi ecx eax + ret +Delete_Block: +;input: +; eax - handle +;output: +; none + pushad + mov edi,eax + sub eax,[num_physical_mem_blocks] + neg eax + dec eax + mov esi,physical_mem_block.sizeof + imul eax,esi + imul edi,esi + add edi,physical_mem_blocks + lea esi,[edi+physical_mem_block.sizeof] + mov ecx,eax + shr ecx,2 + cld + rep movsd + popad + ret +Allocate_Physical_Block: +;input: +; eax - size +;output: +; eax - address or 0 if not enough memory. + pushad + cmp [num_physical_mem_blocks],max_physical_mem_blocks + jge .error + mov ebx,eax + xor eax,eax + mov esi,physical_mem_blocks +.loop: + cmp dword [esi+physical_mem_block.flags],0 + jnz .next + cmp [esi+physical_mem_block.size],ebx + jg .addblock + jz .noaddblock +.next: + inc eax + add esi,physical_mem_block.sizeof + cmp eax,[num_physical_mem_blocks] + jl .loop +.error: + popad + xor eax,eax + ret +.noaddblock: + mov eax,[esi+physical_mem_block.start] + mov [esp+28],eax + mov eax,[0x3010] + mov eax,[eax+TASKDATA.pid] + mov [esi+physical_mem_block.flags],eax + popad + ret +.addblock: + call Insert_Block + inc dword [num_physical_mem_blocks] + mov eax,[esi+physical_mem_block.start] + mov [esp+28],eax + mov ecx,[0x3010] + mov ecx,[ecx+TASKDATA.pid] + mov [esi+physical_mem_block.flags],ecx + mov ecx,[esi+physical_mem_block.size] + mov [esi+physical_mem_block.size],ebx + sub ecx,ebx + mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx + add ebx,[esi+physical_mem_block.start] + mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx + mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 + popad + ret +Free_Physical_Block: +;input: +; eax - address +;output: +; none + pushad + test eax,eax + jz .ret + mov ebx,eax + xor eax,eax + mov esi,physical_mem_blocks +.loop: + cmp ebx,[esi+physical_mem_block.start] + jz .endloop + inc eax + add esi,physical_mem_block.sizeof + cmp eax,[num_physical_mem_blocks] + jl .loop + jmp .ret +.endloop: + mov dword [esi+physical_mem_block.flags],0 + test eax,eax + jz .no_union_previous + cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0 + jnz .no_union_previous + mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start] + add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size] + cmp ebx,[esi+physical_mem_block.start] + jnz .no_union_previous + mov ebx,[esi+physical_mem_block.size] + add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx + call Delete_Block + dec eax + dec [num_physical_mem_blocks] +.no_union_previous: + inc eax + cmp eax,[num_physical_mem_blocks] + jge .no_union_next + cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0 + jnz .no_union_next + mov ebx,[esi+physical_mem_block.start] + add ebx,[esi+physical_mem_block.size] + cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start] + jnz .no_union_next + mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size] + add [esi+physical_mem_block.size],ebx + call Delete_Block + dec [num_physical_mem_blocks] +.no_union_next: +.ret: + popad + ret + +sys_allocate_physical_block: +;eax - subfunction number + mov eax,ebx + call Allocate_Physical_Block + mov [esp+36],eax + ret +sys_free_physical_block: +;eax - subfunction number + mov eax,ebx + call Free_Physical_Block + ret +sys_set_buffer: + add ecx,std_application_base_address +isys_set_buffer: ;for using in kernel +;eax - subfunction number +;ebx - physical address +;ecx - buffer start +;edx - buffer size + lea edi,[ebx+second_base_address] + mov esi,ecx + mov ecx,edx + cld + rep movsb + ret +sys_get_buffer: + add ecx,std_application_base_address +isys_get_buffer: ;for using in kernel +;eax - subfunction number +;ebx - physical address +;ecx - buffer start +;edx - buffer size + mov edi,ecx + lea esi,[ebx+second_base_address] + mov ecx,edx + cld + rep movsb + ret +sys_internal_services: + cmp eax,4 + jle sys_sheduler + cmp eax,5 + jz sys_allocate_physical_block + cmp eax,6 + jz sys_free_physical_block + cmp eax,7 + jz sys_set_buffer + cmp eax,8 + jz sys_get_buffer + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/core/sched.inc b/kernel/tags/kolibri0.6.0.0/core/sched.inc new file mode 100644 index 0000000000..5effb54a4b --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/sched.inc @@ -0,0 +1,191 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; IRQ0 HANDLER (TIMER INTERRUPT) ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +align 32 +irq0: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + + inc dword [timer_ticks] + + mov eax, [timer_ticks] + call playNote ; <<<--- Speaker driver + + cmp eax,[next_usage_update] + jb .nocounter + add eax,100 + mov [next_usage_update],eax + call updatecputimes + .nocounter: + + cmp [0xffff], byte 1 + jne .change_task + + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + mov [0xffff], byte 0 + + restore_ring3_context + iret + + .change_task: + call update_counters + + call find_next_task + mov ecx, eax + + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + test ecx, ecx ; if there is only one running process + jnz .return + + call do_change_task + + .return: + restore_ring3_context + iret + + +align 4 +change_task: + + pushfd + cli + pushad + + call update_counters + call find_next_task + test eax, eax ; the same task -> skip switch + jnz .return + + mov [0xffff],byte 1 + call do_change_task + + .return: + popad + popfd + + ret + + +uglobal + align 4 + far_jump: + .offs dd ? + .sel dw ? + context_counter dd ? ;noname & halyavin + next_usage_update dd ? + timer_ticks dd ? + prev_slot dd ? + event_sched dd ? +endg + + +update_counters: + mov edi, [0x3010] + mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add + call _rdtsc + sub eax, ebx + add eax, [edi+TASKDATA.counter_sum] ; counter sum + mov [edi+TASKDATA.counter_sum], eax +ret + + +; Find next task to execute +; result: ebx = number of the selected task +; eax = 1 if the task is the same +; edi = address of the data for the task in ebx +; [0x3000] = ebx and [0x3010] = edi +; corrupts other regs +find_next_task: + mov ebx, [0x3000] + mov edi, [0x3010] + mov [prev_slot], ebx + + .waiting_for_termination: + .waiting_for_reuse: + .waiting_for_event: + .suspended: + cmp ebx, [0x3004] + jb @f + mov edi, 0x3000 + xor ebx, ebx + @@: + + add edi,0x20 + inc ebx + + mov al, byte [edi+TASKDATA.state] + test al, al + jz .found + cmp al, 1 + jz .suspended + cmp al, 2 + jz .suspended + cmp al, 3 + je .waiting_for_termination + cmp al, 4 + je .waiting_for_termination + cmp al, 9 + je .waiting_for_reuse + + mov [0x3000],ebx + mov [0x3010],edi + + cmp al, 5 + jne .noevents + call get_event_for_app + test eax, eax + jz .waiting_for_event + mov [event_sched], eax + mov [edi+TASKDATA.state], byte 0 + .noevents: + .found: + mov [0x3000],ebx + mov [0x3010],edi + call _rdtsc + mov [edi+TASKDATA.counter_add],eax + + xor eax, eax + cmp ebx, [prev_slot] + sete al +ret + +; in: ebx = TSS selector index +do_change_task: + shl ebx, 3 + xor eax, eax + add ebx, tss0 + mov [far_jump.sel], bx ; selector + mov [far_jump.offs], eax ; offset + jmp pword [far_jump] + inc [context_counter] ;noname & halyavin +ret + + + +align 4 +updatecputimes: + + mov eax,[idleuse] + mov [idleusesec],eax + mov [idleuse],dword 0 + mov ecx, [0x3004] + mov edi, 0x3020 + .newupdate: + mov ebx,[edi+TASKDATA.counter_sum] + mov [edi+TASKDATA.cpu_usage],ebx + mov [edi+TASKDATA.counter_sum],dword 0 + add edi,0x20 + dec ecx + jnz .newupdate + + ret diff --git a/kernel/tags/kolibri0.6.0.0/core/sync.inc b/kernel/tags/kolibri0.6.0.0/core/sync.inc new file mode 100644 index 0000000000..c5f04a37fb --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/sync.inc @@ -0,0 +1,111 @@ +if ~defined sync_inc +sync_inc_fix: +sync_inc fix sync_inc_fix +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;Synhronization for MenuetOS. ;; +;;Author: Halyavin Andrey, halyavin@land.ru ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;simplest mutex. +macro SimpleMutex name +{ +; iglobal + name dd 0 + name#.type = 1 +; endg +} +macro WaitSimpleMutex name +{ + local start_wait,ok +start_wait=$ + cli + cmp [name],dword 0 + jz ok + sti + call change_task + jmp start_wait +ok=$ + push eax + mov eax,dword [0x3010+second_base_address] + mov eax,[eax+TASKDATA.pid] + mov [name],eax + pop eax + sti +} +macro ReleaseSimpleMutex name +{ + mov [name],dword 0 +} +macro TryWaitSimpleMutex name ;result in eax and in flags +{ + local ok,try_end + cmp [name],dword 0 + jz ok + xor eax,eax + jmp try_end +ok=$ + xor eax,eax + inc eax +try_end=$ +} +macro SimpleCriticalSection name +{ +; iglobal + name dd 0 + dd 0 + name#.type=2 +; endg +} +macro WaitSimpleCriticalSection name +{ + local start_wait,first_wait,inc_counter,end_wait + push eax + mov eax,[0x3010+second_base_address] + mov eax,[eax+TASKDATA.pid] +start_wait=$ + cli + cmp [name],dword 0 + jz first_wait + cmp [name],eax + jz inc_counter + sti + call change_task + jmp start_wait +first_wait=$ + mov [name],eax + mov [name+4],dword 1 + jmp end_wait +inc_counter=$ + inc dword [name+4] +end_wait=$ + sti + pop eax +} +macro ReleaseSimpleCriticalSection name +{ + local release_end + dec dword [name+4] + jnz release_end + mov [name],dword 0 +release_end=$ +} +macro TryWaitSimpleCriticalSection name ;result in eax and in flags +{ + local ok,try_end + mov eax,[0x3000+second_base_address] + mov eax,[eax+TASKDATA.pid] + cmp [name],eax + jz ok + cmp [name],0 + jz ok + xor eax,eax + jmp try_end +ok=$ + xor eax,eax + inc eax +try_end=$ +} +_cli equ call MEM_HeapLock +_sti equ call MEM_HeapUnLock +end if + diff --git a/kernel/tags/kolibri0.6.0.0/core/sys32.inc b/kernel/tags/kolibri0.6.0.0/core/sys32.inc new file mode 100644 index 0000000000..55befcfc39 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/sys32.inc @@ -0,0 +1,1006 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; MenuetOS process management, protected ring3 ;; +;; ;; +;; Distributed under GPL. See file COPYING for details. ;; +;; Copyright 2003 Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 32 + +; GDT TABLE + +gdts: + + dw gdte-$-1 + dd gdts + dw 0 + +int_code_l: +os_code_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 + +int_data_l: +os_data_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 + +; --------------- APM --------------------- +apm_code_32: + dw 0x10 ; limit 64kb + db 0, 0, 0 + dw 11011111b *256 +10011010b + db 0x00 +apm_code_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10011010b + db 0x00 +apm_data_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10010010b + db 0x00 +; ----------------------------------------- + +app_code_l: + dw ((0x80000000-std_application_base_address) shr 12) and 0xffff + dw 0 + db 0 + dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) + db std_application_base_address shr 24 + +app_data_l: + dw (0x80000000-std_application_base_address) shr 12 and 0xffff + dw 0 + db 0 + dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) + db std_application_base_address shr 24 + +graph_data_l: + + dw 0x3ff + dw 0x0000 + db 0x00 + dw 11010000b *256 +11110010b + db 0x00 + +tss0_l: + times (max_processes+10) dd 0,0 + +gdte: + + + +idtreg: + dw 8*0x41-1 + dd idts+8 +label idts at 0xB100-8 + + + +uglobal + tss_sceleton: + l.back dw 0,0 + l.esp0 dd 0 + l.ss0 dw 0,0 + l.esp1 dd 0 + l.ss1 dw 0,0 + l.esp2 dd 0 + l.ss2 dw 0,0 + l.cr3 dd 0 + l.eip dd 0 + l.eflags dd 0 + l.eax dd 0 + l.ecx dd 0 + l.edx dd 0 + l.ebx dd 0 + l.esp dd 0 + l.ebp dd 0 + l.esi dd 0 + l.edi dd 0 + l.es dw 0,0 + l.cs dw 0,0 + l.ss dw 0,0 + l.ds dw 0,0 + l.fs dw 0,0 + l.gs dw 0,0 + l.ldt dw 0,0 + l.trap dw 0 + l.io dw 0 +endg + + +build_process_gdt_tss_pointer: + + mov ecx,tss_data + mov edi,0 + setgdtl2: + mov [edi+gdts+ tss0 +0], word tss_step + mov [edi+gdts+ tss0 +2], cx + mov eax,ecx + shr eax,16 + mov [edi+gdts+ tss0 +4], al + mov [edi+gdts+ tss0 +7], ah + mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b + add ecx,tss_step + add edi,8 + cmp edi,8*(max_processes+5) + jbe setgdtl2 + + ret + + +build_interrupt_table: + + mov edi, idts+8 + mov esi, sys_int + mov ecx, 0x40 + @@: + mov eax, [esi] + mov [edi], ax ; lower part of offset + mov [edi+2], word os_code ; segment selector + shr eax, 16 + mov [edi+4], word 10001110b shl 8 ; interrupt descriptor + mov [edi+6], ax + add esi, 4 + add edi, 8 + dec ecx + jnz @b + + ;mov edi,8*0x40+idts+8 + mov [edi + 0], word (i40 and ((1 shl 16)-1)) + mov [edi + 2], word os_code + mov [edi + 4], word 11101110b*256 + mov [edi + 6], word (i40 shr 16) + + ret + + + +iglobal + sys_int: + dd e0,debug_exc,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15 + dd e16,e17 + times 14 dd unknown_interrupt + + dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7 + dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15 + + times 16 dd unknown_interrupt + + dd i40 +endg + +macro save_ring3_context +{ + push ds es + pushad +} +macro restore_ring3_context +{ + popad + pop es ds +} + +; simply return control to interrupted process +unknown_interrupt: + iret + +macro exc_wo_code [num] +{ + forward + e#num : + save_ring3_context + mov bl, num + jmp exc_c +} + +macro exc_w_code [num] +{ + forward + e#num : + add esp, 4 + save_ring3_context + mov bl, num + jmp exc_c +} + +exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 16 ; 18, 19 +exc_w_code 8, 10, 11, 12, 13, 14, 17 + +exc_c: + mov ax, os_data + mov ds, ax + mov es, ax + +; test if debugging + cli + mov eax, [0x3000] + shl eax, 8 + mov eax, [0x80000+eax+APPDATA.debugger_slot] + test eax, eax + jnz .debug + sti +; not debuggee => say error and terminate + add esp, 28h + movzx eax, bl + mov [error_interrupt], eax + call show_error_parameters + + mov edx, [0x3010] + mov [edx + TASKDATA.state], byte 4 + + jmp change_task + +.debug: +; we are debugged process, notify debugger and suspend ourself +; eax=debugger PID + cld + movzx ecx, bl + push ecx + mov ecx, [0x3010] + push dword [ecx+TASKDATA.pid] ; PID of current process + push 12 + pop ecx + push 1 ; 1=exception + call debugger_notify + pop ecx + pop ecx + pop ecx + mov edx, [0x3010] + mov byte [edx+TASKDATA.state], 1 ; suspended + call change_task + restore_ring3_context + iretd + +;;;;;;;;;;;;;;;;;;;;;;; +;; FPU ERROR HANDLER ;; +;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +e7: + save_ring3_context + clts + mov ax, os_data + mov ds, ax + mov es, ax + + mov eax, [prev_user_of_fpu] + shl eax, 8 + add eax, 0x80000 + APPDATA.fpu_save_area + fsave [eax] + + mov eax, [0x3000] + mov [prev_user_of_fpu], eax + shl eax, 8 + add eax, 0x80000 + cmp [eax + APPDATA.is_fpu_saved], 0 + je @f + frstor [eax+APPDATA.fpu_save_area] + @@: + mov [eax + APPDATA.is_fpu_saved], 1 + restore_ring3_context + iret + +iglobal + prev_user_of_fpu dd 1 +endg + + +writehex: + pusha + + mov edi, [write_error_to] + mov esi, 8 + @@: + mov ecx, eax + and ecx, 0xf + + mov cl,[ecx+hexletters] + mov [edi],cl + dec edi + + shr eax,4 + dec esi + jnz @b + + popa + ret + +iglobal + hexletters db '0123456789ABCDEF' + + error_interrupt dd -1 + + process_error db 'K : Process - forced terminate INT: 00000000',13,10,0 + process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0 + process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0 + system_error db 'K : Kernel error',13,10,0 +endg + +uglobal + write_error_to dd 0x0 +endg + +show_error_parameters: + + mov [write_error_to],process_pid+43 + mov eax,[0x3000] + shl eax, 5 + mov eax,[0x3000+TASKDATA.pid+eax] + call writehex + + mov [write_error_to],process_error+43 + mov eax,[error_interrupt] + call writehex + + cmp dword [esp+4+4], os_code ; CS + jnz @f + mov esi,system_error + call sys_msg_board_str + @@: + mov eax, [esp+4] ; EIP + + mov [write_error_to],process_eip+43 + call writehex + + mov esi,process_error + call sys_msg_board_str + + mov esi,process_pid + call sys_msg_board_str + + mov esi,process_eip + call sys_msg_board_str + + ret + + + +; irq1 -> hid/keyboard.inc + + +macro irqh [num] +{ + forward + p_irq#num : + save_ring3_context + mov edi, num + jmp irq_c +} + +irqh 2,5,7,8,9,10,11,14,15 + + irq_c: + mov ax, os_data + mov ds, ax + mov es, ax + call irqhandler + restore_ring3_context + iret + +p_irq6: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call fdc_irq + call ready_for_next_irq + restore_ring3_context + iret + +p_irq3: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + cmp [com2_mouse_detected],0 + je old_irq3_handler + call check_mouse_data_com2 + jmp p_irq3_1 + old_irq3_handler: + mov edi,3 + call irqhandler + p_irq3_1: + restore_ring3_context + iret + +p_irq4: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + cmp [com1_mouse_detected],0 + je old_irq4_handler + call check_mouse_data_com1 + jmp p_irq4_1 + old_irq4_handler: + mov edi,4 + call irqhandler + p_irq4_1: + restore_ring3_context + iret + +p_irq12: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call check_mouse_data_ps2 + restore_ring3_context + iret + +ready_for_next_irq: + mov [check_idle_semaphore],5 + mov al, 0x20 + out 0x20, al + ret + +ready_for_next_irq_1: + mov [check_idle_semaphore],5 + mov al, 0x20 + out 0xa0,al + out 0x20, al + ret + +irqD: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + + mov dx,0xf0 + mov al,0 + out dx,al + + mov dx,0xa0 + mov al,0x20 + out dx,al + mov dx,0x20 + out dx,al + + restore_ring3_context + + iret + + +irqhandler: + + push edi + + mov esi,edi ; 1 + shl esi,6 ; 1 + add esi,irq00read ; 1 + shl edi,12 ; 1 + add edi,0x2E0000 + mov ecx,16 + + mov [check_idle_semaphore],5 + + irqnewread: + dec ecx + js irqover + + mov dx,[esi] ; 2+ + + cmp dx,0 ; 1 + jz irqover + cmp [esi+3],byte 1 ; 2 ; byte read + jne noirqbyte ; 4-11 + + in al,dx + + mov edx,[edi] + cmp edx,4000 + je irqfull + mov ebx,edi + add ebx,0x10 + add ebx,edx + mov [ebx],al + inc edx + mov [edi],edx + + add esi,4 + jmp irqnewread + + noirqbyte: + + + cmp [esi+3],byte 2 ; word read + jne noirqword + + in ax,dx + + mov edx,[edi] + cmp edx,4000 + je irqfull + mov ebx,edi + add ebx,0x10 + add ebx,edx + mov [ebx],ax + add edx,2 + mov [edi],edx + add esi,4 + jmp irqnewread + + noirqword: + irqfull: + irqover: + + mov al,0x20 ; ready for next irq + out 0x20,al + + pop ebx + cmp ebx,7 + jbe noa0 + out 0xa0,al + noa0: + + ret + + + +set_application_table_status: + push eax + + mov eax,[0x3000] + shl eax, 5 + add eax,0x3000+TASKDATA.pid + mov eax,[eax] + + mov [application_table_status],eax + + pop eax + + ret + + +clear_application_table_status: + push eax + + mov eax,[0x3000] + shl eax, 5 + add eax,0x3000+TASKDATA.pid + mov eax,[eax] + + cmp eax,[application_table_status] + jne apptsl1 + mov [application_table_status],0 + apptsl1: + + pop eax + + ret + + + +sys_resize_app_memory: + ; eax = 1 - resize + ; ebx = new amount of memory + + cmp eax,1 + jne .no_application_mem_resize + + jmp new_mem_resize ;resize for new type of processes + + + .no_application_mem_resize: + + ret + + + +get_app_params: + + push eax + + cmp [0x90000+6],word '00' + jne no_00_header + + mov eax,[0x90000+12] + mov [app_start],eax + mov eax,[0x90000+16] + mov [app_i_end],eax + mov eax,[0x90000+20] + mov [app_mem],eax +; \begin{diamond}[20.08.2006] +; sanity check (functions 19,58 load app_i_end bytes and that must +; fit in allocated memory to prevent kernel faults) + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] + shr eax,1 + sub eax,0x10 + mov [app_esp],eax + mov eax,[0x90000+24] + mov [app_i_param],eax + mov [app_i_icon],dword 0 + + pop eax + clc + ret + + no_00_header: + + + cmp [0x90000+6],word '01' + jne no_01_header + + mov eax,[0x90000+12] + mov [app_start],eax + mov eax,[0x90000+16] + mov [app_i_end],eax + mov eax,[0x90000+20] + mov [app_mem],eax +; \begin{diamond}[20.08.2006] + cmp eax,[app_i_end] + jb no_01_header +; \end{diamond}[20.08.2006] + mov eax,[0x90000+24] + mov [app_esp],eax + mov eax,[0x90000+28] + mov [app_i_param],eax + mov eax,[0x90000+32] + mov [app_i_icon],eax + + pop eax + clc + ret + + no_01_header: + + pop eax + stc + ret + + +uglobal + new_process_place dd 0x0 + app_start dd 0x0 + app_i_end dd 0x0 + app_mem dd 0x0 + app_esp dd 0x0 + app_i_param dd 0x0 + app_i_icon dd 0x0 + ;app_mem_pos dd 0x0 + appl_path dd 0x0 + appl_path_size dd 0x0 +endg + + +sys_threads: + +; eax=1 create thread +; +; ebx=thread start +; ecx=thread stack value +; +; on return : eax = pid +jmp new_sys_threads + +iglobal + process_terminating db 'K : Process - terminating',13,10,0 + process_terminated db 'K : Process - done',13,10,0 +endg + + +terminate: ; terminate application + push esi + mov esi,process_terminating + call sys_msg_board_str + pop esi + +@@: + cli + cmp [application_table_status],0 + je term9 + sti + call change_task + jmp @b + term9: + + call set_application_table_status + + mov eax,esi + call dispose_app_cr3_table + + cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1 + jne fpu_ok_1 + mov [prev_user_of_fpu],1 + fpu_ok_1: + + mov [0xf400],byte 0 ; empty keyboard buffer + mov [0xf500],byte 0 ; empty button buffer + + +; remove defined hotkeys + mov eax, hotkey_list +.loop: + cmp [eax+8], esi + jnz .cont + mov ecx, [eax] + jecxz @f + push dword [eax+12] + pop dword [ecx+12] +@@: + mov ecx, [eax+12] + push dword [eax] + pop dword [ecx] + xor ecx, ecx + mov [eax], ecx + mov [eax+4], ecx + mov [eax+8], ecx + mov [eax+12], ecx +.cont: + add eax, 16 + cmp eax, hotkey_list+256*16 + jb .loop +; remove hotkeys in buffer + mov eax, hotkey_buffer +.loop2: + cmp [eax], esi + jnz .cont2 + and dword [eax+4], 0 + and dword [eax], 0 +.cont2: + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb .loop2 + + mov ecx,esi ; remove buttons + bnewba2: + mov edi,[0xfe88] + mov eax,edi + cld + movzx ebx,word [edi] + inc bx + bnewba: + dec bx + jz bnmba + add eax,0x10 + cmp cx,[eax] + jnz bnewba + pusha + mov ecx,ebx + inc ecx + shl ecx,4 + mov ebx,eax + add eax,0x10 + call memmove + dec dword [edi] + popa + jmp bnewba2 + bnmba: + + pusha ; save window coordinates for window restoring + cld + shl esi,5 + add esi,window_data + mov eax,[esi+WDATA.box.left] + mov [dlx],eax + add eax,[esi+WDATA.box.width] + mov [dlxe],eax + mov eax,[esi+WDATA.box.top] + mov [dly],eax + add eax,[esi+WDATA.box.height] + mov [dlye],eax + + xor eax, eax + mov [esi+WDATA.box.left],eax + mov [esi+WDATA.box.width],eax + mov [esi+WDATA.box.top],eax + mov [esi+WDATA.box.height],eax + mov [esi+WDATA.cl_workarea],eax + mov [esi+WDATA.cl_titlebar],eax + mov [esi+WDATA.cl_frames],eax + mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn + lea edi, [esi-window_data+draw_data] + mov ecx,32/4 + rep stosd + popa + +; debuggee test + pushad + mov edi, esi + shl edi, 5 + mov eax, [0x80000+edi*8+APPDATA.debugger_slot] + test eax, eax + jz .nodebug + push 8 + pop ecx + push dword [0x3000+edi+TASKDATA.pid] ; PID + push 2 + call debugger_notify + pop ecx + pop ecx +.nodebug: + popad + + pusha ; at 0x80000+ + mov edi,esi + shl edi,8 + add edi,0x80000 + mov ecx,256/4 + xor eax, eax + rep stosd + popa + + pusha ; name to spaces + mov edi,esi + shl edi,8 + add edi,0x80000+APPDATA.app_name + mov ecx,11 + mov eax,' ' + rep stosb + popa + + + ; activate window + movzx eax, word [0xC000 + esi*2] + cmp eax, [0x3004] + jne .dont_activate + pushad + .check_next_window: + dec eax + cmp eax, 1 + jbe .nothing_to_activate + lea esi, [0xc400+eax*2] + movzx edi, word [esi] ; edi = process + shl edi, 5 + cmp [0x3000 + edi + TASKDATA.state], byte 9 ; skip dead slots + je .check_next_window + add edi, window_data + call waredraw + .nothing_to_activate: + popad + .dont_activate: + + push esi ; remove hd1 & cd & flp reservation + shl esi, 5 + mov esi, [esi+0x3000+TASKDATA.pid] + cmp [hd1_status], esi + jnz @f + mov [hd1_status], 0 +@@: + cmp [cd_status], esi + jnz @f + mov [cd_status], 0 +@@: + cmp [flp_status], esi + jnz @f + mov [flp_status], 0 +@@: + pop esi + + pusha ; remove all irq reservations + mov eax,esi + shl eax, 5 + mov eax,[eax+0x3000+TASKDATA.pid] + mov edi,irq_owner + mov ecx,16 + newirqfree: + scasd + jne nofreeirq + mov [edi-4],dword 0 + nofreeirq: + loop newirqfree + popa + + + pusha ; remove all port reservations + mov edx,esi + shl edx, 5 + add edx,0x3000 + mov edx,[edx+TASKDATA.pid] + + rmpr0: + + mov esi,[0x2d0000] + + cmp esi,0 + je rmpr9 + + rmpr3: + + mov edi,esi + shl edi,4 + add edi,0x2d0000 + + cmp edx,[edi] + je rmpr4 + + dec esi + jnz rmpr3 + + jmp rmpr9 + + rmpr4: + + mov ecx,256 + sub ecx,esi + shl ecx,4 + + mov esi,edi + add esi,16 + cld + rep movsb + + dec dword [0x2d0000] + + jmp rmpr0 + + rmpr9: + + popa + mov edi,esi ; do not run this process slot + shl edi, 5 + mov [edi+0x3000 + TASKDATA.state],byte 9 +; debugger test - terminate all debuggees + mov eax, 2 + mov ecx, 0x80000+2*0x100+APPDATA.debugger_slot +.xd0: + cmp eax, [0x3004] + ja .xd1 + cmp dword [ecx], esi + jnz @f + and dword [ecx], 0 + pushad + xchg eax, ebx + mov eax, 2 + call sys_system + popad +@@: + inc eax + add ecx, 0x100 + jmp .xd0 +.xd1: +; call systest + sti ; .. and life goes on + + mov eax, [dlx] + mov ebx, [dly] + mov ecx, [dlxe] + mov edx, [dlye] + call calculatescreen + xor eax, eax + xor esi, esi + call redrawscreen + + mov [0xfff4],byte 0 ; no mouse background + mov [0xfff5],byte 0 ; draw mouse + + mov [application_table_status],0 + mov esi,process_terminated + call sys_msg_board_str + + ret + +iglobal + boot_sched_1 db 'Building gdt tss pointer',0 + boot_sched_2 db 'Building IDT table',0 +endg + + +build_scheduler: + + mov esi,boot_sched_1 + call boot_log + call build_process_gdt_tss_pointer + + mov esi,boot_sched_2 + call boot_log + call build_interrupt_table + + ret + diff --git a/kernel/tags/kolibri0.6.0.0/core/syscall.inc b/kernel/tags/kolibri0.6.0.0/core/syscall.inc new file mode 100644 index 0000000000..13630d2279 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/core/syscall.inc @@ -0,0 +1,151 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSTEM CALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 32 +i40: + push ds es + pushad + cld + + mov ax,word os_data + mov ds,ax + mov es,ax + + ; for syscall trace function + call save_registers + + ; load all registers in crossed order + mov edi,[esp+28] ; eax + mov eax,[esp+16] ; ebx + mov ebx,[esp+24] ; ecx + mov ecx,[esp+20] ; edx + mov edx,[esp+4] ; esi + mov esi,[esp+0] ; edi + + ; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler + sti + push eax + and edi,0xff + call dword [servetable+edi*4] + pop eax + cli + + popad + pop es ds + iretd + +align 4 +save_registers: + mov esi, [0x3010] + mov eax, [esi+TASKDATA.pid] ; load PID + lea esi, [esp+4] + inc [save_syscall_count] + mov edi,[save_syscall_count] + and edi,0xF + shl edi,6 + add edi,save_syscall_data+32 + mov [edi-32],eax + mov ecx,32 / 4 + cld + rep movsd + ret + +uglobal + save_syscall_count dd 0x0 +endg + +label save_syscall_data dword at 0x5000 + + +iglobal + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; SYSTEM FUNCTIONS TABLE ;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + servetable: + + dd sys_drawwindow ; 0-DrawWindow + dd syscall_setpixel ; 1-SetPixel + dd sys_getkey ; 2-GetKey + dd sys_clock ; 3-GetTime + dd syscall_writetext ; 4-WriteText + dd delay_hs ; 5-DelayHs + dd syscall_openramdiskfile ; 6-OpenRamdiskFile + dd syscall_putimage ; 7-PutImage + dd sys_button ; 8-DefineButton + dd sys_cpuusage ; 9-GetProcessInfo + dd sys_waitforevent ; 10-WaitForEvent + dd sys_getevent ; 11-CheckForEvent + dd sys_redrawstat ; 12-BeginDraw and EndDraw + dd syscall_drawrect ; 13-DrawRect + dd syscall_getscreensize ; 14-GetScreenSize + dd sys_background ; 15-bgr + dd sys_cachetodiskette ; 16-FlushFloppyCache + dd sys_getbutton ; 17-GetButton + dd sys_system ; 18-System Services + dd undefined_syscall ; 19-reserved + dd sys_midi ; 20-ResetMidi and OutputMidi + dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. + dd sys_settime ; 22-setting date,time,clock and alarm-clock + dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent + dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist + dd sys_sb16 ; 25-SetSb16 + dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,. + dd sys_wss ; 27-SetWssMainVol and SetWssCdVol + dd sys_sb16II ; 28-SetSb16 + dd sys_date ; 29-GetDate +; dd syscall_readhd ; 30-ReadHd - obsolete + dd undefined_syscall ; 30-reserved +; dd syscall_starthdapp ; 31-StartHdApp - obsolete + dd undefined_syscall ; 31-reserved + dd syscall_delramdiskfile ; 32-DelRamdiskFile + dd syscall_writeramdiskfile; 33-WriteRamdiskFile +; dd read_floppy_file ; 34-ReadFloppyDrive - obsolete + dd undefined_syscall ; 34-reserved + dd syscall_getpixel ; 35-GetPixel + dd syscall_readstring ; 36-ReadString (not yet ready) + dd readmousepos ; 37-GetMousePosition_ScreenRelative,. + dd syscall_drawline ; 38-DrawLine + dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,. + dd set_app_param ; 40-WantEvents + dd syscall_getirqowner ; 41-GetIrqOwner + dd get_irq_data ; 42-ReadIrqData + dd sys_outport ; 43-SendDeviceData + dd sys_programirq ; 44-ProgramIrqs + dd reserve_free_irq ; 45-ReserveIrq and FreeIrq + dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea + dd display_number ; 47-WriteNum + dd display_settings ; 48-SetRedrawType and SetButtonType + dd sys_apm ; 49-Advanced Power Management (APM) + dd random_shaped_window ; 50-Window shape & scale + dd syscall_threads ; 51-Threads + dd stack_driver_stat ; 52-Stack driver status + dd socket ; 53-Socket interface + dd user_events ; 54-User events + dd sound_interface ; 55-Sound interface + dd write_to_hd ; 56-Write a file to hd +; dd delete_from_hd ; 57-Delete a file from hd - obsolete + dd undefined_syscall ; 57-reserved + dd file_system ; 58-Common file system interface + dd sys_trace ; 59-System call trace + dd new_sys_ipc ; 60-Inter Process Communication + dd sys_gs ; 61-Direct graphics access + dd sys_pci ; 62-PCI functions + dd sys_msg_board ; 63-System message board + dd sys_resize_app_memory ; 64-Resize application memory usage + dd undefined_syscall ; 65-UTF + dd sys_process_def ; 66-Process definitions - keyboard + dd sys_window_move ; 67-Window move or resize + dd sys_internal_services ; 68-Some internal services + dd sys_debug_services ; 69-Debug + dd file_system_lfn ; 70-Common file system interface, version 2 + dd syscall_windowsettings ; 71-Window settings + + times 255 - ( ($-servetable) /4 ) dd undefined_syscall + + dd sys_end ; -1-end application +endg diff --git a/kernel/tags/kolibri0.6.0.0/detect/commouse.inc b/kernel/tags/kolibri0.6.0.0/detect/commouse.inc new file mode 100644 index 0000000000..77967e06cf --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/commouse.inc @@ -0,0 +1,135 @@ +;************************************************** +;* ПОИСК МЫШИ ПО ПОСЛЕДОВАТЕЛЬНЫМ ПОРТАМ * +;* Процедура подготавливает глобальные переменные * +;* COMPortNum и COMPortBaseAddr для подпрограммы * +;* установки обработчика прерывания * +;************************************************** +; Автор исходного текста Кулаков Владимир Геннадьевич. +; Адаптация и доработка Mario79 + +Detect_COM_Mouse: + pusha + call MSMouseSearch + cmp AL,'M' + jne @f + mov [com1_mouse_detected],1 + pusha + + mov eax,4 + shl eax,2 + mov [irq_owner+eax],byte 1 + + inc dword [0x2d0000] + mov edi,[0x2d0000] + shl edi,4 + mov [0x2d0000+edi+0],dword 1 + mov [0x2d0000+edi+4],dword 0x3f0 + mov [0x2d0000+edi+8],dword 0x3ff + + popa + mov esi,boot_setmouse_type+22 + call boot_log + @@: + sub [COMPortBaseAddr],100h + call MSMouseSearch + cmp AL,'M' + jne @f + mov [com2_mouse_detected],1 + pusha + + mov eax,3 + shl eax,2 + mov [irq_owner+eax],byte 1 + + inc dword [0x2d0000] + mov edi,[0x2d0000] + shl edi,4 + mov [0x2d0000+edi+0],dword 1 + mov [0x2d0000+edi+4],dword 0x2f0 + mov [0x2d0000+edi+8],dword 0x2ff + + popa + mov esi,boot_setmouse_type+44 + call boot_log + @@: + popa + jmp end_detecting_mouse + +MSMouseSearch: + ; ПОИСК МЫШИ ЧЕРЕЗ COM-ПОРТЫ +MouseSearch: + ; Устанавливаем скорость + ; приема/передачи 1200 бод + mov DX,[COMPortBaseAddr] + add DX,3 + in AL,DX + or AL,80h ;установить бит DLAB + out DX,AL + mov DX,[COMPortBaseAddr] + mov AL,60h ;1200 бод + out DX,AL + inc DX + mov AL,0 + out DX,AL + ; Установить длину слова 7 бит, 1 стоповый бит, + ; четность не контролировать + mov DX,[COMPortBaseAddr] + add DX,3 + mov AL,00000010b + out DX,AL + ; Запретить все прерывания + mov DX,[COMPortBaseAddr] + inc DX + mov AL,0 + out DX,AL +; Проверить, что устройство подключено и является +; мышью типа MSMouse + ; Отключить питание мыши и прерывания + mov DX,[COMPortBaseAddr] + add DX,4 ;регистр управления модемом + mov AL,0 ;сбросить DTR, RTS и OUT2 + out DX,AL + ; Ожидать 5 "тиков" (0,2 с) + mov ecx,0xffff +dT_1: + dec ecx + cmp ecx,0 + jne dT_1 + mov ecx,0xffff + ; Включить питание мыши + mov AL,11b ;установить DTR и RTS + out DX,AL + ; Очистить регистр данных + mov DX,[COMPortBaseAddr] + in AL,DX +; Цикл опроса порта +WaitData: + ; Ожидать еще 10 "тиков" + dec ecx + cmp ecx,0 + je NoMouse + ; Проверить наличие идентификационного байта + mov DX,[COMPortBaseAddr] + add DX,5 + in AL,DX + test AL,1 ;Данные готовы? + jz WaitData + ; Ввести данные + mov DX,[COMPortBaseAddr] + in AL,DX +NoMouse: + ret + +iglobal +COMPortBaseAddr dw 3F8h +;COMPortNum dw 0 +endg + +iglobal +boot_setmouse_type db 'Detected - PS2 mouse',0 + db 'Detected - COM1 mouse',0 + db 'Detected - COM2 mouse',0 +endg + +end_detecting_mouse: + diff --git a/kernel/tags/kolibri0.6.0.0/detect/dev_fd.inc b/kernel/tags/kolibri0.6.0.0/detect/dev_fd.inc new file mode 100644 index 0000000000..753844d716 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/dev_fd.inc @@ -0,0 +1,20 @@ +;*************************************************** +; предварительная очистка области таблицы +; поиск и занесение в таблицу приводов FDD +; автор Mario79 +;*************************************************** + xor eax,eax + mov edi,0x40000 + mov ecx,16384 + cld + rep stosd + + mov al,0x10 + out 0x70,al + mov cx,0xff +wait_cmos: + dec cx + cmp cx,0 + jne wait_cmos + in al,0x71 + mov [0x40000],al diff --git a/kernel/tags/kolibri0.6.0.0/detect/dev_hdcd.inc b/kernel/tags/kolibri0.6.0.0/detect/dev_hdcd.inc new file mode 100644 index 0000000000..dd1d4646b2 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/dev_hdcd.inc @@ -0,0 +1,357 @@ +;****************************************************** +; поиск приводов HDD и CD +; автор исходного текста Кулаков Владимир Геннадьевич. +; адаптация и доработка Mario79 +;****************************************************** + +;**************************************************** +;* ПОИСК HDD и CD * +;**************************************************** +FindHDD: + mov [ChannelNumber],1 + mov [DiskNumber],0 + call FindHDD_3 + mov [DiskNumber],1 + call FindHDD_3 + inc [ChannelNumber] + mov [DiskNumber],0 + call FindHDD_3 + mov [DiskNumber],1 + call FindHDD_1 + jmp EndFindHDD + +FindHDD_1: + call DeviceReset + cmp [DevErrorCode],0 + jne FindHDD_2_2 + call ReadHDD_ID + cmp [DevErrorCode],0 + jne FindHDD_2 + inc byte [0x40001] + ret + FindHDD_2: + call ReadCD_ID + cmp [DevErrorCode],0 + jne FindHDD_2_2 + inc byte [0x40001] + inc byte [0x40001] + FindHDD_2_2: + ret + +FindHDD_3: + call FindHDD_1 + shl byte [0x40001],2 + ret + + +; Адрес считываемого сектора в режиме LBA +SectorAddress DD ? + +;************************************************* +;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* ChannelNumber - номер канала (1 или 2); * +;* DiskNumber - номер диска на канале (0 или 1). * +;* Идентификационный блок данных считывается * +;* в массив Sector512. * +;************************************************* +ReadHDD_ID: +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать команду идентификации устройства + mov [ATAFeatures],0 + mov [ATAHead],0 + mov [ATACommand],0ECh + call SendCommandToHDD + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End ;закончить, сохранив код ошибки + mov DX,[ATABasePortAddr] + add DX,7 ;адрес регистра состояния + mov ecx,0xffff +@@WaitCompleet: + ; Проверить время выполнения команды + dec ecx + cmp ecx,0 + je @@Error1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitCompleet + test AL,1 ;состояние сигнала ERR + jnz @@Error6 + 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 ;принять блок данных + jmp @@End +; Записать код ошибки +@@Error1: + mov [DevErrorCode],1 + jmp @@End +@@Error6: + mov [DevErrorCode],6 +@@End: ret + + + +; Стандартные базовые адреса каналов 1 и 2 +StandardATABases DW 1F0h, 170h +; Номер канала +ChannelNumber DW ? +; Номер диска +DiskNumber DB ? +; Базовый адрес группы портов контроллера 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 - ошибка при выполнении +; команды) +DevErrorCode DB ? + +;**************************************************** +;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* 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 к приему команды + ; Выбрать нужный диск + mov DX,[ATABasePortAddr] + add DX,6 ;адрес регистра головок + mov AL,[DiskNumber] + 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 + je @@Err1 +; mov eax,[timer_ticks] +; sub eax,[TickCounter_1] +; cmp eax,300 ;ожидать 300 тиков +; ja @@Err1 ;ошибка тайм-аута + ; Прочитать регистр состояния + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady + ; Проверить состояние сигнала DRQ + test AL,08h + jnz @@WaitHDReady +; Загрузить команду в регистры контроллера + cli + mov DX,[ATABasePortAddr] + inc DX ;регистр "особенностей" + mov AL,[ATAFeatures] + out DX,AL + inc DX ;счетчик секторов + mov AL,[ATASectorCount] + out DX,AL + inc DX ;регистр номера сектора + mov AL,[ATASectorNumber] + out DX,AL + inc DX ;номер цилиндра (младший байт) + mov AX,[ATACylinder] + out DX,AL + inc DX ;номер цилиндра (старший байт) + mov AL,AH + out DX,AL + inc DX ;номер головки/номер диска + mov AL,[DiskNumber] + shl AL,4 + cmp [ATAHead],0Fh ;проверить номер головки + ja @@Err5 + or AL,[ATAHead] + or AL,10100000b + mov AH,[ATAAddressMode] + shl AH,6 + or AL,AH + out DX,AL +; Послать команду + mov AL,[ATACommand] + inc DX ;регистр команд + out DX,AL + sti +; Сбросить признак ошибки + mov [DevErrorCode],0 + jmp @@End_2 +; Записать код ошибки +@@Err1: mov [DevErrorCode],1 + jmp @@End_2 +@@Err2: mov [DevErrorCode],2 + jmp @@End_2 +@@Err3: mov [DevErrorCode],3 + jmp @@End_2 +@@Err4: mov [DevErrorCode],4 + jmp @@End_2 +@@Err5: mov [DevErrorCode],5 +; Завершение работы программы +@@End_2: + ret + +;************************************************* +;* ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI * +;* Входные параметры передаются через глобальные * +;* перменные: * +;* ChannelNumber - номер канала; * +;* DiskNumber - номер диска на канале. * +;* Идентификационный блок данных считывается * +;* в массив Sector512. * +;************************************************* +ReadCD_ID: +; Задать режим CHS + mov [ATAAddressMode],0 +; Послать команду идентификации устройства + mov [ATAFeatures],0 + mov [ATASectorCount],0 + mov [ATASectorNumber],0 + mov [ATACylinder],0 + mov [ATAHead],0 + mov [ATACommand],0A1h + call SendCommandToHDD + cmp [DevErrorCode],0 ;проверить код ошибки + jne @@End_1 ;закончить, сохранив код ошибки +; Ожидать готовность данных HDD + mov DX,[ATABasePortAddr] + add DX,7 ;порт 1х7h + mov ecx,0xffff +@@WaitCompleet_1: + ; Проверить время + dec ecx + cmp ecx,0 + je @@Error1_1 ;ошибка тайм-аута + ; Проверить готовность + in AL,DX + test AL,80h ;состояние сигнала BSY + jnz @@WaitCompleet_1 + test AL,1 ;состояние сигнала ERR + jnz @@Error6_1 + 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 ;число считываемых слов + rep insw + jmp @@End_1 +; Записать код ошибки +@@Error1_1: + mov [DevErrorCode],1 + jmp @@End_1 +@@Error6_1: + mov [DevErrorCode],6 +@@End_1: + ret + +;************************************************* +;* СБРОС УСТРОЙСТВА * +;* Входные параметры передаются через глобальные * +;* переменные: * +;* 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 ;адрес регистра головок + mov AL,[DiskNumber] + cmp AL,1 ;проверить номера диска + ja @@Err4_2 + shl AL,4 + or AL,10100000b + out DX,AL +; Послать команду "Сброс" + mov AL,08h + inc DX ;регистр команд + out DX,AL + mov ecx,0x80000 +@@WaitHDReady_1: + ; Проверить время ожидания + dec ecx + cmp ecx,0 + je @@Err1_2 ;ошибка тайм-аута + ; Прочитать регистр состояния + in AL,DX + ; Проверить состояние сигнала BSY + test AL,80h + jnz @@WaitHDReady_1 +; Сбросить признак ошибки + mov [DevErrorCode],0 + jmp @@End_3 +; Обработка ошибок +@@Err1_2: mov [DevErrorCode],1 + jmp @@End_3 +@@Err3_2: mov [DevErrorCode],3 + jmp @@End_3 +@@Err4_2: mov [DevErrorCode],4 +; Записать код ошибки +@@End_3: + ret + +EndFindHDD: + diff --git a/kernel/tags/kolibri0.6.0.0/detect/disks.inc b/kernel/tags/kolibri0.6.0.0/detect/disks.inc new file mode 100644 index 0000000000..31b02f25cc --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/disks.inc @@ -0,0 +1,4 @@ +include 'dev_fd.inc' +include 'dev_hdcd.inc' +include 'sear_par.inc' + diff --git a/kernel/tags/kolibri0.6.0.0/detect/ps2mouse.inc b/kernel/tags/kolibri0.6.0.0/detect/ps2mouse.inc new file mode 100644 index 0000000000..0dd0b2e845 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/ps2mouse.inc @@ -0,0 +1,131 @@ +MouseSearch_PS2: + jmp MouseSearch_PS2_begin + +mouse_error equ MouseSearch_PS2_begin.error + + kb_cmd_c: + call kb_cmd + jmp check_kbd + + kb_write_c: + call kb_write + jmp check_kbd + + kb_read_c: + call kb_read + ;jmp check_kbd + + check_kbd: + cmp ah, 1 + je mouse_error + ret + +uglobal + mouse_cmd_byte db 0 + mouse_nr_tries db 0 + mouse_nr_resends db 0 + + mouse_error_esp dd 0 +endg + + + mouse_cmd: + mov [mouse_cmd_byte], al + mov [mouse_nr_resends], 5 + .resend: + mov bl, 0xd4 + call kb_cmd_c + mov al, [mouse_cmd_byte] + call kb_write_c + + call mouse_read + + cmp al, 0xFA ; ack + jne .noack + ret + .noack: + cmp al, 0xFE ; resend + jne .noresend + dec [mouse_nr_resends] + jnz .resend + .noresend: + jmp mouse_error + + + mouse_read: + mov [mouse_nr_tries], 100 + .repeat: + call kb_read + cmp ah, 1 + jne .fin + mov esi, 10 + call delay_ms + dec [mouse_nr_tries] + jnz .repeat + jmp mouse_error + .fin: + ret + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +MouseSearch_PS2_begin: + pushad + + mov [mouse_error_esp], esp + + mov bl, 0xAD ; disable keyboard interface + call kb_cmd_c + + mov bl, 0xA8 ; enable mouse interface + call kb_cmd_c + + mov al, 0xFF ; reset + call mouse_cmd + + ; now the mouse is in Reset Mode + ; get the Basic Assurance Test completion code + call mouse_read + cmp al, 0xAA + jne .error ; dead mouse + + ; get device ID + call mouse_read + cmp al, 0x00 + jne .error ; unknown device + + ; reset completed successfully + + ; enable mouse interrupt - IRQ12 + mov bl, 0x20 ; read command byte + call kb_cmd_c + call kb_read_c + or al, 10b + push eax + mov bl, 0x60 ; write command byte + call kb_cmd_c + pop eax + call kb_write_c + + mov al, 0xF4 ; enable data reporting + call mouse_cmd + + mov [ps2_mouse_detected], 1 + mov bl, 0xAE ; enable keyboard interface + call kb_cmd + + mov esi, boot_setmouse_type + call boot_log + + jmp .finish + + +.error: + mov esp, [mouse_error_esp] ; clear stack frame + mov [ps2_mouse_detected], 0 + mov bl, 0xA7 ; disable mouse interface + call kb_cmd + mov bl, 0xAE ; enable keyboard interface + call kb_cmd + +.finish: + popad diff --git a/kernel/tags/kolibri0.6.0.0/detect/sear_par.inc b/kernel/tags/kolibri0.6.0.0/detect/sear_par.inc new file mode 100644 index 0000000000..463ac48e50 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/detect/sear_par.inc @@ -0,0 +1,118 @@ +;**************************************************** +; поиск логических дисков на обнаруженных HDD +; и занесение данных в область таблицы +; автор Mario79 +;**************************************************** + mov [transfer_adress],0x4000a + search_partitions_ide0: + test [0x40001],byte 0x40 + jz search_partitions_ide1 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + mov [fat32part],1 + search_partitions_ide0_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide1 + inc byte [0x40002] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide0_1 + + search_partitions_ide1: + test [0x40001],byte 0x10 + jz search_partitions_ide2 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + mov [fat32part],1 + search_partitions_ide1_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide2 + inc byte [0x40003] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide1_1 + + search_partitions_ide2: + test [0x40001],byte 0x4 + jz search_partitions_ide3 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + mov [fat32part],1 + search_partitions_ide2_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne search_partitions_ide3 + inc byte [0x40004] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide2_1 + + search_partitions_ide3: + test [0x40001],byte 0x1 + jz end_search_partitions_ide + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 + mov [fat32part],1 + search_partitions_ide3_1: + call set_FAT32_variables + cmp [problem_partition],0 + jne end_search_partitions_ide + inc byte [0x40005] + call partition_data_transfer + add [transfer_adress],100 + inc [fat32part] + jmp search_partitions_ide3_1 + + +partition_data_transfer: + mov edi,[transfer_adress] + mov esi,PARTITION_START + xor ecx,ecx + mov cx,69 ;100 + rep movsb + ret +transfer_adress dd 0 +partition_data_transfer_1: + cli + push edi + mov edi,PARTITION_START + mov esi,[transfer_adress] + xor ecx,ecx + mov cx,69 ;100 + rep movsb + pop edi + sti + ret + + end_search_partitions_ide: + +;PARTITION_START dd 0x3f +;PARTITION_END dd 0 +;SECTORS_PER_FAT dd 0x1f3a +;NUMBER_OF_FATS dd 0x2 +;SECTORS_PER_CLUSTER dd 0x8 +;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes +;ROOT_CLUSTER dd 2 ; first rootdir cluster +;FAT_START dd 0 ; start of fat table +;ROOT_START dd 0 ; start of rootdir (only fat16) +;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) +;DATA_START dd 0 ; start of data area (=first cluster 2) +;LAST_CLUSTER dd 0 ; last availabe cluster +;ADR_FSINFO dd 0 ; used only by fat32 +; +;fatRESERVED dd 0x0FFFFFF6 +;fatBAD dd 0x0FFFFFF7 +;fatEND dd 0x0FFFFFF8 +;fatMASK dd 0x0FFFFFFF +; +;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 + diff --git a/kernel/tags/kolibri0.6.0.0/docs/apm/README.TXT b/kernel/tags/kolibri0.6.0.0/docs/apm/README.TXT new file mode 100644 index 0000000000..6351265609 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/docs/apm/README.TXT @@ -0,0 +1,255 @@ +Advanced Power Management + +SYSTEM CALL + +eax = 70 +dx = номер функции APM BIOS (аналогичен ax в реальном режиме) +остальные (bx, cx) регистры по спецификации (см. apm.txt) +результат : по спецификации (включая CF), старшая часть 32 битных регистров не определена + + +MEMORY MAP + +Boot: + 0x9040 - dword - entry point of APM BIOS + 0x9044 - word - version (BCD) + 0x9046 - word - flags + + +ИЗМЕНЕНИЯ + +sys32.inc +syscall.inc +kernel.asm +bootcode.inc + +##############[core\sys32.inc]##################### + +Три новых дескриптора + +............. +............. + +; GDT TABLE + +gdts: + + dw gdte-$-1 + dd gdts + dw 0 + +int_code_l: +os_code_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10011010b + db 0x00 + +int_data_l: +os_data_l: + + dw 0xffff + dw 0x0000 + db 0x00 + dw 11011111b *256 +10010010b + db 0x00 +; --------------- APM --------------------- +apm_code_32: + dw 0x10 ; limit 64kb + db 0, 0, 0 + dw 11011111b *256 +10011010b + db 0x00 +apm_code_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10011010b + db 0x00 +apm_data_16: + dw 0x10 + db 0, 0, 0 + dw 10011111b *256 +10010010b + db 0x00 +; ----------------------------------------- +app_code_l: + dw ((0x80000000-std_application_base_address) shr 12) and 0xffff + dw 0 + db 0 + dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) + db std_application_base_address shr 24 + +app_data_l: + dw (0x80000000-std_application_base_address) shr 12 and 0xffff + dw 0 + db 0 + dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) + db std_application_base_address shr 24 + +graph_data_l: + + dw 0x3ff + dw 0x0000 + db 0x00 + dw 11010000b *256 +11110010b + db 0x00 + +tss0_l: + times (max_processes+10) dd 0,0 + +............. +............. + +##############[core\syscall.inc]################### + +............. +............. + + + dd undefined_syscall ; 65-UTF + dd sys_process_def ; 66-Process definitions - keyboard + dd sys_window_move ; 67-Window move or resize + dd sys_internal_services ; 68-Some internal services + dd sys_debug_services ; 69-Debug + dd sys_apm ; 70-APM + + +............. +............. + +##############[kernel.asm]######################### + + +Часть 1 (после метки "; SAVE REAL MODE VARIABLES"): + +............. +............. + +; SAVE REAL MODE VARIABLES + +; --------------- APM --------------------- + mov eax, [0x2f0000 + 0x9040] ; entry point + mov dword[apm_entry], eax + mov word [apm_entry + 4], apm_code_32 - gdts + + mov eax, [0x2f0000 + 0x9044] ; version & flags + mov [apm_vf], eax +; ----------------------------------------- + +............. +............. + +Часть 2 (системный вызов, расположение не критично, +я расположил перед меткой "undefined_syscall:") + +............. +............. + +; --------------- APM --------------------- +apm_entry dp 0 +apm_vf dd 0 +align 4 +sys_apm: + cmp word [apm_vf], 0 ; Check APM BIOS enable + jne @f + or [esp + 40], byte 1 ; error + mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported + ret + +@@: xchg eax, ecx + xchg ebx, ecx + + cmp al, 3 + ja @f + and [esp + 40], byte 0xfe ; emulate func 0..3 as func 0 + mov eax, [apm_vf] + mov [esp + 36], eax + shr eax, 16 + mov [esp + 32], eax + ret + +@@: call pword [apm_entry] ; call APM BIOS + mov [esp + 8 ], edi + mov [esp + 12], esi + mov [esp + 24], ebx + mov [esp + 28], edx + mov [esp + 32], ecx + mov [esp + 36], eax + setc al + and [esp + 40], byte 0xfe + or [esp + 40], al + ret +; ----------------------------------------- + +align 4 + +undefined_syscall: ; Undefined system call + +............. +............. + +##############[boot\bootcode.inc]################## + +Перед меткой "; DISPLAY VESA INFORMATION" + +............. +............. + +; --------------- APM --------------------- + push 0 + pop es + mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found) + mov ax, 0x5300 + xor bx, bx + int 0x15 + jc apm_end ; APM not found + test cx, 2 + jz apm_end ; APM 32-bit protected-mode interface not supported + mov [es : 0x9044], ax ; Save APM Version + mov [es : 0x9046], cx ; Save APM flags + + ; Write APM ver ---- + jmp @f +msg_apm:db ' APM x.x ', 0 +@@: and ax, 0xf0f + add ax, '00' + mov [msg_apm - 0x10000 + 5], ah + mov [msg_apm - 0x10000 + 7], al + _setcursor 0, 3 + mov si, msg_apm - 0x10000 + call printplain + _setcursor d80x25_top_num,0 + ; ------------------ + + mov ax, 0x5304 ; Disconnect interface + xor bx, bx + int 0x15 + mov ax, 0x5303 ; Connect 32 bit mode interface + xor bx, bx + int 0x15 + ; init selectors + movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment + shl eax, 4 + mov [apm_code_32 - 0x10000 + 2], ax + shr eax, 16 + mov [apm_code_32 - 0x10000 + 4], al + movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment + shl ecx, 4 + mov [apm_code_16 - 0x10000 + 2], cx + shr ecx, 16 + mov [apm_code_16 - 0x10000 + 4], cl + movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment + shl edx, 4 + mov [apm_data_16 - 0x10000 + 2], dx + shr edx, 16 + mov [apm_data_16 - 0x10000 + 4], dl + mov [es : 0x9040], ebx ; offset of APM entry point +apm_end: +; ----------------------------------------- + + +; DISPLAY VESA INFORMATION + +............. +............. + diff --git a/kernel/tags/kolibri0.6.0.0/docs/apm/apm.txt b/kernel/tags/kolibri0.6.0.0/docs/apm/apm.txt new file mode 100644 index 0000000000..5b253195ed --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/docs/apm/apm.txt @@ -0,0 +1,518 @@ +--------p-155300----------------------------- +INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK + AX = 5300h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AH = major version (BCD) + AL = minor version (BCD) + BX = 504Dh ("PM") + CX = flags (see #00472) + CF set on error + AH = error code (06h,09h,86h) (see #00473) +BUG: early versions of the Award Modular BIOS with built-in APM support + reportedly do not set BX on return + +Bitfields for APM flags: +Bit(s) Description (Table 00472) + 0 16-bit protected mode interface supported + 1 32-bit protected mode interface supported + 2 CPU idle call reduces processor speed + 3 BIOS power management disabled + 4 BIOS power management disengaged (APM v1.1) + 5-7 reserved + +(Table 00473) +Values for APM error code: + 01h power management functionality disabled + 02h interface connection already in effect + 03h interface not connected + 04h real-mode interface not connected + 05h 16-bit protected-mode interface already connected + 06h 16-bit protected-mode interface not supported + 07h 32-bit protected-mode interface already connected + 08h 32-bit protected-mode interface not supported + 09h unrecognized device ID + 0Ah invalid parameter value in CX + 0Bh (APM v1.1) interface not engaged + 0Ch (APM v1.2) function not supported + 0Dh (APM v1.2) Resume Timer disabled + 0Eh-1Fh reserved for other interface and general errors + 20h-3Fh reserved for CPU errors + 40h-5Fh reserved for device errors + 60h can't enter requested state + 61h-7Fh reserved for other system errors + 80h no power management events pending + 81h-85h reserved for other power management event errors + 86h APM not present + 87h-9Fh reserved for other power management event errors + A0h-FEh reserved + FFh undefined +--------p-155301----------------------------- +INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE + AX = 5301h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + CF set on error + AH = error code (02h,05h,07h,09h) (see #00473) +Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5302h,AX=5303h,AX=5304h +--------p-155302----------------------------- +INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE + AX = 5302h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AX = real-mode segment base address of protected-mode 16-bit code + segment + BX = offset of entry point + CX = real-mode segment base address of protected-mode 16-bit data + segment + ---APM v1.1--- + SI = APM BIOS code segment length + DI = APM BIOS data segment length + CF set on error + AH = error code (02h,05h,06h,07h,09h) (see #00473) +Notes: the caller must initialize two consecutive descriptors with the + returned segment base addresses; these descriptors must be valid + whenever the protected-mode interface is called, and will have + their limits arbitrarily set to 64K. + the protected mode interface is invoked by making a far call with the + same register values as for INT 15; it must be invoked while CPL=0, + the code segment descriptor must have a DPL of 0, the stack must be + in a 16-bit segment and have enough room for BIOS use and possible + interrupts, and the current I/O permission bit map must allow access + to the I/O ports used for power management. + functions 00h-03h are not available from protected mode + on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5301h,AX=5303h,AX=5304h +--------p-155303----------------------------- +INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE + AX = 5303h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + AX = real-mode segment base address of protected-mode 32-bit code + segment + EBX = offset of entry point + CX = real-mode segment base address of protected-mode 16-bit code + segment + DX = real-mode segment base address of protected-mode 16-bit data + segment + ---APM v1.1--- + SI = APM BIOS code segment length + DI = APM BIOS data segment length + CF set on error + AH = error code (02h,05h,07h,08h,09h) (see #00473) +Notes: the caller must initialize three consecutive descriptors with the + returned segment base addresses for 32-bit code, 16-bit code, and + 16-bit data, respectively; these descriptors must be valid whenever + the protected-mode interface is called, and will have their limits + arbitrarily set to 64K. + the protected mode interface is invoked by making a far call to the + 32-bit code segment with the same register values as for INT 15; it + must be invoked while CPL=0, the code segment descriptor must have a + DPL of 0, the stack must be in a 32-bit segment and have enough room + for BIOS use and possible interrupts, and the current I/O permission + bit map must allow access to the I/O ports used for power management. + functions 00h-03h are not available from protected mode + on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 + compatibility mode until it is informed that the user supports a + newer version of APM (see AX=530Eh) +SeeAlso: AX=5301h,AX=5302h,AX=5304h +--------p-155304----------------------------- +INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE + AX = 5304h + BX = device ID of system BIOS (0000h) +Return: CF clear if successful + CF set on error + AH = error code (03h,09h) (see #00473) +SeeAlso: AX=5301h,AX=5302h,AX=5303h +--------p-155305----------------------------- +INT 15 - Advanced Power Management v1.0+ - CPU IDLE + AX = 5305h +Return: CF clear if successful (after system leaves idle state) + CF set on error + AH = error code (03h,0Bh) (see #00473) +Notes: call when the system is idle and should be suspended until the next + system event or interrupt + should not be called from within a hardware interrupt handler to avoid + reentrance problems + if an interrupt causes the system to resume normal processing, the + interrupt may or may not have been handled when the BIOS returns + from this call; thus, the caller should allow interrupts on return + interrupt handlers may not retain control if the BIOS allows + interrupts while in idle mode even if they are able to determine + that they were called from idle mode + the caller should issue this call continuously in a loop until it needs + to perform some processing of its own +SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h +--------p-155306----------------------------- +INT 15 - Advanced Power Management v1.0+ - CPU BUSY + AX = 5306h +Return: CF clear if successful + CF set on error + AH = error code (03h,0Bh) (see #00473) +Notes: called to ensure that the system runs at full speed even on systems + where the BIOS is unable to recognize increased activity (especially + if interrupts are hooked by other programs and not chained to the + BIOS) + this call may be made even when the system is already running at full + speed, but it will create unnecessary overhead + should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5305h +--------p-155307----------------------------- +INT 15 - Advanced Power Management v1.0+ - SET POWER STATE + AX = 5307h + BX = device ID (see #00474) + CX = system state ID (see #00475) +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) +Note: should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=530Ch + +(Table 00474) +Values for APM device IDs: + 0000h system BIOS + 0001h all devices for which the system BIOS manages power + 01xxh display (01FFh for all attached display devices) + 02xxh secondary storage (02FFh for all attached secondary storage devices) + 03xxh parallel ports (03FFh for all attached parallel ports) + 04xxh serial ports (04FFh for all attached serial ports) +---APM v1.1+ --- + 05xxh network adapters (05FFh for all attached network adapters) + 06xxh PCMCIA sockets (06FFh for all) + 0700h-7FFFh reserved + 80xxh system battery devices (APM v1.2) + 8100h-DFFFh reserved + Exxxh OEM-defined power device IDs + F000h-FFFFh reserved + +(Table 00475) +Values for system state ID: + 0000h ready (not supported for device ID 0001h) + 0001h stand-by + 0002h suspend + 0003h off (not supported for device ID 0001h in APM v1.0) +---APM v1.1--- + 0004h last request processing notification (only for device ID 0001h) + 0005h last request rejected (only for device ID 0001h) + 0006h-001Fh reserved system states + 0020h-003Fh OEM-defined system states + 0040h-007Fh OEM-defined device states + 0080h-FFFFh reserved device states +--------p-155307CX0001----------------------- +INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY + AX = 5307h + CX = 0001h + BX = 0001h (device ID for all power-managed devices) +Return: CF clear +Notes: puts the entire system into stand-by mode; normally called in response + to a System Stand-by Request notification after any necessary + processing, but may also be invoked at the caller's discretion + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the stand-by state is typically exited on an interrupt +SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh +--------p-155307CX0002----------------------- +INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM + AX = 5307h + CX = 0002h + BX = 0001h (device ID for all power-managed devices) +Return: after system is resumed + CF clear +Notes: puts the entire system into a low-power suspended state; normally + called in response to a Suspend System Request notification after + any necessary processing, but may also be invoked at the caller's + discretion + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the caller may need to update its date and time values because the + system could have been suspended for a long period of time +SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh +--------p-155307CX0003----------------------- +INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM + AX = 5307h + CX = 0003h + BX = 0001h (device ID for all power-managed devices) +Return: after system is resumed + CF clear +Notes: if supported by the system's power supply, turns off the system power +SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh +--------p-155308----------------------------- +INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT + AX = 5308h + BX = device ID for all devices power-managed by APM + 0001h (APM v1.1+) + FFFFh (APM v1.0) + CX = new state + 0000h disabled + 0001h enabled +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) +Notes: when power management is disabled, the system BIOS will not + automatically power down devices, enter stand-by or suspended mode, + or perform any power-saving actions in response to AX=5305h calls + should not be called from within a hardware interrupt handler to avoid + reentrance problems + the APM BIOS should never be both disabled and disengaged at the same + time +SeeAlso: AX=5309h,AX=530Dh,AX=530Fh +--------p-155309----------------------------- +INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS + AX = 5309h + BX = device ID for all devices power-managed by APM + 0001h (APM v1.1) + FFFFh (APM v1.0) +Return: CF clear if successful + CF set on error + AH = error code (03h,09h,0Bh) (see #00473) +Note: should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5308h +--------p-15530A----------------------------- +INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS + AX = 530Ah + BX = device ID + 0001h all devices power-managed by APM + 80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) +Return: CF clear if successful + BH = AC line status + 00h off-line + 01h on-line + 02h on backup power (APM v1.1) + FFh unknown + other reserved + BL = battery status (see #00476) + CH = battery flag (APM v1.1+) (see #00477) + CL = remaining battery life, percentage + 00h-64h (0-100) percentage of full charge + FFh unknown + DX = remaining battery life, time (APM v1.1) (see #00478) + ---if specific battery unit specified--- + SI = number of battery units currently installed + CF set on error + AH = error code (09h,0Ah) (see #00473) +Notes: should not be called from within a hardware interrupt handler to avoid + reentrance problems + supported in real mode (INT 15) and both 16-bit and 32-bit protected + mode + +(Table 00476) +Values for APM v1.0+ battery status: + 00h high + 01h low + 02h critical + 03h charging + FFh unknown + other reserved +SeeAlso: #00477,#00478 + +Bitfields for APM v1.1+ battery flag: +Bit(s) Description (Table 00477) + 0 high + 1 low + 2 critical + 3 charging + 4 selected battery not present (APM v1.2) + 5-6 reserved (0) + 7 no system battery +Note: all bits set (FFh) if unknown +SeeAlso: #00476,#00478 + +Bitfields for APM v1.1+ remaining battery life: +Bit(s) Description (Table 00478) + 15 time units: 0=seconds, 1=minutes + 14-0 battery life in minutes or seconds +Note: all bits set (FFFFh) if unknown +SeeAlso: #00476,#00477 +--------p-15530B----------------------------- +INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT + AX = 530Bh +Return: CF clear if successful + BX = event code (see #00479) + CX = event information (APM v1.2) if BX=0003h or BX=0004h + bit 0: PCMCIA socket was powered down in suspend state + CF set on error + AH = error code (03h,0Bh,80h) (see #00473) +Notes: although power management events are often asynchronous, notification + will not be made until polled via this call to permit software to + only receive event notification when it is prepared to process + power management events; since these events are not very time- + critical, it should be sufficient to poll once or twice per second + the critical resume notification is made after the system resumes + from an emergency suspension; normally, the system BIOS only notifies + its partner that it wishes to suspend and relies on the partner to + actually request the suspension, but no notification is made on an + emergency suspension + should not be called from within a hardware interrupt handler to avoid + reentrance problems +SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" + +(Table 00479) +Values for APM event code: + 0001h system stand-by request + 0002h system suspend request + 0003h normal resume system notification + 0004h critical resume system notification + 0005h battery low notification +---APM v1.1--- + 0006h power status change notification + 0007h update time notification + 0008h critical system suspend notification + 0009h user system standby request notification + 000Ah user system suspend request notification + 000Bh system standby resume notification +---APM v1.2--- + 000Ch capabilities change notification (see AX=5310h) +------ + 000Dh-00FFh reserved system events + 01xxh reserved device events + 02xxh OEM-defined APM events + 0300h-FFFFh reserved +--------p-15530C----------------------------- +INT 15 - Advanced Power Management v1.1+ - GET POWER STATE + AX = 530Ch + BX = device ID (see #00474) +Return: CF clear if successful + CX = system state ID (see #00475) + CF set on error + AH = error code (01h,09h) (see #00473) +SeeAlso: AX=5307h +--------p-15530D----------------------------- +INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT + AX = 530Dh + BX = device ID (see #00474) + CX = function + 0000h disable power management + 0001h enable power management +Return: CF clear if successful + CF set on error + AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) +Desc: specify whether automatic power management should be active for a + given device +SeeAlso: AX=5308h,AX=530Fh +--------p-15530E----------------------------- +INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION + AX = 530Eh + BX = device ID of system BIOS (0000h) + CH = APM driver major version (BCD) + CL = APM driver minor version (BCD) (02h for APM v1.2) +Return: CF clear if successful + AH = APM connection major version (BCD) + AL = APM connection minor version (BCD) + CF set on error + AH = error code (03h,09h,0Bh) (see #00473) +SeeAlso: AX=5300h,AX=5303h +--------p-15530F----------------------------- +INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT + AX = 530Fh + BX = device ID (see #00474) + CX = function + 0000h disengage power management + 0001h engage power management +Return: CF clear if successful + CF set on error + AH = error code (01h,09h) (see #00473) +Notes: unlike AX=5308h, this call does not affect the functioning of the APM + BIOS + when cooperative power management is disengaged, the APM BIOS performs + automatic power management of the system or device +SeeAlso: AX=5308h,AX=530Dh +--------p-155310----------------------------- +INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES + AX = 5310h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved +Return: CF clear if successful + BL = number of battery units supported (00h if no system batteries) + CX = capabilities flags (see #00480) + CF set on error + AH = error code (01h,09h,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces; it does not require that a + connection be established prior to use + this function will return the capabilities currently in effect, not + any new settings which have been made but do not take effect until + a system restart +SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h + +Bitfields for APM v1.2 capabilities flags: +Bit(s) Description (Table 00480) + 15-8 reserved + 7 PCMCIA Ring Indicator will wake up system from suspend mode + 6 PCMCIA Ring Indicator will wake up system from standby mode + 5 Resume on Ring Indicator will wake up system from suspend mode + 4 Resume on Ring Indicator will wake up system from standby mode + 3 resume timer will wake up system from suspend mode + 2 resume timer will wake up system from standby mode + 1 can enter global suspend state + 0 can enter global standby state +--------p-155311----------------------------- +INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER + AX = 5311h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable Resume Timer + 01h get Resume Timer + 02h set Resume Timer + CH = resume time, seconds (BCD) + DL = resume time, minutes (BCD) + DH = resume time, hours (BCD) + SI = resume date (BCD), high byte = month, low byte = day + DI = resume date, year (BCD) +Return: CF clear if successful + ---if getting timer--- + CH = resume time, seconds (BCD) + DL = resume time, minutes (BCD) + DH = resume time, hours (BCD) + SI = resume date (BCD), high byte = month, low byte = day + DI = resume date, year (BCD) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces +SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h +--------p-155312----------------------------- +INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING + AX = 5312h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable Resume on Ring Indicator + 01h enable Resume on Ring Indicator + 02h get Resume on Ring Indicator status +Return: CF clear if successful + CX = resume status (0000h disabled, 0001h enabled) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces +SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h +--------p-155313----------------------------- +INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS + AX = 5313h + BX = device ID (see #00474) + 0000h (APM BIOS) + other reserved + CL = function + 00h disable timer-based requests + 01h enable timer-based requests + 02h get timer-based requests status +Return: CF clear if successful + CX = timer-based requests status (0000h disabled, 0001h enabled) + CF set on error + AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) +Notes: this function is supported via the INT 15, 16-bit protected mode, and + 32-bit protected mode interfaces + some BIOSes set AH on return even when successful +SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h diff --git a/kernel/tags/kolibri0.6.0.0/docs/sysfuncr.txt b/kernel/tags/kolibri0.6.0.0/docs/sysfuncr.txt new file mode 100644 index 0000000000..b97ccb56e8 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/docs/sysfuncr.txt @@ -0,0 +1,4484 @@ +‘€‘’…ЊЌ›… ”“ЌЉ–€€ ЋЏ…ђЂ–€ЋЌЌЋ‰ ‘€‘’…Њ› Kolibri 0.6.0.0 + +Ќ®¬Ґа дг­ЄжЁЁ Ї®¬Ґй Ґвбп ў ॣЁбва eax. +‚맮ў бЁб⥬­®© дг­ЄжЁЁ ®бгйҐбвў«пҐвбп Є®¬ ­¤®© "int 0x40". +‚ᥠॣЁбвал, Єа®¬Ґ пў­® гЄ § ­­ле ў ў®§ўа й Ґ¬®¬ §­ зҐ­ЁЁ, + ўЄ«оз п ॣЁбва д« Ј®ў eflags, б®еа ­повбп. + + +====================================================================== +============== ”г­ЄжЁп 0 - ®ЇаҐ¤Ґ«Ёвм Ё ­ аЁб®ў вм ®Є­®. ============= +====================================================================== +ЋЇаҐ¤Ґ«пҐв ®Є­® ЇаЁ«®¦Ґ­Ёп. ђЁбгҐв а ¬Єг ®Є­ , § Ј®«®ў®Є Ё а Ў®зго +®Ў« бвм. „«п ®Є®­ б® бЄЁ­®¬ ®ЇаҐ¤Ґ«пҐв бв ­¤ ав­лҐ Є­®ЇЄЁ § ЄалвЁп Ё +¬Ё­Ё¬Ё§ жЁЁ. +Џ а ¬Ґвал: + * eax = 0 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  Ї® ®бЁ y]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = 0xXYRRGGBB, Ј¤Ґ: + * Y = бвЁ«м ®Є­ : + * Y=0 - вЁЇ I - ®Є­® дЁЄбЁа®ў ­­ле а §¬Ґа®ў + * Y=1 - в®«мЄ® ®ЇаҐ¤Ґ«Ёвм ®Ў« бвм ®Є­ , ­ЁзҐЈ® ­Ґ аЁб®ў вм + * Y=2 - вЁЇ II - ®Є­® Ё§¬Ґ­пҐ¬ле а §¬Ґа®ў + * Y=3 - ®Є­® б® бЄЁ­®¬ + * ®бв «м­лҐ ў®§¬®¦­лҐ §­ зҐ­Ёп (®в 4 ¤® 15) § аҐ§ҐаўЁа®ў ­л, + ўл§®ў дг­ЄжЁЁ б в ЄЁ¬Ё Y ЁЈ­®аЁагҐвбп + * RR, GG, BB = ᮮ⢥вб⢥­­® Єа б­ п, §Ґ«Ґ­ п, бЁ­пп + б®бв ў«пойЁҐ жўҐв  а Ў®зҐ© ®Ў« бвЁ ®Є­  + (ЁЈ­®аЁагҐвбп ¤«п бвЁ«п Y=2) + * X = DCBA (ЎЁвл) + * A = 1 - г ®Є­  Ґбвм § Ј®«®ў®Є; ¤«п бвЁ«п Y=3  ¤аҐб бва®ЄЁ + § Ј®«®ўЄ  § ¤ свбп ў edi, ¤«п Їа®зЁе бвЁ«Ґ© + ЁбЇ®«м§гҐвбп Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 71 + * B = 1 - Є®®а¤Ё­ вл ўбҐе Ја дЁзҐбЄЁе ЇаЁ¬ЁвЁў®ў § ¤ овбп + ®в­®бЁвҐ«м­® Є«ЁҐ­вбЄ®© ®Ў« бвЁ ®Є­  + * C § аҐ§ҐаўЁа®ў ­ (гбв ­ ў«Ёў ©вҐ ў 0) + * 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 б § Ј®«®ўЄ®¬ (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' Ё§ бЄЁ­  + * аЁбгҐвбп § Ј®«®ў®Є (Ї® Є авЁ­Є ¬ Ё§ бЄЁ­ ) ў Їаאַ㣮«м­ЁЄҐ + (0,0) - (xsize,_skinh-1) + * Ґб«Ё ysize>=26, в® § Єа иЁў Ґвбп а Ў®з п ®Ў« бвм ®Є­  - + Їаאַ㣮«м­ЁЄ б «Ґўл¬ ўҐае­Ё¬ гЈ«®¬ (5,_skinh) Ё Їа ўл¬ ­Ё¦­Ё¬ + (xsize-5,ysize-5) - 梥⮬, гЄ § ­­л¬ ў edx (б гзҐв®¬ Ја ¤ЁҐ­в ) + * ®ЇаҐ¤Ґ«повбп ¤ўҐ бв ­¤ ав­лҐ Є­®ЇЄЁ: § ЄалвЁп Ё ¬Ё­Ё¬Ё§ жЁЁ + (ᬮваЁ дг­ЄжЁо 8) + * Ґб«Ё A=1 Ё ў edi (­Ґ­г«Ґў®©) гЄ § вҐ«м ­  бва®Єг § Ј®«®ўЄ , + в® ®­  ўлў®¤Ёвбп ў § Ј®«®ўЄҐ ў ¬ҐбвҐ, ®ЇаҐ¤Ґ«пҐ¬®¬ бЄЁ­®¬ + * ‡­ зҐ­ЁҐ ЇҐаҐ¬Ґ­­®© _skinh ¤®бвгЇ­® Є Є १г«мв в ўл§®ў  + Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 48 + +====================================================================== +================= ”г­ЄжЁп 1 - Ї®бв ўЁвм в®зЄг ў ®Є­Ґ. ================ +====================================================================== +Џ а ¬Ґвал: + * eax = 1 - ­®¬Ґа дг­ЄжЁЁ + * ebx = x-Є®®а¤Ё­ в  (®в­®бЁвҐ«м­® ®Є­ ) + * ecx = y-Є®®а¤Ё­ в  (®в­®бЁвҐ«м­® ®Є­ ) + * edx = 0x00RRGGBB - 梥в в®зЄЁ + edx = 0x01xxxxxx - Ё­ўҐавЁа®ў вм 梥в в®зЄЁ + (¬« ¤иЁҐ 24 ЎЁв  ЁЈ­®аЁаговбп) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +============== ”г­ЄжЁп 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. + +====================================================================== +================ ”г­ЄжЁп 3 - Ї®«гзЁвм бЁб⥬­®Ґ ўаҐ¬п. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 3 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00SSMMHH, Ј¤Ґ HH:MM:SS = з бл:¬Ё­гвл:ᥪ㭤л + * Є ¦¤л© н«Ґ¬Ґ­в ў®§ўа й Ґвбп Є Є BCD-зЁб«®, ­ ЇаЁ¬Ґа, + ¤«п ўаҐ¬Ґ­Ё 23:59:59 १г«мв в Ўг¤Ґв 0x00595923 +‡ ¬Ґз ­Ёп: + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 9 дг­ЄжЁЁ 26 - Ї®«г祭ЁҐ ўаҐ¬Ґ­Ё + б ¬®¬Ґ­в  § ЇгбЄ  бЁб⥬л; ®­  ў® ¬­®ЈЁе б«гз пе 㤮Ў­ҐҐ, + Ї®бЄ®«мЄг ў®§ўа й Ґв Їа®бв® DWORD-§­ зҐ­ЁҐ бзҐвзЁЄ  ўаҐ¬Ґ­Ё. + * ‘Ёб⥬­®Ґ ўаҐ¬п ¬®¦­® гбв ­®ўЁвм дг­ЄжЁҐ© 22. + +====================================================================== +============== ”г­ЄжЁп 4 - ўлўҐбвЁ бва®Єг ⥪бв  ў ®Є­®. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 4 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] + * ecx = 0xX0RRGGBB, Ј¤Ґ + * RR, GG, BB § ¤ ов 梥в ⥪бв  + * X=ABnn (ЎЁвл): + * nn § ¤ Ґв ЁбЇ®«м§гҐ¬л© иаЁдв: 0=бЁб⥬­л© ¬®­®иЁаЁ­­л©, + 1=бЁб⥬­л© иаЁдв ЇҐаҐ¬Ґ­­®© иЁаЁ­л + * A=0 - ўлў®¤Ёвм esi бЁ¬ў®«®ў, A=1 - ўлў®¤Ёвм ASCIIZ-бва®Єг + * B=1 - § Єа иЁў вм д®­ 梥⮬ edi + * edx = гЄ § вҐ«м ­  ­ з «® бва®ЄЁ + * esi = ¤«п A=0 ¤«Ё­  бва®ЄЁ, ¤®«¦­  Ўлвм ­Ґ Ў®«миҐ 255; + ¤«п A=1 ЁЈ­®аЁагҐвбп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏҐаўл© бЁб⥬­л© иаЁдв бзЁвлў Ґвбп ЇаЁ § Јаг§ЄҐ Ё§ д ©«  char.mt, + ўв®а®© - Ё§ char2.mt. + * ЋЎ  иаЁдв  Ё¬Ґов ўлб®вг 9 ЇЁЄбҐ«Ґ©, иЁаЁ­  ¬®­®иЁаЁ­­®Ј® иаЁдв  + а ў­  6 ЇЁЄбҐ«Ґ©. + +====================================================================== +========================= ”г­ЄжЁп 5 - Ї г§ . ========================= +====================================================================== +‡ ¤Ґа¦Ёў Ґв ўлЇ®«­Ґ­ЁҐ Їа®Ја ¬¬л ­  § ¤ ­­®Ґ ўаҐ¬п. +Џ а ¬Ґвал: + * eax = 5 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ўаҐ¬п ў б®вле ¤®«пе ᥪ㭤л +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏҐаҐ¤ з  ebx=0 ­Ґ ЇҐаҐ¤ Ґв гЇа ў«Ґ­ЁҐ б«Ґ¤го饬㠯а®жҐббг Ё + ў®®ЎйҐ ­Ґ Їа®Ё§ў®¤Ёв ­ЁЄ ЄЁе ¤Ґ©бвўЁ©. …б«Ё ¤Ґ©б⢨⥫쭮 + вॡгҐвбп ЇҐаҐ¤ вм гЇа ў«Ґ­ЁҐ б«Ґ¤го饬㠯а®жҐббг + (§ Є®­зЁвм ⥪гйЁ© Єў ­в ўаҐ¬Ґ­Ё), ЁбЇ®«м§г©вҐ Ї®¤дг­ЄжЁо 1 + дг­ЄжЁЁ 68. + * ЏаЁ ⥪г饩 ॠ«Ё§ жЁЁ Їа®Ё§®©¤Ґв ­Ґ¬Ґ¤«Ґ­­л© ў®§ўа в Ё§ дг­ЄжЁЁ, + Ґб«Ё б«®¦Ґ­ЁҐ ebx б ⥪гйЁ¬ §­ зҐ­ЁҐ¬ бзҐвзЁЄ  ўаҐ¬Ґ­Ё ўл§®ўҐв + 32-ЎЁв­®Ґ ЇҐаҐЇ®«­Ґ­ЁҐ. + +====================================================================== +=============== ”г­ЄжЁп 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-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї ЇЄЁ ­  а ¬¤ЁбЄҐ. + +====================================================================== +=============== ”г­ЄжЁп 7 - ўлўҐбвЁ Ё§®Ўа ¦Ґ­ЁҐ ў ®Є­®. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 7 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё§®Ўа ¦Ґ­ЁҐ ў д®а¬ вҐ BBGGRRBBGGRR... + * ecx = [а §¬Ґа Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл Ё§®Ўа ¦Ґ­Ёп - нв® Є®®а¤Ё­ вл ўҐае­ҐЈ® «Ґў®Ј® гЈ«  + Ё§®Ўа ¦Ґ­Ёп ®в­®бЁвҐ«м­® ®Є­ . + * ђ §¬Ґа Ё§®Ўа ¦Ґ­Ёп ў Ў ©в е Ґбвм 3*xsize*ysize. + +====================================================================== +=============== ”г­ЄжЁп 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. + +====================================================================== +============= ”г­ЄжЁп 9 - Ё­д®а¬ жЁп ® Ї®в®ЄҐ ўлЇ®«­Ґ­Ёп. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 9 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа  1 ЉЎ + * ecx = ­®¬Ґа б«®в  Ї®в®Є  + ecx = -1 - Ї®«гзЁвм Ё­д®а¬ жЁо ® ⥪г饬 Ї®в®ЄҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¬ ЄбЁ¬ «м­л© ­®¬Ґа б«®в  Ї®в®Є  + * ЎгдҐа, ­  Є®в®ал© гЄ §лў Ґв ebx, ᮤҐа¦Ёв б«Ґ¤гойго Ё­д®а¬ жЁо: + * +0: dword: ЁбЇ®«м§®ў ­ЁҐ Їа®жҐбб®а  (бЄ®«мЄ® в Єв®ў ў ᥪ㭤г + г室Ёв ­  ЁбЇ®«­Ґ­ЁҐ Ё¬Ґ­­® нв®Ј® Ї®в®Є ) + * +4: word: Ї®§ЁжЁп ®Є­  Ї®в®Є  ў ®Є®­­®¬ бвнЄҐ + * +6: word: (­Ґ Ё¬ҐҐв ®в­®иҐ­Ёп Є § Їа®иҐ­­®¬г Ї®в®Єг) + ­®¬Ґа б«®в  Ї®в®Є , ®Є­® Є®в®а®Ј® ­ е®¤Ёвбп ў ®Є®­­®¬ бвнЄҐ + ў Ї®§ЁжЁЁ ecx + * +8: word: § аҐ§ҐаўЁа®ў ­® + * +10 = +0xA: 11 Ў ©в: Ё¬п Їа®жҐбб  + (Ё¬п ᮮ⢥вбвўго饣® ЁбЇ®«­пҐ¬®Ј® д ©«  ў д®а¬ вҐ 8+3) + * +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): ®Є­® бўса­гв® ў § Ј®«®ў®Є +‡ ¬Ґз ­Ёп: + * ‘«®вл ­г¬Ґаговбп б 1. + * ‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ­Ґ Ґбвм ®ЎйҐҐ зЁб«® Ї®в®Є®ў, Ї®бЄ®«мЄг + Ўлў ов бў®Ў®¤­лҐ б«®вл. + * ЏаЁ ᮧ¤ ­ЁЁ Їа®жҐбб   ўв®¬ вЁзҐбЄЁ ᮧ¤ Ґвбп Ї®в®Є ўлЇ®«­Ґ­Ёп. + * ”г­ЄжЁп ўл¤ Ґв Ё­д®а¬ жЁо ® Ї®в®ЄҐ. Љ ¦¤л© Їа®жҐбб Ё¬ҐҐв + е®вп Ўл ®¤Ё­ Ї®в®Є. Ћ¤Ё­ Їа®жҐбб ¬®¦Ґв ᮧ¤ вм ­ҐбЄ®«мЄ® Ї®в®Є®ў, + ў н⮬ б«гз Ґ Є ¦¤л© Ї®в®Є Ї®«гз Ґв бў®© б«®в, ЇаЁзҐ¬ Ї®«п + +10, +22, +26 ў нвЁе б«®в е б®ўЇ ¤ ов. + „«п ЇаЁ«®¦Ґ­Ё© ­Ґ бгйҐбвўгҐв ®ЎйҐЈ® бЇ®б®Ў  ®ЇаҐ¤Ґ«Ёвм, + ЇаЁ­ ¤«Ґ¦ в «Ё ¤ў  Ї®в®Є  ®¤­®¬г Їа®жҐббг. + * ЂЄвЁў­®Ґ ®Є­® - ®Є­®, ­ е®¤п饥бп ­  ўҐаиЁ­Ґ ®Є®­­®Ј® бвнЄ , + ®­® Ї®«гз Ґв б®®ЎйҐ­Ёп ® ўў®¤Ґ б Є« ўЁ вгал. „«п ­ҐЈ® Ї®§ЁжЁп ў + ®Є®­­®¬ бвнЄҐ б®ўЇ ¤ Ґв б ў®§ўа й Ґ¬л¬ §­ зҐ­ЁҐ¬. + * ‘«®в 1 ᮮ⢥вбвўгҐв бЇҐжЁ «м­®¬г Ї®в®Єг ®ЇҐа жЁ®­­®© бЁб⥬л, + ¤«п Є®в®а®Ј®: + * ®Є­® ­ е®¤Ёвбп ў­Ё§г ®Є®­­®Ј® бвнЄ , Ї®«п +4 Ё +6 ᮤҐа¦ в + §­ зҐ­ЁҐ 1 + * Ё¬п Їа®жҐбб  - "OS/IDLE" (¤®Ї®«­Ґ­­®Ґ Їа®ЎҐ« ¬Ё) + *  ¤аҐб Їа®жҐбб  ў Ї ¬пвЁ а ўҐ­ 0, а §¬Ґа ЁбЇ®«м§гҐ¬®© Ї ¬пвЁ + 16 Mb (0x1000000) + * PID=1 + * Є®®а¤Ё­ вл Ё а §¬Ґал ®Є­ , а ў­® Є Є Ё Є«ЁҐ­вбЄ®© ®Ў« бвЁ, + гб«®ў­® Ї®« Ј овбп а ў­л¬Ё 0 + * б®бв®п­ЁҐ б«®в  - ўбҐЈ¤  0 (ўлЇ®«­пҐвбп) + * ўаҐ¬п ўлЇ®«­Ґ­Ёп бЄ« ¤лў Ґвбп Ё§ ўаҐ¬Ґ­Ё, г室п饣® ­  + б®Ўб⢥­­® а Ў®вг, Ё ўаҐ¬Ґ­Ё Їа®бв®п ў ®¦Ё¤ ­ЁЁ ЇаҐалў ­Ёп + (Є®в®а®Ґ ¬®¦­® Ї®«гзЁвм ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 18). + * Ќ зЁ­ п б® б«®в  2, а §¬Ґй овбп ®Ўлз­лҐ ЇаЁ«®¦Ґ­Ёп. + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп а §¬Ґй овбп ў Ї ¬пвЁ Ї®  ¤аҐбг 0x10000000 + (Є®­бв ­в  п¤а  std_application_base_address). + Ќ «®¦Ґ­Ёп ­Ґ Їа®Ёб室Ёв, Ї®бЄ®«мЄг г Є ¦¤®Ј® Їа®жҐбб  бў®п + в Ў«Ёж  бва ­Ёж. + * ЏаЁ ᮧ¤ ­ЁЁ Ї®в®Є  Ґ¬г ­ §­ з овбп б«®в ў бЁб⥬­®© в Ў«ЁжҐ Ё + Ё¤Ґ­вЁдЁЄ в®а (Process/Thread IDentifier = PID/TID), Є®в®алҐ ¤«п + § ¤ ­­®Ј® Ї®в®Є  ­Ґ Ё§¬Ґ­повбп б® ўаҐ¬Ґ­Ґ¬. + Џ®б«Ґ § ўҐа襭Ёп Ї®в®Є  ҐЈ® б«®в ¬®¦Ґв Ўлвм § ­®ў® ЁбЇ®«м§®ў ­ + ¤«п ¤агЈ®Ј® Ї®в®Є . €¤Ґ­вЁдЁЄ в®а Ї®в®Є  ­Ґ ¬®¦Ґв Ўлвм ­ §­ зҐ­ + ¤агЈ®¬г Ї®в®Єг ¤ ¦Ґ Ї®б«Ґ § ўҐа襭Ёп ЇҐаў®Ј®. + Ќ §­ з Ґ¬лҐ ­®ўл¬ Ї®в®Є ¬ Ё¤Ґ­вЁдЁЄ в®ал ¬®­®в®­­® а бвгв. + * …б«Ё Ї®в®Є ҐйҐ ­Ґ ®ЇаҐ¤Ґ«Ё« бў®Ґ ®Є­® ўл§®ў®¬ дг­ЄжЁЁ 0, в® + Ї®«®¦Ґ­ЁҐ Ё а §¬Ґал нв®Ј® ®Є­  Ї®« Ј овбп ­г«п¬Ё. + * Љ®®а¤Ё­ вл Є«ЁҐ­вбЄ®© ®Ў« бвЁ ®Є­  ЎҐагвбп ®в­®бЁвҐ«м­® ®Є­ . + * ‚ ¤ ­­л© ¬®¬Ґ­в ЁбЇ®«м§гҐвбп в®«мЄ® з бвм ЎгдҐа  а §¬Ґа®¬ + 71 = 0x47 Ў ©в . ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ४®¬Ґ­¤гҐвбп ЁбЇ®«м§®ў вм ЎгдҐа + а §¬Ґа®¬ 1 ЉЎ ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ, ў Ўг¤г饬 ¬®Јгв Ўлвм + ¤®Ў ў«Ґ­л ­ҐЄ®в®алҐ Ї®«п. + +====================================================================== +==================== ”г­ЄжЁп 10 - ®¦Ё¤ вм б®ЎлвЁп. =================== +====================================================================== +…б«Ё ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв , в® ¦¤Ґв Ї®пў«Ґ­Ёп б®®ЎйҐ­Ёп ў ®зҐаҐ¤Ё. +‚ в Є®¬ б®бв®п­ЁЁ Ї®в®Є ­Ґ Ї®«гз Ґв Їа®жҐбб®а­®Ј® ўаҐ¬Ґ­Ё. +‡ вҐ¬ бзЁвлў Ґв б®®ЎйҐ­ЁҐ Ё§ ®зҐаҐ¤Ё. + +Џ а ¬Ґвал: + * eax = 10 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п Їа®ўҐаЄЁ, Ґбвм «Ё б®®ЎйҐ­ЁҐ ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 11. + —в®Ўл ¦¤ вм ­Ґ Ў®«ҐҐ ®ЇаҐ¤Ґ«Ґ­­®Ј® ўаҐ¬Ґ­Ё, ЁбЇ®«м§г©вҐ + дг­ЄжЁо 23. + +====================================================================== +======= ”г­ЄжЁп 11 - Їа®ўҐаЁвм, Ґбвм «Ё б®ЎлвЁҐ, ЎҐ§ ®¦Ё¤ ­Ёп. ======= +====================================================================== +…б«Ё ў ®зҐаҐ¤Ё б®®ЎйҐ­Ё© Ґбвм Є Є®Ґ-в® б®ЎлвЁҐ, в® бзЁвлў Ґв Ё +ў®§ўа й Ґв ҐЈ®. …б«Ё ®зҐаҐ¤м Їгбв , ў®§ўа й Ґв ­г«м. +Џ а ¬Ґвал: + * eax = 11 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв  + * Ё­ зҐ eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п ®¦Ё¤ ­Ёп Ї®пў«Ґ­Ёп б®ЎлвЁп ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 10. + —в®Ўл ¦¤ вм ­Ґ Ў®«ҐҐ ®ЇаҐ¤Ґ«Ґ­­®Ј® ўаҐ¬Ґ­Ё, ЁбЇ®«м§г©вҐ + дг­ЄжЁо 23. + +====================================================================== +=========== ”г­ЄжЁп 12 - ­ з вм/§ Є®­зЁвм ЇҐаҐаЁб®ўЄг ®Є­ . ========== +====================================================================== + +-------------- Џ®¤дг­ЄжЁп 1 - ­ з вм ЇҐаҐаЁб®ўЄг ®Є­ . --------------- +Џ а ¬Ґвал: + * eax = 12 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------------- Џ®¤дг­ЄжЁп 2 - § Є®­зЁвм ЇҐаҐаЁб®ўЄг ®Є­ . ------------- +Џ а ¬Ґвал: + * eax = 12 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­ з «  ЇҐаҐаЁб®ўЄЁ г¤ «пҐв ўбҐ ®ЇаҐ¤Ґ«с­­лҐ + дг­ЄжЁҐ© 8 Є­®ЇЄЁ, Ёе б«Ґ¤гҐв ®ЇаҐ¤Ґ«Ёвм Ї®ўв®а­®. + +====================================================================== +============ ”г­ЄжЁп 13 - ­ аЁб®ў вм Їаאַ㣮«м­ЁЄ ў ®Є­Ґ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 13 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [а §¬Ґа Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  Ї® ®бЁ y]*65536 + [а §¬Ґа Ї® ®бЁ y] + * edx = 梥в 0xRRGGBB Ё«Ё 0x80RRGGBB ¤«п Ја ¤ЁҐ­в­®© § «ЁўЄЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®¤ Є®®а¤Ё­ в ¬Ё Ї®­Ё¬ овбп Є®®а¤Ё­ вл «Ґў®Ј® ўҐае­ҐЈ® гЈ«  + Їаאַ㣮«м­ЁЄ  ®в­®бЁвҐ«м­® ®Є­ . + +====================================================================== +================ ”г­ЄжЁп 14 - Ї®«гзЁвм а §¬Ґал нЄа ­ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 14 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [xsize]*65536 + [ysize], Ј¤Ґ + * xsize = x-Є®®а¤Ё­ в  Їа ў®Ј® ­Ё¦­ҐЈ® гЈ«  нЄа ­  = + а §¬Ґа Ї® Ј®аЁ§®­в «Ё - 1 + * ysize = y-Є®®а¤Ё­ в  Їа ў®Ј® ­Ё¦­ҐЈ® гЈ«  нЄа ­  = + а §¬Ґа Ї® ўҐавЁЄ «Ё - 1 +‡ ¬Ґз ­Ёп: + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 5 дг­ЄжЁЁ 48 - Ї®«гзЁвм а §¬Ґал а Ў®зҐ© + ®Ў« бвЁ нЄа ­ . + +====================================================================== += ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм а §¬Ґа д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. = +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = иЁаЁ­  Ё§®Ўа ¦Ґ­Ёп + * edx = ўлб®в  Ё§®Ўа ¦Ґ­Ёп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®ўҐа®Є ­  Є®а४⭮бвм ­Ґ ¤Ґ« Ґвбп. “бв ­®ўЄ  б«ЁиЄ®¬ Ў®«миЁе + §­ зҐ­Ё© ЇаЁўҐ¤св Є ⮬г, зв® ў д®­ ў®©¤гв ¤ ­­лҐ §  Ја ­ЁжҐ© + ЎгдҐа  д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. ђ §¬Ґа ЎгдҐа  = 0x160000-0x10, зв® + ᮮ⢥вбвўгҐв ¬ ЄбЁ¬ «м­л¬ а §¬Ґа ¬ 800*600. (800*600*3=0x15F900) + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п дг­ЄжЁп Ї®«г祭Ёп а §¬Ґа®ў д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 39. + +====================================================================== += ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 2 - Ї®бв ўЁвм в®зЄг ­  д®­®ў®¬ Ё§®Ўа ¦Ґ­ЁЁ. = +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ᬥ饭ЁҐ + * edx = 梥в в®зЄЁ 0xRRGGBB +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‘¬ҐйҐ­ЁҐ ¤«п в®зЄЁ б Є®®а¤Ё­ в ¬Ё (x,y) ўлзЁб«пҐвбп Є Є + (x+y*xsize)*3. + * …б«Ё гЄ § ­­®Ґ ᬥ饭ЁҐ ЇаҐўли Ґв 0x160000-16 = + 1.375 Mb - 16 bytes, ўл§®ў ЁЈ­®аЁагҐвбп. + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п дг­ЄжЁп Ї®«г祭Ёп в®зЄЁ б д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 2 дг­ЄжЁЁ 39. + +====================================================================== +============ ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 3 - ЇҐаҐаЁб®ў вм д®­. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +===== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм ०Ё¬ ®ваЁб®ўЄЁ д®­ . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ०Ё¬ ®ваЁб®ўЄЁ: + * 1 = § ¬®бвЁвм + * 2 = а бвп­гвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + * …бвм Ї а­ п Є®¬ ­¤  Ї®«г祭Ёп ०Ё¬  ®ваЁб®ўЄЁ д®­  - + Ї®¤дг­ЄжЁп 4 дг­ЄжЁЁ 39. + +====================================================================== +===== ”г­ЄжЁп 15, Ї®¤дг­ЄжЁп 5 - Ї®¬ҐбвЁвм Ў«®Є ЇЁЄбҐ«Ґ© ­  д®­. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 15 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ ў д®а¬ вҐ BBGGRRBBGGRR... + * edx = ᬥ饭ЁҐ ў ¤ ­­ле д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп + * esi = а §¬Ґа ¤ ­­ле ў Ў ©в е = 3 * зЁб«® ЇЁЄбҐ«Ґ© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Ў«®Є ўл«Ґ§ Ґв §  Ја ­Ёжг 0x160000-16 = 1.375 Mb - 16 bytes, + в® ўл§®ў ЁЈ­®аЁагҐвбп. + * –ўҐв Є ¦¤®Ј® ЇЁЄбҐ«п еа ­Ёвбп Є Є 3-Ў ©в­ п ўҐ«ЁзЁ­  BBGGRR. + * ЏЁЄбҐ«Ё д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп § ЇЁблў овбп Ї®б«Ґ¤®ў вҐ«м­® + б«Ґў  ­ Їа ў®, ᢥаег ў­Ё§. + * ‘¬ҐйҐ­ЁҐ ЇЁЄбҐ«п б Є®®а¤Ё­ в ¬Ё (x,y) Ґбвм (x+y*xsize)*3. + * „«п ®Ў­®ў«Ґ­Ёп нЄа ­  (Ї®б«Ґ § ўҐа襭Ёп бҐаЁЁ Є®¬ ­¤, а Ў®в ойЁе б + д®­®¬) ўл§лў ©вҐ Ї®¤дг­ЄжЁо 3 ЇҐаҐаЁб®ўЄЁ д®­ . + +====================================================================== +============= ”г­ЄжЁп 16 - б®еа ­Ёвм а ¬¤ЁбЄ ­  ¤ЁбЄҐвг. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 16 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 Ё«Ё ebx = 2 - ­  Є Єго ¤ЁбЄҐвг б®еа ­пвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  + +====================================================================== +============== ”г­ЄжЁп 17 - Ї®«гзЁвм Є®¤ ­ ¦ в®© Є­®ЇЄЁ. ============= +====================================================================== +‡ ЎЁа Ґв Є®¤ ­ ¦ в®© Є­®ЇЄЁ Ё§ ЎгдҐа . +Џ а ¬Ґвал: + * eax = 17 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ЎгдҐа Їгбв, ў®§ўа й Ґвбп eax=1 + * Ґб«Ё ЎгдҐа ­ҐЇгбв, в® ў®§ўа й Ґвбп al=0, бв аиЁҐ 24 ЎЁв  eax + ᮤҐа¦ в Ё¤Ґ­вЁдЁЄ в®а Є­®ЇЄЁ (ў з бв­®бвЁ, ў ah ®Є §лў Ґвбп + ¬« ¤иЁ© Ў ©в Ё¤Ґ­вЁдЁЄ в®а ; Ґб«Ё ўбҐ Є­®ЇЄЁ Ё¬Ґов Ё¤Ґ­вЁдЁЄ в®а, + ¬Ґ­миЁ© 256, в® ¤«п а §«ЁзҐ­Ёп ¤®бв в®з­® ah) +‡ ¬Ґз ­Ёп: + * "ЃгдҐа" еа ­Ёв в®«мЄ® ®¤­г Є­®ЇЄг, ЇаЁ ­ ¦ вЁЁ ­®ў®© Є­®ЇЄЁ + Ё­д®а¬ жЁп ® бв а®© вҐапҐвбп. + * ЏаЁ ўл§®ўҐ нв®© дг­ЄжЁЁ ЇаЁ«®¦Ґ­ЁҐ¬ б ­Ґ ЄвЁў­л¬ ®Є­®¬ + ў®§ўа й Ґвбп ®вўҐв "ЎгдҐа Їгбв". + +====================================================================== +======== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 1 - § ўҐаиЁвм а Ў®вг бЁб⥬л. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ўбҐЈ¤  ў®§ўа й Ґвбп eax = 0 Є Є ЇаЁ§­ Є гбЇҐе  +‡ ¬Ґз ­Ёп: + * Ќ  Ї®б«Ґ¤­Ґ¬ и ЈҐ Ї®пў«пҐвбп ¬Ґ­о ўл室  Ё§ бЁб⥬л, ®¦Ё¤ о饥 + ॠЄжЁЁ Ї®«м§®ў вҐ«п. + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 9, § ўҐа襭ЁҐ а Ў®вл бЁб⥬л б Ї а ¬Ґв஬, + зв®Ўл д®абЁа®ў вм ўлЎ®а ў ¬Ґ­о ўл室 . + +====================================================================== +==== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 2 - § ўҐаиЁвм Їа®жҐбб/Ї®в®Є Ї® б«®вг. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа б«®в  Їа®жҐбб /Ї®в®Є  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЌҐ«м§п § ўҐаиЁвм Ї®в®Є ®ЇҐа жЁ®­­®© бЁб⥬л OS/IDLE (­®¬Ґа б«®в  + 1), ¬®¦­® § ўҐаиЁвм «оЎ®© ®Ўлз­л© Ї®в®Є/Їа®жҐбб. + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 18 - § ўҐа襭ЁҐ + Їа®жҐбб /Ї®в®Є  б § ¤ ­­л¬ Ё¤Ґ­вЁдЁЄ в®а®¬. + +====================================================================== += ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 3 - ᤥ« вм  ЄвЁў­л¬ ®Є­® § ¤ ­­®Ј® Ї®в®Є . = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа б«®в  Ї®в®Є  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаЁ гЄ § ­ЁЁ Є®а४⭮Ј®, ­® ­ҐбгйҐбвўго饣® б«®в   ЄвЁўЁ§ЁагҐвбп + Є Є®Ґ-в® ®Є­®. + * “§­ вм, Є Є®Ґ ®Є­® пў«пҐвбп  ЄвЁў­л¬, ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7. + +====================================================================== + ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм бзсвзЁЄ Їгбвле в Єв®ў ў ᥪ㭤г. +====================================================================== +Џ®¤ Їгбвл¬Ё в Єв ¬Ё Ї®­Ё¬ Ґвбп ўаҐ¬п, ў Є®в®а®Ґ Їа®жҐбб®а Їа®бв Ёў Ґв +ў ®¦Ё¤ ­ЁЁ ЇаҐалў ­Ёп (ў Ё­бвагЄжЁЁ hlt). + +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = §­ зҐ­ЁҐ бзсвзЁЄ  Їгбвле в Єв®ў ў ᥪ㭤г + +====================================================================== +======== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 5 - Ї®«гзЁвм в Єв®ўго з бв®вг. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = в Єв®ў п з бв®в  (Ї® ¬®¤г«о 2^32 в Єв®ў = 4ѓѓж) + +====================================================================== + ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 6 - б®еа ­Ёвм а ¬¤ЁбЄ ў д ©« ­  ¦сбвЄ®¬ ¤ЁбЄҐ. +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx ®ЇаҐ¤Ґ«пҐв Їгвм Є д ©«г: + * 1 = ў Ї ЇЄҐ "/KOLIBRI" + * 2 = ў Є®а­Ґў®¬ Є в «®ЈҐ + * 3 = edx гЄ §лў Ґв ­  Їгвм (Ё¬Ґ­  Ї Ї®Є ў д®а¬ вҐ 8+3, + а §¤Ґ«с­­лҐ '/') +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * Ё­ зҐ eax = Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * €¬п д ©«  дЁЄбЁа®ў ­®, "menuet.img" (Ј«®Ў «м­ п ЇҐаҐ¬Ґ­­ п п¤а  + image_save Ё§ preboot.inc) + * Ќ  Є Є®¬ а §¤Ґ«Ґ Є Є®Ј® ¤ЁбЄ  д ©« Ўг¤Ґв б®еа ­с­, ®ЇаҐ¤Ґ«пҐвбп + Ї®¤дг­ЄжЁҐ© 7 Ё Ї®¤дг­ЄжЁҐ© 8 дг­ЄжЁЁ 21. + * ‚ᥠЇ ЇЄЁ ў гЄ § ­­®¬ ЇгвЁ ¤®«¦­л бгйҐбвў®ў вм, Ё­ зҐ ўҐа­свбп + §­ зҐ­ЁҐ 5, "д ©« ­Ґ ­ ©¤Ґ­". + +====================================================================== +====== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 7 - Ї®«гзЁвм ­®¬Ґа  ЄвЁў­®Ј® ®Є­ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа  ЄвЁў­®Ј® ®Є­  (­®¬Ґа б«®в  Ї®в®Є , ®Є­® Є®в®а®Ј® +  ЄвЁў­®) +‡ ¬Ґз ­Ёп: + * ЂЄвЁў­®Ґ ®Є­® ­ е®¤Ёвбп ўўҐаег ®Є®­­®Ј® бвнЄ  Ё Ї®«гз Ґв + б®®ЎйҐ­Ёп ®Ў® ўбс¬ ўў®¤Ґ б Є« ўЁ вгал. + * ‘¤Ґ« вм ®Є­®  ЄвЁў­л¬ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 3. + +====================================================================== +==== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 8 - ®вЄ«озЁвм/а §аҐиЁвм §ўгЄ бЇЁЄҐа . ==== +====================================================================== +ЏаЁ ®вЄ«озс­­®¬ §ўгЄҐ ўл§®ўл Ї®¤дг­ЄжЁЁ 55 дг­ЄжЁЁ 55 ЁЈ­®аЁаговбп. +ЏаЁ ўЄ«озс­­®¬ - ­ Їа ў«повбп ­  ўбв஥­­л© бЇЁЄҐа. + +--------------- Џ®¤Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм б®бв®п­ЁҐ. ---------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 1 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - §ўгЄ бЇЁЄҐа  а §аҐис­; 1 - § ЇаҐйс­ + +-------------- Џ®¤Ї®¤дг­ЄжЁп 2 - ЇҐаҐЄ«озЁвм б®бв®п­ЁҐ. -------------- +ЏҐаҐЄ«оз Ґв б®бв®п­Ёп а §аҐиҐ­Ёп/§ ЇаҐйҐ­Ёп. +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== += ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 9 - § ўҐа襭ЁҐ а Ў®вл бЁб⥬л б Ї а ¬Ґв஬. = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ї а ¬Ґва: + * 1 = ­  Ї®б«Ґ¤­Ґ¬ и ЈҐ § ўҐа襭Ёп а Ў®вл б®еа ­Ёвм а ¬¤ЁбЄ ­  + ¤ЁбЄҐвг, Ї®б«Ґ 祣® ўлўҐбвЁ ¬Ґ­о ўл室  Ё § Їа®бЁвм г + Ї®«м§®ў вҐ«п ¤ «м­Ґ©иЁҐ ¤Ґ©бвўЁп + * 2 = ўлЄ«озЁвм Є®¬ЇмовҐа + * 3 = ЇҐаҐ§ Јаг§Ёвм Є®¬ЇмовҐа + * 4 = ЇҐаҐ§ ЇгбвЁвм п¤а® Ё§ д ©«  kernel.mnt ­  а ¬¤ЁбЄҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ЇаЁ ­ҐўҐа­®¬ ecx ॣЁбвал ­Ґ ¬Ґ­повбп (в.Ґ. eax=18) + * ЇаЁ Їа ўЁ«м­®¬ ўл§®ўҐ ўбҐЈ¤  ў®§ўа й Ґвбп ЇаЁ§­ Є гбЇҐе  eax=0 +‡ ¬Ґз ­Ёп: + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ЇаЁ ­ҐўҐа­®¬ + ўл§®ўҐ, ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў Ї®б«Ґ¤гойЁе ўҐабЁпе п¤а . + * Њ®¦­® ЁбЇ®«м§®ў вм Ї®¤дг­ЄжЁо 1, зв®Ўл ­  Ї®б«Ґ¤­Ґ¬ и ЈҐ + § ўҐа襭Ёп а Ў®вл Ї®«м§®ў вҐ«м б ¬ аҐи «, зв® Ґ¬г ­г¦­®. + * ЌҐ ४®¬Ґ­¤гҐвбп ЁбЇ®«м§®ў вм §­ зҐ­ЁҐ ecx=1 (зв®Ўл ­Ґ а §¤а ¦ вм + Ї®«м§®ў вҐ«п Ё§«Ёи­Ё¬Ё ў®Їа®б ¬Ё); б®еа ­Ёвм а ¬¤ЁбЄ ­  ¤ЁбЄҐвг + ¬®¦­® дг­ЄжЁҐ© 16 (Є®в®а п ¤®ЇгбЄ Ґв гв®з­Ґ­ЁҐ, ­  Є Єго Ё¬Ґ­­® + ¤ЁбЄҐвг ЇЁб вм),   § ўҐаиЁвм а Ў®вг б ¬Ґ­о ўл室  ¬®¦­® 㦥 + гЇ®¬п­гв®© Ї®¤дг­ЄжЁҐ© 1. + +====================================================================== +======== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 10 - ᢥа­гвм ®Є­® ЇаЁ«®¦Ґ­Ёп. ======= +====================================================================== +‘ў®а зЁў Ґв б®Ўб⢥­­®Ґ ®Є­®. +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЊЁ­Ё¬Ё§Ёа®ў ­­®Ґ ®Є­® б в®зЄЁ §аҐ­Ёп дг­ЄжЁЁ 9 б®еа ­пҐв Ї®«®¦Ґ­ЁҐ + Ё а §¬Ґал. + * ‚®ббв ­®ў«Ґ­ЁҐ ®Є­  ЇаЁ«®¦Ґ­Ёп Їа®Ёб室Ёв ЇаЁ  ЄвЁўЁ§Ёа®ў ­ЁЁ + Ї®¤дг­ЄжЁҐ© 3. + * ЋЎлз­® ­Ґв ­Ґ®Ўе®¤Ё¬®бвЁ пў­® бў®а зЁў вм/а §ў®а зЁў вм бў®с ®Є­®: + бў®а зЁў ­ЁҐ ®Є­  ®бгйҐбвў«пҐвбп бЁб⥬®© ЇаЁ ­ ¦ вЁЁ ­  Є­®ЇЄг + ¬Ё­Ё¬Ё§ жЁЁ (Є®в®а п ¤«п ®Є®­ б® бЄЁ­®¬ ®ЇаҐ¤Ґ«пҐвбп  ўв®¬ вЁзҐбЄЁ + дг­ЄжЁҐ© 0, ¤«п ®Є®­ ЎҐ§ бЄЁ­  Ґс ¬®¦­® ®ЇаҐ¤Ґ«Ёвм дг­ЄжЁҐ© 8), + ў®ббв ­®ў«Ґ­ЁҐ - ЇаЁ«®¦Ґ­ЁҐ¬ @panel. + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 11 ===================== +============= Џ®«гзЁвм Ё­д®а¬ жЁо ® ¤ЁбЄ®ў®© Ї®¤бЁб⥬Ґ. ============= +====================================================================== +Џ а ¬Ґвал: + * 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. + * +6: 4 db: § аҐ§ҐаўЁа®ў ­® +”®а¬ в в Ў«Ёжл: Ї®«­ п ўҐабЁп: + * +0: 10 db: в ЄЁҐ ¦Ґ, Є Є Ё ў Є®а®вЄ®© ўҐабЁЁ + * +10: 100 db: ¤ ­­лҐ ¤«п ЇҐаў®Ј® а §¤Ґ«  + * +110: 100 db: ¤ ­­лҐ ¤«п ўв®а®Ј® а §¤Ґ«  + * ... + * +10+100*(n-1): 100 db: ¤ ­­лҐ ¤«п Ї®б«Ґ¤­ҐЈ® а §¤Ґ«  +ђ §¤Ґ«л а бЇ®«®¦Ґ­л ў б«Ґ¤го饬 Ї®ап¤ЄҐ: б­ з «  Ї®б«Ґ¤®ў вҐ«м­® ўбҐ +а бЇ®§­ ­­лҐ а §¤Ґ«л ­  HD ­  IDE0 (Ґб«Ё Ґбвм), +§ вҐ¬ ­  HD ­  IDE1 (Ґб«Ё Ґбвм) Ё в.¤. ¤® IDE3. +”®а¬ в Ё­д®а¬ жЁЁ ® а §¤Ґ«Ґ (Ї®Є  Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® FAT): + * +0: dword: ­ з «м­л© дЁ§ЁзҐбЄЁ© ᥪв®а а §¤Ґ«  + * +4: dword: Ї®б«Ґ¤­Ё© дЁ§ЁзҐбЄЁ© ᥪв®а а §¤Ґ«  + (ЇаЁ­ ¤«Ґ¦Ёв а §¤Ґ«г) + * +8: dword: ᥪв®а®ў ў ®¤­®© Є®ЇЁЁ FAT + * +12 = +0xC: dword: зЁб«® Є®ЇЁ© FAT + * +16 = +0x10: dword: зЁб«® ᥪв®а®ў ў Є« бвҐаҐ + * +20 = +0x14: dword: Ў ©в ў ᥪв®аҐ; ⥪гй п ॠ«Ё§ жЁп ®¦Ё¤ Ґв, + зв® §¤Ґбм 0x200 = 512 + * +24 = +0x18: dword: ЇҐаўл© Є« бвҐа Є®а­Ґў®Ј® Є в «®Ј  ў FAT32, + 0 ¤«п FAT16 + * +28 = +0x1C: dword: ­ з «м­л© дЁ§ЁзҐбЄЁ© ᥪв®а FAT + * +32 = +0x20: dword: ЇҐаўл© дЁ§ЁзҐбЄЁ© ᥪв®а Є®а­Ґў®Ј® Є в «®Ј  + ¤«п FAT16, ЁЈ­®аЁагҐвбп ¤«п FAT32 + * +36 = +0x24: dword: зЁб«® ᥪв®а®ў ў Є®а­Ґў®¬ Є в «®ЈҐ ¤«п FAT16, + 0 ¤«п FAT32 + * +40 = +0x28: dword: дЁ§ЁзҐбЄЁ© ᥪв®а ­ з «  ®Ў« бвЁ ¤ ­­ле + * +44 = +0x2C: dword: ¬ ЄбЁ¬ «м­л© ­®¬Ґа Є« бвҐа  + * +48 = +0x30: dword: дЁ§ЁзҐбЄЁ© ᥪв®а Ё­д®а¬ жЁЁ ® + д ©«®ў®© бЁб⥬Ґ ¤«п FAT32, ЁЈ­®аЁагҐвбп ¤«п FAT16 + * +52 = +0x34: dword: §­ зҐ­ЁҐ, ЁбЇ®«м§гҐ¬®Ґ Є Є Ја ­Ёж  + бЇҐжЁ «м­ле §­ зҐ­Ё© ў FAT + * +56 = +0x38: dword: §­ зҐ­ЁҐ, ЁбЇ®«м§гҐ¬®Ґ ¤«п Ї«®еЁе Є« бвҐа®ў + ў FAT + * +60 = +0x3C: dword: §­ зҐ­ЁҐ, ЁбЇ®«м§гҐ¬®Ґ Є Є ¬ аЄҐа Є®­ж  + ЇаЁ § ЇЁбЁ 楯®зЄЁ ў FAT + * +64 = +0x40: dword: ¬ бЄ , ­ Є« ¤лў Ґ¬ п ­  н«Ґ¬Ґ­в FAT + * +68 = +0x44: byte: вЁЇ д ©«®ў®© бЁб⥬л: 16 Ё«Ё 32 + * +69 = +0x45: 31 db: § аҐ§ҐаўЁа®ў ­® +‡ ¬Ґз ­Ёп: + * Љ®а®вЄ п в Ў«Ёж  ¬®¦Ґв Ўлвм ЁбЇ®«м§®ў ­  ¤«п Ї®«г祭Ёп Ё­д®а¬ жЁЁ + ®Ў Ё¬ҐойЁебп гбва®©бвў е. + * ЏҐаўлҐ ¤ў  Ї®«п Ё­д®а¬ жЁЁ ® а §¤Ґ«Ґ ў Ї®«­®© ўҐабЁЁ в Ў«Ёжл + б®®Ўй ов Ї а ¬Ґвал а §¤Ґ« , ®бв ўиЁҐбп - Ї а ¬Ґвал д ©«®ў®© + бЁб⥬л FAT. „«п ¤агЈЁе д ©«®ўле бЁб⥬ (Є®Ј¤  ®­Ё Ўг¤гв + Ї®¤¤Ґа¦Ёў вмбп) бЇҐжЁдЁзҐбЄ п ¤«п д ©«®ў®© бЁбвҐ¬л Ё­д®а¬ жЁп, + ҐбвҐб⢥­­®, Ўг¤Ґв ¤агЈ®©, ­® ЇҐаўлҐ ¤ў  Ї®«п + б®еа ­пвбп ­ҐЁ§¬Ґ­­л¬Ё. + +====================================================================== +========== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 13 - Ї®«гзЁвм ўҐабЁо п¤а . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ЎгдҐа (­Ґ ¬Ґ­ҐҐ 16 Ў ©в), Єг¤  Ўг¤Ґв Ї®¬ҐйҐ­  + Ё­д®а¬ жЁп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‘вагЄвга  ЎгдҐа : +db a,b,c,d ¤«п ўҐабЁЁ a.b.c.d +db UID_xxx: ®¤­® Ё§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 +db 'name',0 - ASCIIZ-бва®Є  б Ё¬Ґ­Ґ¬ +„«п п¤а  Kolibri 0.6.0.0: +db 0,6,0,0 +db 2 +db 'Kolibri',0 + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 14 ===================== +======= Ћ¦Ё¤ вм ­ з «  ®Ўа в­®Ј® 室  «гз  а §ўсавЄЁ ¬®­Ёв®а . ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 14 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 Є Є ЇаЁ§­ Є гбЇҐе  +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ЇаҐ¤­ §­ зҐ­  ЁбЄ«озЁвҐ«м­® ¤«п  ЄвЁў­ле + ўлб®Є®Їа®Ё§ў®¤ЁвҐ«м­ле Ја дЁзҐбЄЁе ЇаЁ«®¦Ґ­Ё©; ЁбЇ®«м§гҐвбп ¤«п + Ї« ў­®Ј® ўлў®¤  Ја дЁЄЁ. + +====================================================================== +== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 15 - Ї®¬ҐбвЁвм Єгаб®а ¬лиЁ ў 業ва нЄа ­ . = +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 15 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 Є Є ЇаЁ§­ Є гбЇҐе  + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 16 ===================== +============ Џ®«гзЁвм а §¬Ґа бў®Ў®¤­®© ®ЇҐа вЁў­®© Ї ¬пвЁ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 16 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = а §¬Ґа бў®Ў®¤­®© Ї ¬пвЁ ў ЄЁ«®Ў ©в е + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 17 ===================== +============ Џ®«гзЁвм а §¬Ґа Ё¬Ґо饩бп ®ЇҐа вЁў­®© Ї ¬пвЁ. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 17 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ®ЎйЁ© а §¬Ґа Ё¬Ґо饩бп Ї ¬пвЁ ў ЄЁ«®Ў ©в е + +====================================================================== +====================== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 18 ===================== +============= ‡ ўҐаиЁвм Їа®жҐбб/Ї®в®Є Ї® Ё¤Ґ­вЁдЁЄ в®аг. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 18 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Їа®жҐбб /Ї®в®Є  (PID/TID) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎЄ  (Їа®жҐбб ­Ґ ­ ©¤Ґ­ Ё«Ё пў«пҐвбп бЁб⥬­л¬) +‡ ¬Ґз ­Ёп: + * ЌҐ«м§п § ўҐаиЁвм Ї®в®Є ®ЇҐа жЁ®­­®© бЁб⥬л OS/IDLE (­®¬Ґа б«®в  + 1), ¬®¦­® § ўҐаиЁвм «оЎ®© ®Ўлз­л© Ї®в®Є/Їа®жҐбб. + * ‘¬®ваЁ в Є¦Ґ Ї®¤дг­ЄжЁо 2 - § ўҐа襭ЁҐ + Їа®жҐбб /Ї®в®Є  Ї® § ¤ ­­®¬г б«®вг. + +====================================================================== +=== ”г­ЄжЁп 18, Ї®¤дг­ЄжЁп 19 - Ї®«гзЁвм/гбв ­®ўЁвм ­ бва®©ЄЁ ¬лиЁ. == +====================================================================== + +------------- Џ®¤Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм бЄ®а®бвм ¬лиЁ. -------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ⥪гй п бЄ®а®бвм ¬лиЁ + +------------ Џ®¤Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм бЄ®а®бвм ¬лиЁ. ------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 1 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = ­®ў®Ґ §­ зҐ­ЁҐ бЄ®а®бвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +------------- Џ®¤Ї®¤дг­ЄжЁп 2 - Ї®«гзЁвм § ¤Ґа¦Єг ¬лиЁ. -------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ⥪гй п § ¤Ґа¦Є  ¬лиЁ + +------------ Џ®¤Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм § ¤Ґа¦Єг ¬лиЁ. ------------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 3 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = ­®ў®Ґ §­ зҐ­ЁҐ § ¤Ґа¦ЄЁ ¬лиЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +-------- Џ®¤Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм Ї®«®¦Ґ­ЁҐ Єгаб®а  ¬лиЁ. -------- +Џ а ¬Ґвал: + * eax = 18 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 19 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 4 - ­®¬Ґа Ї®¤Ї®¤дг­ЄжЁЁ + * edx = [Є®®а¤Ё­ в  Ї® ®бЁ x]*65536 + [Є®®а¤Ё­ в  Ї® ®бЁ y] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ђҐЄ®¬Ґ­¤гҐ¬ п бЄ®а®бвм ¬лиЁ (ў Ї®¤Ї®¤дг­ЄжЁЁ 1) ®в 1 ¤® 9. + “бв ­ ў«Ёў Ґ¬ п ўҐ«ЁзЁ­  ­Ґ Їа®ўҐапҐвбп Є®¤®¬ п¤а , Ї®н⮬г + ЁбЇ®«м§г©вҐ ®бв®а®¦­®, ЇаЁ ­ҐЄ®а४⭮¬ §­ зҐ­ЁЁ Єгаб®а ¬®¦Ґв + "§ ¬са§­гвм". ‘Є®а®бвм ¬лиЁ ¬®¦­® ॣ㫨஢ вм ў ЇаЁ«®¦Ґ­ЁЁ SETUP. + * ђҐЄ®¬Ґ­¤гҐ¬ п ўҐ«ЁзЁ­  § ¤Ґа¦ЄЁ (ў Ї®¤Ї®¤дг­ЄжЁЁ 3) = 10. + ЊҐ­миЁҐ §­ зҐ­Ёп ­Ґ ®Ўа Ў влў овбп COM-¬ли ¬Ё. ЏаЁ ®зҐ­м Ў®«миЁе + §­ зҐ­Ёпе ­Ґў®§¬®¦­® ЇҐаҐ¤ўЁ¦Ґ­ЁҐ ¬лиЁ ­  1 ЇЁЄбҐ«м Ё Єгаб®а Ўг¤Ґв + ЇалЈ вм ­  ўҐ«ЁзЁ­г гбв ­®ў«Ґ­­®© бЄ®а®бвЁ (Ї®¤Ї®¤дг­ЄжЁп 1). + “бв ­ ў«Ёў Ґ¬ п ўҐ«ЁзЁ­  ­Ґ Їа®ўҐапҐвбп Є®¤®¬ п¤а . + ‚Ґ«ЁзЁ­г § ¤Ґа¦ЄЁ ¬®¦­® ¬Ґ­пвм ў ЇаЁ«®¦Ґ­ЁЁ SETUP. + * Џ®¤Ї®¤дг­ЄжЁп 4 ­Ґ Їа®ўҐапҐв ЇҐаҐ¤ ­­®Ґ §­ зҐ­ЁҐ. ЏҐаҐ¤ ўл§®ў®¬ + ­Ґ®Ўе®¤Ё¬® г§­ вм ⥪г饥 а §аҐиҐ­ЁҐ нЄа ­  (Ї®¤дг­ЄжЁҐ© 14) + Ё Їа®ўҐаЁвм, зв® гбв ­ ў«Ёў Ґ¬®Ґ Ї®«®¦Ґ­ЁҐ ­Ґ ўл室Ёв §  ЇаҐ¤Ґ«л + нЄа ­ . + +====================================================================== +==================== ”г­ЄжЁп 20 - Ё­вҐа䥩б MIDI. ==================== +====================================================================== + +------------------------ Џ®¤дг­ЄжЁп 1 - бЎа®б ------------------------ +Џ а ¬Ґвал: + * eax = 20 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + +-------------------- Џ®¤дг­ЄжЁп 2 - ўлўҐбвЁ Ў ©в --------------------- +Џ а ¬Ґвал: + * eax = 20 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl = Ў ©в ¤«п ўлў®¤  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ (®¤Ё­ Є®ў® ¤«п ®ЎҐЁе Ї®¤дг­ЄжЁ©): + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«с­ Ў §®ўл© Ї®ав +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм ®ЇаҐ¤Ґ«с­ Ў §®ўл© Ї®а⠢맮ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 21. + +====================================================================== +==== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм Ў §®ўл© Ї®ав MPU MIDI. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа Ў §®ў®Ј® Ї®ав  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎ®з­л© ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Ї®ав  ¤®«¦Ґ­ 㤮ў«Ґвў®апвм гб«®ўЁп¬ 0x100<=ecx<=0xFFFF. + * “бв ­®ўЄ  Ў §л ­г¦­  ¤«п а Ў®вл дг­ЄжЁЁ 20. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 26. + +====================================================================== +===== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм а бЄ« ¤Єг Є« ўЁ вгал. ==== +====================================================================== +ђ бЄ« ¤Є  Є« ўЁ вгал ЁбЇ®«м§гҐвбп ¤«п ЇаҐ®Ўа §®ў ­Ёп бЄ ­Є®¤®ў, +Ї®бвгЇ ойЁе ®в Є« ўЁ вгал, ў 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 ЇҐаҐЄ«оз Ґв а бЄ« ¤ЄЁ Ї® § Їа®бг Ї®«м§®ў вҐ«п. + +====================================================================== +=========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм Ў §г CD. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ў §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * Ѓ §  CD ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 24. + * Џ®«гзЁвм гбв ­®ў«Ґ­­го Ў §г CD ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 26. + +====================================================================== +== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 4 - гбв ­®ўЁвм Ў §®ўл© Ї®ав Sound Blaster. = +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа Ў §®ў®Ј® Ї®ав  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎ®з­л© ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Ї®ав  ¤®«¦Ґ­ 㤮ў«Ґвў®апвм гб«®ўЁп¬ 0x100<=ecx<=0xFFFF. + * “бв ­®ўЄ  Ў §л ­г¦­  ¤«п а Ў®вл дг­ЄжЁ© 25, 28, 55. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 26. + +====================================================================== +========= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 5 - гбв ­®ўЁвм п§лЄ бЁб⥬л. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = п§лЄ бЁб⥬л (1=eng, 2=fi, 3=ger, 4=rus) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * џ§лЄ бЁб⥬л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, ­ЁЄ Є + ­Ґ ЁбЇ®«м§гҐ¬ п б ¬Ё¬ п¤а®¬, ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel аЁбгҐв + ᮮ⢥вбвўгойго ЁЄ®­Єг. + * Џа®ўҐа®Є ­  Є®а४⭮бвм ­Ґ ¤Ґ« Ґвбп, Ї®бЄ®«мЄг п¤а® нвг + ЇҐаҐ¬Ґ­­го ­Ґ ЁбЇ®«м§гҐв. + * Џ®«гзЁвм п§лЄ бЁбвҐ¬л ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 5 дг­ЄжЁЁ 26. + +====================================================================== +======= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 6 - гбв ­®ўЁвм Ў §®ўл© Ї®ав WSS. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ў §®ўл© Ї®ав +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ®иЁЎ®з­л© ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Ї®ав  ¤®«¦Ґ­ 㤮ў«Ґвў®апвм гб«®ўЁо 0x100<=ecx. + * Ѓ §  WSS ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 27. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© Ў §®ўл© Ї®ав WSS ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 26. + +====================================================================== +=========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 7 - гбв ­®ўЁвм Ў §г HD. =========== +====================================================================== +Ѓ §  HD ­г¦­  ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© ¦сбвЄЁ© ¤ЁбЄ ЇЁб вм, ЇаЁ +ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиЁе дг­ЄжЁ© а Ў®вл б д ©«®ў®© бЁб⥬®© Ё дг­ЄжЁ©, +­Ґпў­® ЁбЇ®«м§гойЁе ¦сбвЄЁ© ¤ЁбЄ (вЁЇ  Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 18); +ЇаЁ ЁбЇ®«м§®ў ­ЁЁ дг­ЄжЁ© 58 Ё 70 Ё ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  +/HD0,/HD1,/HD2,/HD3 нвЁ дг­ЄжЁЁ б ¬Ё гбв ­ ў«Ёў ов Ў §г. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ў §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм Ў §г. + * ЌҐ б«Ґ¤гҐв Ё§¬Ґ­пвм Ў §г, Є®Ј¤  Є Є®Ґ-­ЁЎг¤м ЇаЁ«®¦Ґ­ЁҐ а Ў®в Ґв + б ¦сбвЄЁ¬ ¤ЁбЄ®¬. …б«Ё ­Ґ е®вЁвҐ Ј«оЄ®ў бЁб⥬л. + * Џ®«гзЁвм гбв ­®ў«Ґ­­го Ў §г ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7 дг­ЄжЁЁ 26. + * ‘«Ґ¤гҐв в Є¦Ґ ®ЇаҐ¤Ґ«Ёвм ЁбЇ®«м§гҐ¬л© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  + Ї®¤дг­ЄжЁҐ© 8. + +====================================================================== +========== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 8 - гбв ­®ўЁвм а §¤Ґ« HD. ========== +====================================================================== +ђ §¤Ґ« HD ­г¦Ґ­ ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  +ЇЁб вм, ЇаЁ ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиЁе дг­ЄжЁ© а Ў®вл б д ©«®ў®© +бЁб⥬®© Ё дг­ЄжЁ©, ­Ґпў­® ЁбЇ®«м§гойЁе ¦сбвЄЁ© ¤ЁбЄ (вЁЇ  +Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 18); ЇаЁ ЁбЇ®«м§®ў ­ЁЁ дг­ЄжЁ© 58 Ё 70 +Ё ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  /HD0,/HD1,/HD2,/HD3 нвЁ дг­ЄжЁЁ б ¬Ё +гбв ­ ў«Ёў ов Ў §г Ё а §¤Ґ«. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = а §¤Ґ« HD (бзЁв п б 1) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм а §¤Ґ«. + * ЌҐ б«Ґ¤гҐв Ё§¬Ґ­пвм а §¤Ґ«, Є®Ј¤  Є Є®Ґ-­ЁЎг¤м ЇаЁ«®¦Ґ­ЁҐ а Ў®в Ґв + б ¦сбвЄЁ¬ ¤ЁбЄ®¬. …б«Ё ­Ґ е®вЁвҐ Ј«оЄ®ў бЁб⥬л. + * Џ®«гзЁвм гбв ­®ў«Ґ­­л© а §¤Ґ« ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 8 + дг­ЄжЁЁ 26. + * Џа®ўҐа®Є ­  Є®а४⭮бвм ­Ґ ¤Ґ« Ґвбп. + * “§­ вм зЁб«® а §¤Ґ«®ў ­  ¦сбвЄ®¬ ¤ЁбЄҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 18. + * ‘«Ґ¤гҐв в Є¦Ґ ®ЇаҐ¤Ґ«Ёвм ЁбЇ®«м§гҐ¬го Ў §г ¦сбвЄ®Ј® ¤ЁбЄ  + Ї®¤дг­ЄжЁҐ© 7. + +====================================================================== +===== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 10 - гбв ­®ўЁвм Є ­ « DMA ¤«п §ўгЄ . ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа Є ­ «  (®в 0 ¤® 3 ўЄ«озЁвҐ«м­®) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = -1 - ­ҐўҐа­л© ­®¬Ґа Є ­ «  +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Є ­ «  DMA ЁбЇ®«м§гҐвбп ў + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 55. + * Џ®«гзЁвм Є ­ « DMA ¤«п §ўгЄ  ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 10 дг­ЄжЁЁ 26. + +====================================================================== +====================== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 11 ===================== +=========== ђ §аҐиЁвм/§ ЇаҐвЁвм ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є HD. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0/1 - § ЇаҐвЁвм/а §аҐиЁвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ LBA-з⥭ЁЁ (Ї®¤дг­ЄжЁп 8 дг­ЄжЁЁ 58). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * Џ®«гзЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 26. + +====================================================================== +====================== ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 12 ===================== +========== ђ §аҐиЁвм/§ ЇаҐвЁвм ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0/1 - § ЇаҐвЁвм/а §аҐиЁвм +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ а Ў®вҐ б иЁ­®© PCI (дг­ЄжЁп 62). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * Џ®«гзЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 12 дг­ЄжЁЁ 26. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 1 ============= +==== €­ЁжЁ «Ё§Ёа®ў вм + Ї®«гзЁвм Ё­д®а¬ жЁо ® ¤а ©ўҐаҐ vmode.mdr. ==== +====================================================================== +Џ а ¬Ґвал: + * 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, ­ЁзҐЈ® ­Ґ ¤Ґ« п). + * ‚ ⥪г饩 ॠ«Ё§ жЁЁ Ї®¤¤Ґа¦Ёў Ґвбп в®«мЄ® ®¤­  з бв®в  а §ўсавЄЁ + ­  ўЁ¤Ґ®аҐ¦Ё¬. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 2 ============= +============= Џ®«гзЁвм Ё­д®а¬ жЁо ® ⥪г饬 ўЁ¤Ґ®аҐ¦Ё¬Ґ. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 2 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­; + ebx,ecx а §аги овбп + * eax = [иЁаЁ­ ]*65536 + [ўлб®в ] + * ebx = з бв®в  ўҐавЁЄ «м­®© а §ўсавЄЁ (ў ѓж) + * ecx = ­®¬Ґа ⥪г饣® ўЁ¤Ґ®аҐ¦Ё¬  +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * …б«Ё ­г¦­л в®«мЄ® а §¬Ґал нЄа ­ , 楫Ґб®®Ўа §­Ґ© ЁбЇ®«м§®ў вм + дг­ЄжЁо 14 б гзс⮬ в®Ј®, зв® ®­  ў®§ўа й Ґв а §¬Ґал ­  1 ¬Ґ­миҐ. + +====================================================================== += ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм ўЁ¤Ґ®аҐ¦Ё¬. +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 3 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  + * edx = [з бв®в  а §ўсавЄЁ]*65536 + [­®¬Ґа ўЁ¤Ґ®аҐ¦Ё¬ ] +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­, ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ Ё«Ё + Їа®Ё§®и«  ®иЁЎЄ  + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * Ќ®¬Ґа ўЁ¤Ґ®аҐ¦Ё¬  Ё з бв®в  ¤®«¦­л Ўлвм ў в Ў«ЁжҐ, ў®§ўа й Ґ¬®© + дг­ЄжЁҐ© ¤а ©ўҐа  1. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 4 ============= +================= ‚Ґа­гвмбп Є ­ з «м­®¬г ўЁ¤Ґ®аҐ¦Ё¬г. ================ +====================================================================== +‚®§ўа й Ґв нЄа ­ ў ўЁ¤Ґ®аҐ¦Ё¬, гбв ­®ў«Ґ­­л© ЇаЁ § Јаг§ЄҐ бЁб⥬л. +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 4 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + +====================================================================== +============= ”г­ЄжЁп 21, Ї®¤дг­ЄжЁп 13, Ї®¤Ї®¤дг­ЄжЁп 5 ============= +======== “ўҐ«ЁзЁвм/㬥­миЁвм а §¬Ґа ўЁ¤Ё¬®© ®Ў« бвЁ ¬®­Ёв®а . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 21 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 5 - ­®¬Ґа дг­ЄжЁЁ ¤а ©ўҐа  + * edx = 0/1 - 㬥­миЁвм/㢥«ЁзЁвм а §¬Ґа Ї® Ј®аЁ§®­в «Ё + ­  ®¤­г Ї®§ЁжЁо + * edx = 2/3 - ў ⥪г饩 ॠ«Ё§ жЁЁ ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп; Ї« ­ЁагҐвбп + Є Є 㬥­м襭ЁҐ/㢥«ЁзҐ­ЁҐ а §¬Ґа  Ї® ўҐавЁЄ «Ё ­  ®¤­г Ї®§ЁжЁо +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤а ©ўҐа ­Ґ § Ја㦥­ Ё«Ё ­Ґ Ё­ЁжЁ «Ё§Ёа®ў ­ + * eax = 0 - гбЇҐи­® + * ebx, ecx а §аги овбп +‡ ¬Ґз ­Ёп: + * „а ©ўҐа ЇаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм Ё­ЁжЁ «Ё§Ёа®ў ­ ўл§®ў®¬ + дг­ЄжЁЁ ¤а ©ўҐа  1. + * ”г­ЄжЁп ў«ЁпҐв в®«мЄ® ­  дЁ§ЁзҐбЄЁ© а §¬Ґа Ё§®Ўа ¦Ґ­Ёп + ­  ¬®­Ёв®аҐ; «®ЈЁзҐбЄЁ© а §¬Ґа (зЁб«® ЇЁЄбҐ«Ґ©) ­Ґ ¬Ґ­пҐвбп. + +====================================================================== +============ ”г­ЄжЁп 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 - гбв ­®ўЁвм Ўг¤Ё«м­ЁЄ + * ecx = 0x00SSMMHH +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї а ¬Ґва § ¤ ­ ­ҐўҐа­® + * eax = 2 - CMOS-Ў в аҐ©ЄЁ а §ап¤Ё«Ёбм +‡ ¬Ґз ­Ёп: + * –Ґ­­®бвм гбв ­®ўЄЁ ¤­п ­Ґ¤Ґ«Ё ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©, + Ї®бЄ®«мЄг ®­ ¬ «® Ј¤Ґ ЁбЇ®«м§гҐвбп + (¤Ґ­м ­Ґ¤Ґ«Ё ¬®¦­® а ббзЁв вм Ї® ¤ вҐ). + * Ѓг¤Ё«м­ЁЄ ¬®¦­® гбв ­®ўЁвм ­  ба Ў влў ­ЁҐ ў § ¤ ­­®Ґ ўаҐ¬п + Є ¦¤лҐ бгвЄЁ. ЏаЁ н⮬ ®вЄ«озЁвм ҐЈ® бгйҐбвўгойЁ¬Ё бЁб⥬­л¬Ё + дг­ЄжЁп¬Ё ­Ґ«м§п. + * ‘а Ў влў ­ЁҐ Ўг¤Ё«м­ЁЄ  § Є«оз Ґвбп ў ЈҐ­Ґа жЁЁ IRQ8. + * ‚®®ЎйҐ-в® CMOS Ї®¤¤Ґа¦Ёў Ґв ¤«п Ўг¤Ё«м­ЁЄ  гбв ­®ўЄг §­ зҐ­Ёп + 0xFF ў Є зҐб⢥ ®¤­®Ј® Ё§ Ї а ¬Ґва®ў Ё ®§­ з Ґв нв®, зв® + ᮮ⢥вбвўгойЁ© Ї а ¬Ґва ЁЈ­®аЁагҐвбп. Ќ® ў ⥪г饩 ॠ«Ё§ жЁЁ + нв® ­Ґ Їа®©¤св (ўҐа­свбп §­ зҐ­ЁҐ 1). + * Ѓг¤Ё«м­ЁЄ - Ј«®Ў «м­л© бЁб⥬­л© аҐбгаб; гбв ­®ўЄ  Ўг¤Ё«м­ЁЄ  +  ўв®¬ вЁзҐбЄЁ ®в¬Ґ­пҐв ЇаҐ¤л¤гйго гбв ­®ўЄг. ‚Їа®зҐ¬, ­  ¤ ­­л© + ¬®¬Ґ­в ­Ё ®¤­  Їа®Ја ¬¬  ҐЈ® ­Ґ ЁбЇ®«м§гҐв. + +====================================================================== +============== ”г­ЄжЁп 23 - ®¦Ё¤ вм б®ЎлвЁп б в ©¬ г⮬. ============= +====================================================================== +…б«Ё ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв , ¦¤св Ї®пў«Ґ­Ёп б®®ЎйҐ­Ёп ў ®зҐаҐ¤Ё, +­® ­Ґ Ў®«ҐҐ гЄ § ­­®Ј® ўаҐ¬Ґ­Ё. ‡ вҐ¬ бзЁвлў Ґв б®®ЎйҐ­ЁҐ Ё§ ®зҐаҐ¤Ё. + +Џ а ¬Ґвал: + * eax = 23 - ­®¬Ґа дг­ЄжЁЁ + * ebx = в ©¬ гв (ў б®вле ¤®«пе ᥪ㭤л) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - ®зҐаҐ¤м б®®ЎйҐ­Ё© Їгбв  + * Ё­ зҐ eax = б®ЎлвЁҐ (ᬮваЁ бЇЁб®Є б®ЎлвЁ©) +‡ ¬Ґз ­Ёп: + * “зЁвлў овбп в®«мЄ® ⥠ᮡлвЁп, Є®в®алҐ ўе®¤пв ў ¬ бЄг, + гбв ­ ў«Ёў Ґ¬го дг­ЄжЁҐ© 40. Џ® 㬮«з ­Ёо нв® б®ЎлвЁп + ЇҐаҐаЁб®ўЄЁ, ­ ¦ вЁп ­  Є« ўЁиЁ Ё ­  Є­®ЇЄЁ. + * „«п Їа®ўҐаЄЁ, Ґбвм «Ё б®®ЎйҐ­ЁҐ ў ®зҐаҐ¤Ё, ЁбЇ®«м§г©вҐ дг­ЄжЁо 11. + —в®Ўл ¦¤ вм бЄ®«м гЈ®¤­® ¤®«Ј®, ЁбЇ®«м§г©вҐ дг­ЄжЁо 10. + * ЏҐаҐ¤ з  ebx=0 ЇаЁў®¤Ёв Є ¬®¬Ґ­в «м­®¬г ў®§ўа йҐ­Ёо eax=0. + * ЏаЁ ⥪г饩 ॠ«Ё§ жЁЁ Їа®Ё§®©¤св ­Ґ¬Ґ¤«Ґ­­л© ў®§ўа в Ё§ дг­ЄжЁЁ + б eax=0, Ґб«Ё б«®¦Ґ­ЁҐ ebx б ⥪гйЁ¬ §­ зҐ­ЁҐ¬ бзсвзЁЄ  ўаҐ¬Ґ­Ё + ўл§®ўҐв 32-ЎЁв­®Ґ ЇҐаҐЇ®«­Ґ­ЁҐ. + +====================================================================== +======= ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 1 - ­ з вм Їа®ЁЈалў вм CD-audio. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0x00FRSSMM, Ј¤Ґ + * MM = ­ з «м­ п ¬Ё­гв  + * SS = ­ з «м­ п ᥪ㭤  + * FR = ­ з «м­л© д३¬ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  CD +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав CD ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + * ‚ ᥪ㭤Ґ 75 д३¬®ў, ў ¬Ё­г⥠60 ᥪ㭤. + * ”г­ЄжЁп  бЁ­еа®­­  (ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, Є®Ј¤  ­ з «®бм + Їа®ЁЈалў ­ЁҐ). + +====================================================================== +===== ”г­ЄжЁп 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 + ЇҐаўле ¤®а®¦Є е. ‚ Ў®«миЁ­б⢥ б«гз Ґў нв®Ј® ¤®бв в®з­®. + +====================================================================== +==== ”г­ЄжЁп 24, Ї®¤дг­ЄжЁп 3 - ®бв ­®ўЁвм Їа®ЁЈалў Ґ¬®Ґ CD-audio. === +====================================================================== +Џ а ¬Ґвал: + * eax = 24 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  CD +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав CD ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + +====================================================================== +============== ”г­ЄжЁп 25 - гбв ­®ўЁвм Ја®¬Є®бвм SBPro. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 25 - ­®¬Ґа дг­ЄжЁЁ + * ebx = зв® гбв ­ ў«Ёў вм: + * 1 - гбв ­®ўЁвм ®Ўйго Ја®¬Є®бвм + * 2 - гбв ­®ўЁвм Ја®¬Є®бвм CD-audio + * cl = га®ўҐ­м Ја®¬Є®бвЁ: бв аиЁҐ 4 ЎЁв  ¤«п «Ґў®© Є®«®­ЄЁ, + ¬« ¤иЁҐ 4 - ¤«п Їа ў®© +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  SB + * eax = 2 - ­ҐўҐа­ п Ї®¤дг­ЄжЁп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав SB ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 21. + * ‘¬®ваЁ в Є¦Ґ дг­ЄжЁо 28 + гбв ­®ўЄЁ §ўгЄ  ¤«п Ў®«ҐҐ Ї®§¤­ҐЈ® бв ­¤ ав  SB16. + +====================================================================== +===== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм Ў §®ўл© Ї®ав MPU MIDI. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа Ї®ав  +‡ ¬Ґз ­Ёп: + * “бв ­®ўЁвм Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 21. + +====================================================================== +====== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 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 ЇҐаҐЄ«оз Ґв а бЄ« ¤ЄЁ Ї® § Їа®бг Ї®«м§®ў вҐ«п. + +====================================================================== +============ ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 3 - Ї®«гзЁвм Ў §г CD. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ў §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‡ ¬Ґз ­Ёп: + * Ѓ §  CD ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 24. + * “бв ­®ўЁвм Ў §г CD ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 3 дг­ЄжЁЁ 21. + +====================================================================== +=== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм Ў §®ўл© Ї®ав Sound Blaster. == +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа Ў §®ў®Ј® Ї®ав  +‡ ¬Ґз ­Ёп: + * “бв ­®ўЄ  Ў §л ­г¦­  ¤«п а Ў®вл дг­ЄжЁ© 25, 55. + * “бв ­®ўЁвм Ў §®ўл© Ї®ав ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 21. + +====================================================================== +========== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 5 - Ї®«гзЁвм п§лЄ бЁб⥬л. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = п§лЄ бЁб⥬л (1=eng, 2=fi, 3=ger, 4=rus) +‡ ¬Ґз ­Ёп: + * џ§лЄ бЁб⥬л - Ј«®Ў «м­ п бЁб⥬­ п ЇҐаҐ¬Ґ­­ п, ­ЁЄ Є + ­Ґ ЁбЇ®«м§гҐ¬ п б ¬Ё¬ п¤а®¬, ®¤­ Є® ЇаЁ«®¦Ґ­ЁҐ @panel аЁбгҐв + ᮮ⢥вбвўгойго ЁЄ®­Єг (ЁбЇ®«м§гп ®ЇЁблў Ґ¬го дг­ЄжЁо). + * “бв ­®ўЁвм п§лЄ бЁбвҐ¬л ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 5 дг­ЄжЁЁ 21. + +====================================================================== +======== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 6 - Ї®«гзЁвм Ў §®ўл© Ї®ав WSS. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ў §®ўл© Ї®ав +‡ ¬Ґз ­Ёп: + * Ѓ §  WSS ЁбЇ®«м§гҐвбп дг­ЄжЁҐ© 27. + * “бв ­®ўЁвм Ў §®ўл© Ї®ав WSS ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 21. + +====================================================================== +============ ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 7 - Ї®«гзЁвм Ў §г HD. ============ +====================================================================== +Ѓ §  HD ­г¦­  ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© ¦сбвЄЁ© ¤ЁбЄ ЇЁб вм, ЇаЁ +ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиЁе дг­ЄжЁ© а Ў®вл б д ©«®ў®© бЁб⥬®© Ё дг­ЄжЁ©, +­Ґпў­® ЁбЇ®«м§гойЁе ¦сбвЄЁ© ¤ЁбЄ (вЁЇ  Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 18); +ЇаЁ ЁбЇ®«м§®ў ­ЁЁ дг­ЄжЁ© 58 Ё 70 Ё ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  +/HD0,/HD1,/HD2,/HD3 нвЁ дг­ЄжЁЁ б ¬Ё гбв ­ ў«Ёў ов Ў §г. +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = Ў §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм Ў §г. + * “бв ­®ўЁвм Ў §г ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 7 дг­ЄжЁЁ 21. + * Џ®«гзЁвм ЁбЇ®«м§гҐ¬л© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  ¬®¦­® Ї®¤дг­ЄжЁҐ© 8. + +====================================================================== +=========== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 8 - Ї®«гзЁвм а §¤Ґ« HD. =========== +====================================================================== +ђ §¤Ґ« HD ­г¦Ґ­ ¤«п ®ЇаҐ¤Ґ«Ґ­Ёп, ­  Є Є®© а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  +ЇЁб вм, ЇаЁ ЁбЇ®«м§®ў ­ЁЁ гбв аҐўиЁе дг­ЄжЁ© а Ў®вл б д ©«®ў®© +бЁб⥬®© Ё дг­ЄжЁ©, ­Ґпў­® ЁбЇ®«м§гойЁе ¦сбвЄЁ© ¤ЁбЄ (вЁЇ  +Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 18); ЇаЁ ЁбЇ®«м§®ў ­ЁЁ дг­ЄжЁ© 58 Ё 70 Ё +ᮢ६Ґ­­®Ј® бЁ­в ЄбЁб  /HD0,/HD1,/HD2,/HD3 нвЁ дг­ЄжЁЁ б ¬Ё +гбв ­ ў«Ёў ов Ў §г Ё а §¤Ґ«. +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = а §¤Ґ« HD (бзЁв п б 1) +‡ ¬Ґз ­Ёп: + * ‹оЎ®Ґ ЇаЁ«®¦Ґ­ЁҐ ў «оЎ®© ¬®¬Ґ­в ўаҐ¬Ґ­Ё ¬®¦Ґв Ё§¬Ґ­Ёвм а §¤Ґ«. + * “бв ­®ўЁвм а §¤Ґ« ¬®¦­® ўл§®ў®¬ Ї®¤дг­ЄжЁЁ 8 дг­ЄжЁЁ 21. + * “§­ вм зЁб«® а §¤Ґ«®ў ­  ¦сбвЄ®¬ ¤ЁбЄҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 18. + * Џ®«гзЁвм ЁбЇ®«м§гҐ¬го Ў §г ¦сбвЄ®Ј® ¤ЁбЄ  ¬®¦­® Ї®¤дг­ЄжЁҐ© 7. + +====================================================================== +=== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 9 - Ї®«гзЁвм §­ зҐ­ЁҐ бзсвзЁЄ  ўаҐ¬Ґ­Ё. === +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® б®вле ¤®«Ґ© ᥪ㭤л, Їа®иҐ¤иЁе б ¬®¬Ґ­в  + § ЇгбЄ  бЁб⥬л +‡ ¬Ґз ­Ёп: + * ‘зсвзЁЄ ЎҐасвбп Ї® ¬®¤г«о 2^32, з⮠ᮮ⢥вбвўгҐв ­Ґ¬­®ЈЁ¬ Ў®«ҐҐ + 497 бгв®Є. + * ‘Ёб⥬­®Ґ ўаҐ¬п ¬®¦­® Ї®«гзЁвм дг­ЄжЁҐ© 3. + +====================================================================== +====== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 10 - Ї®«гзЁвм Є ­ « DMA ¤«п §ўгЄ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ­®¬Ґа Є ­ «  (®в 0 ¤® 3 ўЄ«озЁвҐ«м­®) +‡ ¬Ґз ­Ёп: + * Ќ®¬Ґа Є ­ «  DMA ЁбЇ®«м§гҐвбп ў Ї®¤дг­ЄжЁЁ 1 дг­ЄжЁЁ 55. + * “бв ­®ўЁвм Є ­ « DMA ¤«п §ўгЄ  ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 10 дг­ЄжЁЁ 21. + +====================================================================== +====================== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 11 ===================== +=========== “§­ вм, а §аҐис­ «Ё ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є HD. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0/1 - § ЇаҐйс­/а §аҐис­ +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ LBA-з⥭ЁЁ (Ї®¤дг­ЄжЁп 8 дг­ЄжЁЁ 58). + * “бв ­®ўЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 11 дг­ЄжЁЁ 21. + +====================================================================== +====================== ”г­ЄжЁп 26, Ї®¤дг­ЄжЁп 12 ===================== +========== “§­ вм, а §аҐис­ «Ё ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 26 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0/1 - § ЇаҐйс­/а §аҐис­ +‡ ¬Ґз ­Ёп: + * €бЇ®«м§гҐвбп ЇаЁ а Ў®вҐ б иЁ­®© PCI (дг­ЄжЁп 62). + * ’ҐЄгй п ॠ«Ё§ жЁп ЁбЇ®«м§гҐв в®«мЄ® ¬« ¤иЁ© ЎЁв ecx. + * “бв ­®ўЁвм ⥪г饥 б®бв®п­ЁҐ ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 12 дг­ЄжЁЁ 21. + +====================================================================== +==== ”г­ЄжЁп 27 - гбв ­®ўЁвм Ја®¬Є®бвм Windows Sound System (WSS). === +====================================================================== +Џ а ¬Ґвал: + * eax = 27 - ­®¬Ґа дг­ЄжЁЁ + * ebx = зв® гбв ­ ў«Ёў вм: + * 1 - гбв ­®ўЁвм ®Ўйго Ја®¬Є®бвм + * 2 - гбв ­®ўЁвм Ја®¬Є®бвм Line In + * cl = га®ўҐ­м Ја®¬Є®бвЁ (0x0=б ¬л© ўлб®ЄЁ©, 0x1F=б ¬л© ­Ё§ЄЁ©, + гбв ­®ў«Ґ­­л© ЎЁв 0x80=®вЄ«озЁвм) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  WSS + * eax = 2 - ­ҐўҐа­ п Ї®¤дг­ЄжЁп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав WSS ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 6 дг­ЄжЁЁ 21. + * “бв ­®ўЄ  ®ЎйҐ© Ја®¬Є®бвЁ д ЄвЁзҐбЄЁ ЁЈ­®аЁагҐвбп + (ў®§ўа й Ґвбп eax=0). + * ‚ бв а®© ¤®Єг¬Ґ­в жЁЁ Ё ў Ёб室­ЁЄ е п¤а  Ї®¤дг­ЄжЁп 2 + ®иЁЎ®з­® ­ §ў ­  Ја®¬Є®бвмо CD-audio. + +====================================================================== +=============== ”г­ЄжЁп 28 - гбв ­®ўЁвм Ја®¬Є®бвм SB16. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 28 - ­®¬Ґа дг­ЄжЁЁ + * ebx = зв® гбв ­ ў«Ёў вм: + * 1 - гбв ­®ўЁвм ®Ўйго Ја®¬Є®бвм + * 2 - гбв ­®ўЁвм Ја®¬Є®бвм CD-audio + * cl = га®ўҐ­м Ја®¬Є®бвЁ (0=off, 0xFF=max) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  SB + * eax = 2 - ­ҐўҐа­ п Ї®¤дг­ЄжЁп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ­г¦­® ®ЇаҐ¤Ґ«Ёвм Ў §®ўл© Ї®ав SB ўл§®ў®¬ + Ї®¤дг­ЄжЁЁ 4 дг­ЄжЁЁ 21. + * ќв  дг­ЄжЁп ЇаҐ¤®бв ў«пҐв Ў®«миҐ ў аЁ ­в®ў ¤«п Ја®¬Є®бвЁ, + 祬 дг­ЄжЁп 25. + +====================================================================== +================ ”г­ЄжЁп 29 - Ї®«гзЁвм бЁб⥬­го ¤ вг. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 29 - ­®¬Ґа дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00DDMMYY, Ј¤Ґ + (ЁбЇ®«м§гҐвбп ¤ў®Ёз­®-¤ҐбпвЁз­®Ґ Є®¤Ёа®ў ­ЁҐ, BCD) + * YY = ¤ўҐ ¬« ¤иЁҐ жЁдал Ј®¤  (00..99) + * MM = ¬Ґбпж (01..12) + * DD = ¤Ґ­м (01..31) +‡ ¬Ґз ­Ёп: + * ‘Ёб⥬­го ¤ вг ¬®¦­® гбв ­®ўЁвм дг­ЄжЁҐ© 22. + +====================================================================== +================ ”г­ЄжЁп 32 - г¤ «Ёвм д ©« б а ¬¤ЁбЄ . =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 32 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®; Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« ; дг­ЄжЁп 58 Ї®§ў®«пҐв ўлЇ®«­пвм + ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * ’ҐЄгй п ॠ«Ё§ жЁп ў®§ўа й Ґв в®«мЄ® §­ зҐ­Ёп 0(гбЇҐе) Ё + 5(д ©« ­Ґ ­ ©¤Ґ­). + * €¬п д ©«  ¤®«¦­® Ўлвм «ЁЎ® ў д®а¬ вҐ 8+3 бЁ¬ў®«®ў (ЇҐаўлҐ + 8 бЁ¬ў®«®ў - б®Ўб⢥­­® Ё¬п, Ї®б«Ґ¤­ЁҐ 3 - а биЁаҐ­ЁҐ, + Є®а®вЄЁҐ Ё¬Ґ­  Ё а биЁаҐ­Ёп ¤®Ї®«­повбп Їа®ЎҐ« ¬Ё), + «ЁЎ® ў д®а¬ вҐ 8.3 бЁ¬ў®«®ў "FILE.EXT"/"FILE.EX " + (Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ 3 бЁ¬ў®« , + ¤®Ї®«­Ґ­­®Ґ ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ Їа®ЎҐ« ¬Ё). + €¬п д ©«  ¤®«¦­® Ўлвм § ЇЁб ­® § Ј« ў­л¬Ё ЎгЄў ¬Ё. + ‡ ўҐаи ойЁ© бЁ¬ў®« б Є®¤®¬ 0 ­Ґ ­г¦Ґ­ (­Ґ ASCIIZ-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї Ї®Є ­  а ¬¤ЁбЄҐ. + +====================================================================== +=============== ”г­ЄжЁп 33 - § ЇЁб вм д ©« ­  а ¬¤ЁбЄ. =============== +====================================================================== +Џ а ¬Ґвал: + * eax = 33 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * б«Ґ¤гҐв гбв ­ ў«Ёў вм esi=0 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« ; дг­ЄжЁп 70 Ї®§ў®«пҐв ўлЇ®«­пвм + ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * …б«Ё гЄ § вм ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ ў esi Ё ­  а ¬¤ЁбЄҐ 㦥 Ґбвм + гЄ § ­­л© д ©«, в® Ўг¤Ґв ᮧ¤ ­ Ґйс ®¤Ё­ д ©« б ⥬ ¦Ґ Ё¬Ґ­Ґ¬. + * ‚ Їа®вЁў­®¬ б«гз Ґ д ©« ЇҐаҐ§ ЇЁблў Ґвбп. + * €¬п д ©«  ¤®«¦­® Ўлвм «ЁЎ® ў д®а¬ вҐ 8+3 бЁ¬ў®«®ў + (ЇҐаўлҐ 8 бЁ¬ў®«®ў - б®Ўб⢥­­® Ё¬п, Ї®б«Ґ¤­ЁҐ 3 - а биЁаҐ­ЁҐ, + Є®а®вЄЁҐ Ё¬Ґ­  Ё а биЁаҐ­Ёп ¤®Ї®«­повбп Їа®ЎҐ« ¬Ё), + «ЁЎ® ў д®а¬ вҐ 8.3 бЁ¬ў®«®ў "FILE.EXT"/"FILE.EX " + (Ё¬п ­Ґ Ў®«ҐҐ 8 бЁ¬ў®«®ў, в®зЄ , а биЁаҐ­ЁҐ 3 бЁ¬ў®« , + ¤®Ї®«­Ґ­­®Ґ ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ Їа®ЎҐ« ¬Ё). + €¬п д ©«  ¤®«¦­® Ўлвм § ЇЁб ­® § Ј« ў­л¬Ё ЎгЄў ¬Ё. + ‡ ўҐаи ойЁ© бЁ¬ў®« б Є®¤®¬ 0 ­Ґ ­г¦Ґ­ (­Ґ ASCIIZ-бва®Є ). + * ќв  дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв Ї Ї®Є ­  а ¬¤ЁбЄҐ. + +====================================================================== +============ ”г­ЄжЁп 35 - Їа®зЁв вм 梥в в®зЄЁ ­  нЄа ­Ґ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 35 + * ebx = y*xsize+x, Ј¤Ґ + * (x,y) = Є®®а¤Ё­ вл в®зЄЁ (бзЁв п ®в 0) + * xsize = а §¬Ґа нЄа ­  Ї® Ј®аЁ§®­в «Ё +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 梥в 0x00RRGGBB +‡ ¬Ґз ­Ёп: + * “§­ вм а §¬Ґал нЄа ­  ¬®¦­® ўл§®ў®¬ дг­ЄжЁЁ 14. ЋЎа вЁвҐ ў­Ё¬ ­ЁҐ, + зв® ®­  ўлзЁв Ґв 1 Ё§ ®Ў®Ёе а §¬Ґа®ў. + * Љ ўЁ¤Ґ®Ї ¬пвЁ Ґбвм в Є¦Ґ Їаאַ© ¤®бвгЇ (ЎҐ§ ўл§®ў®ў бЁб⥬­ле + дг­ЄжЁ©) зҐаҐ§ ᥫҐЄв®а gs. Џ а ¬Ґвал ⥪г饣® ўЁ¤Ґ®аҐ¦Ё¬  + ¬®¦­® Ї®«гзЁвм дг­ЄжЁҐ© 61. + +====================================================================== +========== ”г­ЄжЁп 37 - Ї®«гзЁвм Є®®а¤Ё­ вл/б®бв®п­ЁҐ ¬лиЁ. ========== +====================================================================== + +-------------- Џ®¤дг­ЄжЁп 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. + +----------------- Џ®¤дг­ЄжЁп 2 - ­ ¦ влҐ Є­®ЇЄЁ ¬лиЁ ----------------- +Џ а ¬Ґвал: + * eax = 37 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax ᮤҐа¦Ёв Ё­д®а¬ жЁо ® ­ ¦ вле Є­®ЇЄ е ¬лиЁ: + * ЎЁв 0 гбв ­®ў«Ґ­ = «Ґў п Є­®ЇЄ  ­ ¦ в  + * ЎЁв 1 гбв ­®ў«Ґ­ = Їа ў п Є­®ЇЄ  ­ ¦ в  + * Їа®зЁҐ ЎЁвл бЎа®иҐ­л + +====================================================================== +================== ”г­ЄжЁп 38 - ­ аЁб®ў вм ®в१®Є. ================== +====================================================================== +Џ а ¬Ґвал: + * eax = 38 - ­®¬Ґа дг­ЄжЁЁ + * ebx = [Є®®а¤Ё­ в  ­ з «  Ї® ®бЁ x]*65536 + + [Є®®а¤Ё­ в  Є®­ж  Ї® ®бЁ x] + * ecx = [Є®®а¤Ё­ в  ­ з «  Ї® ®бЁ y]*65536 + + [Є®®а¤Ё­ в  Є®­ж  Ї® ®бЁ y] + * edx = 0x00RRGGBB - 梥в + edx = 0x01xxxxxx - аЁб®ў вм Ё­ўҐаб­л© ®в१®Є + (¬« ¤иЁҐ 24 ЎЁв  ЁЈ­®аЁаговбп) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Љ®®а¤Ё­ вл ЎҐагвбп ®в­®бЁвҐ«м­® ®Є­ . + * Љ®­Ґз­ п в®зЄ  в Є¦Ґ аЁбгҐвбп. + +====================================================================== +== ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм а §¬Ґа д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. == +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [иЁаЁ­ ]*65536 + [ўлб®в ] +‡ ¬Ґз ­Ёп: + * …бвм Ї а­ п Є®¬ ­¤  гбв ­®ўЄЁ а §¬Ґа®ў д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп - + Ї®¤дг­ЄжЁп 1 дг­ЄжЁЁ 15. Џ®б«Ґ Є®в®а®©, ࠧ㬥Ґвбп, б«Ґ¤гҐв + § ­®ў® ®ЇаҐ¤Ґ«Ёвм б ¬® Ё§®Ўа ¦Ґ­ЁҐ. + +====================================================================== += ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 2 - Їа®зЁв вм в®зЄг б д®­®ў®Ј® Ё§®Ўа ¦Ґ­Ёп. = +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ᬥ饭ЁҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0x00RRGGBB - 梥в в®зЄЁ, Ґб«Ё ᬥ饭ЁҐ ¤®ЇгбвЁ¬® + (¬Ґ­миҐ 0x160000-16) + * eax = 2 - Ё­ зҐ +‡ ¬Ґз ­Ёп: + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ ў б«гз Ґ ­ҐўҐа­®Ј® + ᬥ饭Ёп, ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў б«Ґ¤гойЁе ўҐабЁпе п¤а . + * ‘¬ҐйҐ­ЁҐ в®зЄЁ б Є®®а¤Ё­ в ¬Ё (x,y) ўлзЁб«пҐвбп Є Є (x+y*xsize)*3. + * …бвм Ї а­ п дг­ЄжЁп гбв ­®ўЄЁ в®зЄЁ ­  д®­®ў®¬ Ё§®Ўа ¦Ґ­ЁЁ - + Ї®¤дг­ЄжЁп 2 дг­ЄжЁЁ 15. + +====================================================================== +====== ”г­ЄжЁп 39, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм ०Ё¬ ®ваЁб®ўЄЁ д®­ . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 39 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 1 - § ¬®бвЁвм + * eax = 2 - а бвп­гвм +‡ ¬Ґз ­Ёп: + * …бвм Ї а­ п дг­ЄжЁп гбв ­®ўЄЁ ०Ё¬  ®ваЁб®ўЄЁ д®­  - + Ї®¤дг­ЄжЁп 4 дг­ЄжЁЁ 15. + +====================================================================== +======== ”г­ЄжЁп 40 - гбв ­®ўЁвм ¬ бЄг ¤«п ®¦Ё¤ Ґ¬ле б®ЎлвЁ©. ======== +====================================================================== +Њ бЄ  ¤«п ®¦Ё¤ Ґ¬ле б®ЎлвЁ© ў«ЁпҐв ­  дг­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё 10, +11, 23 - ®­Ё б®®Ўй ов в®«мЄ® ® б®ЎлвЁпе, а §аҐис­­ле нв®© ¬ бЄ®©. +Џ а ¬Ґвал: + * eax = 40 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ¬ бЄ : ЎЁв i ᮮ⢥вбвўгҐв б®ЎлвЁо i+1 (б¬. бЇЁб®Є б®ЎлвЁ©) + (гбв ­®ў«Ґ­­л© ЎЁв а §аҐи Ґв Ё§ўҐйҐ­ЁҐ ® б®ЎлвЁЁ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Њ бЄ  Ї® 㬮«з ­Ёо (7=111b) а §аҐи Ґв Ё§ўҐйҐ­Ёп ® ЇҐаҐаЁб®ўЄҐ + Ё ­ ¦ вЁпе Є« ўЁи Ё Є­®Ї®Є. + ќв®Ј® ¤®бв в®з­® ¤«п Ў®«миЁ­бвў  ЇаЁ«®¦Ґ­Ё©. + * ‘®ЎлвЁп, § ЇаҐйс­­лҐ ў ¬ бЄҐ, ўбс а ў­® б®еа ­повбп, Ґб«Ё + ЇаЁе®¤пв; ® ­Ёе Їа®бв® ­Ґ Ё§ўҐй ов дг­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё. + * ”г­ЄжЁЁ а Ў®вл б б®ЎлвЁп¬Ё гзЁвлў ов ¬ бЄг ­  ¬®¬Ґ­в + ўл§®ў  дг­ЄжЁЁ,   ­Ґ ­  ¬®¬Ґ­в Ї®бвгЇ«Ґ­Ёп б®®ЎйҐ­Ёп. + +====================================================================== +================= ”г­ЄжЁп 41 - г§­ вм ў« ¤Ґ«мж  IRQ. ================= +====================================================================== +Џ а ¬Ґвал: + * eax = 41 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = PID ў« ¤Ґ«мж  + * eax = 0, Ґб«Ё ў« ¤Ґ«мж  ­Ґв + * eax = -1 ¤«п ­ҐЄ®а४⭮Ј® ebx + +====================================================================== +========== ”г­ЄжЁп 42 - Їа®зЁв вм ¤ ­­лҐ, Ї®«г祭­лҐ Ї® IRQ. ========= +====================================================================== +ЏаЁ ў®§­ЁЄ­®ўҐ­ЁЁ IRQ бЁб⥬  ¬®¦Ґв бзЁвлў вм ¤ ­­лҐ Ё§ гЄ § ­­ле +а ­ҐҐ дг­ЄжЁҐ© 44 Ї®ав®ў Ё § ЇЁблў вм нвЁ ¤ ­­лҐ ў ЎгдҐа. +ЋЇЁблў Ґ¬ п дг­ЄжЁп бзЁвлў Ґв Ї®Ў ©в­® ¤ ­­лҐ Ё§ нв®Ј® ЎгдҐа . +Џ а ¬Ґвал: + * eax = 42 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: (бЁвг жЁо ¬®¦­® а §«ЁзЁвм Ї® §­ зҐ­Ёо ecx) + * Ґб«Ё Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 IRQ + (Ё«Ё ­®¬Ґа IRQ § ¤ ­ ­ҐўҐа­®): + * ecx = 2 + * Ґб«Ё ¤ ­­ле ­Ґв: + * eax = 0 + * ecx = 1 + * ebx а §аги Ґвбп + * Ґб«Ё ўбс ў Ї®ап¤ЄҐ Ё ¤ ­­лҐ Ўл«Ё: + * eax = а §¬Ґа ¤ ­­ле, Ґйс ­Ґ Їа®зЁв ­­ле Ё§ ЎгдҐа  (ў Ў ©в е) + * ecx = 0 + * ebx = ®зҐаҐ¤­®© Ў ©в +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® Ї®в®Є ¤®«¦Ґ­ § аҐ§ҐаўЁа®ў вм ¤«п ᥡп гЄ § ­­л© IRQ + дг­ЄжЁҐ© 45. + * ђ §¬Ґа ЎгдҐа  ¤«п ¤ ­­ле - 4000 Ў ©в, ЇаЁ ЇҐаҐЇ®«­Ґ­ЁЁ + "ᢥ¦ЁҐ" ¤ ­­лҐ ЇҐаҐбв ов § ЇЁблў вмбп ў ЎгдҐа. + +====================================================================== +=================== ”г­ЄжЁп 43 - ўў®¤/ўлў®¤ ў Ї®ав. ================== +====================================================================== + +------------------------ ‚лў®¤ ¤ ­­ле ў Ї®ав ------------------------- +Џ а ¬Ґвал: + * 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 - нв® §­ зЁвҐ«м­® + Ўлбв॥ Ё ­ҐбЄ®«мЄ® Є®а®зҐ Ё Їа®йҐ. €§ ­Ґ§ аҐ§ҐаўЁа®ў ­­ле + Ї®ав®ў зЁв вм ўбс а ў­® ­Ґ«м§п. + +====================================================================== +======== ”г­ЄжЁп 44 - ®ЇаҐ¤Ґ«Ёвм ¤Ґ©бвўЁп ЇаЁ Ї®бвгЇ«Ґ­ЁЁ IRQ. ======= +====================================================================== +ЏаЁ ў®§­ЁЄ­®ўҐ­ЁЁ IRQ бЁб⥬  ¬®¦Ґв бзЁвлў вм ¤ ­­лҐ Ё§ гЄ § ­­ле нв®© +дг­ЄжЁҐ© Ї®ав®ў Ё § ЇЁблў вм нвЁ ¤ ­­лҐ ў ЎгдҐа, ®вЄг¤  Ёе ¬®¦­® +Їа®зЁв вм дг­ЄжЁҐ© 42. +Џ а ¬Ґвал: + * eax = 44 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  ¬ ббЁў бвагЄвга, ®ЇЁблў ойЁе Ї® ®¤­®¬г Ї®авг: + * +0: word: 0 ®§­ з Ґв Є®­Ґж ¬ ббЁў , Ё­ зҐ ­®¬Ґа Ї®ав  + * +2: byte: § аҐ§ҐаўЁа®ў ­® (ЁЈ­®аЁагҐвбп) + * +3: byte: 1=бзЁвлў вм Ў ©в Ё§ нв®Ј® Ї®ав , 2=бзЁвлў вм б«®ў® + * ecx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - Ї®в®Є ­Ґ пў«пҐвбп ў« ¤Ґ«м楬 гЄ § ­­®Ј® IRQ +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® Ї®в®Є ¤®«¦Ґ­ § аҐ§ҐаўЁа®ў вм §  б®Ў®© + гЄ §лў Ґ¬л© IRQ дг­ЄжЁҐ© 45. + * ЏаЁ­Ё¬ овбп ў® ў­Ё¬ ­ЁҐ в®«мЄ® ЇҐаўлҐ 16 Ї®ав®ў. + * ’ҐЄгй п ॠ«Ё§ жЁп а бб¬ ваЁў Ґв ­ҐЇа ўЁ«м­®Ґ §­ зҐ­ЁҐ Ї®«п +3 + Є Є бЁЈ­ « ЇаҐЄа йҐ­Ёп ®Ўа Ў®вЄЁ IRQ. + +====================================================================== +============ ”г­ЄжЁп 45 - § аҐ§ҐаўЁа®ў вм/®бў®Ў®¤Ёвм IRQ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 45 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - § аҐ§ҐаўЁа®ў вм, 1 = ®бў®Ў®¤Ёвм + * ecx = ­®¬Ґа IRQ, 0..15 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  (­ҐўҐа­л© ­®¬Ґа IRQ Ё«Ё + Ї®ЇлвЄ  § аҐ§ҐаўЁа®ў вм ­Ґбў®Ў®¤­л© IRQ Ё«Ё ®бў®Ў®¤Ёвм IRQ, ­Ґ + § аҐ§ҐаўЁа®ў ­­л© ⥪гйЁ¬ Ї®в®Є®¬) +‡ ¬Ґз ­Ёп: + * ђҐ§ҐаўЁа®ў ­ЁҐ IRQ ­г¦­® ¤«п а Ў®вл дг­ЄжЁ© 42 Ё 44. + * ’®«мЄ® ®¤Ё­ Ї®в®Є ¬®¦Ґв § аҐ§ҐаўЁа®ў вм Є®­ЄаҐв­л© IRQ. + * IRQ, ®Ўа Ў влў Ґ¬лҐ бЁб⥬®© б ¬®бв®п⥫쭮, १ҐаўЁаговбп + бЁб⥬®© (Ї®в®Є®¬ 1) ЇаЁ § Јаг§ЄҐ. + * ЏаЁ § ўҐа襭ЁЁ Ї®в®Є   ўв®¬ вЁзҐбЄЁ ®бў®Ў®¦¤ овбп + ўбҐ § аҐ§ҐаўЁа®ў ­­лҐ Ё¬ IRQ. + +====================================================================== += ”г­ЄжЁп 46 - § аҐ§ҐаўЁа®ў вм/®бў®Ў®¤Ёвм ЈагЇЇг Ї®ав®ў ўў®¤ /ўлў®¤ . +====================================================================== +Љ § аҐ§ҐаўЁа®ў ­­л¬ Ї®ав ¬ ¬®¦­® ®Ўа й вмбп ­ Їап¬го Ё§ ЇаЁ«®¦Ґ­Ёп +Є®¬ ­¤ ¬Ё in/out (४®¬Ґ­¤гҐ¬л© бЇ®б®Ў) Ё ўл§®ў®¬ дг­ЄжЁЁ 43 +(­ҐаҐЄ®¬Ґ­¤гҐ¬л© бЇ®б®Ў). +Џ а ¬Ґвал: + * eax = 46 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - § аҐ§ҐаўЁа®ў вм, 1 - ®бў®Ў®¤Ёвм + * ecx = ­®¬Ґа ­ з «  ¤Ё Ї §®­  Ї®ав®ў + * edx = ­®¬Ґа Є®­ж  ¤Ё Ї §®­  Ї®ав®ў (ўЄ«озЁвҐ«м­®) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ®иЁЎЄ  +‡ ¬Ґз ­Ёп: + * ‚ б«гз Ґ १ҐаўЁа®ў ­Ёп Ї®ав®ў ®иЁЎЄ®© бзЁв Ґвбп ўлЇ®«­Ґ­ЁҐ + ®¤­®Ј® Ё§ гб«®ўЁ©: + * ­ з «м­л©  ¤аҐб Ў®«миҐ Є®­Ґз­®Ј®; + * гЄ § ­­л© ¤Ё Ї §®­ ᮤҐа¦Ёв ­ҐЄ®а४в­л© ­®¬Ґа Ї®ав  + (Є®а४в­лҐ - ®в 0 ¤® 0xFFFF); + * ЇаҐўл襭® ®Ја ­ЁзҐ­ЁҐ ­  ®ЎйҐҐ зЁб«® § аҐ§ҐаўЁа®ў ­­ле ®Ў« б⥩ + - ¤®ЇгбЄ Ґвбп ¬ ЄбЁ¬г¬ 255; + * гЄ § ­­л© ¤Ё Ї §®­ ЇҐаҐбҐЄ Ґвбп б ®¤­Ё¬ Ё§ + а ­ҐҐ § аҐ§ҐаўЁа®ў ­­ле + * ‚ б«гз Ґ ®бў®Ў®¦¤Ґ­Ёп Ї®ав®ў ®иЁЎЄ®© бзЁв Ґвбп Ї®ЇлвЄ  + ®бў®Ў®¦¤Ґ­Ёп ¤Ё Ї §®­ , Є®в®ал© а ­ҐҐ ­Ґ Ўл« 楫ЁЄ®¬ + § аҐ§ҐаўЁа®ў ­ нв®© ¦Ґ дг­ЄжЁҐ© (б в ЄЁ¬Ё ¦Ґ §­ зҐ­Ёп¬Ё ecx,edx). + * ЏаЁ ®Ў­ а㦥­ЁЁ ®иЁЎЄЁ (ў ®Ў®Ёе б«гз пе) ­ЁЄ ЄЁе ¤Ґ©бвўЁ© + ­Ґ Їа®Ё§ў®¤Ёвбп. + * ЏаЁ § Јаг§ЄҐ бЁб⥬  १ҐаўЁагҐв §  б®Ў®© Ї®авл 0..0xff,   ЇаЁ + ®Ў­ а㦥­ЁЁ COM-¬лиЁ - ¤®Ї®«­ЁвҐ«м­® ¤Ё Ї §®­ COM-Ї®ав®ў + 0x3f0..0x3ff Ё/Ё«Ё 0x2f0..0x2ff. + * ЏаЁ § ўҐа襭ЁЁ Ї®в®Є   ўв®¬ вЁзҐбЄЁ ®бў®Ў®¦¤ овбп ўбҐ + § аҐ§ҐаўЁа®ў ­­лҐ Ё¬ Ї®авл. + +====================================================================== +================= ”г­ЄжЁп 47 - ўлўҐбвЁ зЁб«® ў ®Є­®. ================= +====================================================================== +Џ а ¬Ґвал: + * eax = 47 - ­®¬Ґа дг­ЄжЁЁ + * ebx = Ї а ¬Ґвал ЇаҐ®Ўа §®ў ­Ёп зЁб«  ў ⥪бв: + * bl = 0 - ecx ᮤҐа¦Ёв зЁб«® + * bl = 1 - ecx ᮤҐа¦Ёв гЄ § вҐ«м ­  dword-зЁб«® + * bh = 0 - ®в®Ўа ¦ вм ў ¤ҐбпвЁз­®© бЁб⥬Ґ бзЁб«Ґ­Ёп + * bh = 1 - ®в®Ўа ¦ вм ў иҐбв­ ¤ж вҐаЁз­®© бЁб⥬Ґ + * bh = 2 - ®в®Ўа ¦ вм ў ¤ў®Ёз­®© бЁб⥬Ґ + * ЎЁвл 16-21 = бЄ®«мЄ® жЁда ®в®Ўа ¦ вм + * ЎЁвл 22-31 § аҐ§ҐаўЁа®ў ­л Ё ¤®«¦­л Ўлвм гбв ­®ў«Ґ­л ў 0 + * 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 (ўлў®¤  ⥪бв ). + +====================================================================== +======= ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 0 - ЇаЁ¬Ґ­Ёвм ­ бва®©ЄЁ нЄа ­ . ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - § аҐ§ҐаўЁа®ў ­® +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ЇҐаҐаЁб®ўлў Ґв нЄа ­ Ї®б«Ґ Ё§¬Ґ­Ґ­Ёп Ї а ¬Ґва®ў + Ї®¤дг­ЄжЁп¬Ё 1 Ё 2. + * ‚맮ў дг­ЄжЁЁ ЎҐ§ ЇаҐ¤иҐбвўгойЁе ўл§®ў®ў гЄ § ­­ле Ї®¤дг­ЄжЁ© + ЁЈ­®аЁагҐвбп. + * ‚맮ў дг­ЄжЁЁ б ­Ґ­г«Ґўл¬ ecx ЁЈ­®аЁагҐвбп. + +====================================================================== +========= ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм бвЁ«м Є­®Ї®Є. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = вЁЇ Є­®Ї®Є: + * 0 = Ї«®бЄЁҐ + * 1 = ®Ўкс¬­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®б«Ґ ўл§®ў  ®ЇЁблў Ґ¬®© дг­ЄжЁЁ б«Ґ¤гҐв ЇҐаҐаЁб®ў вм нЄа ­ + Ї®¤дг­ЄжЁҐ© 0. + * ’ЁЇ Є­®Ї®Є ў«ЁпҐв в®«мЄ® ­  Ёе Їа®аЁб®ўЄг дг­ЄжЁҐ© 8. + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм бв ­¤ ав­лҐ жўҐв  ®Є®­. === +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  в Ў«Ёжг 梥⮢ + * edx = а §¬Ґа в Ў«Ёжл 梥⮢ + (¤®«¦Ґ­ Ўлвм 40 Ў ©в ¤«п Ўг¤г饩 б®ў¬ҐбвЁ¬®бвЁ) +”®а¬ в в Ў«Ёжл 梥⮢ гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 3. +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џ®б«Ґ ўл§®ў  ®ЇЁблў Ґ¬®© дг­ЄжЁЁ б«Ґ¤гҐв ЇҐаҐаЁб®ў вм нЄа ­ + Ї®¤дг­ЄжЁҐ© 0. + * ’ Ў«Ёж  бв ­¤ ав­ле 梥⮢ ў«ЁпҐв в®«мЄ® ­  ЇаЁ«®¦Ґ­Ёп, + Є®в®алҐ нвг в Ў«Ёжг пў­л¬ ®Ўа §®¬ Ї®«гз ов (Ї®¤дг­ЄжЁҐ© 3) Ё + ЁбЇ®«м§гов (гЄ §лў п жўҐв  Ё§ ­Ґс ЇаЁ ўл§®ў е дг­ЄжЁ© аЁб®ў ­Ёп). + * ’ Ў«Ёж  бв ­¤ ав­ле 梥⮢ ўе®¤Ёв ў бЄЁ­ Ё гбв ­ ў«Ёў Ґвбп § ­®ў® + ЇаЁ гбв ­®ўЄҐ бЄЁ­  (Ї®¤дг­ЄжЁЁ 8). + * ’ Ў«Ёжг 梥⮢ ¬®¦­® Їа®б¬ ваЁў вм/Ё§¬Ґ­пвм Ё­вҐа ЄвЁў­® б Ї®¬®ймо + ЇаЁ«®¦Ґ­Ёп desktop. + +====================================================================== +===== ”г­ЄжЁп 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. + +====================================================================== +========== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 4 - Ї®«гзЁвм ўлб®вг бЄЁ­ . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ўлб®в  бЄЁ­  +‡ ¬Ґз ­Ёп: + * ‚лб®в®© бЄЁ­  Ї® ®ЇаҐ¤Ґ«Ґ­Ёо бзЁв Ґвбп ўлб®в  § Ј®«®ўЄ  ®Є®­, + ЁбЇ®«м§гойЁе бЄЁ­. + * ‘¬®ваЁ в Є¦Ґ ®Ўйго бвагЄвгаг ®Є­  ў ®ЇЁб ­ЁЁ дг­ЄжЁЁ 0. + +====================================================================== +===== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 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. + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 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). + +====================================================================== +====================== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 7 ====================== +============ Џ®«гзЁвм ®Ў« бвм бЄЁ­  ¤«п ⥪бв  § Ј®«®ўЄ . ============ +====================================================================== +‚®§ўа й Ґв ®Ў« бвм § Ј®«®ўЄ  ®Є­  б® бЄЁ­®¬, ЇаҐ¤­ §­ зҐ­­го +¤«п ўлў®¤  ⥪бв  § Ј®«®ўЄ . +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +‡ ¬Ґз ­Ёп: + * €бЇ®«м§®ў ­ЁҐ/­ҐЁбЇ®«м§®ў ­ЁҐ нв®© дг­ЄжЁЁ - + «Ёз­®Ґ ¤Ґ«® ЇаЁ«®¦Ґ­Ёп. + * ђҐЄ®¬Ґ­¤гҐвбп гзЁвлў вм §­ зҐ­Ёп, ў®§ўа й Ґ¬лҐ нв®© дг­ЄжЁҐ©, + ЇаЁ ўлЎ®аҐ ¬Ґбв  ¤«п аЁб®ў ­Ёп ⥪бв  § Ј®«®ўЄ  (дг­ЄжЁҐ© 4) Ё«Ё + Є Є®Ј®-­ЁЎг¤м § ¬Ґ­ЁвҐ«п ⥪бв  § Ј®«®ўЄ  + (Ї® гᬮв७Ёо ЇаЁ«®¦Ґ­Ёп). + +====================================================================== +==== ”г­ЄжЁп 48, Ї®¤дг­ЄжЁп 8 - гбв ­®ўЁвм ЁбЇ®«м§гҐ¬л© бЄЁ­ ®Є®­. === +====================================================================== +Џ а ¬Ґвал: + * eax = 48 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  Ў«®Є ¤«п дг­ЄжЁЁ 58, ў Є®в®а®¬ гбв ­®ў«Ґ­® + Ї®«Ґ Їа®¬Ґ¦гв®з­®Ј® ЎгдҐа  Ё гЄ § ­® Ё¬п д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * Ё­ зҐ eax = Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л; Ґб«Ё д ©« ­Ґ § ¤ св бЄЁ­, + в® ў®§ўа й Ґвбп ®иЁЎЄ  3 (­ҐЁ§ўҐбв­ п д ©«®ў п бЁб⥬ ). +‡ ¬Ґз ­Ёп: + * ЏаЁ гбЇҐи­®© § Јаг§ЄҐ бЄЁ­  ўбҐ ®Є­  Ё§ўҐй овбп ® ­Ґ®Ўе®¤Ё¬®бвЁ + ЇҐаҐаЁб®ўЄЁ (б®ЎлвЁҐ 1). + * ЏаЁ § Јаг§ЄҐ бЁб⥬  бзЁвлў Ґв бЄЁ­ Ё§ д ©«  default.skn + ­  а ¬¤ЁбЄҐ. + * Џ®«м§®ў вҐ«м ¬®¦Ґв Ё§¬Ґ­пвм бЄЁ­ бв вЁзҐбЄЁ, ᮧ¤ ў бў®© + default.skn, Ё«Ё ¤Ё­ ¬ЁзҐбЄЁ б Ї®¬®ймо ЇаЁ«®¦Ґ­Ёп desktop. + +====================================================================== +============ ”г­ЄжЁп 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 ®ЇЁблў Ґвбп ў ¤®Єг¬Ґ­вҐ + "Advanced Power Management (APM) BIOS Specification" + (Revision 1.2), ¤®бвгЇ­®¬ ­  + http://www.microsoft.com/whdc/archive/amp_12.mspx; + Єа®¬Ґ в®Ј®, ®­  ўЄ«о祭  ў Ё§ўҐбв­л© Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). + +====================================================================== +================= ”г­ЄжЁп 50 - гбв ­®ўЄ  д®а¬л ®Є­ . ================= +====================================================================== +ЋЎлз­лҐ ®Є­  ЇаҐ¤бв ў«пов б®Ў®© Їаאַ㣮«м­ЁЄЁ. ‘ Ї®¬®ймо нв®© дг­ЄжЁЁ +®Є­г ¬®¦­® ЇаЁ¤ вм Їа®Ё§ў®«м­го д®а¬г. ”®а¬  § ¤ свбп ­ Ў®а®¬ в®зҐЄ +ў­гваЁ ®Ўа ¬«по饣® Їаאַ㣮«м­ЁЄ , ЇаЁ­ ¤«Ґ¦ йЁе ®Є­г. Џ®«®¦Ґ­ЁҐ Ё +а §¬Ґал ®Ўа ¬«по饣® Їаאַ㣮«м­ЁЄ  § ¤ овбп дг­ЄжЁҐ© 0 Ё Ё§¬Ґ­повбп +дг­ЄжЁҐ© 67. + +--------------- “бв ­®ўЄ  ¤ ­­ле б Ё­д®а¬ жЁҐ© ® д®а¬Ґ --------------- +Џ а ¬Ґвал: + * 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 Ї®«гз Ґ¬ ЇЁЄбҐ«м) Ё Є®®а¤Ё­ в ¬Ё «Ґў®Ј® ўҐае­ҐЈ® гЈ«  + (a mod (xsize shr scale), a div (xsize shr scale)) + * ђ §¬Ґа ¤ ­­ле: (xsize shr scale)*(ysize shr scale). + * „ ­­лҐ ¤®«¦­л ЇаЁбгвбвў®ў вм ў Ї ¬пвЁ Ё ­Ґ ¬Ґ­пвмбп + Ї®б«Ґ гбв ­®ўЄЁ д®а¬л. + * ‘Ёб⥬  Їа®б¬ ваЁў Ґв ¤ ­­лҐ ® д®а¬Ґ ЇаЁ Є ¦¤®© ЇҐаҐаЁб®ўЄҐ ®Є­  + дг­ЄжЁҐ© 0. + * ‚맮ў Ї®¤дг­ЄжЁЁ 0 б ­г«Ґўл¬ гЄ § вҐ«Ґ¬ ЇаЁў®¤Ёв Є ў®§ўа вг + Є Їаאַ㣮«м­®© д®а¬Ґ. + +====================================================================== +===================== ”г­ЄжЁп 51 - ᮧ¤ вм Ї®в®Є. ==================== +====================================================================== +Џ а ¬Ґвал: + * eax = 51 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - Ґ¤Ё­б⢥­­ п Ї®¤дг­ЄжЁп + * ecx =  ¤аҐб в®зЄЁ ўе®¤  Ї®в®Є  (­ з «м­л© eip) + * edx = гЄ § вҐ«м бвнЄ  Ї®в®Є  (­ з «м­л© esp) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  (ў бЁб⥬Ґ б«ЁиЄ®¬ ¬­®Ј® Ї®в®Є®ў) + * Ё­ зҐ eax = TID - Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + +====================================================================== += ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм Є®­дЁЈга жЁо бҐвҐў®Ј® ¤а ©ўҐа . +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¤ў®©­®Ґ б«®ў® Є®­дЁЈга жЁЁ +‡ ¬Ґз ­Ёп: + * ‘«®ў® Є®­дЁЈга жЁЁ ¬®¦­® гбв ­®ўЁвм Ї®¤дг­ЄжЁҐ© 2. + * џ¤а® ­Ґ ЁбЇ®«м§гҐв ᮮ⢥вбвўгойго ЇҐаҐ¬Ґ­­го. + –Ґ­­®бвм нв®© ЇҐаҐ¬Ґ­­®© Ё а Ў®в ойЁе б ­Ґ© Ї®¤дг­ЄжЁ© 0 Ё 2 + ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©. + +====================================================================== +======= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм «®Є «м­л© IP- ¤аҐб. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = IP- ¤аҐб (4 Ў ©в ) +‡ ¬Ґз ­Ёп: + * ‹®Є «м­л© IP- ¤аҐб гбв ­ ў«Ёў Ґвбп Ї®¤дг­ЄжЁҐ© 3. + +====================================================================== + ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм Є®­дЁЈга жЁо бҐвҐў®Ј® ¤а ©ўҐа . +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ¤ў®©­®Ґ б«®ў® Є®­дЁЈга жЁЁ; Ґб«Ё ¬« ¤иЁҐ 7 ЎЁв ®Ўа §гов + зЁб«® 3, нв® ў®бЇаЁ­Ё¬ Ґвбп Є Є § Їа®б ­  [ЇҐаҐ-]Ё­ЁжЁ «Ё§ жЁо + Ethernet-Є авл, ў Їа®вЁў­®¬ б«гз Ґ Ethernet ўлЄ«оз Ґвбп +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ­Ґ § Їа®иҐ­ Ethernet-Ё­вҐа䥩б, в® ў®§ўа й Ґвбп eax=2, + ­® нв® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў Ўг¤гйЁе ўҐабЁпе п¤а  + * Ґб«Ё § Їа®иҐ­ Ethernet-Ё­вҐа䥩б, в® eax=0 ®§­ з Ґв ®иЁЎЄг + (®вбгвбвўЁҐ Ethernet-Є авл),   ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ - гбЇҐе +‡ ¬Ґз ­Ёп: + * ‘«®ў® Є®­дЁЈга жЁЁ ¬®¦­® Їа®зЁв вм Ї®¤дг­ЄжЁҐ© 0. + * џ¤а® ­Ґ ЁбЇ®«м§гҐв ᮮ⢥вбвўгойго ЇҐаҐ¬Ґ­­го. + –Ґ­­®бвм нв®© ЇҐаҐ¬Ґ­­®©, Ї®¤дг­ЄжЁЁ 0 Ё з бвЁ Ї®¤дг­ЄжЁЁ 2, + гбв ­ ў«Ёў о饩 нвг ЇҐаҐ¬Ґ­­го, ЇаҐ¤бв ў«пҐвбп ᮬ­ЁвҐ«м­®©. + +====================================================================== +====== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 3 - гбв ­®ўЁвм «®Є «м­л© IP- ¤аҐб. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = IP- ¤аҐб (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=3, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ўҐабЁпе +‡ ¬Ґз ­Ёп: + * ‹®Є «м­л© IP- ¤аҐб ¬®¦­® Ї®«гзЁвм Ї®¤дг­ЄжЁҐ© 1. + +====================================================================== += ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 6 - ¤®Ў ўЁвм ¤ ­­лҐ ў б⥪ ўе®¤­®© ®зҐаҐ¤Ё. = +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * edx = а §¬Ґа ¤ ­­ле + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ®иЁЎЄ  + * eax = 0 - гбЇҐи­® +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп ЇаҐ¤­ §­ зҐ­  в®«мЄ® ¤«п ¬Ґ¤«Ґ­­ле бҐвҐўле ¤а ©ўҐа®ў + (PPP, SLIP). + * ђ §¬Ґа ¤ ­­ле ­Ґ ¤®«¦Ґ­ ЇаҐў®б室Ёвм 1500 Ў ©в, + е®вп Їа®ўҐа®Є Є®а४⭮бвЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +====================== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 8 ====================== +============= Џа®зЁв вм ¤ ­­лҐ Ё§ бҐвҐў®© ®зҐаҐ¤Ё ўлў®¤ . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * esi = гЄ § вҐ«м ­  ЎгдҐа а §¬Ґа®¬ 1500 Ў ©в +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Їа®зЁв ­­ле Ў ©в (ў ⥪г饩 ॠ«Ё§ жЁЁ + «ЁЎ® 0 = ­Ґв ¤ ­­ле, «ЁЎ® 1500) + * ¤ ­­лҐ бЄ®ЇЁа®ў ­л ў ЎгдҐа +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп ЇаҐ¤­ §­ зҐ­  в®«мЄ® ¤«п ¬Ґ¤«Ґ­­ле бҐвҐўле ¤а ©ўҐа®ў + (PPP, SLIP). + +====================================================================== +=========== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 9 - Ї®«гзЁвм gateway IP. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = gateway IP (4 Ў ©в ) + +====================================================================== +========= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 10 - Ї®«гзЁвм ¬ бЄг Ї®¤бҐвЁ. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 10 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ¬ бЄ  Ї®¤бҐвЁ + +====================================================================== +========= ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 11 - гбв ­®ўЁвм gateway IP. ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 11 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = gateway IP (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=11, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ॠ«Ё§ жЁпе + +====================================================================== +======== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 12 - гбв ­®ўЁвм ¬ бЄг Ї®¤бҐвЁ. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 12 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ¬ бЄ  Ї®¤бҐвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=12, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў Ўг¤гйЁе ўҐабЁпе + +====================================================================== +============ ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 13 - Ї®«гзЁвм DNS IP. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 13 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = DNS IP (4 Ў ©в ) + +====================================================================== +=========== ”г­ЄжЁп 52, Ї®¤дг­ЄжЁп 14 - гбв ­®ўЁвм DNS IP. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 52 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 14 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = DNS IP (4 Ў ©в ) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ⥪гй п ॠ«Ё§ жЁп ў®§ўа й Ґв eax=14, ­® нв® ¬®¦Ґв Ўлвм Ё§¬Ґ­Ґ­® + ў б«Ґ¤гойЁе ўҐабЁпе + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 0 - ®вЄалвм UDP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * edx = г¤ «с­­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * esi = г¤ «с­­л© IP +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 = 0xFFFFFFFF - ®иЁЎЄ ; ebx а §аги Ґвбп + * eax = ен­¤« б®ЄҐв  (­ҐЄ®в®а®Ґ зЁб«®, ®¤­®§­ з­® Ё¤Ґ­вЁдЁжЁаго饥 + б®ЄҐв Ё Ё¬Ґо饥 б¬лб« в®«мЄ® ¤«п бЁб⥬л) - гбЇҐи­®; + ebx а §аги Ґвбп + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 1 - § Єалвм UDP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ­ҐўҐа­л© ен­¤« + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ § Єалў Ґв  ўв®¬ вЁзҐбЄЁ ўбҐ б®ЄҐвл Ї®в®Є  + ЇаЁ ҐЈ® § ўҐа襭ЁЁ. ‚ з бв­®бвЁ, ­Ґ б«Ґ¤гҐв ЇаЁЎЁў вм Ї®в®Є + б Єг祩 ®вЄалвле б®ЄҐв®ў - Ўг¤Ґв гвҐзЄ  аҐбгаб®ў. + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ ¤Ґ« Ґв Їа®ўҐа®Є ­  Є®а४⭮бвм + (Ґ¤Ё­б⢥­­®Ґ, ­  зв® ў®§ўа й Ґвбп ®иЁЎЄ , - Ї®ЇлвЄ  § Єалвм + ­Ґ®вЄалвл© б®ЄҐв б Є®а४в­л¬ ен­¤«®¬). + +====================================================================== +============== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 2 - ®Їа®б б®ЄҐв . ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Ї®«г祭­ле Ў ©в + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄЁ Є®а४⭮бвЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +======== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 3 - Їа®зЁв вм Ў ©в Ё§ б®ЄҐв . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * Ґб«Ё ­Ґв ЇаЁ­пвле ¤ ­­ле: eax=0, bl=0, + Їа®зЁҐ Ў ©вл ebx а §аги овбп + * Ґб«Ё Ўл«Ё ЇаЁ­пвлҐ ¤ ­­лҐ: eax=зЁб«® ®бв ўиЁебп Ў ©в + (ў®§¬®¦­®, 0), bl=Їа®зЁв ­­л© Ў ©в, Їа®зЁҐ Ў ©вл ebx а §аги овбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄЁ Є®а४⭮бвЁ ­Ґ Їа®Ё§ў®¤Ёвбп. + +====================================================================== +========== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 4 - § ЇЁб вм ў UDP-б®ЄҐв. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0xffffffff - ­ҐўҐа­л© ен­¤« + * eax = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄ  ­  Їа ўЁ«м­®бвм ен­¤«  ¬Ё­Ё¬ «м­  - ЁбЄ«оз овбп в®«мЄ® + ­Ґ ®зҐ­м ­ҐЇа ўЁ«м­лҐ ­Ґ®вЄалвлҐ ен­¤«л. + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-28, е®вп + ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 5 - ®вЄалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = «®Є «м­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * edx = г¤ «с­­л© Ї®ав (гзЁвлў Ґвбп в®«мЄ® ¬« ¤иҐҐ б«®ў®) + * esi = г¤ «с­­л© IP + * edi = ०Ё¬ ®вЄалвЁп: SOCKET_PASSIVE=0 Ё«Ё SOCKET_ACTIVE=1 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 = 0xFFFFFFFF - ®иЁЎЄ ; ebx а §аги Ґвбп + * eax = ен­¤« б®ЄҐв  (­ҐЄ®в®а®Ґ зЁб«®, ®¤­®§­ з­® Ё¤Ґ­вЁдЁжЁаго饥 + б®ЄҐв Ё Ё¬Ґо饥 б¬лб« в®«мЄ® ¤«п бЁб⥬л) - гбЇҐи­®; + ebx а §аги Ґвбп + +====================================================================== +====== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 6 - Ї®«гзЁвм б®бв®п­ЁҐ TCP-б®ЄҐв . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = бв вгб б®ЄҐв : ®¤­® Ё§ + * TCB_LISTEN = 1 + * TCB_SYN_SENT = 2 + * TCB_SYN_RECEIVED = 3 + * TCB_ESTABLISHED = 4 + * TCB_FIN_WAIT_1 = 5 + * TCB_FIN_WAIT_2 = 6 + * TCB_CLOSE_WAIT = 7 + * TCB_CLOSING = 8 + * TCB_LAST_ASK = 9 + * TCB_TIME_WAIT = 10 + * TCB_CLOSED = 11 + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐа®Є Є®а४⭮бвЁ ­Ґ Їа®Ё§ў®¤Ёвбп. + +====================================================================== +========== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў TCP-б®ЄҐв. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  + * edx = зЁб«® Ў ©в ¤«п § ЇЁбЁ + * esi = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0xffffffff - ®иЁЎЄ  + * eax = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ + * eax = 0 - гбЇҐи­® + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Џа®ўҐаЄ  ­  Їа ўЁ«м­®бвм ен­¤«  ¬Ё­Ё¬ «м­  - ЁбЄ«оз овбп в®«мЄ® + ­Ґ ®зҐ­м ­ҐЇа ўЁ«м­лҐ ­Ґ®вЄалвлҐ ен­¤«л. + * —Ёб«® Ў ©в ¤«п § ЇЁбЁ ­Ґ ¬®¦Ґв ЇаҐўли вм 1500-40, + е®вп ᮮ⢥вбвўго饩 Їа®ўҐаЄЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +============ ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 8 - § Єалвм TCP-б®ЄҐв. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ен­¤« б®ЄҐв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ­ҐўҐа­л© ен­¤« + * eax = 0xffff - ­Ґ¤®бв в®з­® Ї ¬пвЁ ¤«п Ї ЄҐв  § ЄалвЁп б®ЄҐв  + * eax = 0 - гбЇҐи­® + * ў® ¬­®ЈЁе б«гз пе eax а §аги Ґвбп (ў®§ўа й Ґвбп १г«мв в дг­ЄжЁЁ + queue) - ўЁ¤Ё¬®, нв® Ў Ј, Є®в®ал© Ўг¤Ґв ЁбЇа ў«Ґ­ + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ § Єалў Ґв  ўв®¬ вЁзҐбЄЁ ўбҐ б®ЄҐвл Ї®в®Є  + ЇаЁ ҐЈ® § ўҐа襭ЁЁ. ‚ з бв­®бвЁ, ­Ґ б«Ґ¤гҐв ЇаЁЎЁў вм Ї®в®Є + б Єг祩 ®вЄалвле б®ЄҐв®ў - Ўг¤Ґв гвҐзЄ  аҐбгаб®ў. + * ’ҐЄгй п ॠ«Ё§ жЁп ­Ґ ¤Ґ« Ґв Їа®ўҐа®Є ­  Є®а४⭮бвм + (Ґ¤Ё­б⢥­­®Ґ, ­  зв® ў®§ўа й Ґвбп ®иЁЎЄ , - Ї®ЇлвЄ  § Єалвм + ­Ґ®вЄалвл© б®ЄҐв б Є®а४в­л¬ ен­¤«®¬). + +====================================================================== +== ”г­ЄжЁп 53, Ї®¤дг­ЄжЁп 9 - Їа®ўҐаЁвм, бў®Ў®¤Ґ­ «Ё «®Є «м­л© Ї®ав. = +====================================================================== +Џ а ¬Ґвал: + * eax = 53 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 9 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ­®¬Ґа «®Є «м­®Ј® Ї®ав  (ЁбЇ®«м§говбп в®«мЄ® ¬« ¤иЁҐ 16 ЎЁв) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - Ї®ав ЁбЇ®«м§гҐвбп + * eax = 1 - Ї®ав бў®Ў®¤Ґ­ + * ebx а §аги Ґвбп + +====================================================================== + ”г­ЄжЁп 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=­Ґ ЄвЁўҐ­, + ­Ґ­г«Ґў®Ґ §­ зҐ­ЁҐ= ЄвЁўҐ­ + +====================================================================== +======== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 0 - § Јаг§Ёвм ¤ ­­лҐ ¤«п SB16. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м ­  ¤ ­­лҐ (Є®ЇЁагҐвбп 64 ЄЁ«®Ў ©в , ЁбЇ®«м§гҐвбп + бв®«мЄ®, бЄ®«мЄ® гбв ­®ў«Ґ­® Ї®¤дг­ЄжЁҐ© 2) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ”®а¬ в Ё а §¬Ґа ¤ ­­ле гбв ­ ў«Ёў овбп Ї®¤дг­ЄжЁҐ© 2. + +====================================================================== +==== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 1 - ­ з вм Їа®ЁЈалў вм ¤ ­­лҐ ­  SB16. === +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤ ­­лҐ ¤®«¦­л Ўлвм § Ја㦥­л Ї®¤дг­ЄжЁҐ© 0 Ё + ®ЇаҐ¤Ґ«с­ Ёе д®а¬ в Ї®¤дг­ЄжЁҐ© 2. + * ”г­ЄжЁп ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, Є®Ј¤  ­ з «®бм Їа®ЁЈалў ­ЁҐ ¤ ­­ле; + Ї®б«Ґ нв®Ј® Їа®ЁЈалў ­ЁҐ Ё¤св ­Ґ§ ўЁбЁ¬® ®в ЇаЁ«®¦Ґ­Ёп (Ё ў®®ЎйҐ + ­Ґ вॡгҐв § Јаг§ЄЁ Їа®жҐбб®а ). + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦­л Ўлвм ®ЇаҐ¤Ґ«Ґ­л Ў §®ўл© Ї®ав SB16 + (Ї®¤дг­ЄжЁҐ© 4 дг­ЄжЁЁ 21) Ё Є ­ « DMA + (Ї®¤дг­ЄжЁҐ© 10 дг­ЄжЁЁ 21). + +====================================================================== +====== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм д®а¬ в ¤ ­­ле SB16. ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 55 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = 0 - гбв ­®ўЁвм а §ап¤­®бвм + * edx = 1 - 8ЎЁв ¬®­® + * edx = 2 - 8ЎЁв бвҐаҐ® + * ecx = 1 - гбв ­®ўЁвм а §¬Ґа ¤ ­­ле + * edx = а §¬Ґа ў Ў ©в е + * ecx = 2 - гбв ­®ўЁвм з бв®вг Їа®ЁЈалў ­Ёп + * edx = з бв®в  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЏаЁ § Јаг§ЄҐ бЁб⥬л гбв ­ ў«Ёў овбп б«Ґ¤гойЁҐ Ї а ¬Ґвал + Ї® 㬮«з ­Ёо: а §ап¤­®бвм - 8 ЎЁв ¬®­®, а §¬Ґа - 64 ЉЎ, + з бв®в  44100 ѓж. ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ४®¬Ґ­¤гҐвбп пў­® гбв ­ ў«Ёў вм + ­Ґ®Ўе®¤Ё¬лҐ §­ зҐ­Ёп, Ї®бЄ®«мЄг ®­Ё ¬®Ј«Ё Ўлвм ЇҐаҐгбв ­®ў«Ґ­л + Є Є®©-­ЁЎг¤м Їа®Ја ¬¬®©. + +====================================================================== +====================== ”г­ЄжЁп 55, Ї®¤дг­ЄжЁп 55 ===================== +========== Ќ з вм Їа®ЁЈалў вм ¤ ­­лҐ ­  ўбв஥­­®¬ бЇЁЄҐаҐ. ========== +====================================================================== +Џ а ¬Ґвал: + * 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. + * ”г­ЄжЁп ў®§ўа й Ґв гЇа ў«Ґ­ЁҐ, б®®ЎйЁў Єг¤  б«Ґ¤гҐв Ё­д®а¬ жЁо + ® § Їа®бҐ. ‘ ¬® Їа®ЁЈалў ­ЁҐ Ё¤св ­Ґ§ ўЁбЁ¬® ®в Їа®Ја ¬¬л. + * „ ­­лҐ ¤®«¦­л б®еа ­пвмбп ў Ї ¬пвЁ Ї® Єа ©­Ґ© ¬ҐаҐ + ¤® Є®­ж  Їа®ЁЈалў ­Ёп. + +====================================================================== +============= ”г­ЄжЁп 56 - § ЇЁб вм д ©« ­  ¦сбвЄЁ© ¤ЁбЄ. ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 56 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё¬п д ©«  + * ecx = а §¬Ґа ¤ ­­ле ¤«п § ЇЁбЁ (ў Ў ©в е) + * edx = гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ + * esi = гЄ § вҐ«м ­  Їгвм (ASCIIZ-бва®Єг) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« ; дг­ЄжЁп 70 Ї®§ў®«пҐв ўлЇ®«­пвм + ⥠¦Ґ ¤Ґ©бвўЁп б а биЁаҐ­­л¬Ё ў®§¬®¦­®бвп¬Ё. + * „ ­­ п дг­ЄжЁп ЇаҐ¤Ї®« Ј Ґв, зв® ў® ўаҐ¬п Ґс ўл§®ў  ®¤­Ё¬ + ЇаЁ«®¦Ґ­ЁҐ¬ ­ЁЄ Є®Ґ ¤агЈ®Ґ ЇаЁ«®¦Ґ­ЁҐ ­Ґ а Ў®в Ґв + б ¦сбвЄЁ¬ ¤ЁбЄ®¬. + * Џгвм Є д ©«г - ASCIIZ-бва®Є , Є®в®а п ¬®¦Ґв Ўлвм Їгбв®© + (Ґб«Ё д ©« ᮧ¤ свбп ў Є®а­Ґў®¬ Є в «®ЈҐ) Ё«Ё Ё¬Ґвм д®а¬ в + /d1/d2/.../dn, Ј¤Ґ ўбҐ Ё¬Ґ­  Ї Ї®Є ¤®«¦­л Ё¬Ґвм д®а¬ в 8+3, в.Ґ. + 8 бЁ¬ў®«®ў Ё¬Ґ­Ё Ё 3 бЁ¬ў®«  а биЁаҐ­Ёп ЎҐ§ а §¤Ґ«ЁвҐ«п, + ЇаЁ ­Ґ®Ўе®¤Ё¬®бвЁ ¤®Ї®«­Ґ­­лҐ Їа®ЎҐ« ¬Ё; + ўбҐ ЎгЄўл ¤®«¦­л Ўлвм § Ј« ў­лҐ. + * €¬п Є д ©«г в Є¦Ґ ¤®«¦­® Ё¬Ґвм д®а¬ в 8+3. + +====================================================================== +============== ”г­ЄжЁп 58 - а Ў®в  б д ©«®ў®© бЁб⥬®©. ============== +====================================================================== +Џ а ¬Ґвал: + * eax = 58 + * 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), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + 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 - з⥭ЁҐ д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 1 - ЇҐаҐ§ ЇЁбм д ©«  + * Ї®¤дг­ЄжЁп 2 - г¤ «Ґ­ЁҐ д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 4 - ᮧ¤ ­ЁҐ Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 5 - ЇҐаҐЁ¬Ґ­®ў ­ЁҐ/ЇҐаҐ¬ҐйҐ­ЁҐ д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 8 - LBA-з⥭ЁҐ б гбва®©бвў  + * Ї®¤дг­ЄжЁп 15 - Ї®«г祭ЁҐ Ё­д®а¬ жЁЁ ® д ©«®ў®© бЁб⥬Ґ + +====================================================================== +========== ”г­ЄжЁп 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. + * …б«Ё д ©« Є®­зЁ«бп а ­миҐ, 祬 Ўл« Їа®зЁв ­ Ї®б«Ґ¤­Ё© § Їа®иҐ­­л© + Ў«®Є, в® дг­ЄжЁп Їа®зЁв Ґв, бЄ®«мЄ® ᬮ¦Ґв, Ї®б«Ґ 祣® ўҐа­св + 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. + +====================================================================== +============ ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 1 - ЇҐаҐ§ ЇЁб вм д ©«. =========== +====================================================================== +…б«Ё д ©« ­Ґ бгйҐбвўгҐв, ®­ ᮧ¤ свбп. +…б«Ё д ©« бгйҐбвўгҐв, ®­ ЇҐаҐ§ ЇЁблў Ґвбп. +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 1 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ЁЈ­®аЁагҐвбп (гбв ­ ў«Ёў ©вҐ ў 0) + * +8: dword: зЁб«® Ў ©в ¤«п § ЇЁбЁ + * +12 = +0xC: dword: гЄ § вҐ«м ­  ¤ ­­лҐ ¤«п § ЇЁбЁ + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ќв  дг­ЄжЁп гбв аҐ« , ЁбЇ®«м§г©вҐ Ї®¤дг­ЄжЁо 2 дг­ЄжЁЁ 70. + +====================================================================== +=========== ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 2 - г¤ «Ёвм д ©«/Ї ЇЄг. =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 2 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ЁЈ­®аЁагҐвбп + * +8: dword: ЁЈ­®аЁагҐвбп + * +12 = +0xC: dword: ЁЈ­®аЁагҐвбп + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ЏаЁ а Ў®вҐ б ¤ЁбЄҐв®© ­Ґ б«Ґ¤гҐв г¤ «пвм ­ҐЇгбвго Ї ЇЄг. + Љ®¤ а Ў®вл б ¦сбвЄЁ¬ ¤ЁбЄ®¬ ­ҐЇгбвлҐ Ї ЇЄЁ г¤ «пҐв Є®а४⭮ + (в.Ґ. ४габЁў­® б® ўбҐ¬Ё д ©« ¬Ё Ё ў«®¦Ґ­­л¬Ё Ї ЇЄ ¬Ё). + ђ ¬¤ЁбЄ Ї Ї®Є ­Ґ Ї®¤¤Ґа¦Ёў Ґв. + +====================================================================== +============== ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 4 - ᮧ¤ вм Ї ЇЄг. ============= +====================================================================== +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 4 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ЁЈ­®аЁагҐвбп + * +8: dword: ЁЈ­®аЁагҐвбп + * +12 = +0xC: dword: ЁЈ­®аЁагҐвбп + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ђ ¬¤ЁбЄ Ё ¤ЁбЄҐвл ­Ґ Ї®¤¤Ґа¦Ёў ов нвг дг­ЄжЁо, + ®­  в®«мЄ® ¤«п ¦сбвЄЁе ¤ЁбЄ®ў. + +====================================================================== +== ”г­ЄжЁп 58, Ї®¤дг­ЄжЁп 5 - ЇҐаҐЁ¬Ґ­®ў вм/ЇҐаҐ¬ҐбвЁвм д ©«/Ї ЇЄг. == +====================================================================== +Џ а ¬Ґвал: + * eax = 58 - ­®¬Ґа дг­ЄжЁЁ + * ebx = гЄ § вҐ«м ­  Ё­д®а¬ жЁ®­­го бвагЄвгаг +”®а¬ в Ё­д®а¬ жЁ®­­®© бвагЄвгал: + * +0: dword: 5 = ­®¬Ґа Ї®¤дг­ЄжЁЁ + * +4: dword: ЁЈ­®аЁагҐвбп + * +8: dword: ЁЈ­®аЁагҐвбп + * +12 = +0xC: dword: ЁЈ­®аЁагҐвбп + * +16 = +0x10: dword: гЄ § вҐ«м ­  ЎгдҐа ¤«п а Ў®вл бЁб⥬л + (4096 Ў ©в) + * +20 = +0x14: ASCIIZ-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + * +20+n: (ба §г Ї®б«Ґ § ўҐаи о饣® ­г«Ґў®Ј® бЁ¬ў®« ) ­®ў®Ґ + ASCIIZ-Ё¬п, ¤®«¦­® ­ зЁ­ вмбп б /hd/1, зв® Ё­вҐаЇаҐвЁагҐвбп Є Є + ¦сбвЄЁ© ¤ЁбЄ, гЄ § ­­л© ў ЇҐаў®¬ Ё¬Ґ­Ё + (ЇҐаҐ¬ҐйҐ­ЁҐ б ®¤­®Ј® ¤ЁбЄ  ­  ¤агЈ®© ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * ђ ¬¤ЁбЄ Ё ¤ЁбЄҐвл ­Ґ Ї®¤¤Ґа¦Ёў ов нвг дг­ЄжЁо, + ®­  в®«мЄ® ¤«п ¦сбвЄЁе ¤ЁбЄ®ў. + * …б«Ё ­®ў®Ґ ASCIIZ-Ё¬п бЁ«м­® ­ҐЇа ўЁ«м­®Ґ, в.Ґ. ­Ґ ­ зЁ­ Ґвбп б + /hd/1, /hd/first, /harddisk/1, /harddisk/first Ё«Ё Ї®б«Ґ нв®Ј® + ­ з «  Ё¤св Їа®ЎҐ« Ё«Ё бЁ¬ў®« б Є®¤®¬ 0, в® дг­ЄжЁп ў®§ўа й Ґв, + Є Є ­Ё бва ­­®, Є®¤ ®иЁЎЄЁ 4. ќв® Ґ¤Ё­б⢥­­ п дг­ЄжЁп, Є®в®а п + ў®®ЎйҐ ў®§ўа й Ґв нв®в Є®¤. + +====================================================================== +========= ”г­ЄжЁп 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 = ebx = 1 + * Ґб«Ё гЄ § ­® ­ҐЇа ўЁ«м­®Ґ Ё¬п гбва®©бвў  + (§  ЁбЄ«о祭ЁҐ¬ ЇаҐ¤л¤г饣® б«гз п): + * eax = 5 + * ebx ­Ґ ¬Ґ­пҐвбп + * Ґб«Ё LBA-¤®бвгЇ § ЇаҐйс­ Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 21: + * eax = 2 + * ebx а §аги Ґвбп + * ¤«п а ¬¤ЁбЄ : Ї®ЇлвЄ  з⥭Ёп Ў«®Є  §  ЇаҐ¤Ґ« ¬Ё а ¬¤ЁбЄ  + (18*2*80 Ў«®Є®ў) ЇаЁў®¤Ёв Є + * eax = 3 + * ebx = 0 + * ЇаЁ гбЇҐи­®¬ з⥭ЁЁ: + * eax = ebx = 0 +‡ ¬Ґз ­Ёп: + * ђ §¬Ґа Ў«®Є  - 512 Ў ©в; зЁв Ґвбп ®¤Ё­ Ў«®Є. + * ЌҐ б«Ґ¤гҐв Ї®« Ј вмбп ­  ў®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ, + ®­® ¬®¦Ґв Ё§¬Ґ­Ёвмбп ў б«Ґ¤гойЁе ўҐабЁпе. + * ’ॡгҐвбп, зв®Ўл Ўл« а §аҐис­ LBA-¤®бвгЇ Є гбва®©бвў ¬ + Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 21. “§­ вм нв® ¬®¦­® ўл§®ў®¬ + Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 26. + * LBA-з⥭ЁҐ ¤ЁбЄҐвл ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп. + * ”г­ЄжЁп бзЁвлў Ґв ¤ ­­лҐ дЁ§ЁзҐбЄ®Ј® ¦сбвЄ®Ј® ¤ЁбЄ ; + Ґб«Ё Ї® Є ЄЁ¬-в® ЇаЁзЁ­ ¬ ­г¦­л ¤ ­­лҐ Є®­ЄаҐв­®Ј® а §¤Ґ« , + ЇаЁ¤свбп ®ЇаҐ¤Ґ«пвм ­ з «м­л© ᥪв®а нв®Ј® а §¤Ґ«  + («ЁЎ® ­ Їап¬го зҐаҐ§ MBR, «ЁЎ® Ё§ а биЁаҐ­­®© бвагЄвгал, + ў®§ўа й Ґ¬®© в®© ¦Ґ Ї®¤дг­ЄжЁҐ© 11 дг­ЄжЁЁ 18). + * ”г­ЄжЁп ­Ґ Їа®ўҐапҐв Є®¤ ®иЁЎЄЁ ¦сбвЄ®Ј® ¤ЁбЄ , в Є зв® § Їа®б + ­ҐбгйҐбвўго饣® ᥪв®а  ўбс а ў­® зв®-в® Їа®зЁв Ґв + (ўҐа®пв­ҐҐ ўбҐЈ®, ­г«Ё, ­® нв® ®ЇаҐ¤Ґ«пҐвбп гбва®©бвў®¬) Ё + нв® Ўг¤Ґв бзЁв вмбп гᯥ宬 (eax=0). + +====================================================================== += ”г­ЄжЁп 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 = 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, ў®§ўа й ой п + Ё­д®а¬ жЁо ® д ©«®ў®© бЁб⥬Ґ. Џ® а биЁаҐ­­®© в Ў«ЁжҐ ¤ЁбЄ®ў®© + Ї®¤бЁбвҐ¬л ¬®¦­® ®ЇаҐ¤Ґ«Ёвм а §¬Ґа Є« бвҐа  (в ¬ ®­ еа ­Ёвбп + ў ᥪв®а е) Ё ®ЎйҐҐ зЁб«® Є« бвҐа®ў ¤«п ¦сбвЄЁе ¤ЁбЄ®ў. + +====================================================================== +=== ”г­ЄжЁп 59 - Ї®«гзЁвм Ё­д®а¬ жЁо ® Ї®б«Ґ¤­Ёе бЁб⥬­ле ўл§®ў е. == +====================================================================== +Џ®«гз Ґв ¤ ­­лҐ ® ўбҐе бЁб⥬­ле ўл§®ў е ўбҐе Їа®жҐбб®ў. +Џ а ¬Ґвал: + * eax = 59 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - Ґ¤Ё­б⢥­­ п Ї®¤дг­ЄжЁп + * ecx = гЄ § вҐ«м ­  ЎгдҐа + * edx = а §¬Ґа ЎгдҐа  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ®ЎйҐҐ зЁб«® бЁб⥬­ле ўл§®ў®ў, + ᤥ« ­­ле б ¬®¬Ґ­в  § Јаг§ЄЁ бЁб⥬л (Ї® ¬®¤г«о 2^32) + * ebx = 0 +”®а¬ в Ё­д®а¬ жЁЁ ®Ў ®¤­®¬ ўл§®ўҐ: (а §¬Ґа = 0x40 = 64 Ў ©в ) + * +0: dword: PID Їа®жҐбб /Ї®в®Є  + * +4: 7*dword: ¬гб®а + * +32 = +0x20: dword: §­ зҐ­ЁҐ edi ЇаЁ ўл§®ўҐ + * +36 = +0x24: dword: esi + * +40 = +0x28: dword: ebp + * +44 = +0x2C: dword: гЄ § вҐ«м бвнЄ  ®Ўа Ў®взЁЄ  п¤а  + * +48 = +0x30: dword: ebx + * +52 = +0x34: dword: edx + * +56 = +0x38: dword: ecx + * +60 = +0x3C: dword: eax (=­®¬Ґа бЁб⥬­®© дг­ЄжЁЁ) +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ЁбЇ®«м§гҐвбп в®«мЄ® ў ЇаЁ«®¦Ґ­ЁЁ systrace. + „®ў®«м­® ваг¤­® ЇаҐ¤бв ўЁвм бЁвг жЁо, ў Є®в®а®© нв® ЇаЁ«®¦Ґ­ЁҐ + Ё«Ё нв  дг­ЄжЁп ¤Ґ©б⢨⥫쭮 Ї®«Ґ§­л,   ў®в ўбҐ бЁб⥬­лҐ ўл§®ўл + ¤«п Ї®¤¤Ґа¦ЄЁ нв®© дг­ЄжЁЁ ­ҐбЄ®«мЄ® § ¬Ґ¤«повбп + (е®вп Ё ­Ґ­ ¬­®Ј®)... + * ‚ бўп§Ё б нвЁ¬ Ґбвм ЇаҐ¤«®¦Ґ­ЁҐ Ї®¤¤Ґа¦Єг нв®© дг­ЄжЁЁ + Ё§ п¤а  гЎа вм ᮢᥬ, ў¬ҐбвҐ б ЇаЁ«®¦Ґ­ЁҐ¬ systrace. + * €­д®а¬ жЁп ® бЁб⥬­ле ўл§®ў е б®еа ­пҐвбп ў + бЁб⥬­®¬ Є®«м楢®¬ ЎгдҐаҐ ­  0x10 ўе®¤®ў. + ќв  дг­ЄжЁп Їа®бв® Є®ЇЁагҐв гЄ § ­­л© ®Ўкс¬ ¤ ­­ле + Ё§ гЇ®¬п­гв®Ј® ЎгдҐа  Ї® гЄ § ­­®¬г  ¤аҐбг. + * Љ Є®© Ё§ ўе®¤®ў ў ЎгдҐаҐ ᮮ⢥вбвўгҐв Ї®б«Ґ¤­Ґ¬г ўл§®ўг, + ¬®¦­® ®ЇаҐ¤Ґ«Ёвм Ї® §­ зҐ­Ёо eax,   Ё¬Ґ­­®, + ўе®¤ (eax and 0xF) (Ї® ᬥ饭Ёо (eax and 0xF)*0x40). + * ‚ ⥪г饩 ॠ«Ё§ жЁЁ ў®§¬®¦­л ।Є® ўбваҐз ойЁҐбп + Їа®Ў«Ґ¬л а ббЁ­еа®­Ё§ жЁЁ, Є®Ј¤  ® ­ҐЄ®в®але ўл§®ў е + Ё­д®а¬ жЁп гбв аҐў Ґв. + * Џ®¤ бЁб⥬­л© ЎгдҐа ўл¤Ґ«Ґ­  бва ­Ёж , 4ЉЎ. + ђ §¬Ґа ўе®¤  = 64 Ў ©в . + Џ®зҐ¬г ЁбЇ®«м§гҐвбп в®«мЄ® 16 ўе®¤®ў - ­ҐЇ®­пв­®. + * ‡­ зҐ­ЁҐ esp ў ¬®¬Ґ­в бЁб⥬­®Ј® ўл§®ў  + нв®© дг­ЄжЁҐ© г§­ вм ­Ґ«м§п. + * Џа®ўҐаЄЁ Є®а४⭮бвЁ edx ў ⥪г饩 ॠ«Ё§ жЁЁ ­Ґ ¤Ґ« Ґвбп. + +====================================================================== +=========== ”г­ЄжЁп 60 - Inter Process Communication (IPC). ========== +====================================================================== +IPC ЇаЁ¬Ґ­пҐвбп ¤«п Ї®бл«®Є б®®ЎйҐ­Ё© ®в ®¤­®Ј® Їа®жҐбб /Ї®в®Є  +¤агЈ®¬г. ЏаЁ н⮬ б«Ґ¤гҐв ЇаҐ¤ў аЁвҐ«м­® ¤®Ј®ў®аЁвмбп ® ⮬, Є Є +Ё­вҐаЇаҐвЁа®ў вм Є®­ЄаҐв­®Ґ б®®ЎйҐ­ЁҐ. + +-------- Џ®¤дг­ЄжЁп 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: ¤ ­­лҐ б®®ЎйҐ­Ёп + +--------------- Џ®¤дг­ЄжЁп 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 - Ї®«гзЁвм Ї а ¬Ґвал ¤«п ЇаאַЈ® ¤®бвгЇ  Є Ја дЁЄҐ. === +====================================================================== +Џа®Ја ¬¬Ґ ¤®бвгЇ­л ¤ ­­лҐ Ја дЁзҐбЄ®Ј® нЄа ­  (®Ў« бвм Ї ¬пвЁ, Є®в®а п +б®Ўб⢥­­® Ё ®в®Ўа ¦ Ґв ᮤҐа¦Ё¬®Ґ нЄа ­ ) ­ Їап¬го ЎҐ§ ўл§®ў®ў +бЁб⥬­ле дг­ЄжЁ© зҐаҐ§ ᥫҐЄв®а gs: + mov eax, [gs:0] +Ї®¬ҐбвЁв ў eax ЇҐаўл© dword ЎгдҐа , ᮤҐа¦ йЁ© Ё­д®а¬ жЁо ® 梥⥠+«Ґў®© ўҐае­Ґ© в®зЄЁ (Ё, ў®§¬®¦­®, жўҐв  ­ҐбЄ®«мЄЁе б«Ґ¤гойЁе). + mov [gs:0], eax +ЇаЁ а Ў®вҐ ў ०Ё¬ е 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 = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® ЎЁв ­  ЇЁЄбҐ«м (24 Ё«Ё 32) + +------------------------ —Ёб«® Ў ©в ­  бва®Єг ------------------------ +Џ а ¬Ґвал: + * eax = 61 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® Ў ©в, Є®в®а®Ґ § ­Ё¬ Ґв ®¤­  бва®Є  а §ўсавЄЁ + (Ј®аЁ§®­в «м­ п «Ё­Ёп ­  нЄа ­Ґ) + +====================================================================== +===== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм ўҐабЁо PCI-Ё­вҐа䥩б . ===== +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * ah.al = ўҐабЁп PCI-Ё­вҐадҐ©б  (ah=ўҐабЁп, al=Ї®¤ўҐабЁп) + * бв а襥 б«®ў® eax ®Ў­г«Ґ­® +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * …б«Ё PCI BIOS ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп, в® §­ зҐ­ЁҐ ax ­Ґ®ЇаҐ¤Ґ«Ґ­®. + +====================================================================== +==== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм ­®¬Ґа Ї®б«Ґ¤­Ґ© PCI-иЁ­л. === +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * al = ­®¬Ґа Ї®б«Ґ¤­Ґ© PCI-иЁ­л; ®бв ўиЁҐбп Ў ©вл eax а §аги овбп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * …б«Ё PCI BIOS ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп, в® §­ зҐ­ЁҐ al ­Ґ®ЇаҐ¤Ґ«Ґ­®. + +====================================================================== +====================== ”г­ЄжЁп 62, Ї®¤дг­ЄжЁп 2 ====================== +== Џ®«гзЁвм ¬Ґе ­Ё§¬ ®Ўа йҐ­Ёп Є Є®­дЁЈга жЁ®­­®¬г Їа®бва ­бвўг PCI. = +====================================================================== +Џ а ¬Ґвал: + * eax = 62 - ­®¬Ґа дг­ЄжЁЁ + * bl = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 - ¤®бвгЇ Є PCI § ЇаҐйс­; Ё­ зҐ + * al = ¬Ґе ­Ё§¬ (1 Ё«Ё 2); Їа®зЁҐ Ў ©вл eax а §аги овбп +‡ ¬Ґз ­Ёп: + * ЏаҐ¤ў аЁвҐ«м­® ¤®«¦Ґ­ Ўлвм а §аҐис­ ­Ё§Є®га®ў­Ґўл© ¤®бвгЇ Є PCI + ¤«п ЇаЁ«®¦Ґ­Ё© Ї®¤дг­ЄжЁҐ© 12 дг­ЄжЁЁ 21. + * ЊҐе ­Ё§¬ ®Ўа йҐ­Ёп ўлЎЁа Ґвбп ў ᮮ⢥вбвўЁЁ + б е а ЄвҐаЁбвЁЄ ¬Ё ®Ў®а㤮ў ­Ёп. + * Џ®¤дг­ЄжЁЁ з⥭Ёп Ё § ЇЁбЁ  ўв®¬ вЁзҐбЄЁ а Ў®в ов + б ўлЎа ­­л¬ ¬Ґе ­Ё§¬®¬. + +====================================================================== +======== ”г­ЄжЁп 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 + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); + бЇЁб®Є ўв®але ¤®«¦Ґ­ Ўлвм гЄ § ­ ў ¤®Єг¬Ґ­в жЁЁ Ї® гбва®©бвўг. + +====================================================================== +======= ”г­ЄжЁп 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; + бЇЁб®Є ўв®але ¤®«¦Ґ­ Ўлвм гЄ § ­ ў ¤®Єг¬Ґ­в жЁЁ Ї® гбва®©бвўг. + +====================================================================== +================ ”г­ЄжЁп 63 - а Ў®в  б ¤®бЄ®© ®в« ¤ЄЁ. =============== +====================================================================== +„®бЄ  ®в« ¤ЄЁ ЇаҐ¤бв ў«пҐв б®Ў®© бЁб⥬­л© ЎгдҐа (­  512 Ў ©в), +ў Є®в®ал© «оЎ п Їа®Ја ¬¬  ¬®¦Ґв § ЇЁб вм (ў®®ЎйҐ Ј®ў®ап, Їа®Ё§ў®«м­лҐ) +¤ ­­лҐ Ё Ё§ Є®в®а®Ј® ¤агЈ п Їа®Ја ¬¬  ¬®¦Ґв нвЁ ¤ ­­лҐ Їа®зЁв вм. +…бвм б®Ј« иҐ­ЁҐ, ў ᮮ⢥вбвўЁЁ б Є®в®ал¬ § ЇЁблў Ґ¬лҐ ¤ ­­лҐ - +⥪бв®ўлҐ бва®ЄЁ, Ё­вҐаЇаҐвЁагҐ¬лҐ Є Є ®в« ¤®з­лҐ б®®ЎйҐ­Ёп ® 室Ґ +ўлЇ®«­Ґ­Ёп Їа®Ја ¬¬л. џ¤а® ў ®ЇаҐ¤Ґ«с­­ле бЁвг жЁпе в Є¦Ґ § ЇЁблў Ґв +­  ¤®бЄг ®в« ¤ЄЁ ᢥ¤Ґ­Ёп ® ўлЇ®«­Ґ­ЁЁ ­ҐЄ®в®але дг­ЄжЁ©; +Ї® б®Ј« иҐ­Ёо б®®ЎйҐ­Ёп п¤а  ­ зЁ­ овбп б ЇаҐдЁЄб  "K : ". +„«п Їа®б¬®ва  ¤®бЄЁ ®в« ¤ЄЁ ᮧ¤ ­® ЇаЁ«®¦Ґ­ЁҐ board, +Є®в®а®Ґ бзЁвлў Ґв ¤ ­­лҐ Ё§ ЎгдҐа  Ё ®в®Ўа ¦ Ґв Ёе ў бў®с¬ ®Є­Ґ. board +Ї®­Ё¬ Ґв Ї®б«Ґ¤®ў вҐ«м­®бвм Є®¤®ў 13,10 Є Є ЇҐаҐе®¤ ­  ­®ўго бва®Єг. +‘Ё¬ў®« б ­г«Ґўл¬ Є®¤®¬ ў Є®­жҐ бва®ЄЁ ­Ґ ®Ўп§ вҐ«Ґ­, ­® Ё ­Ґ ¬Ґи Ґв. +‚ бўп§Ё б Ї®пў«Ґ­ЁҐ¬ ®в« ¤зЁЄ  業­®бвм ¤®бЄЁ ®в« ¤ЄЁ ­ҐбЄ®«мЄ® +б­Ё§Ё« бм, Ї®бЄ®«мЄг ®в« ¤зЁЄ Ї®§ў®«пҐв Ї®«­®бвмо Є®­ва®«Ёа®ў вм 室 +ўлЇ®«­Ґ­Ёп Їа®Ја ¬¬л, ЇаЁзс¬ ¤«п нв®Ј® ­Ґ вॡгҐвбп ­ЁЄ ЄЁе гбЁ«Ё© +б® бв®а®­л б ¬®© Їа®Ја ¬¬л. ’Ґ¬ ­Ґ ¬Ґ­ҐҐ ў® ¬­®ЈЁе б«гз пе +¤®бЄ  ®в« ¤ЄЁ Їа®¤®«¦ Ґв ®бв ў вмбп Ї®«Ґ§­®©. + +---------------------------- ‡ ЇЁбм Ў ©в  ---------------------------- +Џ а ¬Ґвал: + * eax = 63 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * cl = Ў ©в ¤ ­­ле +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Ѓ ©в § ЇЁблў Ґвбп ў ЎгдҐа. „«Ё­  ЎгдҐа  - 512 Ў ©в. + ЏаЁ ЇҐаҐЇ®«­Ґ­ЁЁ ЎгдҐа  ўбҐ Ї®«г祭­лҐ ¤ ­­лҐ вҐаповбп + Ё § Ї®«­Ґ­ЁҐ ­ зЁ­ Ґвбп б­®ў  б ­г«п. + * „«п ўлў®¤  ­  ¤®бЄг ®в« ¤ЄЁ Ў®«ҐҐ б«®¦­ле ®ЎкҐЄв®ў (бва®Є, зЁбҐ«) + ¤®бв в®з­® нв®© дг­ЄжЁЁ, ўл§лў Ґ¬®© ў жЁЄ«Ґ. Њ®¦­® ­Ґ ЇЁб вм + ўагз­го ᮮ⢥вбвўгойЁ© Є®¤,   ў®бЇ®«м§®ў вмбп д ©«®¬ debug.inc, + ўе®¤пйЁ¬ ў ¤ЁбваЁЎгвЁў. + +---------------------------- —⥭ЁҐ Ў ©в  ---------------------------- +‡ ЎЁа Ґв Ў ©в Ё§ ЎгдҐа . +Џ а ¬Ґвал: + * eax = 63 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = ebx = 0 - ЎгдҐа Їгбв + * eax = Ў ©в, ebx = 1 - Ў ©в гбЇҐи­® Їа®зЁв ­ + +====================================================================== +========== ”г­ЄжЁп 64 - ЇҐаҐа бЇаҐ¤Ґ«Ёвм Ї ¬пвм ЇаЁ«®¦Ґ­Ёп. ========== +====================================================================== +Џ а ¬Ґвал: + * eax = 64 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - Ґ¤Ё­б⢥­­ п Ї®¤дг­ЄжЁп + * ecx = ­®ўл© а §¬Ґа Ї ¬пвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­® + * eax = 1 - ­Ґ¤®бв в®з­® Ї ¬пвЁ +‡ ¬Ґз ­Ёп: + * Ќ  ¤ ­­л© ¬®¬Ґ­в нв  дг­ЄжЁп пў«пҐвбп Ґ¤Ё­б⢥­­л¬ б।бвў®¬ ¤«п + ¤Ё­ ¬ЁзҐбЄ®Ј® ўл¤Ґ«Ґ­Ёп/®бў®Ў®¦¤Ґ­Ёп Ї ¬пвЁ ЇаЁ«®¦Ґ­Ёп. + +====================================================================== +================= ”г­ЄжЁп 66 - а Ў®в  б Є« ўЁ вга®©. ================= +====================================================================== +ђҐ¦Ё¬ ўў®¤  ў«ЁпҐв ­  १г«мв вл з⥭Ёп Є« ўЁи дг­ЄжЁҐ© 2. +ЏаЁ § Јаг§ЄҐ Їа®Ја ¬¬л ¤«п ­Ґс гбв ­ ў«Ёў Ґвбп ASCII-०Ё¬ ўў®¤ . + +-------- Џ®¤дг­ЄжЁп 1 - гбв ­®ўЁвм ०Ё¬ ўў®¤  б Є« ўЁ вгал. --------- +Џ а ¬Ґвал: + * eax = 66 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = ०Ё¬: + * 0 = ®Ўлз­л© (ASCII-бЁ¬ў®«л) + * 1 = бЄ ­Є®¤л +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +--------- Џ®¤дг­ЄжЁп 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 ўЄ«озс­ + * Їа®зЁҐ ЎЁвл бЎа®иҐ­л + +----- Џ®¤дг­ЄжЁп 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 - ­Ґв в Є®© Ј®ап祩 Є« ўЁиЁ +‡ ¬Ґз ­Ёп: + * ЏаЁ § ўҐа襭ЁЁ Їа®жҐбб /Ї®в®Є  г¤ «повбп ўбҐ гбв ­®ў«Ґ­­лҐ Ё¬ + Ј®апзЁҐ Є« ўЁиЁ. + * ‚맮ў дг­ЄжЁЁ ­Ґ ў«ЁпҐв ­  ¤агЈЁҐ ЇаЁ«®¦Ґ­Ёп. + …б«Ё ¤агЈ®Ґ ЇаЁ«®¦Ґ­ЁҐ ®ЇаҐ¤Ґ«Ё«® нвг ¦Ґ Є®¬ЎЁ­ жЁо, + ®­® Ї®-ЇаҐ¦­Ґ¬г Ўг¤Ґв Ї®«гз вм 㢥¤®¬«Ґ­Ёп. + +====================================================================== +============ ”г­ЄжЁп 67 - Ё§¬Ґ­Ёвм Ї®«®¦Ґ­ЁҐ/а §¬Ґал ®Є­ . =========== +====================================================================== +Џ а ¬Ґвал: + * eax = 67 - ­®¬Ґа дг­ЄжЁЁ + * ebx = ­®ў п x-Є®®а¤Ё­ в  ®Є­  + * ecx = ­®ў п y-Є®®а¤Ё­ в  ®Є­  + * edx = ­®ўл© x-а §¬Ґа ®Є­  + * esi = ­®ўл© y-а §¬Ґа ®Є­  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‡­ зҐ­ЁҐ -1 ¤«п Ї а ¬Ґва  ®§­ з Ґв "­Ґ Ё§¬Ґ­пвм"; ­ ЇаЁ¬Ґа, ¤«п + ЇҐаҐ¬ҐйҐ­Ёп ®Є­  ЎҐ§ Ё§¬Ґ­Ґ­Ёп а §¬Ґа®ў ¬®¦­® гЄ § вм edx=esi=-1. + * ЏаҐ¤ў аЁвҐ«м­® ®Є­® ¤®«¦­® Ўлвм ®ЇаҐ¤Ґ«Ґ­® дг­ЄжЁҐ© 0. + Ћ­  ¦Ґ § ¤ св ­ з «м­лҐ Є®®а¤Ё­ вл Ё а §¬Ґал ®Є­ . + * ђ §¬Ґал ®Є­  Ї®­Ё¬ овбп ў б¬лб«Ґ дг­ЄжЁЁ 0, в.Ґ. + ­  ®¤Ё­ ЇЁЄбҐ«м ¬Ґ­миҐ, 祬 ॠ«м­лҐ а §¬Ґал. + * ‚맮ў дг­ЄжЁЁ ¤«п ¬ ЄбЁ¬Ё§Ёа®ў ­­ле ®Є®­ Їа®бв® ЁЈ­®аЁагҐвбп. + * „«п ®Є®­ ᮮ⢥вбвўгойЁе бвЁ«Ґ© Ї®«®¦Ґ­ЁҐ Ё/Ё«Ё а §¬Ґал ¬®Јгв Ўлвм + Ё§¬Ґ­Ґ­л Ї®«м§®ў вҐ«Ґ¬; ⥪гйЁҐ Ї®«®¦Ґ­ЁҐ Ё а §¬Ґал ¬®Јгв Ўлвм + Ї®«гзҐ­л ўл§®ў®¬ дг­ЄжЁЁ 9. + * ”г­ЄжЁп Ї®бл« Ґв ®Є­г б®ЎлвЁҐ ЇҐаҐаЁб®ўЄЁ (б Є®¤®¬ 1). + +====================================================================== +=== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 0 - Ї®«гзЁвм бзсвзЁЄ ЇҐаҐЄ«о祭Ё© § ¤ з. == +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = зЁб«® ЇҐаҐЄ«о祭Ё© § ¤ з б ¬®¬Ґ­в  § Јаг§ЄЁ бЁб⥬л + (Ї® ¬®¤г«о 2^32) + +====================================================================== +====================== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 1 ====================== +============ ЏҐаҐЄ«озЁвмбп ­  б«Ґ¤гойЁ© Ї®в®Є ўлЇ®«­Ґ­Ёп. ============ +====================================================================== +”г­ЄжЁп § ўҐаи Ґв ⥪гйЁ© Єў ­в ўаҐ¬Ґ­Ё, ўл¤Ґ«Ґ­­л© Ї®в®Єг, +Ё ЇҐаҐЄ«оз Ґвбп ­  б«Ґ¤гойЁ©. +(Љ Є®© Ї®в®Є Є Є®Ј® Їа®жҐбб  Ўг¤Ґв б«Ґ¤гойЁ¬, ЇаҐ¤бЄ § вм ­Ґ«м§п). +Џ®§¤­ҐҐ, Є®Ј¤  ¤® ⥪г饣® Ї®в®Є  ¤®©¤св ®зҐаҐ¤м, +ўлЇ®«­Ґ­ЁҐ ў®§®Ў­®ўЁвбп. +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +=============== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 2 - Єни + 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: + * eax = (cr0 and 0x60000000): + * eax = 0 - Єни ўЄ«озс­ + * eax <> 0 - Єни ўлЄ«о祭 + * ¤«п ecx=2 Ё ecx=3: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп + +====================================================================== +========== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 3 - Їа®зЁв вм MSR-ॣЁбва. ========= +====================================================================== +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. €­ зҐ ў®§­ЁЄ­Ґв 㦥 ¤агЈ®Ґ ЁбЄ«о祭ЁҐ ў п¤аҐ, + Є®в®а®Ґ ўбс а ў­® ЇаЁЎмсв Ї®в®Є. + +====================================================================== +========= ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 4 - § ЇЁб вм ў MSR-ॣЁбва. ========= +====================================================================== +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 +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * ebx:eax = Є®ЇЁп esi:edi +‡ ¬Ґз ­Ёп: + * “Є § ­ЁҐ ў ecx ­ҐбгйҐбвўго饣® Ё«Ё ­ҐаҐ «Ё§®ў ­­®Ј® ¤«п ¤ ­­®Ј® + Їа®жҐбб®а  MSR Ї®ў«Ґзсв ЁбЄ«о祭ЁҐ ў п¤аҐ, Є®в®а®Ґ ЇаЁЎмсв Ї®в®Є. + * ЏаҐ¤ў аЁвҐ«м­® б«Ґ¤гҐв ®ЇаҐ¤Ґ«Ёвм, Ї®¤¤Ґа¦Ёў овбп «Ё MSR ў 楫®¬, + Є®¬ ­¤®© cpuid. €­ зҐ ў®§­ЁЄ­Ґв 㦥 ¤агЈ®Ґ ЁбЄ«о祭ЁҐ ў п¤аҐ, + Є®в®а®Ґ ўбс а ў­® ЇаЁЎмсв Ї®в®Є. + +====================================================================== +======= ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 5 - ўл¤Ґ«Ёвм дЁ§ЁзҐбЄго Ї ¬пвм. ======= +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = а §¬Ґа (ў Ў ©в е) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = дЁ§ЁзҐбЄЁ©  ¤аҐб ўл¤Ґ«Ґ­­®© Ї ¬пвЁ +‡ ¬Ґз ­Ёп: + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп ­Ґ ¤®«¦­л ЁбЇ®«м§®ў вм нвг дг­ЄжЁо, ®­  + ЇаҐ¤­ §­ зҐ­  ¤«п б«гз п, Є®Ј¤  ЇаЁ а Ў®вҐ б Є ЄЁ¬-«ЁЎ® + гбва®©бвў®¬ вॡгҐвбп а §¬ҐбвЁвм ¤ ­­лҐ Ї® Ё§ўҐбв­®¬г дЁ§ЁзҐбЄ®¬г +  ¤аҐбг. (‚ бгй­®бвЁ, нв  дг­ЄжЁп а §а Ў влў « бм ¤«п AC97WAV.) + * —Ёб«® Ў«®Є®ў дЁ§ЁзҐбЄ®© Ї ¬пвЁ ®Ја ­ЁзҐ­® (Є®­бв ­в®© 24, + ЇаЁзс¬ нв  Є®­бв ­в  ўЄ«оз Ґв Ё ­ҐбЄ®«мЄ® Ў«®Є®ў Ї ¬пвЁ + ¤«п ­ ¤®Ў­®б⥩ п¤а ). + * Ћбў®Ў®¤Ёвм ўл¤Ґ«Ґ­­го в ЄЁ¬ ®Ўа §®¬ Ї ¬пвм ¬®¦­® + Ї®¤дг­ЄжЁҐ© 6, Є®ЇЁа®ў ­ЁҐ¬ ¤ ­­ле вг¤ /®Ўа в­® + § ­Ё¬ овбп Ї®¤дг­ЄжЁЁ 7 Ё 8. + +====================================================================== +====== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 6 - ®бў®Ў®¤Ёвм дЁ§ЁзҐбЄго Ї ¬пвм. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = дЁ§ЁзҐбЄЁ©  ¤аҐб Ї ¬пвЁ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп ­Ґ ¤®«¦­л ЁбЇ®«м§®ў вм нвг дг­ЄжЁо, ®­  + ЇаҐ¤­ §­ зҐ­  ¤«п б«гз п, Є®Ј¤  ЇаЁ а Ў®вҐ б Є ЄЁ¬-«ЁЎ® + гбва®©бвў®¬ вॡгҐвбп а §¬ҐбвЁвм ¤ ­­лҐ Ї® Ё§ўҐбв­®¬г дЁ§ЁзҐбЄ®¬г +  ¤аҐбг. (‚ бгй­®бвЁ, нв  дг­ЄжЁп а §а Ў влў « бм ¤«п AC97WAV.) + * Џ ¬пвм ¤®«¦­  Ўлвм а ­ҐҐ ўл¤Ґ«Ґ­  Ї®¤дг­ЄжЁҐ© 5. + +====================================================================== +=== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ¤ ­­лҐ ў дЁ§ЁзҐбЄго Ї ¬пвм. == +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = дЁ§ЁзҐбЄЁ©  ¤аҐб + * edx = гЄ § вҐ«м ­  ¤ ­­лҐ (ў ЇаЁ«®¦Ґ­ЁЁ) + * esi = а §¬Ґа ¤ ­­ле (ў Ў ©в е) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп ­Ґ ¤®«¦­л ЁбЇ®«м§®ў вм нвг дг­ЄжЁо, ®­  + ЇаҐ¤­ §­ зҐ­  ¤«п б«гз п, Є®Ј¤  ЇаЁ а Ў®вҐ б Є ЄЁ¬-«ЁЎ® + гбва®©бвў®¬ вॡгҐвбп а §¬ҐбвЁвм ¤ ­­лҐ Ї® Ё§ўҐбв­®¬г дЁ§ЁзҐбЄ®¬г +  ¤аҐбг. (‚ бгй­®бвЁ, нв  дг­ЄжЁп а §а Ў влў « бм ¤«п AC97WAV.) + * „Ё Ї §®­ дЁ§ЁзҐбЄЁе  ¤аҐб®ў ¤®«¦Ґ­ «Ґ¦ вм ў­гваЁ а ­ҐҐ ўл¤Ґ«Ґ­­®Ј® + Ї®¤дг­ЄжЁҐ© 5 Ў«®Є  дЁ§ЁзҐбЄ®© Ї ¬пвЁ. + * Џа®ўҐа®Є Є®а४⭮бвЁ ­Ґ Їа®Ё§ў®¤Ёвбп. + +====================================================================== +== ”г­ЄжЁп 68, Ї®¤дг­ЄжЁп 8 - Їа®зЁв вм ¤ ­­лҐ Ё§ дЁ§ЁзҐбЄ®© Ї ¬пвЁ. = +====================================================================== +Џ а ¬Ґвал: + * eax = 68 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = дЁ§ЁзҐбЄЁ©  ¤аҐб + * edx = гЄ § вҐ«м ­  ЎгдҐа ¤«п ¤ ­­ле (ў ЇаЁ«®¦Ґ­ЁЁ) + * esi = а §¬Ґа ¤ ­­ле (ў Ў ©в е) +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ЋЎлз­лҐ ЇаЁ«®¦Ґ­Ёп ­Ґ ¤®«¦­л ЁбЇ®«м§®ў вм нвг дг­ЄжЁо, ®­  + ЇаҐ¤­ §­ зҐ­  ¤«п б«гз п, Є®Ј¤  ЇаЁ а Ў®вҐ б Є ЄЁ¬-«ЁЎ® + гбва®©бвў®¬ вॡгҐвбп а §¬ҐбвЁвм ¤ ­­лҐ Ї® Ё§ўҐбв­®¬г дЁ§ЁзҐбЄ®¬г +  ¤аҐбг. (‚ бгй­®бвЁ, нв  дг­ЄжЁп а §а Ў влў « бм ¤«п AC97WAV.) + * „Ё Ї §®­ дЁ§ЁзҐбЄЁе  ¤аҐб®ў ¤®«¦Ґ­ «Ґ¦ вм ў­гваЁ а ­ҐҐ ўл¤Ґ«Ґ­­®Ј® + Ї®¤дг­ЄжЁҐ© 5 Ў«®Є  дЁ§ЁзҐбЄ®© Ї ¬пвЁ. + * Џа®ўҐа®Є Є®а४⭮бвЁ ­Ґ Їа®Ё§ў®¤Ёвбп. + +====================================================================== +======================== ”г­ЄжЁп 69 - ®в« ¤Є . ======================= +====================================================================== +Џа®жҐбб ¬®¦Ґв § Јаг§Ёвм ¤агЈ®© Їа®жҐбб Є Є ®в« ¦Ёў Ґ¬л© гбв ­®ўЄ®© +ᮮ⢥вбвўго饣® ЎЁв  ЇаЁ ўл§®ўҐ Ї®¤дг­ЄжЁЁ 16 дг­ЄжЁЁ 58 +Ё«Ё Ї®¤дг­ЄжЁЁ 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. + +‚ᥠЇ®¤дг­ЄжЁЁ ЇаЁ¬Ґ­Ё¬л в®«мЄ® Є Їа®жҐбб ¬/Ї®в®Є ¬, § Їг饭­л¬ +Ё§ ⥪г饣® дг­ЄжЁҐ© 58 Ё«Ё 70 б гбв ­®ў«Ґ­­л¬ д« Ј®¬ ®в« ¤ЄЁ. +Ћв« ¤Є  ¬­®Ј®Ї®в®з­ле Їа®Ја ¬¬ Ї®Є  ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп. +Џ®«­л© бЇЁб®Є Ї®¤дг­ЄжЁ©: + * Ї®¤дг­ЄжЁп 0 - ®ЇаҐ¤Ґ«Ёвм ®Ў« бвм ¤ ­­ле ¤«п ®в« ¤®з­ле б®®ЎйҐ­Ё© + * Ї®¤дг­ЄжЁп 1 - Ї®«гзЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 2 - гбв ­®ўЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 3 - ®вЄ«озЁвмбп ®в ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 4 - ЇаЁ®бв ­®ўЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є + * Ї®¤дг­ЄжЁп 5 - ў®§®Ў­®ўЁвм ўлЇ®«­Ґ­ЁҐ ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є  + * Ї®¤дг­ЄжЁп 6 - Їа®зЁв вм Ё§ Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў Ї ¬пвм ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * Ї®¤дг­ЄжЁп 8 - § ўҐаиЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є + * Ї®¤дг­ЄжЁп 9 - гбв ­®ўЁвм/б­пвм  ЇЇ а в­го в®зЄг ®бв ­®ў  + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 0 ====================== +========= ЋЇаҐ¤Ґ«Ёвм ®Ў« бвм ¤ ­­ле ¤«п ®в« ¤®з­ле б®®ЎйҐ­Ё©. ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 0 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = гЄ § вҐ«м +”®а¬ в ®Ў« бвЁ ¤ ­­ле: + * +0: dword: N = а §¬Ґа ЎгдҐа  (­Ґ бзЁв п нв®Ј® § Ј®«®ўЄ ) + * +4: dword: § ­пв® ў ЎгдҐаҐ + * +8: N*byte: ЎгдҐа +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®«Ґ а §¬Ґа  ®ваЁж вҐ«м­®, ЎгдҐа бзЁв Ґвбп § Ў«®ЄЁа®ў ­­л¬ + Ё ЇаЁ Ї®бвгЇ«Ґ­ЁЁ ­®ў®Ј® б®®ЎйҐ­Ёп бЁб⥬  Ўг¤Ґв ¦¤ вм. + „«п бЁ­еа®­Ё§ жЁЁ ®Ўа ¬«п©вҐ ўбо а Ў®вг б ЎгдҐа®¬ ®ЇҐа жЁп¬Ё + Ў«®ЄЁа®ўЄЁ/а §Ў«®ЄЁа®ўЄЁ + neg [bufsize] + * „ ­­лҐ ў ЎгдҐаҐ ва Євговбп Є Є ¬ ббЁў н«Ґ¬Ґ­в®ў ЇҐаҐ¬Ґ­­®© ¤«Ё­л - + б®®ЎйҐ­Ё©. ”®а¬ в б®®ЎйҐ­Ёп гЄ § ­ ў ®ЎйҐ¬ ®ЇЁб ­ЁЁ. + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 1 ====================== +========= Џ®«гзЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ========= +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + * edx = ¤«Ё­  бвагЄвгал Є®­вҐЄбв , ¤®«¦­® Ўлвм 0x28=40 Ў ©в + * esi = гЄ § вҐ«м ­  бвагЄвгаг Є®­вҐЄбв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в бвагЄвгал Є®­вҐЄбв : (FPU Ї®Є  ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп) + * +0: dword: eip + * +4: dword: eflags + * +8: dword: eax + * +12 = +0xC: dword: ecx + * +16 = +0x10: dword: edx + * +20 = +0x14: dword: ebx + * +24 = +0x18: dword: esp + * +28 = +0x1C: dword: ebp + * +32 = +0x20: dword: esi + * +36 = +0x24: dword: edi +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®в®Є ўлЇ®«­пҐв Є®¤ 0-Є®«мж , ў®§ўа й Ґвбп + б®бв®п­ЁҐ ॣЁбва®ў 3-Є®«мж . + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 2 ====================== +======== “бв ­®ўЁвм б®бв®п­ЁҐ ॣЁбва®ў ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ======== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 2 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а Ї®в®Є  + * edx = ¤«Ё­  бвагЄвгал Є®­вҐЄбв , ¤®«¦­® Ўлвм 0x28=40 Ў ©в + * esi = гЄ § вҐ«м ­  бвагЄвгаг Є®­вҐЄбв  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +”®а¬ в бвагЄвгал Є®­вҐЄбв  гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 1. +‡ ¬Ґз ­Ёп: + * …б«Ё Ї®в®Є ўлЇ®«­пҐв Є®¤ 0-Є®«мж , гбв ­ ў«Ёў Ґвбп + б®бв®п­ЁҐ ॣЁбва®ў 3-Є®«мж . + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 3 - ®вЄ«озЁвмбп ®в ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . = +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 3 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * …б«Ё Їа®жҐбб Ўл« ЇаЁ®бв ­®ў«Ґ­, ®­ ў®§®Ў­®ў«пҐв ўлЇ®«­Ґ­ЁҐ. + +====================================================================== +==== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 4 - ЇаЁ®бв ­®ўЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є. ==== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа Їа®жҐбб  + * ebx = 4 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 5 ====================== +============ ‚®§®Ў­®ўЁвм ўлЇ®«­Ґ­ЁҐ ®в« ¦Ёў Ґ¬®Ј® Ї®в®Є . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 5 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====================== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 6 ====================== +============= Џа®зЁв вм Ё§ Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . ============ +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 6 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а + * edx = бЄ®«мЄ® Ў ©в зЁв вм + * esi =  ¤аҐб Ї ¬пвЁ ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб  + * edi = гЄ § вҐ«м ­  ЎгдҐа ¤«п ¤ ­­ле +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 ЇаЁ ®иЁЎЄҐ (­ҐўҐа­л© PID Ё«Ё ЎгдҐа) + * Ё­ зҐ eax = зЁб«® Їа®зЁв ­­ле Ў ©в (ў®§¬®¦­®, 0, + Ґб«Ё ў esi б«ЁиЄ®¬ Ў®«м讥 §­ зҐ­ЁҐ) +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== + ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 7 - § ЇЁб вм ў Ї ¬пвм ®в« ¦Ёў Ґ¬®Ј® Їа®жҐбб . +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 7 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а + * edx = бЄ®«мЄ® Ў ©в ЇЁб вм + * esi =  ¤аҐб Ї ¬пвЁ ў ®в« ¦Ёў Ґ¬®¬ Їа®жҐбᥠ+ * edi = гЄ § вҐ«м ­  ¤ ­­лҐ +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = -1 ЇаЁ ®иЁЎЄҐ (­ҐўҐа­л© PID Ё«Ё ЎгдҐа) + * Ё­ зҐ eax = зЁб«® § ЇЁб ­­ле Ў ©в (ў®§¬®¦­®, 0, + Ґб«Ё ў esi б«ЁиЄ®¬ Ў®«м讥 §­ зҐ­ЁҐ) +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + +====================================================================== +====== ”г­ЄжЁп 69, Ї®¤дг­ЄжЁп 8 - § ўҐаиЁвм ®в« ¦Ёў Ґ¬л© Ї®в®Є. ====== +====================================================================== +Џ а ¬Ґвал: + * eax = 69 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 8 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx = Ё¤Ґ­вЁдЁЄ в®а +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * Џа®жҐбб ¤®«¦Ґ­ Ўлвм § Ја㦥­ ¤«п ®в« ¤ЄЁ (Є Є гЄ § ­® ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ). + * ”г­ЄжЁп  ­ «®ЈЁз­  Ї®¤дг­ЄжЁЁ 2 дг­ЄжЁЁ 18 б ¤ўг¬п ®в«ЁзЁп¬Ё: + вॡгҐвбп ўлЇ®«­Ґ­ЁҐ ЇҐаў®Ј® § ¬Ґз ­Ёп Ё ЇаЁ­Ё¬ Ґвбп PID, +   ­Ґ ­®¬Ґа б«®в . + +====================================================================== +====================== ”г­ЄжЁп 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, ® Є®в®а®¬ бЁб⥬  б®®Ўй Ґв ®в« ¤зЁЄг. + * ’®зЄ  ®бв ­®ў  ­  § ЇЁбм Ё з⥭ЁҐ/§ ЇЁбм ба Ў влў Ґв Ї®б«Ґ + ўлЇ®«­Ґ­Ёп ўл§ў ўиҐ© Ґс Ё­бвагЄжЁЁ. + +====================================================================== += ”г­ЄжЁп 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-бва®Є  б Ё¬Ґ­Ґ¬ д ©«  + Ё«Ё + * +20 = +0x14: db 0 + * +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), + 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), + IDE2 (Secondary Master), IDE3 (Secondary Slave) +ЏаЁ¬Ґал: + * '/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 +„®бвгЇ­лҐ Ї®¤дг­ЄжЁЁ: + * Ї®¤дг­ЄжЁп 0 - з⥭ЁҐ д ©«  + * Ї®¤дг­ЄжЁп 1 - з⥭ЁҐ Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 2 - ᮧ¤ ­ЁҐ/ЇҐаҐ§ ЇЁбм д ©«  + * Ї®¤дг­ЄжЁп 3 - § ЇЁбм ў бгйҐбвўгойЁ© д ©« + * Ї®¤дг­ЄжЁп 4 - гбв ­®ўЄ  а §¬Ґа  д ©«  + * Ї®¤дг­ЄжЁп 5 - Ї®«г祭ЁҐ  ваЁЎгв®ў д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 6 - гбв ­®ўЄ   ваЁЎгв®ў д ©« /Ї ЇЄЁ + * Ї®¤дг­ЄжЁп 7 - § ЇгбЄ Їа®Ја ¬¬л +„«п CD-ЇаЁў®¤®ў ў бўп§Ё б  ЇЇ а в­л¬Ё ®Ја ­ЁзҐ­Ёп¬Ё ¤®бвгЇ­л +в®«мЄ® Ї®¤дг­ЄжЁЁ 0,1,5 Ё 7, ўл§®ў ¤агЈЁе Ї®¤дг­ЄжЁ© § ўҐаиЁвбп +®иЁЎЄ®© б Є®¤®¬ 2. + +====================================================================== += ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 0 - з⥭ЁҐ д ©«  б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. = +====================================================================== +Џ а ¬Ґвал: + * 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, Ґб«Ё д ©« ­Ґ ­ ©¤Ґ­ +‡ ¬Ґз ­Ёп: + * …б«Ё д ©« Є®­зЁ«бп а ­миҐ, 祬 Ўл« Їа®зЁв ­ Ї®б«Ґ¤­Ё© § Їа®иҐ­­л© + Ў«®Є, в® дг­ЄжЁп Їа®зЁв Ґв, бЄ®«мЄ® ᬮ¦Ґв, Ї®б«Ґ 祣® ўҐа­св + eax=6 (EOF). + * ”г­ЄжЁп ­Ґ Ї®§ў®«пҐв зЁв вм Ї ЇЄЁ + (ўҐа­свбп eax=10, access denied). + +====================================================================== += ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 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-Ё¬п Ї ЇЄЁ, Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +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 + * ... +‘вагЄвга  § Ј®«®ўЄ : + * +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 ====================== +======== ‘®§¤ ­ЁҐ/ЇҐаҐ§ ЇЁбм д ©«  б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. ======== +====================================================================== +Џ а ¬Ґвал: + * 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). + +====================================================================== +====================== ”г­ЄжЁп 70, Ї®¤дг­ЄжЁп 3 ====================== +======== ‡ ЇЁбм ў бгйҐбвўгойЁ© д ©« б Ї®¤¤Ґа¦Є®© ¤«Ё­­ле Ё¬с­. ======= +====================================================================== +Џ а ¬Ґвал: + * 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). + +====================================================================== +========= ”г­ЄжЁп 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-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * …б«Ё ­®ўл© а §¬Ґа д ©«  ¬Ґ­миҐ бв а®Ј®, д ©« гᥪ Ґвбп. …б«Ё + ­®ўл© а §¬Ґа Ў®«миҐ бв а®Ј®, д ©« а биЁапҐвбп ­г«Ґўл¬Ё бЁ¬ў®« ¬Ё. + …б«Ё ­®ўл© а §¬Ґа а ўҐ­ бв а®¬г, Ґ¤Ё­б⢥­­л¬ १г«мв в®¬ ўл§®ў  + пў«пҐвбп гбв ­®ўЄ  ¤ вл/ўаҐ¬Ґ­Ё ¬®¤ЁдЁЄ жЁЁ Ё ¤®бвгЇ  ў ⥪гйЁҐ. + * …б«Ё бў®Ў®¤­®Ј® ¬Ґбв  ­  ¤ЁбЄҐ ­Ґ¤®бв в®з­® ¤«п а биЁаҐ­Ёп д ©« , + в® дг­ЄжЁп а биЁаЁв ­ бЄ®«мЄ® ў®§¬®¦­®, Ї®б«Ґ 祣® ўҐа­св + Є®¤ ®иЁЎЄЁ 8. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +=== ”г­ЄжЁп 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-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +€­д®а¬ жЁп ® д ©«Ґ ў®§ўа й Ґвбп ў д®а¬ вҐ Ѓ„‚Љ +(Ў«®Є  ¤ ­­ле ўе®¤  Є в «®Ј ), гЄ § ­­®¬ ў ®ЇЁб ­ЁЁ +Ї®¤дг­ЄжЁЁ 1, ­® ЎҐ§ Ё¬Ґ­Ё д ©«  +(в® Ґбвм ЇҐаўлҐ 40 = 0x28 Ў ©в). +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв ўЁавг «м­лҐ Ї ЇЄЁ вЁЇ  /, /rd Ё + Є®а­ҐўлҐ Ї ЇЄЁ вЁЇ  /rd/1. + +====================================================================== +===== ”г­ЄжЁп 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-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax = 0 - гбЇҐи­®, Ё­ зҐ Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +ЂваЁЎгвл д ©«  - ЇҐаўлҐ 32 Ў ©в  ў Ѓ„‚Љ (Ў«®ЄҐ ¤ ­­ле ўе®¤  Є в «®Ј ), +д®а¬ в Є®в®а®Ј® гЄ § ­ ў ®ЇЁб ­ЁЁ Ї®¤дг­ЄжЁЁ 1 +(в® Ґбвм ЎҐ§ Ё¬Ґ­Ё Ё а §¬Ґа  д ©« ). ЂваЁЎгв д ©«/Ї ЇЄ /¬ҐвЄ  ⮬  +(ЎЁвл 3,4 ў dword'Ґ +0) ­Ґ ¬Ґ­пҐвбп. +Ѓ ©в +4 (д®а¬ в Ё¬Ґ­Ё) ЁЈ­®аЁагҐвбп. +‡ ¬Ґз ­Ёп: + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґв ўЁавг «м­лҐ Ї ЇЄЁ вЁЇ  /, /rd Ё + Є®а­ҐўлҐ Ї ЇЄЁ вЁЇ  /rd/1. + * ”г­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п CD (ўҐа­свбп Є®¤ ®иЁЎЄЁ 2). + +====================================================================== +============ ”г­ЄжЁп 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-Ё¬п д ©« , Їа ўЁ«  д®а¬Ёа®ў ­Ёп Ё¬с­ гЄ § ­л ў + ®ЎйҐ¬ ®ЇЁб ­ЁЁ + Ё«Ё + * +20 = +0x14: db 0 + * +21 = +0x15: dd гЄ § вҐ«м ­  ASCIIZ-бва®Єг б Ё¬Ґ­Ґ¬ д ©«  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * eax > 0 - Їа®Ја ¬¬  § Ја㦥­ , eax ᮤҐа¦Ёв PID + * eax < 0 - Їа®Ё§®и«  ®иЁЎЄ , -eax ᮤҐа¦Ёв + Є®¤ ®иЁЎЄЁ д ©«®ў®© бЁб⥬л + * ebx а §аги Ґвбп +‡ ¬Ґз ­Ёп: + * Љ®¬ ­¤­ п бва®Є  ¤®«¦­  § Є ­зЁў вмбп бЁ¬ў®«®¬ б Є®¤®¬ 0 + (ASCIIZ-бва®Є ); гзЁвлў овбп «ЁЎ® ўбҐ бЁ¬ў®«л ¤® § ўҐаи о饣® ­г«п + ўЄ«озЁвҐ«м­®, «ЁЎ® ЇҐаўлҐ 256 бЁ¬ў®«®ў, ў § ўЁбЁ¬®бвЁ ®в в®Ј®, + зв® ¬Ґ­миҐ. + * …б«Ё Їа®жҐбб § ЇгбЄ Ґвбп Є Є ®в« ¦Ёў Ґ¬л©, ®­ ᮧ¤ свбп + ў § ¬®а®¦Ґ­­®¬ б®бв®п­ЁЁ; ¤«п § ЇгбЄ  ЁбЇ®«м§г©вҐ + Ї®¤дг­ЄжЁо 5 дг­ЄжЁЁ 69. + +====================================================================== +=== ”г­ЄжЁп 71, Ї®¤дг­ЄжЁп 1 - гбв ­®ўЁвм § Ј®«®ў®Є ®Є­  Їа®Ја ¬¬л. == +====================================================================== +Џ а ¬Ґвал: + * eax = 71 - ­®¬Ґа дг­ЄжЁЁ + * ebx = 1 - ­®¬Ґа Ї®¤дг­ЄжЁЁ + * ecx =  ¤аҐб бва®ЄЁ § Ј®«®ўЄ  +‚®§ўа й Ґ¬®Ґ §­ зҐ­ЁҐ: + * дг­ЄжЁп ­Ґ ў®§ўа й Ґв §­ зҐ­Ёп +‡ ¬Ґз ­Ёп: + * ‘ва®Є  § Ј®«®ўЄ  ¤®«¦­  Ўлвм ў д®а¬ вҐ ASCIIZ. ‚ § Ј®«®ўЄҐ + ®в®Ўа ¦ Ґвбп ­Ґ Ў®«ҐҐ 255 бЁ¬ў®«®ў ­Ґ§ ўЁбЁ¬® ®в Ї®«­®© ¤«Ё­л + бва®ЄЁ. + * —в®Ўл гЎа вм § Ј®«®ў®Є, ЇҐаҐ¤ ©вҐ NULL ў ecx. + +====================================================================== +========== ”г­ЄжЁп -1 - § ўҐаиЁвм ўлЇ®«­Ґ­ЁҐ Ї®в®Є /Їа®жҐбб  ========= +====================================================================== +Џ а ¬Ґвал: + * 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) + +====================================================================== +==================== Љ®¤л ®иЁЎ®Є д ©«®ў®© бЁб⥬л ==================== +====================================================================== + * 0 = гбЇҐи­® + * 1 = ­Ґ ®ЇаҐ¤Ґ«Ґ­  Ў §  Ё/Ё«Ё а §¤Ґ« ¦сбвЄ®Ј® ¤ЁбЄ  (Ї®¤дг­ЄжЁп¬Ё + 7, 8 дг­ЄжЁЁ 21) + * 2 = дг­ЄжЁп ­Ґ Ї®¤¤Ґа¦Ёў Ґвбп ¤«п ¤ ­­®© д ©«®ў®© бЁб⥬л + * 3 = ­ҐЁ§ўҐбв­ п д ©«®ў п бЁб⥬  + * 4 = ў®§ўа й Ґвбп в®«мЄ® дг­ЄжЁҐ© rename ЇаЁ ЇҐаҐ¤ зҐ бЁ«м­® + ­ҐўҐа­®Ј® Ї а ¬Ґва  Ё ­ЁЄ Є ­Ґ ᮮ⢥вбвўгҐв ®ЇЁб ­Ёо + ў Ёб室­ЁЄ е п¤а  "partition not defined at hd" + * 5 = д ©« ­Ґ ­ ©¤Ґ­ + * 6 = д ©« § Є®­зЁ«бп + * 7 = гЄ § вҐ«м ў­Ґ Ї ¬пвЁ ЇаЁ«®¦Ґ­Ёп + * 8 = ¤ЁбЄ § Ї®«­Ґ­ + * 9 = в Ў«Ёж  FAT а §аг襭  + * 10 = ¤®бвгЇ § ЇаҐйс­ + * 11 = ®иЁЎЄ  гбва®©бвў  +ЏаЁ § ЇгбЄҐ Їа®Ја ¬¬л ў®§¬®¦­л в Є¦Ґ б«Ґ¤гойЁҐ Є®¤л ®иЁЎ®Є: + * 30 = 0x1E = ­Ґ¤®бв в®з­® Ї ¬пвЁ + * 31 = 0x1F = д ©« ­Ґ пў«пҐвбп ЁбЇ®«­Ё¬л¬ + * 32 = 0x20 = б«ЁиЄ®¬ ¬­®Ј® Їа®жҐбб®ў diff --git a/kernel/tags/kolibri0.6.0.0/docs/sysfuncs.txt b/kernel/tags/kolibri0.6.0.0/docs/sysfuncs.txt new file mode 100644 index 0000000000..f426a73acd --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/docs/sysfuncs.txt @@ -0,0 +1,4437 @@ +SYSTEM FUNCTIONS of OS Kolibri 0.6.0.0 + +Number of the function is located in the register eax. +The call of the system function is executed by "int 0x40" command. +All registers except explicitly declared in the returned value, + including eflags, are preserved. + + +====================================================================== +============== Function 0 - define and draw the window. ============== +====================================================================== +Defines an application window. Draws a frame of the window, header and +working area. For skinned windows defines standard close and minimize +buttons. +Parameters: + * eax = 0 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = 0xXYRRGGBB, where: + * Y = style of the window: + * Y=0 - type I - fixed-size window + * Y=1 - only define window area, draw nothing + * Y=2 - type II - variable-size window + * Y=3 - skinned window + * other possible values (from 4 up to 15) are reserved, + function call with such Y is ignored + * RR, GG, BB = accordingly red, green, blue components of a color + of the working area of the window (are ignored for style Y=2) + * X = DCBA (bits) + * A = 1 - window has caption; for style Y=3 caption string + must be passed in edi, for other styles use + subfunction 1 of function 71 + * B = 1 - coordinates of all graphics primitives are relative to + window client area + * C is reserved (set to 0) + * D = 0 - normal filling of the working area, 1 - gradient + The following parameters are intended for windows + of a type I and II, and ignored for styles Y=1,3: + * esi = 0xXYRRGGBB - color of the header + * RR, GG, BB define color + * Y=0 - usual window, Y=1 - unmovable window + * X defines a gradient of header: X=0 - no gradient, + X=8 - usual gradient, + for windows of a type II X=4 - negative gradient + * other values of X and Y are reserved + * edi = 0x00RRGGBB - color of the frame +Returned value: + * function does not return value +Remarks: + * Position and sizes of the window are installed by the first + call of this function and are ignored at subsequent; to change + position and/or sizes of already created window use function 67. + * For windows with style Y=3 and caption (A=1) caption string is set + by the first call of this function and is ignored at subsequent + (strictly speaking, is ignored after a call to subfunction 2 + of function 12 - end redraw); to change caption of already created + window use subfunction 1 of function 71. + * If the window has appropriate styles, position and/or sizes can be + changed by user. Current position and sizes can be obtained + by function 9. + * The window must fit on the screen. If the transferred + coordinates and sizes do not satisfy to this condition, + appropriate coordinate (or, probably, both) is considered as zero, + and if it does not help too, the appropriate size + (or, probably, both) is installed in a size of the screen. + + Further let us designate xpos,ypos,xsize,ysize - values passed + in ebx,ecx. The coordinates are resulted concerning + the left upper corner of the window, which, thus, is set as (0,0), + coordinates of the right lower corner essence (xsize,ysize). + * The sizes of the window are understood in sence of coordinates + of the right lower corner. This concerns all other functions too. + It means, that the real sizes are on 1 pixel more. + * The window of type I looks as follows: + * draw external frame of color indicated in edi, 1 pixel in width + * draw header - rectangle with the left upper corner (1,1) and + right lower (xsize-1,min(25,ysize)) color indicated in esi + (taking a gradient into account) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (1,21) and right lower + (xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color + indicated in edx (taking a gradient into account) + * if A=1 and caption has been already set by subfunction 1 + of function 71, it is drawn in the corresponding place of header + * The window of style Y=1 looks as follows: + * completely defined by the application + * The window of type II looks as follows: + * draw external frame of width 1 pixel with the "shaded" color + edi (all components of the color decrease twice) + * draw intermediate frame of width 3 pixels with color edi + * draw internal frame of width 1 pixel with the "shaded" color edi + * draw header - rectangle with the left upper corner (4,4) + and right lower (xsize-4,min(20,ysize)) color, indicated in esi + (taking a gradient into account) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (5,20) and right lower + (xsize-5,ysize-5) with color indicated in edx + (taking a gradient into account) + * if A=1 and caption has been already set by subfunction 1 + of function 71, it is drawn in the corresponding place of header + * The skinned window looks as follows: + * draw external frame of width 1 pixel + with color 'outer' from the skin + * draw intermediate frame of width 3 pixel + with color 'frame' from the skin + * draw internal frame of width 1 pixel + with color 'inner' from the skin + * draw header (on bitmaps from the skin) in a rectangle + (0,0) - (xsize,_skinh-1) + * if ysize>=26, fill the working area of the window - + rectangle with the left upper corner (5,_skinh) and right lower + (xsize-5,ysize-5) with color indicated in edx + (taking a gradient into account) + * define two standard buttons: close and minimize + (see function 8) + * if A=1 and edi contains (nonzero) pointer to caption string, + it is drawn in place in header defined in the skin + * value _skinh is accessible as the result of call + subfunction 4 of function 48 + +====================================================================== +================ Function 1 - put pixel in the window. =============== +====================================================================== +Parameters: + * eax = 1 - function number + * ebx = x-coordinate (relative to the window) + * ecx = y-coordinate (relative to the window) + * edx = 0x00RRGGBB - color of a pixel + edx = 0x01xxxxxx - invert color of a pixel + (low 24 bits are ignored) +Returned value: + * function does not return value + +====================================================================== +============ Function 2 - get the code of the pressed key. =========== +====================================================================== +Takes away the code of the pressed key from the buffer. +Parameters: + * eax = 2 - function number +Returned value: + * if the buffer is empty, function returns eax=1 + * if the buffer is not empty, function returns al=0, + ah=code of the pressed key, high word of eax is zero + * if there is "hotkey", function returns al=2, + ah=scancode of the pressed key (0 for control keys), + high word of eax contains a status of control keys at the moment + of pressing a hotkey +Remarks: + * There is a common system buffer of the pressed keys + by a size of 120 bytes, organized as queue. + * There is one more common system buffer on 120 "hotkeys". + * If the application with the inactive window calls this function, + the buffer of the pressed keys is considered to be empty. + * By default this function returns ASCII-codes; to switch + to the scancodes mode (and back) use function 66. + However, hotkeys are always notificated as scancodes. + * To find out, what keys correspond to what codes, start + the application keyascii and scancode. + * Scancodes come directly from keyboard and are fixed; + ASCII-codes turn out with usage of the conversion tables, + which can be set by subfunction 2 of function 21 + and get by subfunction 2 of function 26. + * As a consequence, ASCII-codes take into account current + keyboard layout (rus/en) as opposed to scancodes. + * This function notifies only about those hotkeys, which were + defined by this thread by subfunction 4 of function 66. + +====================================================================== +==================== Function 3 - get system time. =================== +====================================================================== +Parameters: + * eax = 3 - function number +Returned value: + * eax = 0x00SSMMHH, where HH:MM:SS = Hours:Minutes:Seconds + * each item is BCD-number, for example, + for time 23:59:59 function returns 0x00595923 +Remarks: + * See also subfunction 9 of function 26 - get time from + the moment of start of the system; it is more convenient, because + returns simply DWORD-value of the time counter. + * System time can be set by function 22. + +====================================================================== +============ Function 4 - draw text string in the window. ============ +====================================================================== +Parameters: + * eax = 4 - function number + * ebx = [coordinate on axis x]*65536 + [coordinate on axis y] + * ecx = 0xX0RRGGBB, where + * RR, GG, BB specify text color + * X=ABnn (bits): + * nn specifies the used font: 0=system monospaced, + 1=system font of variable width + * A=0 - output esi characters, A=1 - output ASCIIZ-string + * B=1 - fill background with the color edi + * edx = pointer to the beginning of the string + * esi = for A=0 length of the string, must not exceed 255; + for A=1 is ignored +Returned value: + * function does not return value +Remarks: + * First system font is read out at loading from the file char.mt, + second - from char2.mt. + * Both fonts have height 9 pixels, width of the monospaced font + is equal to 6 pixels. + +====================================================================== +========================= Function 5 - delay. ======================== +====================================================================== +Delays execution of the program on the given time. +Parameters: + * eax = 5 - function number + * ebx = time in the 1/100 of second +Returned value: + * function does not return value +Remarks: + * Passing ebx=0 does not transfer control to the next process + and does not make any operations at all. If it is really required + to transfer control to the next process (to complete a current + time slice), use subfunction 1 of function 68. + * At current implementation there will be an immediate return from + the function, if the addition of ebx with current value of + time counter will call 32-bit overflow. + +====================================================================== +============== Function 6 - read the file from ramdisk. ============== +====================================================================== +Parameters: + * eax = 6 - function number + * ebx = pointer to the filename + * ecx = number of start block, beginning from 1; + ecx=0 - read from the beginning of the file (same as ecx=1) + * edx = number of blocks to read; + edx=0 - read one block (same as edx=1) + * esi = pointer to memory area for the data +Returned value: + * eax = file size in bytes, if the file was successfully read + * eax = -1, if the file was not found +Remarks: + * This function is out-of-date; function 70 allows + to fulfil the same operations with the extended possibilities. + * Block = 512 bytes. + * For reading all file you can specify the certainly large value + in edx, for example, edx = -1; but in this case be ready that + the program will "fall", if the file will appear too large and can + not be placed in the program memory. + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +=============== Function 7 - draw image in the window. =============== +====================================================================== +Paramters: + * eax = 7 - function number + * ebx = pointer to the image in the format BBGGRRBBGGRR... + * ecx = [size on axis x]*65536 + [size on axis y] + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] +Returned value: + * function does not return value +Remarks: + * Coordinates of the image are coordinates of the upper left corner + of the image relative to the window. + * Size of the image in bytes is 3*xsize*ysize. + +====================================================================== +=============== Function 8 - define/delete the button. =============== +====================================================================== +Parameters for button definition: + * eax = 8 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = 0xXYnnnnnn, where: + * nnnnnn = identifier of the button + * high (31st) bit of edx is cleared + * if 30th bit of edx is set - do not draw the button + * if 29th bit of edx is set - do not draw a frame + at pressing the button + * esi = 0x00RRGGBB - color of the button +Parameters for button deleting: + * eax = 8 - function number + * edx = 0x80nnnnnn, where nnnnnn - identifier of the button +Returned value: + * function does not return value +Remarks: + * Sizes of the button must be more than 0 and less than 0x8000. + * For skinned windows definition of the window + (call of 0th function) creates two standard buttons - + for close of the window with identifier 1 and + for minimize of the window with identifier 0xffff. + * The creation of two buttons with same identifiers is admitted. + * The button with the identifier 0xffff at pressing is interpreted + by the system as the button of minimization, the system handles + such pressing independently, not accessing to the application. + In rest it is usual button. + * Total number of buttons for all applications is limited to 4095. + +====================================================================== +============ Function 9 - information on execution thread. =========== +====================================================================== +Parameters: + * eax = 9 - function number + * ebx = pointer to 1-Kb buffer + * ecx = number of the slot of the thread + ecx = -1 - get information on the current thread +Returned value: + * eax = maximum number of the slot of a thread + * buffer pointed to by ebx contains the following information: + * +0: dword: usage of the processor (how many time units + per second leaves on execution of this thread) + * +4: word: position of the window of thread in the window stack + * +6: word: (has no relation to the specified thread) + number of the thread slot, which window has in the window stack + position ecx + * +8: word: reserved + * +10 = +0xA: 11 bytes: name of the process + (name of corresponding executable file in the format 8+3) + * +21 = +0x15: byte: reserved, this byte is not changed + * +22 = +0x16: dword: address of the process in memory + * +26 = +0x1A: dword: size of used memory - 1 + * +30 = +0x1E: dword: identifier (PID/TID) + * +34 = +0x22: dword: coordinate of the thread window on axis x + * +38 = +0x26: dword: coordinate of the thread window on axis y + * +42 = +0x2A: dword: size of the thread window on axis x + * +46 = +0x2E: dword: size of the thread window on axis y + * +50 = +0x32: word: status of the thread slot: + * 0 = thread is running + * 1 = thread is suspended + * 2 = thread is suspended while waiting for event + * 3 = thread is terminating as a result of call to function -1 + or under duress as a result of call to subfunction 2 + of function 18 or termination of the system + * 4 = thread is terminating as a result of exception + * 5 = thread waits for event + * 9 = requested slot is free, all other information on the slot + is not meaningful + * +52 = +0x34: word: reserved, this word is not changed + * +54 = +0x36: dword: coordinate of the client area on axis x + * +58 = +0x3A: dword: coordinate of the client area on axis y + * +62 = +0x3E: dword: width of the client area + * +66 = +0x42: dword: height of the client area + * +70 = +0x46: byte: state of the window - bitfield + * bit 0 (mask 1): window is maximized + * bit 1 (mask 2): window is minimized to panel + * bit 2 (mask 4): window is rolled up +Remarks: + * Slots are numbered starting from 1. + * Returned value is not a total number of threads, because there + can be free slots. + * When process is starting, system automatically creates + execution thread. + * Function gives information on the thread. Each process has + at least one thread. One process can create many threads, + in this case each thread has its own slot and the fields + +10, +22, +26 in these slots coincide. + Applications have no common way to define whether two threads + belong to one process. + * The active window - window on top of the window stack - + receives the messages on a keyboard input. For such window + the position in the window stack coincides with returned value. + * Slot 1 corresponds to special system thread, for which: + * the window is in the bottom of the window stack, the fields + +4 and +6 contain value 1 + * name of the process - "OS/IDLE" (supplemented by spaces) + * address of the process in memory is 0, size of used memory is + 16 Mb (0x1000000) + * PID=1 + * coordinates and sizes of the window and the client area are by + convention set to 0 + * status of the slot is always 0 (running) + * the execution time adds of time leaving on operations itself + and idle time in waiting for interrupt (which can be got by call + to subfunction 4 of function 18). + * Beginning from slot 2, the normal applications are placed. + * The normal applications are placed in memory at the address + 0x10000000 (kernel constand 'std_application_base_address'). + There is no intersection, as each process has its own page table. + * At creation of the thread it is assigned the slot + in the system table and identifier (Process/Thread IDentifier = + PID/TID), which do not vary with time for given thread. + After completion of the thread its slot can be anew used + for another thread. The thread identifier can not be assigned + to other thread even after completion of this thread. + Identifiers, assigned to new threads, grow monotonously. + * If the thread has not yet defined the window by call to + function 0, the position and the sizes + of its window are considered to be zero. + * Coordinates of the client area are relative to the window. + * At the moment only the part of the buffer by a size + 71 = 0x37 bytes is used. Nevertheless it is recommended to use + 1-Kb buffer for the future compatibility, in the future + some fields can be added. + +====================================================================== +==================== Function 10 - wait for event. =================== +====================================================================== +If the message queue is empty, waits for appearance of the message +in queue. In this state thread does not consume CPU time. +Then reads out the message from queue. + +Parameters: + * eax = 10 - function number +Returned value: + * eax = event (see the list of events) +Remarks: + * Those events are taken into account only which enter into + a mask set by function 40. By default it is + redraw, key and button events. + * To check, whether there is a message in queue, use function 11. + To wait for no more than given time, use function 23. + +====================================================================== +=============== Function 11 - check for event, no wait. ============== +====================================================================== +If the message queue contains event, function reads out +and return it. If the queue is empty, function returns 0. +Parameters: + * eax = 11 - function number +Returned value: + * eax = 0 - message queue is empty + * else eax = event (see the list of events) +Remarks: + * Those events are taken into account only, which enter into + a mask set by function 40. By default it is + redraw, key and button events. + * To wait for event, use function 10. + To wait for no more than given time, use function 23. + +====================================================================== +=============== Function 12 - begin/end window redraw. =============== +====================================================================== + +---------------- Subfunction 1 - begin window redraw. ---------------- +Parameters: + * eax = 12 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value + +----------------- Subfunction 2 - end window redraw. ----------------- +Parameters: + * eax = 12 - function number + * ebx = 2 - subfunction number +Returned value: + * function does not return value +Remarks: + * Subfunction 1 deletes all buttons defined with + function 8, they must be defined again. + +====================================================================== +============ Function 13 - draw a rectangle in the window. =========== +====================================================================== +Parameters: + * eax = 13 - function number + * ebx = [coordinate on axis x]*65536 + [size on axis x] + * ecx = [coordinate on axis y]*65536 + [size on axis y] + * edx = color 0xRRGGBB or 0x80RRGGBB for gradient fill +Returned value: + * function does not return value +Remarks: + * Coordinates are understood as coordinates of the left upper corner + of a rectangle relative to the window. + +====================================================================== +=================== Function 14 - get screen size. =================== +====================================================================== +Parameters: + * eax = 14 - function number +Returned value: + * eax = [xsize]*65536 + [ysize], where + * xsize = x-coordinate of the right lower corner of the screen = + horizontal size - 1 + * ysize = y-coordinate of the right lower corner of the screen = + vertical size - 1 +Remarks: + * See also subfunction 5 of function 48 - get sizes of + working area of the screen. + +====================================================================== +== Function 15, subfunction 1 - set a size of the background image. == +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 1 - subfunction number + * ecx = width of the image + * edx = height of the image +Returned value: + * function does not return value +Remarks: + * There is no checks for correctness. The setting of too large + values will result that the background will contain data abroad + of buffer for the background image. Buffer size = 0x160000-0x10, + that corresponds to maximum size 800*600. (800*600*3=0x15F900) + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get size of the background image - + subfunction 1 of function 39. + +====================================================================== +=== Function 15, subfunction 2 - put pixel on the background image. == +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 2 - subfunction number + * ecx = offset + * edx = color of a pixel 0xRRGGBB +Returned value: + * function does not return value +Remarks: + * Offset for a pixel with coordinates (x,y) is calculated as + (x+y*xsize)*3. + * If the given offset exceeds 0x160000-16 = 1.375 Mb - 16 bytes, + the call is ignored. + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get pixel on the background image - + subfunction 2 of function 39. + +====================================================================== +=========== Function 15, subfunction 3 - redraw background. ========== +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 3 - subfunction number +Returned value: + * function does not return value + +====================================================================== +== Function 15, subfunction 4 - set drawing mode for the background. = +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 4 - subfunction number + * ecx = drawing mode: + * 1 = tile + * 2 = stretch +Returned value: + * function does not return value +Remarks: + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + * There is a pair function for get drawing mode of the background - + subfunction 4 of function 39. + +====================================================================== +===================== Function 15, subfunction 5 ===================== +============ Put block of pixels on the background image. ============ +====================================================================== +Parameters: + * eax = 15 - function number + * ebx = 5 - subfunction number + * ecx = pointer to the data in the format BBGGRRBBGGRR... + * edx = offset in data of the background image + * esi = size of data in bytes = 3 * number of pixels +Returned value: + * function does not return value +Remarks: + * If the block gets out abroad 0x160000-16 = 1.375 Mb - 16 bytes, + the call is ignored. + * Color of each pixel is stored as 3-bytes value BBGGRR. + * Pixels of the background image are written sequentially + from left to right, from up to down. + * Offset of pixel with coordinates (x,y) is (x+y*xsize)*3. + * For update of the screen (after completion of a series of commands + working with a background) call subfunction 3. + +====================================================================== +=============== Function 16 - save ramdisk on a floppy. ============== +====================================================================== +Parameters: + * eax = 16 - function number + * ebx = 1 or ebx = 2 - on which floppy save +Returned value: + * eax = 0 - success + * eax = 1 - error + +====================================================================== +======= Function 17 - get the identifier of the pressed button. ====== +====================================================================== +Takes away the code of the pressed button from the buffer. +Parameters: + * eax = 17 - function number +Returned value: + * if the buffer is empty, function returns eax=1 + * if the buffer is not empty, function returns al=0, + high 24 bits of eax contain button identifier (in particular, ah + contains low byte of the identifier; if all buttons have + the identifier less than 256, ah is enough to distinguish). +Remarks: + * "Buffer" keeps only one button, at pressing the new button the + information about old is lost. + * The call of this function by an application with inactive window + will return answer "buffer is empty". + +====================================================================== +============ Function 18, subfunction 1 - system shutdown. =========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 1 - subfunction number +Returned value: + * function always return eax = 0 as tag of success +Remarks: + * On the last step menu of exit from the system appears and waits + response of the user. + * See also subfunction 9, system shutdown with + the parameter to force the choice in the exit menu. + +====================================================================== += Function 18, subfunction 2 - terminate process/thread by the slot. = +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 2 - subfunction number + * ecx = number of the slot of process/thread +Returned value: + * function does not return value +Remarks: + * It is impossible to terminate system thread OS/IDLE (with + number of the slot 1), + it is possible to terminate any normal process/thread. + * See also subfunction 18 - terminate + process/thread by the identifier. + +====================================================================== +===================== Function 18, subfunction 3 ===================== +============= Make active the window of the given thread. ============ +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 3 - subfunction number + * ecx = number of the thread slot +Returned value: + * function does not return value +Remarks: + * If correct, but nonexistent slot is given, + some window is made active. + * To find out, which window is active, use subfunction 7. + +====================================================================== +===================== Function 18, subfunction 4 ===================== +=========== Get counter of idle time units per one second. =========== +====================================================================== +Idle time units are units, in which the processor stands idle +in waiting for interrupt (in the command 'hlt'). + +Parameters: + * eax = 18 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = value of the counter of idle time units per one second + +====================================================================== +========== Function 18, subfunction 5 - get CPU clock rate. ========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = clock rate (modulo 2^32 clock ticks = 4GHz) + +====================================================================== + Function 18, subfunction 6 - save ramdisk to the file on hard drive. +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 6 - subfunction number + * ecx defines path to the file: + * 1 = in the folder "/KOLIBRI" + * 2 = in the root folder + * 3 = edx points to the path (names of folders in the format 8+3, + divided by '/') +Returned value: + * eax = 0 - success + * else eax = error code of the file system +Замечания: + * Filename is fixed, "menuet.img" (global kernel variable + 'image_save' from 'preboot.inc') + * Drive and partition are defined by subfunction 7 + and subfunction 8 of function 21. + * All folders in the given path must exist, otherwise function + returns value 5, "file not found". + +====================================================================== +=========== Function 18, subfunction 7 - get active window. ========== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = number of the active window + (number of the slot of the thread with active window) +Remarks: + * Active window is at the top of the window stack and receives + messages on all keyboard input. + * To make a window active, use subfunction 3. + +====================================================================== +== Function 18, subfunction 8 - disable/enable the internal speaker. = +====================================================================== +If speaker sound is disabled, all calls to subfunction 55 of +function 55 are ignored. If speaker sound is enabled, +they are routed on builtin speaker. + +------------------- Subsubfunction 1 - get status. ------------------- +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 1 - number of the subsubfunction +Returned value: + * eax = 0 - speaker sound is enabled; 1 - disabled + +----------------- Subsubfunction 2 - toggle status. ------------------ +Toggles states of disable/enable. +Parameters: + * eax = 18 - function number + * ebx = 8 - subfunction number + * ecx = 2 - number of the subsubfunction +Returned value: + * function does not return value + +====================================================================== +== Function 18, subfunction 9 - system shutdown with the parameter. == +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 9 - subfunction number + * ecx = parameter: + * 1 = on the last step of shutdown save ramdisk on a floppy and + then show the exit menu and request further operations + from the user + * 2 = turn off computer + * 3 = reboot computer + * 4 = restart the kernel from the file 'kernel.mnt' on ramdisk +Returned value: + * at incorrect ecx the registers do not change (i.e. eax=18) + * by correct call function always returns eax=0 + as the tag of success +Remarks: + * Do not rely on returned value by incorrect call, it can be + changed in future versions of the kernel. + * It is possible to use subfunction 1, that on the last step + the user makes choice himself. + * It is not recommended to use value ecx=1 (to not irritate the user + with excessive questions); to save ramdisk on a floppy use + function 16 (which admits specification, on which floppy to + write), and to shutdown with the exit menu use already mentioned + subfunction 1. + +====================================================================== +===== Function 18, subfunction 10 - minimize application window. ===== +====================================================================== +Minimizes the own window. +Parameters: + * eax = 18 - function number + * ebx = 10 - subfunction number +Returned value: + * function does not return value +Remarks: + * The minimized window from the point of view of function 9 + keeps position and sizes. + * Restoring of an application window occurs at its activation by + subfunction 3. + * Usually there is no necessity to minimize/restire a window + obviously: minimization of a window is carried out by the system + at pressing the minimization button (for skinned windows + it is defined automatically by function 0, + for other windows it can be defined manually by function 8), + restore of a window is done by the application '@panel'. + +====================================================================== + Function 18, subfunction 11 - get information on the disk subsystem. +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 11 - subfunction number + * ecx = type of the table: + * 1 = short version, 10 bytes + * 2 = full version, 65536 bytes + * edx = pointer to the buffer (in the application) for the table +Returned value: + * function does not return value +Format of the table: short version: + * +0: byte: information about FDD's (drives for floppies), + AAAABBBB, where AAAA gives type of the first drive, BBBB - + of the second regarding to the following list: + * 0 = there is no drive + * 1 = 360Kb, 5.25'' + * 2 = 1.2Mb, 5.25'' + * 3 = 720Kb, 3.5'' + * 4 = 1.44Mb, 3.5'' + * 5 = 2.88Mb, 3.5'' (such drives are not used anymore) + For example, for the standard configuration from one 1.44-drive + here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B: + the value is 24h. + * +1: byte: information about hard disks and CD-drives, AABBCCDD, + where AA corresponds to the controller IDE0, ..., DD - IDE3: + * 0 = device is absent + * 1 = hard drive + * 2 = CD-drive + For example, in the case HD on IDE0 and CD on IDE2 + this field contains 48h. + * +2: 4 db: number of the retrieved partitions on hard disks + at accordingly IDE0,...,IDE3. + If the hard disk on IDEx is absent, appropriate byte is zero, + otherwise it shows number of the recognized partitions, which + can be not presented (if the drive is not formatted or if + the file system is not supported). Current version of the kernel + supports only FAT16 and FAT32 for hard disks. + * +6: 4 db: reserved +Format of the table: full version: + * +0: 10 db: same as for the short version + * +10: 100 db: data for the first partition + * +110: 100 db: data for the second partition + * ... + * +10+100*(n-1): 100 db: data for the last partition +The partitions are located as follows: at first sequentially all +recoginzed partitions on HD on IDE0 (if present), +then on HD on IDE1 (if present) and so on up to IDE3. +Format of the information about partition +(at moment only FAT is supported): + * +0: dword: first physical sector of the partition + * +4: dword: last physical sector of the partition + (belongs to the partition) + * +8: dword: sectors per one copy of FAT + * +12 = +0xC: dword: number of copies of FAT + * +16 = +0x10: dword: number of sectors per cluster + * +20 = +0x14: dword: bytes per sector; + current implementation expects 0x200 = 512 in this field + * +24 = +0x18: dword: first root cluster in FAT32, 0 for FAT16 + * +28 = +0x1C: dword: first physical sector of FAT + * +32 = +0x20: dword: first physical root sector for FAT16, + ignored for FAT32 + * +36 = +0x24: dword: number of root sectors for FAT16, + 0 for FAT32 + * +40 = +0x28: dword: physical sector of the beginning of + the data area + * +44 = +0x2C: dword: maximum number of a cluster + * +48 = +0x30: dword: physical sector of the information + about the file system for FAT32, ignored for FAT16 + * +52 = +0x34: dword: value used as boundary for special + values in FAT + * +56 = +0x38: dword: value used for bad clusters in FAT + * +60 = +0x3C: dword: value used as the end marker for FAT chain + * +64 = +0x40: dword: mask for FAT items + * +68 = +0x44: byte: file system type: 16 или 32 + * +69 = +0x45: 31 db: reserved +Remarks: + * The short table can be used for obtaining the information about + available devices. + * First two fields in the information about partition + gives the parameters of partition, other - parameters of + FAT file system. For other file systems (when they will be + supported) specific for file system information will be, of + course, another, but first two fields will have the same sense. + +====================================================================== +========== Function 18, subfunction 13 - get kernel version. ========= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 13 - subfunction number + * ecx = pointer to the buffer (not less than 16 bytes), where + the information will be placed +Returned value: + * function does not return value +Structure of the buffer: +db a,b,c,d for version a.b.c.d +db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 +db 'name',0 - ASCIIZ-string with the name +For Kolibri 0.6.0.0 kernel: +db 0,6,0,0 +db 2 +db 'Kolibri',0 + +====================================================================== +======= Function 18, subfunction 14 - wait for screen retrace. ======= +====================================================================== +Waits for the beginning of retrace of the scanning ray of the screen +monitor. +Parameters: + * eax = 18 - function number + * ebx = 14 - subfunction number +Returned value: + * eax = 0 as the tag of success +Remarks: + * Function is intended only for active high-efficiency graphics + applications; is used for smooth output of a graphics. + +====================================================================== +== Function 18, subfunction 15 - center mouse cursor on the screen. == +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 15 - subfunction number +Returned value: + * eax = 0 as the tag of success + +====================================================================== +========= Function 18, subfunction 16 - get size of free RAM. ======== +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 16 - subfunction number +Returned value: + * eax = size of free memory in kilobytes + +====================================================================== +======== Function 18, subfunction 17 - get full amount of RAM. ======= +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 17 - subfunction number +Returned value: + * eax = total size of existing memory in kilobytes + +====================================================================== +===================== Function 18, subfunction 18 ==================== +============= Terminate process/thread by the identifier. ============ +====================================================================== +Parameters: + * eax = 18 - function number + * ebx = 18 - subfunction number + * ecx = identifer of process/thread (PID/TID) +Returned value: + * eax = 0 - success + * eax = -1 - error (process is not found or is system) +Remarks: + * It is impossible to terminate system thread OS/IDLE (identifier + 1), it is possible to terminate any normal process/thread. + * See also subfunction 2 - terminate + process/thread by given slot. + +====================================================================== +======== Function 18, subfunction 19 - get/set mouse features. ======= +====================================================================== + +---------------- Subsubfunction 0 - get mouse speed. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 0 - subsubfunction number +Returned value: + * eax = current mouse speed + +---------------- Subsubfunction 1 - set mouse speed. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 1 - subsubfunction number + * edx = new value for speed +Returned value: + * function does not return value + +---------------- Subsubfunction 2 - get mouse delay. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 2 - subsubfunction number +Returned value: + * eax = current mouse delay + +---------------- Subsubfunction 3 - set mouse delay. ----------------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 3 - subsubfunction number + * edx = new value for mouse delay +Returned value: + * function does not return value + +----------- Subsubfunction 4 - set mouse pointer position. ----------- +Parameters: + * eax = 18 - function number + * ebx = 19 - subfunction number + * ecx = 4 - subsubfunction number + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] +Returned value: + * function does not return value +Remarks: + * It is recommended to set speed of the mouse (in subsubfunction 1) + from 1 up to 9. The installed value is not inspected by the kernel + code, so set it carefully, at incorrect value the cursor + can "freeze". Speed of the mouse can be regulated through the + application SETUP. + * Recommended delay of the mouse (in subsubfunction 3) = 10. Lower + value is not handled by COM mice. At the very large values the + movement of the mouse on 1 pixel is impossible and the cursor will + jump on the value of installed speed (subsubfunction 1). The + installed value is not inspected by the kernel code. + Mouse delay can be regulated through the application SETUP. + * The subsubfunction 4 does not check the passed value. Before + its call find out current screen resolution (with function 14) + and check that the value of position is inside the limits of the + screen. + +====================================================================== +==================== Function 20 - MIDI interface. =================== +====================================================================== + +----------------------- Subfunction 1 - reset ------------------------ +Parameters: + * eax = 20 - function number + * ebx = 1 - subfunction number + +-------------------- Subfunction 2 - output byte --------------------- +Parameters: + * eax = 20 - function number + * ebx = 2 - subfunction number + * cl = byte for output +Returned value (is the same for both subfunctions): + * eax = 0 - success + * eax = 1 - base port is not defined +Remarks: + * Previously the base port must be defined by + subfunction 1 of function 21. + +====================================================================== +======== Function 21, subfunction 1 - set MPU MIDI base port. ======== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 1 - subfunction number + * ecx = number of base port +Returned value + * eax = 0 - success + * eax = -1 - erratic number of a port +Remarks: + * Number of a port must satisfy to conditions 0x100<=ecx<=0xFFFF. + * The installation of base is necessary for function 20. + * To get base port use subfunction 1 of function 26. + +====================================================================== +========== Function 21, subfunction 2 - set keyboard layout. ========= +====================================================================== +Keyboard layout is used to convert keyboard scancodes to ASCII-codes, +which will be read by function 2. +Parameters: + * eax = 21 - function number + * ebx = 2 - subfunction number + * ecx = which layout to set: + * 1 = normal layout + * 2 = layout at pressed Shift + * 3 = layout at pressed Alt + * edx = pointer to layout - table of length 128 bytes +Or: + * ecx = 9 + * dx = country identifier (1=eng, 2=fi, 3=ger, 4=rus) +Returned value: + * eax = 0 - success + * eax = 1 - incorrect parameter +Remarks: + * If Alt is pressed, the layout with Alt is used; + if Alt is not pressed, but Shift is pressed, + the layout with Shift is used; + if Alt and Shift are not pressed, but Ctrl is pressed, the normal + layout is used and then from the code is subtracted 0x60; + if no control key is pressed, the normal layout is used. + * To get layout and country identifier use + subfunction 2 of function 26. + * Country identifier is global system variable, which is not used + by the kernel itself; however the application '@panel' displays + the corresponding icon. + * The application @panel switches layouts on user request. + +====================================================================== +============== Function 21, subfunction 3 - set CD base. ============= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 3 - subfunction number + * ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Returned value: + * eax = 0 +Remarks: + * CD base is used by function 24. + * To get CD base use subfunction 3 of function 26. + +====================================================================== +====== Function 21, subfunction 4 - set Sound Blaster base port. ===== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 4 - subfunction number + * ecx = number of the base port +Returned value: + * eax = 0 - success + * eax = -1 - erratic port number +Remarks: + * Number of the port must satisfy to conditions 0x100<=ecx<=0xFFFF. + * The installation of the base is necessary for + functions 25, 28, 55. + * To get base port use subfunction 4 of function 26. + +====================================================================== +========== Function 21, subfunction 5 - set system language. ========= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 5 - subfunction number + * ecx = system language (1=eng, 2=fi, 3=ger, 4=rus) +Returned value: + * eax = 0 +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon. + * Function does not check for correctness, as the kernel does not + use this variable. + * To get system language use subfunction 5 of function 26. + +====================================================================== +=========== Function 21, subfunction 6 - set WSS base port. ========== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 6 - subfunction number + * ecx = base port +Returned value: + * eax = 0 - success + * eax = -1 - erratic port number +Remarks: + * Port number must satisfy to condition 0x100<=ecx. + * WSS base is used by function 27. + * To get WSS base port use subfunction 6 of function 26. + +====================================================================== +============== Function 21, subfunction 7 - set HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +file system functions and functions implicitly using the hard disk +(such as subfunction 6 of function 18); +at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +these function set base themselves. +Parameters: + * eax = 21 - function number + * ebx = 7 - subfunction number + * ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Returned value: + * eax = 0 +Remarks: + * Any application at any time can change the base. + * Do not change base, when any application works with hard disk. + If you do not want system bugs. + * To get HD base use subfunction 7 of function 26. + * It is also necessary to define used partition of hard disk by + subfunction 8. + +====================================================================== +========= Function 21, subfunction 8 - set used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete file system functions and functions implicitly +using the hard disk (such as subfunction 6 of function 18); +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +these functions set base and partition themselves. +Parameters: + * eax = 21 - function number + * ebx = 8 - subfunction number + * ecx = HD partition (beginning from 1) +Return value: + * eax = 0 +Remarks: + * Any application at any time can change partition. + * Do not change partition when any application works with hard disk. + If you do not want system bugs. + * To get used partition use subfunction 8 of function 26. + * There is no correctness checks. + * To get the number of partitions of a hard disk use + subfunction 11 of function 18. + * It is also necessary to define used HD base by subfunction 7. + +====================================================================== +======== Function 21, subfunction 10 - set sound DMA channel. ======== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 10 - subfunction number + * ecx = number of channel (from 0 up to 3 inclusively) +Returned value: + * eax = 0 - success + * eax = -1 - incorrect channel number +Remarks: + * Number of DMA channel is used in subfunction 1 of function 55. + * To get sound DMA channel use subfunction 10 of function 26. + +====================================================================== + Function 21, subfunction 11 - enable/disable low-level access to HD. +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 11 - subfunction number + * ecx = 0/1 - disable/enable +Returned value: + * eax = 0 +Remarks: + * Is used in LBA-read (subfunction 8 of function 58). + * The current implementation uses only low bit of ecx. + * To get current status use subfunction 11 of function 26. + +====================================================================== + Function 21, subfunction 12 - enable/disable low-level access to PCI. +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 12 - subfunction number + * ecx = 0/1 - disable/enable +Returned value: + * eax = 0 +Remarks: + * Is used in operations with PCI bus (function 62). + * The current implementation uses only low bit of ecx. + * To get current status use subfunction 12 of function 26. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 1 =========== +======== Initialize + get information on the driver vmode.mdr. ======= +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 1 - number of the driver function + * edx = pointer to 512-bytes buffer +Returned value: + * if driver is not loaded + (never happens in the current implementation): + * eax = -1 + * ebx, ecx destroyed + * if driver is loaded: + * eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high) + - signature + * ebx = current frequency of the scanning (in Hz) + * ecx destroyed + * buffer pointed to by edx is filled +Format of the buffer: + * +0: 32*byte: driver name, "Trans VideoDriver" + (without quotes, supplemented by spaces) + * +32 = +0x20: dword: driver version (version x.y is encoded as + y*65536+x), for the current implementation is 1 (1.0) + * +36 = +0x24: 7*dword: reserved (0 in the current implementation) + * +64 = +0x40: 32*word: list of supported videomodes (each word + is number of a videomode, after list itself there are zeroes) + * +128 = +0x80: 32*(5*word): list of supported frequences of the + scannings for videomodes: for each videomode listed in the + previous field up to 5 supported frequences are given + (unused positions contain zeroes) +Remarks: + * Function initializes the driver (if it is not initialized yet) + and must be called first, before others (otherwise they will do + nothing and return -1). + * The current implementation supports only one frequency + of the scanning on videomode. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 2 =========== +================ Get information on current videomode. =============== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 2 - number of the driver function +Returned value: + * eax = -1 - driver is not loaded or not initialized; + ebx,ecx are destroyed + * eax = [width]*65536 + [height] + * ebx = frequency of the vertical scanning (in Hz) + * ecx = number of current videomode +Remarks: + * Driver must be initialized by call to + driver function 1. + * If only screen sizes are required, it is more expedient to use + function 14 taking into account that it + returns sizes on 1 less. + +====================================================================== +=== Function 21, subfunction 13, subsubfunction 3 - set videomode. === +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 3 - number of the driver function + * edx = [scanning frequency]*65536 + [videomode number] +Returned value: + * eax = -1 - driver is not loaded, not initialized or + an error has occured + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by driver function 1. + * The videomode number and frequency must be in the table + returned by driver function 1. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 4 =========== +================== Return to the initial videomode. ================== +====================================================================== +Returns the screen to the videomode set at system boot. +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 4 - number of the driver function +Returned value: + * eax = -1 - driver is not loaded or not initialized + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by call to driver function 1. + +====================================================================== +============ Function 21, subfunction 13, subsubfunction 5 =========== +===== Increase/decrease the size of the visible area of monitor. ===== +====================================================================== +Parameters: + * eax = 21 - function number + * ebx = 13 - subfunction number + * ecx = 5 - number of the driver function + * edx = 0/1 - decrease/increase horizontal size on 1 position + * edx = 2/3 - is not supported in the current implementation; + is planned as decrease/increase vertical size on 1 position +Returned value: + * eax = -1 - driver is not loaded or not initialized + * eax = 0 - success + * ebx, ecx destroyed +Remarks: + * Driver must be initialized by call to driver function 1. + * Function influences only the physical size of the screen image; + the logical size (number of pixels) does not change. + +====================================================================== +================= Function 22 - set system date/time. ================ +====================================================================== +Parameters: + * eax = 22 - function number + * ebx = 0 - set time + * ecx = 0x00SSMMHH - time in the binary-decimal code (BCD): + * HH=hour 00..23 + * MM=minute 00..59 + * SS=second 00..59 + * ebx = 1 - set date + * ecx = 0x00DDMMYY - date in the binary-decimal code (BCD): + * DD=day 01..31 + * MM=month 01..12 + * YY=year 00..99 + * ebx = 2 - set day of week + * ecx = 1 for Sunday, ..., 7 for Saturday + * ebx = 3 - set alarm clock + * ecx = 0x00SSMMHH +Returned value: + * eax = 0 - success + * eax = 1 - incorrect parameter + * eax = 2 - CMOS-battery was unloaded +Remarks: + * Value of installation of day of week seems to be doubtful, + as it a little where is used + (day of week can be calculated by date). + * Alarm clock can be set on operation in the given time every day. + But there is no existing system function to disable it. + * Operation of alarm clock consists in generation IRQ8. + * Generally CMOS supports for alarm clock set of value 0xFF + as one of parameters and it means that the appropriate parameter + is ignored. But current implementation does not allow this + (will return 1). + * Alarm clock is a global system resource; the set of + an alarm clock cancels automatically the previous set. + However, at moment no program uses it. + +====================================================================== +============= Function 23 - wait for event with timeout. ============= +====================================================================== +If the message queue is empty, waits for new message in the queue, +but no more than given time. Then reads out a message from the queue. + +Parameters: + * eax = 23 - function number + * ebx = timeout (in 1/100 of second) +Returned value: + * eax = 0 - the message queue is empty + * otherwise eax = event (see the list of events) +Remarks: + * Only those events are taken into account, which enter into + the mask set by function 40. By default it is + redraw, key and button events. + * To check for presence of a message in the queue use function 11. + To wait without timeout use function 10. + * Transmission ebx=0 results in immediate returning eax=0. + * Current implementation returns immediately with eax=0, + if the addition of ebx with the current value of time counter + makes 32-bit overflow. + +====================================================================== +======== Function 24, subfunction 1 - begin to play CD-audio. ======== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 1 - subfunction number + * ecx = 0x00FRSSMM, where + * MM = starting minute + * SS = starting second + * FR = starting frame +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Remarks: + * Previously CD base must be defined by the call to + subfunction 3 of function 21. + * One second includes 75 frames, one minute includes 60 seconds. + * The function is asynchronous (returns control, when play begins). + +====================================================================== +======= Function 24, subfunction 2 - get information on tracks. ====== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 2 - subfunction number + * ecx = pointer to the buffer for the table + (maximum 8*64h+4 bytes=100 tracks) +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Remarks: + * The format of the table with tracks information is the same as + for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h). + Function returns addresses in MSF. + * Previously CD base port must be set by call to + subfunction 3 of function 21. + * Function returns information only about no more than 100 + first tracks. In most cases it is enough. + +====================================================================== +========== Function 24, subfunction 3 - stop play CD-audio. ========== +====================================================================== +Parameters: + * eax = 24 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = 0 - success + * eax = 1 - CD base is not defined +Замечания: + * Previously CD base port must be defined by call to + subfunction 3 of function 21. + +====================================================================== +=================== Function 25 - set SBPro volume. ================== +====================================================================== +Parameters: + * eax = 25 - function number + * ebx = what to set: + * 1 - set common volume + * 2 - set CD-audio volume + * cl = volume level: high 4 bits for the left column, + low 4 bits for the right one +Returned value: + * eax = 0 - success + * eax = 1 - SB base is not defined + * eax = 2 - incorrect subfunction +Remarks: + * Previously SB base port must be defined by + subfunction 4 of function 21. + * See also function 28 which sets + volume for the later standard SB16. + +====================================================================== +======== Function 26, subfunction 1 - get MPU MIDI base port. ======== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = port number +Parameters: + * To set base port use subfunction 1 of function 21. + +====================================================================== +========== Function 26, subfunction 2 - get keyboard layout. ========= +====================================================================== +The keyboard layout is used to convert keyboard scancodes to +ASCII-codes for function 2. +Parameters: + * eax = 26 - function number + * ebx = 2 - subfunction number + * ecx = what layout to get: + * 1 = normal layout + * 2 = layout with pressed Shift + * 3 = layout with pressed Alt + * edx = pointer to the 128-bytes buffer, where the layout will be + copied +Returned value: + * function does not return value +Or: + * eax = 26 - function number + * ebx = 2 - subfunction number + * ecx = 9 +Returned value: + * eax = country identifier (1=eng, 2=fi, 3=ger, 4=rus) +Remarks: + * If Alt is pressed, the layout with Alt is used; + if Alt is not pressed, but Shift is pressed, + the layout with Shift is used; + if Alt and Shift are not pressed, but Ctrl is pressed, the normal + layout is used and then from the code is subtracted 0x60; + if no control key is pressed, the normal layout is used. + * To set layout and country identifier use + subfunction 2 of function 21. + * Country identifier is global system variable, which is not used + by the kernel itself; however the application '@panel' displays + the corresponding icon (using this function). + * The application @panel switches layouts on user request. + +====================================================================== +============== Function 26, subfunction 3 - get CD base. ============= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Remarks: + * CD base is used by function 24. + * To set CD base use subfunction 3 of function 21. + +====================================================================== +====== Function 26, subfunction 4 - get Sound Blaster base port. ===== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = base port number +Remarks: + * Bae port is used by functions 25, 55. + * To set base port use subfunction 4 of function 21. + +====================================================================== +========== Function 26, subfunction 5 - get system language. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = system language (1=eng, 2=fi, 3=ger, 4=rus) +Remarks: + * System language is global system variable and is not used + by the kernel itself, however application @panel draws the + appropriate icon (using this function). + * To set system language use subfunction 5 of function 21. + +====================================================================== +=========== Function 26, subfunction 6 - get WSS base port. ========== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 6 - subfunction number +Returned value: + * eax = base port +Remarks: + * WSS base is used by function 27. + * To set WSS base port use subfunction 6 of function 21. + +====================================================================== +============== Function 26, subfunction 7 - get HD base. ============= +====================================================================== +The HD base defines hard disk to write with usage of obsolete +file system functions and functions implicitly using the hard disk +(such as subfunction 6 of function 18); +at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +these function set base themselves. +Parameters: + * eax = 26 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 +Remarks: + * Any application in any time can change HD base. + * To set base use subfunction 7 of function 21. + * To get used partition of hard disk use subfunction 8. + +====================================================================== +========= Function 26, subfunction 8 - get used HD partition. ======== +====================================================================== +The HD partition defines partition of the hard disk to write with +usage of obsolete file system functions and functions implicitly +using the hard disk (such as subfunction 6 of function 18); +at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 +these functions set base and partition themselves. +Parameters: + * eax = 26 - function number + * ebx = 8 - subfunction number +Returned value: + * eax = HD partition (beginning from 1) +Remarks: + * Any application in any time can change partition. + * To set partition use subfunction 8 of function 21. + * To get number of partitions on a hard disk use + subfunction 11 of function 18. + * To get base of used hard disk, use subfunction 7. + +====================================================================== +=== Function 26, subfunction 9 - get the value of the time counter. == +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = number of 1/100s of second, past from the system boot time +Remarks: + * Counter takes modulo 2^32, that correspond to a little more + than 497 days. + * To get system time use function 3. + +====================================================================== +======== Function 26, subfunction 10 - get sound DMA channel. ======== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 10 - subfunction number +Returned value: + * eax = number of the channel (from 0 to 3 inclusive) +Remarks: + * Number of the DMA channel is used by subfunction 1 of function 55. + * To set the sound DMA channel use subfunction 10 of function 21. + +====================================================================== +===================== Function 26, subfunction 11 ==================== +========== Find out whether low-level HD access is enabled. ========== +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 11 - subfunction number +Returned value: + * eax = 0/1 - disabled/enabled +Remarks: + * Is used in LBA read (subfunction 8 of function 58). + * To set current state use subfunction 11 of function 21. + +====================================================================== +===================== Function 26, subfunction 12 ==================== +========== Find out whether low-level PCI access is enabled. ========= +====================================================================== +Parameters: + * eax = 26 - function number + * ebx = 12 - subfunction number +Returned value: + * eax = 0/1 - disabled/enabled +Remarks: + * Is used by operations with PCI bus (function 62). + * The current implementation uses only low bit of ecx. + * To set the current state use subfunction 12 of function 21. + +====================================================================== +======== Function 27 - set Windows Sound System (WSS) volume. ======== +====================================================================== +Parameters: + * eax = 27 - function number + * ebx = what to set: + * 1 - set common volume + * 2 - set Line In volume + * cl = volume level (0x0=highest, 0x1F=lowest, + if bit 0x80 is set=disable) +Returned value: + * eax = 0 - success + * eax = 1 - WSS base is not defined + * eax = 2 - incorrect subfunction +Remarks: + * Previously WSS base port must be defined by call to + subfunction 6 of function 21. + * Set of common volume is ignored (function simply returns eax=0). + * Old documentation and kernel sources erraticly name function 2 + as CD-audio volume. + +====================================================================== +=================== Function 28 - set SB16 volume. =================== +====================================================================== +Parameters: + * eax = 28 - function number + * ebx = what to install: + * 1 - install common volume + * 2 - install CD-audio volume + * cl = volume level (0=off, 0xFF=max) +Returned value: + * eax = 0 - success + * eax = 1 - SB base is not defined + * eax = 2 - incorrect subfunction +Remarks: + * Previously SB base port must be defined by + subfunction 4 of function 21. + * This function gives more variants for volume, that function 25. + +====================================================================== +=================== Function 29 - get system date. =================== +====================================================================== +Parameters: + * eax = 29 - function number +Returned value: + * eax = 0x00DDMMYY, where + (binary-decimal coding, BCD, is used) + * YY = two low digits of year (00..99) + * MM = month (01..12) + * DD = day (01..31) +Remarks: + * To set system date use function 22. + +====================================================================== +=============== Function 32 - delete file from ramdisk. ============== +====================================================================== +Parameters: + * eax = 32 - function number + * ebx = pointer to the filename +Returned value: + * eax = 0 - success; otherwise file system error code +Remarks: + * This function is obsolete; function 58 allows to fulfill + the same operations with the extended possibilities. + * The current implementation returns only values 0(success) and + 5(file not found). + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +================ Function 33 - write file to ramdisk. ================ +====================================================================== +Parameters: + * eax = 33 - function number + * ebx = pointer to the filename + * ecx = pointer to data for writing + * edx = number of bytes for writing + * should be set esi=0 +Returned value: + * eax = 0 - success, otherwise file system error code +Remarks: + * This function is obsolete; function 70 allows to fulfil + the same operations with extended possibilities. + * If esi contains non-zero value and selected file already exists, + one more file with the same name will be created. + * Otherwise file will be overwritten. + * The filename must be either in the format 8+3 characters + (first 8 characters - name itself, last 3 - extension, + the short names and extensions are supplemented with spaces), + or in the format 8.3 characters "FILE.EXT"/"FILE.EX " + (name no more than 8 characters, dot, extension 3 characters + supplemented if necessary by spaces). + The filename must be written with capital letters. The terminating + character with code 0 is not necessary (not ASCIIZ-string). + * This function does not support folders on the ramdisk. + +====================================================================== +======= Function 35 - read the color of a pixel on the screen. ======= +====================================================================== +Parameters: + * eax = 35 + * ebx = y*xsize+x, where + * (x,y) = coordinates of a pixel (beginning from 0) + * xsize = horizontal screen size +Returned value: + * eax = color 0x00RRGGBB +Remarks: + * To get screen sizes use function 14. Pay attention, + that it subtracts 1 from both sizes. + * There is also direct access (without any system calls) + to videomemory through the selector gs. To get parameters of + the current videomode, use function 61. + +====================================================================== +========= Function 37 - get coordinates/status of the mouse. ========= +====================================================================== + +---------- Subfunction 0 - screen coordinates of the mouse ----------- +Parameters: + * eax = 37 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = x*65536 + y, (x,y)=coordinates of the mouse pointer + (beginning from 0) + +-- Subfunction 1 - coordinates of the mouse relative to the window --- +Parameters: + * eax = 37 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = x*65536 + y, (x,y)=coordinates of the mouse pointer + relative to the application window (beginning from 0) +Remarks: + * The value is calculated by formula (x-xwnd)*65536 + (y-ywnd). + If y>=ywnd, the low word is non-negative and contains + relative y-coordinate, and the high word - relative x-coordinate + (with correct sign). Otherwise the low word is negative and still + contains relative y-coordinate, and to the high word + 1 should be added. + +------------ Subfunction 2 - pressed buttons of the mouse ------------ +Parameters: + * eax = 37 - function number + * ebx = 2 - subfunction number +Returned value: + * eax contains information on the pressed mouse buttons: + * bit 0 is set = left button is pressed + * bit 1 is set = right button is pressed + * other bits are cleared + +====================================================================== +====================== Function 38 - draw line. ====================== +====================================================================== +Parameters: + * eax = 38 - function number + * ebx = [start coordinate on axis x]*65536 + + [end coordinate on axis x] + * ecx = [start coordinate on axis y]*65536 + + [end coordinate on axis y] + * edx = 0x00RRGGBB - color + edx = 0x01xxxxxx - draw inversed line + (low 24 bits are ignored) +Returned value: + * function does not return value +Remarks: + * Coordinates are relative to the window. + * End point is also drawn. + +====================================================================== +== Function 39, subfunction 1 - get a size of the background image. == +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = [width]*65536 + [height] +Remarks: + * There is a pair function to set sizes of background image - + subfunction 1 of function 15. After which it is necessary, + of course, anew to define image. + +====================================================================== +== Function 39, subfunction 2 - get pixel from the background image. = +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 2 - subfunction number + * ecx = offset +Returned value: + * eax = 0x00RRGGBB - pixel color, if offset is valid + (less than 0x160000-16) + * eax = 2 otherwise +Remarks: + * Do not rely on returned value for invalid offsets, it may be + changed in future kernel versions. + * Offset for pixel with coordinates (x,y) + is calculated as (x+y*xsize)*3. + * There is a pair function to set pixel on the background image - + subfunction 2 of function 15. + +====================================================================== +== Function 39, subfunction 4 - get drawing mode for the background. = +====================================================================== +Parameters: + * eax = 39 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = 1 - tile + * eax = 2 - stretch +Remarks: + * There is a pair function to set drawing mode - + subfunction 4 of function 15. + +====================================================================== +=========== Function 40 - set the mask for expected events. ========== +====================================================================== +The mask for expected events affects function working with events +10, 11, 23 - they notify only about events allowed by this mask. +Parameters: + * eax = 40 - function number + * ebx = mask: bit i corresponds to event i+1 (see list of events) + (set bit permits notice on event) +Returned value: + * function does not return value +Remarks: + * Default mask (7=111b) enables nofices about redraw, + keys and buttons. This is enough for many applications. + * Events prohibited in the mask are saved anyway, when come; + they are simply not informed with event functions. + * Event functions take into account the mask on moment of + function call, not on moment of event arrival. + +====================================================================== +==================== Function 41 - get IRQ owner. ==================== +====================================================================== +Parameters: + * eax = 41 - function number + * ebx = IRQ number, 0..15 +Returned value: + * eax = owner PID + * eax = 0, if there is no owner + * eax = -1 for incorrect ebx + +====================================================================== +==================== Function 42 - read IRQ data. ==================== +====================================================================== +When an IRQ occurs, the system reads data from ports indicated +earlier by function 44 and writes this data to +internal buffer. This function reads out data from that buffer +bytewise. +Parameters: + * eax = 42 - function number + * ebx = IRQ number, 0..15 +Returned value: (use value of ecx to distinguish) + * if the thread is not IRQ owner (or IRQ number is incorrect): + * ecx = 2 + * if there is no data: + * eax = 0 + * ecx = 1 + * ebx destroyed + * if all is ok: + * eax = byte size of data, not yet read from buffer + * ecx = 0 + * ebx = current byte +Remarks: + * Previously the thread must reserve indicated IRQ for itself + by function 45. + * The size of data buffer is 4000 bytes, on overflow + "fresh" data cease to be written in the buffer. + +====================================================================== +================ Function 43 - input/output to a port. =============== +====================================================================== + +------------------------ Output data to port ------------------------- +Parameters: + * eax = 43 - function number + * bl = byte for output + * ecx = port number 0xnnnn (from 0 to 0xFFFF) +Returned value: + * eax = 0 - success + * eax = 1 - the thread has not reserved the selected port + +------------------------ Input data from port ------------------------ +Parameters: + * eax = 43 - function number + * ebx is ignored + * ecx = 0x8000nnnn, where nnnn = port number (from 0 to 0xFFFF) +Returned value: + * eax = 0 - success, thus ebx = entered byte + * eax = 1 - the thread has not reserved the selected port +Remarks: + * Previously the thread must reserve the selected port + for itself by function 46. + * Instead of call to this function it is better to use + processor instructions in/out - this is much + faster and a bit shorter and easier. + +====================================================================== +=========== Function 44 - define operations at IRQ arrival. ========== +====================================================================== +At IRQ arrival the system can read the data from ports defined +by this function and write these data to internal buffer, whence +they can be read by функцией 42. +Parameters: + * eax = 44 - function number + * ebx = pointer to the array of structures each describing one port: + * +0: word: 0 means end of array, otherwise port number + * +2: byte: reserved (ignored) + * +3: byte: 1=read byte from this port, 2=read word + * ecx = IRQ number, 0..15 +Returned value: + * eax = 0 - success + * eax = 1 - the thread is not owner of selected IRQ +Remarks: + * Previously the thread must reserve for itself selected IRQ + by function 45. + * First 16 ports are considered only. + * The current implementation considers incorrect value of field +3 + as a signal to terminate IRQ processing. + +====================================================================== +=================== Function 45 - reserve/free IRQ. ================== +====================================================================== +Parameters: + * eax = 45 - function number + * ebx = 0 - reserve, 1 = free + * ecx = IRQ number, 0..15 +Returned value: + * eax = 0 - success + * eax = 1 - error (invalid IRQ number + or attempt to reserve not free IRQ + or to free IRQ, not reserved by this thread) +Remarks: + * IRQ reservation is required for functions 42 and 44. + * Only one thread can reserve the specific IRQ. + * IRQs, handled by the system itself, are reserved by the system + (thread 1) at booting. + * When a thread terminates, all reserved by it IRQs + are freed automatically. + +====================================================================== +====== Function 46 - reserve/free a group of input/output ports. ===== +====================================================================== +To work with reserved ports an application can access directly by +commands in/out (recommended way) and can use function 43 +(not recommended way). +Parameters: + * eax = 46 - function number + * ebx = 0 - reserve, 1 - free + * ecx = start port number + * edx = end port number (inclusive) +Returned value: + * eax = 0 - success + * eax = 1 - error +Remarks: + * For ports reservation: an error occurs if and only if + one from the following condition satisfies: + * start port is more than end port; + * the selected range contains incorrect port number + (correct are from 0 to 0xFFFF); + * limit for the total number of reserved areas is exceeded + (maximum 255 are allowed); + * the selected range intersects with any of earlier reserved + * For ports free: an error is an attempt to free range, + that was not earlier reserved by this function + (with same ecx,edx). + * If an error occurs (for both cases) function performs no action. + * At booting the system reserves for itself ports 0..0xff, and if + COM-mouse is detected - additionally range of COM-ports + 0x3f0..0x3ff and/or 0x2f0..0x2ff. + * When a thread terminates, all reserved by it ports + are freed automatically. + +====================================================================== +============= Function 47 - draw a number in the window. ============= +====================================================================== +Parameters: + * eax = 47 - function number + * ebx = parameters of conversion number to text: + * bl = 0 - ecx contains number + * bl = 1 - ecx contains pointer to dword-number + * bh = 0 - display in decimal number system + * bh = 1 - display in hexadecimal system + * bh = 2 - display in binary system + * биты 16-21 = how many digits to display + * биты 22-31 reserved and must be set to 0 + * ecx = number (if bl=0) or pointer (if bl=1) + * edx = [coordinate on axis x]*65536 + [coordinate on axis y] + * esi = 0xX0RRGGBB: + * RR, GG, BB specify the color + * X = ABnn (bits) + * nn = font (0/1) + * A is ignored + * B=1 - fill background with the color edi +Returned value: + * function does not return value +Remarks: + * The given length must not exceed 60. + * The exactly given amount of digits is output. If number is small + and can be written by smaller amount of digits, it is supplemented + by leading zeroes; if the number is big and can not be written by + given amount of digits, extra digits are not drawn. + * Parameters of fonts are shown in the description of function 4 + (text output). + +====================================================================== +========= Function 48, subfunction 0 - apply screen settings. ======== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 0 - subfunction number + * ecx = 0 - reserved +Returned value: + * function does not return value +Remarks: + * Function redraws the screen after parameters change by + subfunctions 1 and 2. + * Function call without prior call to one of indicated subfunctions + is ignored. + * Function call with nonzero ecx is ignored. + +====================================================================== +=========== Function 48, subfunction 1 - set button style. =========== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 1 - subfunction number + * ecx = button style: + * 0 = flat + * 1 = 3d +Returned value: + * function does not return value +Remarks: + * After call to this function one should redraw the screen by + subfunction 0. + * Button style influences only to their draw of function 8. + +====================================================================== +====== Function 48, subfunction 2 - set standard window colors. ====== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 2 - subfunction number + * ecx = pointer to the color table + * edx = size of the color table + (must be 40 bytes for future compatibility) +Format of the color table is shown in description of subfunction 3. +Returned value: + * function does not return value +Remarks: + * After call to this function one should redraw the screen by + subfunction 0. + * Table of standard colors influences only to applications, + which receive this table obviously (by subfunction 3) + and use it (specifying colors from it to drawing functions). + * Table of standard colors is included in skin and is installed + anew with skin installation (by subfunction 8). + * Color table can be viewed/changed interactively with + the application 'desktop'. + +====================================================================== +====== Function 48, subfunction 3 - get standard window colors. ====== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 3 - subfunction number + * ecx = pointer to the buffer with size edx bytes, + where table will be written + * edx = size of color table + (must be 40 bytes for future compatibility) +Returned value: + * function does not return value +Format of the color table: +each item is dword-value for color 0x00RRGGBB + * +0: dword: frames - color of frame + * +4: dword: grab - color of header + * +8: dword: grab_button - color of button on header bar + * +12 = +0xC: dword: grab_button_text - color of text on button + on header bar + * +16 = +0x10: dword: grab_text - color of text on header + * +20 = +0x14: dword: work - color of working area + * +24 = +0x18: dword: work_button - color of button in working area + * +28 = +0x1C: dword: work_button_text - color of text on button + in working area + * +32 = +0x20: dword: work_text - color of text in working area + * +36 = +0x24: dword: work_graph - color of graphics in working area +Remarks: + * Structure of the color table is described in the standard + include file 'macros.inc' as 'system_colors'; for example, + it is possible to write: + sc system_colors ; variable declaration + ... ; somewhere one must call + ; this function with ecx=sc + mov ecx, [sc.work_button_text] ; read text color on + ; buttin in working area + * A program itself desides to use or not to use color table. + For usage program must simply at calls to drawing functions select + color taken from the table. + * At change of the table of standard colors (by subfunction 2 with + the subsequent application of changes by subfunction 0 or + at skin set by subfunction 8) the system sends to all windows + redraw message (the event with code 1). + * Color table can be viewed/changed interactively with + the application 'desktop'. + +====================================================================== +============ Function 48, subfunction 4 - get skin height. =========== +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 4 - subfunction number +Returned value: + * eax = skin height +Remarks: + * Skin height is defined as the height of a header + of skinned windows. + * See also general structure of window in the description + of function 0. + +====================================================================== +======== Function 48, subfunction 5 - get screen working area. ======= +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 5 - subfunction number +Returned value: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +Remarks: + * The screen working area defines position and coordinates of + a maximized window. + * The screen working area in view of normal work is all screen + without system panel (the application '@panel'). + * (left,top) are coordinates of the left upper corner, + (right,bottom) are coordinates of the right lower one. + Thus the size of working area on x axis can be calculated by + formula right-left+1, on y axis - by formula bottom-right+1. + * See also function 14, + to get sizes of all screen. + * There is a pair function to set working area - subfunction 6. + +====================================================================== +======== Function 48, subfunction 6 - set screen working area. ======= +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 6 - subfunction number + * ecx = [left]*65536 + [right] + * edx = [top]*65536 + [bottom] +Returned value: + * function does not return value +Remarks: + * The screen working area defines position and coordinates of + a maximized window. + * This function is used only by the application '@panel', + which set working area to all screen without system panel. + * (left,top) are coordinates of the left upper corner, + (right,bottom) are coordinates of the right lower one. + Thus the size of working area on x axis can be calculated by + formula right-left+1, on y axis - by formula bottom-right+1. + * If 'left'>='right', x-coordinate of working area is not changed. + If 'left'<0, 'left' will not be set. If 'right' is greater than or + equal to screen width, 'right' will not be set. + Similarly on y axis. + * See also function 14, + to get sizes of all screen. + * There is a pair function to get working area - subfunction 5. + * This function redraws the screen automatically, + updating coordinates and sizes of maximized windows. + The system sends to all windows redraw message (the event 1). + +====================================================================== +=========== Function 48, subfunction 7 - get skin margins. =========== +====================================================================== +Returns the area of a header of a skinned window, intended for +a text of a header. +Parameters: + * eax = 48 - function number + * ebx = 7 - subfunction number +Returned value: + * eax = [left]*65536 + [right] + * ebx = [top]*65536 + [bottom] +Remarks: + * An application decides itself to use or not to use this function. + * It is recommended to take into account returned value + of this function for choice of a place for drawing header text + (by function 4) or a substitute of header text + (at the discretion of an application). + +====================================================================== +============= Function 48, subfunction 8 - set used skin. ============ +====================================================================== +Parameters: + * eax = 48 - function number + * ebx = 8 - subfunction number + * ecx = pointer to a block for function 58, in + which the fields of intermediate buffer and file name are filled +Returned value: + * eax = 0 - success + * otherwise eax = file system error code; if file does not + contain valid skin, function returns error 3 + (unknown file system). +Remarks: + * After successful skin loading the system sends to all windows + redraw message (the event 1). + * At booting the system reads skin from file 'default.skn' + on ramdisk. + * User can change the skin statically by creating hisself + 'default.skn' or dynamically with the application 'desktop'. + +====================================================================== +=========== Function 49 - Advanced Power Management (APM). =========== +====================================================================== +Parameters: + * eax = 49 - function number + * dx = number of the APM function + (analogue of ax in APM specification) + * bx, cx = parameters of the APM function +Returned value: + * 16-bit registers ax, bx, cx, dx, si, di and carry flag CF + are set according to the APM specification + * high halves of 32-bit registers eax, ebx, ecx, + edx, esi, edi are destroyed +Remarks: + * APM 1.2 specification is described in the document + "Advanced Power Management (APM) BIOS Specification" + (Revision 1.2), available at + http://www.microsoft.com/whdc/archive/amp_12.mspx; + besides it is included in famous Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/). + +====================================================================== +=================== Function 50 - set window shape. ================== +====================================================================== +Normal windows have rectangular shape. This function can give to +a window any shape. The shape is given by a set of points inside +the base rectangle belonging to a window. Position and coordinates +of the base rectangle are set by function 0 +and changed by function 67. + +--------------------------- Set shape data --------------------------- +Parameters: + * eax = 50 - function number + * ebx = 0 - subfunction number + * ecx = pointer to shape data (array of bytes 0/1) +Returned value: + * function does not return value + +-------------------------- Set shape scale --------------------------- +Parameters: + * eax = 50 - function number + * ebx = 1 - subfunction number + * ecx sets a scale: each byte of data defines + (2^scale)*(2^scale) pixels +Returned value: + * function does not return value +Remarks: + * Default scale is 0 (scale factor is 1). If in the shape data + one byte corresponds to one pixel, there is no necessity + to set scale. + * Let's designate xsize = window width (in pixels), ysize = height; + pay attention, that they are one pixel more than defined by + functions 0, 67. + * On definition of scale xsize and ysize must be divisible + on 2^scale. + * Byte of data on offset 'a' must be 0/1 and defines belonging + to a window of square with the side 2^scale (if scale=0, + this is one pixel) and coordinates of the left upper corner + (a mod (xsize shr scale), a div (xsize shr scale)) + * Data size: (xsize shr scale)*(ysize shr scale). + * Data must be presented in the memory and not change + after set of shape. + * The system views the shape data at every window redraw by + function 0. + * The call of subfunction 0 with NULL pointer results in return + to the rectangular shape. + +====================================================================== +==================== Function 51 - create thread. ==================== +====================================================================== +Parameters: + * eax = 51 - function number + * ebx = 1 - unique subfunction + * ecx = address of thread entry point (starting eip) + * edx = pointer to thread stack (starting esp) +Returned value: + * eax = -1 - error (there is too many threads) + * otherwise eax = TID - thread identifier + + +====================================================================== +=== Function 52, subfunction 0 - get network driver configuration. === +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = configuration dword +Remarks: + * Configuration dword can be set by subfunction 2. + * The kernel does not use this variable. The value of this + variable and working with it subfunctions 0 and 2 is represented + doubtful. + +====================================================================== +========= Function 52, subfunction 1 - get local IP-address. ========= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = IP-address (4 bytes) +Remarks: + * Local IP-address is set by subfunction 3. + +====================================================================== +=== Function 52, subfunction 2 - set network driver configuration. === +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 2 - subfunction number + * ecx = configuration dword; if low 7 bits derivate the number 3, + function [re-]initializes Ethernet-card, otherwise + Ethernet turns off +Returned value: + * if Ethernet-interface is not requested, function returns eax=2, + but this can be changed in future kernel versions + * if Ethernet-interface is requested, eax=0 means error + (absence of Ethernet-card), and nonzero value - success +Remarks: + * Configuration dword can be read by subfunction 0. + * The kernel does not use this variable. The value of this + variable, subfunction 0 and part of subfunction 2, which set it, + is represented doubtful. + +====================================================================== +========= Function 52, subfunction 3 - set local IP-address. ========= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 3 - subfunction number + * ecx = IP-address (4 bytes) +Returned value: + * the current implementation returns eax=3, but this can be changed + in future versions +Remarks: + * Local IP-address can be get by subfunction 1. + +====================================================================== += Function 52, subfunction 6 - add data to the stack of input queue. = +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 6 - subfunction number + * edx = data size + * esi = data pointer +Returned value: + * eax = -1 - error + * eax = 0 - success +Remarks: + * This function is intended only for slow network drivers + (PPP, SLIP). + * Data size must not exceed 1500 bytes, though function + performs no checks on correctness. + +====================================================================== + Function 52, subfunction 8 - read data from the network output queue. +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 8 - subfunction number + * esi = pointer to 1500-byte buffer +Returned value: + * eax = number of read bytes (in the current implementation + either 0 = no data or 1500) + * data was copied in buffer +Remarks: + * This function is intended only for slow network drivers + (PPP, SLIP). + +====================================================================== +============ Function 52, subfunction 9 - get gateway IP. ============ +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 9 - subfunction number +Returned value: + * eax = gateway IP (4 bytes) + +====================================================================== +=========== Function 52, subfunction 10 - get subnet mask. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 10 - subfunction number +Returned value: + * eax = subnet mask + +====================================================================== +============ Function 52, subfunction 11 - set gateway IP. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 11 - subfunction number + * ecx = gateway IP (4 bytes) +Returned value: + * the current implementation returns eax=11, but this can be changed + in future versions + +====================================================================== +=========== Function 52, subfunction 12 - set subnet mask. =========== +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 12 - subfunction number + * ecx = subnet mask +Returned value: + * the current implementation returns eax=12, but this can be changed + in future versions + +====================================================================== +============== Function 52, subfunction 13 - get DNS IP. ============= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 13 - subfunction number +Returned value: + * eax = DNS IP (4 bytes) + +====================================================================== +============== Function 52, subfunction 14 - set DNS IP. ============= +====================================================================== +Parameters: + * eax = 52 - function number + * ebx = 14 - subfunction number + * ecx = DNS IP (4 bytes) +Returned value: + * the current implementation returns eax=14, but this can be changed + in future versions + +====================================================================== +============ Function 53, subfunction 0 - open UDP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 0 - subfunction number + * ecx = local port (only low word is taken into account) + * edx = remote port (only low word is taken into account) + * esi = remote IP +Returned value: + * eax = -1 = 0xFFFFFFFF - error; ebx destroyed + * eax = socket handle (some number which unambiguously identifies + socket and have sense only for the system) - success; + ebx destroyed + +====================================================================== +=========== Function 53, subfunction 1 - close UDP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 1 - subfunction number + * ecx = socket handle +Returned value: + * eax = -1 - incorrect handle + * eax = 0 - success + * ebx destroyed +Remarks: + * The current implementation does not close automatically all + sockets of a thread at termination. In particular, one should not + kill a thread with many opened sockets - there will be an outflow + of resources. + * The current implementation does no checks on correctness + (function returns error only if thread tries to close not opened + socket with correct handle). + +====================================================================== +============== Function 53, subfunction 2 - poll socket. ============= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 2 - subfunction number + * ecx = socket handle +Returned value: + * eax = number of read bytes + * ebx destroyed +Remarks: + * There is no checks for correctness. + +====================================================================== +========= Function 53, subfunction 3 - read byte from socket. ======== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 3 - subfunction number + * ecx = socket handle +Returned value: + * if there is no read data: eax=0, bl=0, + other bytes of ebx are destroyed + * if there are read data: eax=number of rest bytes + (possibly 0), bl=read byte, other bytes of ebx are destroyed +Remarks: + * There is no checks for correctness. + +====================================================================== +========== Function 53, subfunction 4 - write to UDP-socket. ========= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 4 - subfunction number + * ecx = socket handle + * edx = number of bytes to write + * esi = pointer to data to write +Returned value: + * eax = 0xffffffff - invalid handle + * eax = 0xffff - not enough memory + * eax = 0 - success + * ebx destroyed +Remarks: + * Check on validity of handle is minimal - only not very incorrect + not opened handles are eliminated. + * Number of bytes to write must not exceed 1500-28, though + the appropriate check is not made. + +====================================================================== +============ Function 53, subfunction 5 - open TCP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 5 - subfunction number + * ecx = local port (only low word is taken into account) + * edx = remote port (only low word is taken into account) + * esi = remote IP + * edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1 +Returned value: + * eax = -1 = 0xFFFFFFFF - error; ebx destroys + * eax = socket handle (some number which unambiguously identifies + socket and have sense only for the system) - success; + ebx destroyed + +====================================================================== +========= Function 53, subfunction 6 - get TCP-socket status. ======== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 6 - subfunction number + * ecx = socket handle +Returned value: + * eax = socket status: one of + * TCB_LISTEN = 1 + * TCB_SYN_SENT = 2 + * TCB_SYN_RECEIVED = 3 + * TCB_ESTABLISHED = 4 + * TCB_FIN_WAIT_1 = 5 + * TCB_FIN_WAIT_2 = 6 + * TCB_CLOSE_WAIT = 7 + * TCB_CLOSING = 8 + * TCB_LAST_ASK = 9 + * TCB_TIME_WAIT = 10 + * TCB_CLOSED = 11 + * ebx destroys +Remarks: + * There is no checks for correctness. + +====================================================================== +========== Function 53, subfunction 7 - write to TCP-socket. ========= +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 7 - subfunction number + * ecx = socket handle + * edx = number of bytes to write + * esi = pointer to data to write +Returned value: + * eax = 0xffffffff - error + * eax = 0xffff - not enough memory + * eax = 0 - success + * ebx destroyed +Remarks: + * Check on validity of handle is minimal - only not very incorrect + not opened handles are eliminated. + * Number of bytes to write must not exceed 1500-40, though + the appropriate check is not made. + +====================================================================== +=========== Function 53, subfunction 8 - close TCP-socket. =========== +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 8 - subfunction number + * ecx = socket handle +Returned value: + * eax = -1 - invalid handle + * eax = 0xffff - not enough memory for socket close packet + * eax = 0 - success + * in many cases eax is destroyed (the result of function 'queue' + is returned) - probably this is bug, which will be corrected + * ebx destroyed +Remarks: + * The current implementation does not close automatically all + sockets of a thread at termination. In particular, one should not + kill a thread with many opened sockets - there will be an outflow + of resources. + * The current implementation does no checks on correctness + (function returns error only if thread tries to close not opened + socket with correct handle). + +====================================================================== +=== Function 53, subfunction 9 - check whether local port is free. === +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 9 - subfunction number + * ecx = local port number (low 16 bits are used only) +Returned value: + * eax = 0 - port is used + * eax = 1 - port is free + * ebx destroyed + +====================================================================== += Function 53, subfunction 255 - debug information of network driver. +====================================================================== +Parameters: + * eax = 53 - function number + * ebx = 255 - subfunction number + * ecx = type of requested information (see below) +Returned value: + * eax = requested information + * ebx destroyed +Possible values for ecx: + * 100: length of queue 0 (empty queue) + * 101: length of queue 1 (ip-out queue) + * 102: length of queue 2 (ip-in queue) + * 103: length of queue 3 (net1out queue) + * 200: number of items in the ARP table + * 201: size of the ARP table (in items) (20 for current version) + * 202: read item at edx of the ARP table to the temporary buffer, + whence 5 following types take information; + in this case eax is not defined + * 203: IP-address saved by type 202 + * 204: high dword of MAC-address saved by type 202 + * 205: low word of MAC-address saved by type 202 + * 206: status word saved by type 202 + * 207: ttl word saved by type 202 + * 2: total number of received IP-packets + * 3: total number of transferred IP-packets + * 4: total number of dumped received packets + * 5: total number of received ARP-packets + * 6: status of packet driver, 0=inactive, nonzero=active + +====================================================================== +========== Function 55, subfunction 0 - load data for SB16. ========== +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 0 - subfunction number + * ecx = pointer to data (is copied 64 kilobytes, is used as much as + set by subfunction 2) +Returned value: + * function does not return value +Remarks: + * Format and size of data are set by subfunction 2. + +====================================================================== +======== Function 55, subfunction 1 - begin play data on SB16. ======= +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value +Remarks: + * Previously data must be loaded by subfunction 0 and + their format must be defined by subfunction 2. + * Function returns control, when playing of data began; after that + play goes independently from application (and does not use + processor time at all). + * Previously must be defined SB16 base port + (by subfunction 4 of function 21) and DMA channel + (by subfunction 10 of function 21). + +====================================================================== +======== Function 55, subfunction 2 - set format of SB16 data. ======= +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 2 - subfunction number + * ecx = 0 - set digit capacity + * edx = 1 - 8bit mono + * edx = 2 - 8bit stereo + * ecx = 1 - set data size + * edx = size in bytes + * ecx = 2 - set play frequency + * edx = frequency +Returned value: + * function does not return value +Remarks: + * When the system boots, it sets following default parameters: + digit capacity - 8bit mono, size - 64 Kb, frequency - 44100 Hz. + Nevertheless it is recommended to set necessary values obviously + as they could be reset by some application. + +====================================================================== + Function 55, subfunction 55 - begin to play data on built-in speaker. +====================================================================== +Parameters: + * eax = 55 - function number + * ebx = 55 - subfunction number + * esi = pointer to data +Returned value: + * eax = 0 - success + * eax = 55 - error (speaker is off or busy) +Data is an array of items with variable length. +Format of each item is defined by first byte: + * 0 = end of data + * 1..0x80 = sets sound duration on 1/100 of second; sound note + is defined by immediate value of frequency + * following word (2 bytes) contains frequency divider; + frequency is defined as 1193180/divider + * 0x81 = invalid + * 0x82..0xFF = note is defined by octave and number: + * duration in 1/100 of second = (first byte)-0x81 + * there is one more byte; + * (second byte)=0xFF - delay + * otherwise it looks like a*0x10+b, where b=number of the note in + an octave from 1 to 12, a=number of octave (beginning from 0) +Remarks: + * Speaker play can be disabled/enabled by + subfunction 8 of function 18. + * Function returns control, having informed the system + an information on request. Play itself goes independently from + the program. + * The data must be kept in the memory at least up to the end + of play. + +====================================================================== +=============== Function 56 - write file to hard disk. =============== +====================================================================== +Parameters: + * eax = 56 - function number + * ebx = pointer to the file name + * ecx = size of data to write (in bytes) + * edx = pointer to data to write + * esi = pointer to path (ASCIIZ-string) +Returned value: + * eax = 0 - success, otherwise file system error code +Remarks: + * This function is obsolete; function 70 allows to fulfil the same + operations with the extended possibilities. + * This function assumes that during its call by one application + no other application works with hard disk. + * The path to file is ASCIIZ-string, which may be empty + (if the file is created in the root folder) or have the format + /d1/d2/.../dn, where all folder names must have the 8+3 format, + i.e. 8 characters of name and 3 characters of the extension + without separator, supplemented by blanks if necessary; + all letters must be capital. + * The file name must also have the format 8+3. + +====================================================================== +================ Function 58 - work with file system. ================ +====================================================================== +Parameters: + * eax = 58 + * ebx = pointer to the information structure +Returned value: + * eax = 0 - success; otherwise file system error code + * some subfunctions return value in other registers too +General format of the information structure: + * +0: dword: subfunction number + * +4: dword: number of block + * +8: dword: size + * +12 = +0xC: dword: pointer to data + * +16 = +0x10: dword: pointer to a memory for system operations + (4096 bytes) + * +20 = +0x14: n db: ASCIIZ-string with the file name +Specifications - in documentation on the appropriate subfunction. +Filename is case-insensitive for latin letters, russian letters +must be capital. +Format of filename: +/base/number/dir1/dir2/.../dirn/file, +where /base/number identifies device, on which file is located: +one of + * /RD/1 = /RAMDISK/1 to access ramdisk + * /FD/1 = /FLOPPYDISK/1 to access first floppy drive, + /FD/2 = /FLOPPYDISK/2 to access second one + * /HD/x = /HARDDISK/x - obsolete variant of access to hard disk + (in this case base is defined by subfunction 7 of function 21), + x - partition number (beginning from 1) + * /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices + IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - partition number on the selected hard drive, varies from 1 + to 255 (on each hard drive the indexing starts from 1) +Remarks: + * In the first two cases it is also possible to use FIRST + instead of 1, SECOND instead of 2, but it is not recommended + for convenience of transition to the future extensions. + * Limitation n<=39 is imposed. + * Names of folders and file dir1,...,dirn,file must have the + format 8.3: name no more than 8 characters, dot, extension no + more than 3 characters. Trailing spaces are ignored, no other + spaces is allowed. If name occupies equally 8 characters, + dot may be omitted (though it is not recommended to use this + feature for convenience of transition to the future extensions). + * This function does not support folders on ramdisk. +Examples: + * '/RAMDISK/FIRST/KERNEL.ASM',0 + '/rd/1/kernel.asm',0 + * '/HD0/1/kernel.asm',0 + * '/hd0/1/menuet/pics/tanzania.bmp',0 +Existing subfunctions: + * subfunction 0 - read file/folder + * subfunction 1 - rewrite file + * subfunction 2 - delete file/folder + * subfunction 4 - make folder + * subfunction 5 - rename/move file/folder + * subfunction 8 - LBA-read from device + * subfunction 15 - get file system information + +====================================================================== +=========== Function 58, subfunction 0 - read file/folder. =========== +====================================================================== +Parameters: + * eax = 58 + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 0 = subfunction number + * +4: dword: first block to read (beginning from 0) + * +8: dword: amount of blocks to read + * +12 = +0xC: dword: pointer to buffer for data + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = file size (in bytes) or -1=0xffffffff, if file was not found +Remarks: + * Block size is 512 bytes. + * This function is obsolete, for reading files use subfunction 0 + of function 70, for reading folders - subfunction 1 of + function 70. + * Function can read contents of a folder. Only FAT file system is + supported. The format of FAT-folder is described + in any FAT documentation. + * Size of a folder is determined by size of FAT clusters chain. + * If file was ended before last requested block was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * Function can read root folders /rd/1,/fd/x,/hd[n]/x, but + in the first two cases the current implementation does not follow + to the declared rules: + for /rd/1: + * 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; + * size of ramdisk root folder is 14 blocks, + 0x1C00=7168 байт; but function returns ebx=0 + (except of the case of previous item); + * strangely enough, it is possible to read 14th block (which + generally contains a garbage - I remind, the indexing begins + from 0); + * if some block with the number not less than 14 was requested, + function returns eax=6(EOF); otherwise eax=0. + For /fd/x: + * if the start block is not less than 14, function returns + eax=5 (not found) and ebx=0; + * note that format of FAT12 allows floppies with the root size + more or less than 14 blocks; + * check for length is not performed; + * if data was successful read, function returns + eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1. + * The function handles reading of special folders /,/rd,/fd,/hd[n]; + but the result does not correspond to expected (on operations with + normal files/folders), does not follow the declared rules, + may be changed in future versions of the kernel and consequently + is not described. To obtain the information about the equipment + use subfunction 11 of function 18 or + read corresponding folder with subfunction 1 of function 70. + +====================================================================== +============= Function 58, subfunction 1 - rewrite file. ============= +====================================================================== +If the file does not exist, it is created. +If the file exists, it is rewritten. +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 1 = subfunction number + * +4: dword: ignored (set to 0) + * +8: dword: number of bytes to write + * +12 = +0xC: dword: pointer to data to write + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * This function is obsolete, use subfunction 2 of function 70. + +====================================================================== +========== Function 58, subfunction 2 - delete file/folder. ========== +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 2 = subfunction number + * +4: dword: ignored + * +8: dword: ignored + * +12 = +0xC: dword: ignored + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * By operations with a floppy one should not delete not empty + folder. The code working with hard disk deletes not empty folders + correctly (i.e. recursively with all files and nested folders). + Function 58 does not support folders on ramdisk. + +====================================================================== +============== Function 58, subfunction 4 - make folder. ============= +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 4 = subfunction number + * +4: dword: ignored + * +8: dword: ignored + * +12 = +0xC: dword: ignored + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * Ramdisk and floppies do not support this function, it is only + for hard disks. + +====================================================================== +======== Function 58, subfunction 5 - rename/move file/folder. ======= +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 5 = subfunction number + * +4: dword: ignored + * +8: dword: ignored + * +12 = +0xC: dword: ignored + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + * +20+n: (at once after terminating null character) new + ASCIIZ-name, must start from /hd/1, that is interpreted as + the hard disk, indicated in the first name + (moving from one disk to another is not supported) +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * Ramdisk and floppies do not support this function, it is only + for hard disks. + * If the new ASCIIZ-name is strongly incorrect, i.e. does not start + from /hd/1, /hd/first, /harddisk/1, /harddisk/first or after this + space or null character follows, function returns, strangely + enough, error code 4. It is the only function which returns + this code. + +====================================================================== +========= Function 58, subfunction 8 - LBA-read from device. ========= +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 8 = subfunction number + * +4: dword: number of block to read (beginning from 0) + * +8: dword: ignored (set to 1) + * +12 = +0xC: dword: pointer to buffer for data (512 bytes) + * +16 = +0x10: dword: pointer to buffer for system operations + (4096 bytes) + * +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of + /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, + 1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3. + Instead of digits it is allowed, though not recommended for + convenience of transition to future extensions, to use + 'first','second','third','fourth'. +Returned value: + * for device name /hd/xxx, where xxx is not in the list above: + * eax = ebx = 1 + * for invalid device name (except for the previous case): + * eax = 5 + * ebx does not change + * if LBA-access is disabled by subfunction 11 of function 21: + * eax = 2 + * ebx destroyed + * for ramdisk: attempt to read block outside ramdisk + (18*2*80 blocks) results in + * eax = 3 + * ebx = 0 + * for successful read: + * eax = ebx = 0 +Remarks: + * Block size is 512 bytes; function reads one block. + * Do not depend on returned value, it can be changed + in future versions. + * Function requires that LBA-access to devices is enabled by + subfunction 11 of function 21. To check this one can use + subfunction 11 of function 26. + * LBA-read of floppy is not supported. + * Function reads data on physical hard drive; if for any reason + 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). + * 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 + as success (eax=0). + +====================================================================== +==== Function 58, subfunction 15 - get information on file system. === +====================================================================== +Parameters: + * eax = 58 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 15 = subfunction number + * +4: dword: ignored + * +8: dword: ignored + * +12 = +0xC: dword: ignored + * +16 = +0x10: dword: ignored + * +20 = +0x14: (only second character is checked) + /rd=/RAMDISK or /hd=/HARDDISK +Returned value: + * if the second character does not belong to set {'r','R','h','H'}: + * eax = 3 + * ebx = ecx = dword [fileinfo] = 0 + * for ramdisk: + * eax = 0 (success) + * ebx = total number of clusters = 2847 + * ecx = number of free clusters + * dword [fileinfo] = cluster size = 512 + * for hard disk: base and partition are defined by subfunctions + 7 and 8 of function 21: + * eax = 0 (success) + * ebx = total number of clusters + * ecx = number of free clusters + * dword [fileinfo] = cluster size (in bytes) +Remarks: + * Be not surprised to strange layout of 4th returned parameter + - when this code was writing, at system calls application got + only registers eax,ebx,ecx (from pushad-structure transmitted + as argument to the system function). Now it is corrected, so, + probably, it is meaningful to return cluster size in edx, while + this function is not used yet. + * There exists also subfunction 11 of function 18, + which returns information on file system. From the full table + of disk subsystem it is possible to deduce cluster size (there + it is stored in sectors) and total number of clusters + for hard disks. + +====================================================================== +=============== Function 59 - trace last system calls. =============== +====================================================================== +Gets data on all system calls of all processes. +Parameters: + * eax = 59 - function number + * ebx = 0 - unique subfunction + * ecx = pointer to the buffer + * edx = size of the buffer +Returned value: + * eax = total number of system calls made from system boot + (modulo 2^32) + * ebx = 0 +Format of information on one call: (size = 0x40 = 64 bytes) + * +0: dword: PID of process/thread + * +4: 7*dword: garbage + * +32 = +0x20: dword: value of edi at the call + * +36 = +0x24: dword: esi + * +40 = +0x28: dword: ebp + * +44 = +0x2C: dword: stack pointer of the kernel handler + * +48 = +0x30: dword: ebx + * +52 = +0x34: dword: edx + * +56 = +0x38: dword: ecx + * +60 = +0x3C: dword: eax (=number of system function) +Remarks: + * The function is used only in the application 'systrace'. + It is rather difficult to imagine a situation, in which + this application or this function are really useful; + and all system calls for support of this function are a little + decelerated (though not strongly)... + * So there is a proposition to delete from the kernel + support of this function, together with application 'systrace'. + * The information on system calls saves in the system + ring buffer with 0x10 entries. + This function simply copies the given size of data + from this buffer to the given address. + * One can determine, which entry in the buffer corresponds to + last system call, by value of eax, namely, it is the entry + (eax and 0xF) (at offset (eax and 0xF)*0x40). + * In the current implementation there can be the seldom + meeting problems of unsynchronization, when the information + on some calls becomes outdated. + * Under the system buffer one page, 4Kb, is allocated. + Size of an entry = 64 bytes. Why only 16 entries are used, + is not clearly. + * The value of esp at the moment of system call cannot + be determined by this function. + * The current implementation does not check edx for correctness. + +====================================================================== +========== Function 60 - Inter Process Communication (IPC). ========== +====================================================================== +IPC is used for message dispatching from one process/thread to +another. Previously it is necessary to agree how to interpret +the concrete message. + +----------- Subfunction 1 - set the area for IPC receiving ----------- +Is called by process-receiver. +Parameters: + * eax = 60 - function number + * ebx = 1 - subfunction number + * ecx = pointer to the buffer + * edx = size of the buffer +Returned value: + * eax = 0 - always success +Format of IPC-buffer: + * +0: dword: if nonzero, buffer is considered locked; + lock/unlock the buffer, when you work with it and need that + buffer data are not changed from outside (no new messages) + * +4: dword: occupied place in the buffer (in bytes) + * +8: first message + * +8+n: second message + * ... +Format of a message: + * +0: dword: PID of sender + * +4: dword: message length (not including this header) + * +8: n*byte: message data + +------------------ Subfunction 2 - send IPC message ------------------ +Is called by process-sender. +Parameters: + * eax = 60 - function number + * ebx = 2 - subfunction number + * ecx = PID of receiver + * edx = pointer to the message data + * esi = message length (in bytes) +Returned value: + * eax = 0 - success + * eax = 1 - the receiver has not defined buffer for IPC messages + (can be, still have no time, + and can be, this is not right process) + * eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit + * eax = 3 - overflow of IPC-buffer of the receiver + * eax = 4 - process/thread with such PID does not exist +Remarks: + * Immediately after writing of IPC-message to the buffer the system + sends to the receiver the event with code 7 (see event codes). + +====================================================================== +==== Function 61 - get parameters for the direct graphics access. ==== +====================================================================== +The data of the graphics screen (the memory area which displays +screen contents) are accessible to a program directly, without +any system calls, through the selector gs: + mov eax, [gs:0] +places in eax the first dword of the buffer, which contains +information on color of the left upper point (and, possibly, colors +of several following). + mov [gs:0], eax +by work in VESA modes with LFB sets color of the left upper point +(and, possibly, colors of several following). +To interpret the data of graphics screen program needs to know +some parameters, returning by this function. +Remarks: + * Graphics parameters changes very seldom at work, + namely, only in cases, when user works with the application VRR. + * At videomode change the system redraws all windows (event + with code 1) and redraws the background (event 5). + Same events occur in other cases too, which meet much more often, + than videomode change. + * By operation in videomodes with LFB the selector gs points to + LFB itself, so reading/writing on gs result directly in + change of screen contents. By operation in videomodes without + LFB gs points to some data area in the kernel, and all functions + of screen output fulfil honesty double operation on writing + directly to the screen and writing to this buffer. In result + at reading contents of this buffer the results correspond to + screen contents (with, generally speaking, large color + resolution), and writing is ignored. + One exception is the mode 320*200, for which main loop of the + system thread updates the screen according to mouse movements. + +------------------------- Screen resolution -------------------------- +Parameters: + * eax = 61 - function number + * ebx = 1 - subfunction number +Returned value: + * eax = [resolution on x axis]*65536 + [resolution on y axis] +Remarks: + * One can use function 14 paying attention that + it returns sizes on 1 pixel less. It is fully equivalent way. + +---------------------- Number of bits per pixel ---------------------- +Parameters: + * eax = 61 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = number of bits per pixel (24 or 32) + +-------------------- Number of bytes per scanline -------------------- +Parameters: + * eax = 61 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = number of bytes occupied by one scanline + (horizontal line on the screen) + +====================================================================== +===== Function 62, subfunction 0 - get version of PCI-interface. ===== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 0 - subfunction number +Returned value: + * eax = -1 - PCI access is disabled; otherwise + * ah.al = version of PCI-interface (ah=version, al=subversion) + * high word of eax is zeroed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * If PCI BIOS is not supported, the value of ax is undefined. + +====================================================================== +==== Function 62, subfunction 1 - get number of the last PCI-bus. ==== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 1 - subfunction number +Returned value: + * eax = -1 - access to PCI is disabled; otherwise + * al = number of the last PCI-bus; other bytes of eax are destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * If PCI BIOS is not supported, the value of ax is undefined. + +====================================================================== +===================== Function 62, subfunction 2 ===================== +===== Get mechanism of addressing to the PCI configuration space. ==== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 2 - subfunction number +Returned value: + * eax = -1 - access to PCI is disabled; otherwise + * al = mechanism (1 or 2); other bytes of eax are destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Addressing mechanism is selected depending on + equipment characteristics. + * Subfunctions of read and write work automatically + with the selected mechanism. + +====================================================================== +======== Function 62, subfunctions 4,5,6 - read PCI-register. ======== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 4 - read byte + * bl = 5 - read word + * bl = 6 - read dword + * bh = number of PCI-bus + * ch = dddddfff, where ddddd = number of the device on the bus, + fff = function number of device + * cl = number of register (must be even for bl=5, + divisible by 4 for bl=6) +Returned value: + * eax = -1 - error (access to PCI is disabled or parameters + are not supported); otherwise + * al/ax/eax (depending on requested size) contains the data; + the other part of register eax is destroyed +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Access mechanism 2 supports only 16 devices on a bus and ignores + function number. To get access mechanism use subfunction 2. + * Some registers are standard and exist for all devices, some are + defined by the concrete device. The list of registers of the + first type can be found e.g. in famous + Interrupt List by Ralf Brown + (http://www.pobox.com/~ralf/files.html, + ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); + registers of the second type must be listed + in the device documentation. + +====================================================================== +====== Function 62, subfunctions 8,9,10 - write to PCI-register. ===== +====================================================================== +Parameters: + * eax = 62 - function number + * bl = 8 - write byte + * bl = 9 - write word + * bl = 10 - write dword + * bh = number of PCI-bus + * ch = dddddfff, where ddddd = number of the device on the bus, + fff = function number of device + * cl = number of register (must be even for bl=9, + divisible by 4 for bl=10) + * dl/dx/edx (depending on requested size) contatins + the data to write +Returned value: + * eax = -1 - error (access to PCI is disabled or parameters + are not supported) + * eax = 0 - success +Remarks: + * Previously low-level access to PCI for applications must be + enabled by subfunction 12 of function 21. + * Access mechanism 2 supports only 16 devices on a bus and ignores + function number. To get access mechanism use subfunction 2. + * Some registers are standard and exist for all devices, some are + defined by the concrete device. The list of registers of the + first type can be found e.g. in famous Interrupt List by + Ralf Brown; registers of the second type must be listed + in the device documentation. + +====================================================================== +============== Function 63 - work with the debug board. ============== +====================================================================== +The debug board is the global system buffer (with the size +512 bytes), to which any program can write (generally speaking, +arbitrary) data and from which other program can read these data. +By the agreement written data are text strings interpreted as +debug messages on a course of program execution. The kernel in +some situations also writes to the debug board information on +execution of some functions; by the agreement kernel messages +begins from the prefix "K : ". +For view of the debug board the application 'board' was created, +which reads data from the buffer and displays them in its window. +'board' interpretes the sequence of codes 13,10 as newline. +A character with null code in an end of line is not necessary, +but also does not prevent. +Because debugger has been written, the value of the debug board +has decreased, as debugger allows to inspect completely a course of +program execution without any efforts from the direction of program +itself. Nevertheless in some cases the debug board is still useful. + +----------------------------- Write byte ----------------------------- +Parameters: + * eax = 63 - function number + * ebx = 1 - subfunction number + * cl = data byte +Returned value: + * function does not return value +Remarks: + * Byte is written to the buffer. Buffer size is 512 bytes. + At buffer overflow all obtained data are lost. + * For output to the debug board of more complicated objects + (strings, numbers) it is enough to call this function in cycle. + It is possible not to write the appropriate code manually and use + file 'debug.inc', which is included into the distributive. + +----------------------------- Read byte ------------------------------ +Takes away byte from the buffer. +Parameters: + * eax = 63 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = ebx = 0 - the buffer is empty + * eax = byte, ebx = 1 - byte was successfully read + +====================================================================== +============== Function 64 - resize application memory. ============== +====================================================================== +Parameters: + * eax = 64 - function number + * ebx = 1 - unique subfunction + * ecx = new memory size +Returned value: + * eax = 0 - success + * eax = 1 - not enough memory +Remarks: + * At the moment this function is a sole resource for dynamic + allocation/free of application memory. + +====================================================================== +================== Function 66 - work with keyboard. ================= +====================================================================== +The input mode influences results of reading keys by function 2. +When a program loads, ASCII input mode is set for it. + +-------------- Subfunction 1 - set keyboard input mode. -------------- +Parameters: + * eax = 66 - function number + * ebx = 1 - subfunction number + * ecx = mode: + * 0 = normal (ASCII-characters) + * 1 = scancodes +Returned value: + * function does not return value + +-------------- Subfunction 2 - get keyboard input mode. -------------- +Parameters: + * eax = 66 - function number + * ebx = 2 - subfunction number +Returned value: + * eax = current mode + +------------ Subfunction 3 - get status of control keys. ------------- +Parameters: + * eax = 66 - function number + * ebx = 3 - subfunction number +Returned value: + * eax = bit mask: + * bit 0 (mask 1): left Shift is pressed + * bit 1 (mask 2): right Shift is pressed + * bit 2 (mask 4): left Ctrl is pressed + * bit 3 (mask 8): right Ctrl is pressed + * bit 4 (mask 0x10): left Alt is pressed + * bit 5 (mask 0x20): right Alt is pressed + * bit 6 (mask 0x40): CapsLock is on + * bit 7 (mask 0x80): NumLock is on + * bit 8 (mask 0x100): ScrollLock is on + * other bits are cleared + +-------------- Subfunction 4 - set system-wide hotkey. --------------- +When hotkey is pressed, the system notifies only those applications, +which have installed it; the active application (which receives +all normal input) does not receive such keys. +The notification consists in sending event with the code 2. +Reading hotkey is the same as reading normal key - by function 2. +Parameters: + * eax = 66 - function number + * ebx = 4 - subfunction number + * cl determines key scancode; + use cl=0 to give combinations such as Ctrl+Shift + * edx = 0xXYZ determines possible states of control keys: + * Z (low 4 bits) determines state of LShift and RShift: + * 0 = no key must be pressed; + * 1 = exactly one key must be pressed; + * 2 = both keys must be pressed; + * 3 = must be pressed LShift, but not RShift; + * 4 = must be pressed RShift, but not LShift + * Y - similar for LCtrl and RCtrl; + * X - similar for LAlt and RAlt +Returned value: + * eax=0 - success + * eax=1 - too mant hotkeys (maximum 256 are allowed) +Remarks: + * Hotkey can work either at pressing or at release. Release + scancode of a key is more on 128 than pressing scancode + (i.e. high bit is set). + * Several applications can set the same combination; + all such applications will be informed on pressing + such combination. + +-------------- Subfunction 5 - delete installed hotkey. -------------- +Parameters: + * eax = 66 - function number + * ebx = 5 - subfunction number + * cl = scancode of key and edx = 0xXYZ the same as in subfunction 4 +Returned value: + * eax = 0 - success + * eax = 1 - there is no such hotkey +Remarks: + * When a process/thread terminates, all hotkey installed by it are + deleted. + * The call to this subfunction does not affect other applications. + If other application has defined the same combination, it will + still receive notices. + +====================================================================== +========= Function 67 - change position/sizes of the window. ========= +====================================================================== +Parameters: + * eax = 67 - function number + * ebx = new x-coordinate of the window + * ecx = new y-coordinate of the window + * edx = new x-size of the window + * esi = new y-size of the window +Returned value: + * function does not return value +Remarks: + * The value -1 for a parameter means "do not change"; e.g. to move + the window without resizing it is possible to specify edx=esi=-1. + * Previously the window must be defined by function 0. + It sets initial coordinates and sizes of the window. + * Sizes of the window are understood in sense of function 0, + that is one pixel less than real sizes. + * The function call for maximized windows is simply ignored. + * For windows of appropriate styles position and/or sizes can be + changed by user; current position and sizes can be obtained by + call to function 9. + * The function sends to the window redraw event (with the code 1). + +====================================================================== +====== Function 68, subfunction 0 - get the task switch counter. ===== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 0 - subfunction number +Returned value: + * eax = number of task switches from the system booting + (modulo 2^32) + +====================================================================== +======= Function 68, subfunction 1 - switch to the next thread. ====== +====================================================================== +The function completes the current time slice allocated to the +thread and switches to the next. (Which thread in which process +will be next, is unpredictable). Later, when execution queue +will reach the current thread, execution will be continued. +Parameters: + * eax = 68 - function number + * ebx = 1 - subfunction number +Returned value: + * function does not return value + +====================================================================== +============= Function 68, subfunction 2 - cache + rdpmc. ============ +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 2 - subfunction number + * ecx = required action: + * ecx = 0 - enable instruction 'rdpmc' + (ReaD Performance-Monitoring Counters) for applications + * ecx = 1 - find out whether cache is disabled/enabled + * ecx = 2 - enable cache + * ecx = 3 - disable cache +Returned value: + * for ecx=0: + * eax = the value of cr4 + * for ecx=1: + * eax = (cr0 and 0x60000000): + * eax = 0 - cache is on + * eax <> 0 - cache is off + * for ecx=2 and ecx=3: + * function does not return value + +====================================================================== +=========== Function 68, subfunction 3 - read MSR-register. ========== +====================================================================== +MSR = Model Specific Register; the complete list of MSR-registers +of a processor is included to the documentation on it (for example, +IA-32 Intel Architecture Software Developer's Manual, +Volume 3, Appendix B); each processor family has its own subset +of the MSR-registers. +Parameters: + * eax = 68 - function number + * ebx = 3 - subfunction number + * ecx is ignored + * edx = MSR address +Returned value: + * ebx:eax = high:low dword of the result +Remarks: + * If ecx contains nonexistent or not implemented for this processor + MSR, processor will generate an exception in the kernel, which + will kill the thread. + * Previously it is necessary to check, whether MSRs are supported + as a whole, with the instruction 'cpuid'. Otherwise processor + will generate other exception in the kernel, which will anyway + kill the thread. + +====================================================================== +========= Function 68, subfunction 4 - write to MSR-register. ======== +====================================================================== +MSR = Model Specific Register; the complete list of MSR-registers +of a processor is included to the documentation on it (for example, +IA-32 Intel Architecture Software Developer's Manual, +Volume 3, Appendix B); each processor family has its own subset +of the MSR-registers. +Parameters: + * eax = 68 - function number + * ebx = 4 - subfunction number + * ecx is ignored + * edx = MSR address + * esi:edi = high:low dword +Returned value: + * ebx:eax = copy of esi:edi +Замечания: + * If ecx contains nonexistent or not implemented for this processor + MSR, processor will generate an exception in the kernel, which + will kill the thread. + * Previously it is necessary to check, whether MSRs are supported + as a whole, with the instruction 'cpuid'. Otherwise processor + will generate other exception in the kernel, which will anyway + kill the thread. + +====================================================================== +======= Function 68, subfunction 5 - allocate physical memory. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 5 - subfunction number + * ecx = size (in bytes) +Returned value: + * eax = physical address of allocated memory +Remarks: + * Normal applications must not use this function, it is intended + for the case, when for some device it is required to place + data to the known physical address. (In effect, this function + was developed for AC97WAV.) + * The number of blocks of physical memory is limited (by constant + 24, and this constant includes some blocks for kernel). + * To free a memory allocated by such way use + subfunction 6, to copy data there and back + use subfunctions 7 and 8. + +====================================================================== +========= Function 68, subfunction 6 - free physical memory. ========= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 6 - subfunction number + * ecx = physical address of memory +Returned value: + * function does not return value +Remarks: + * Normal applications must not use this function, it is intended + for the case, when for some device it is required to place + data to the known physical address. (In effect, this function + was developed for AC97WAV.) + * The memory must be previously allocated by subfunction 5. + +====================================================================== +===== Function 68, subfunction 7 - write data to physical memory. ==== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 7 - subfunction number + * ecx = physical address + * edx = pointer to the data (in the application) + * esi = size of the data (in bytes) +Returned value: + * function does not return value +Remarks: + * Normal applications must not use this function, it is intended + for the case, when for some device it is required to place + data to the known physical address. (In effect, this function + was developed for AC97WAV.) + * The range of physical addresses should lie inside of previously + allocated by subfunction 5 block of physical memory. + * There is no check for correctness. + +====================================================================== +==== Function 68, subfunction 8 - read data from physical memory. ==== +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 8 - subfunction number + * ecx = physical address + * edx = pointer to buffer for data (in application) + * esi = size of data (in bytes) +Returned value: + * function does not return value +Remarks: + * Normal applications must not use this function, it is intended + for the case, when for some device it is required to place + data to the known physical address. (In effect, this function + was developed for AC97WAV.) + * The range of physical addresses should lie inside of previously + allocated by subfunction 5 block of physical memory. + * There is no check for correctness. + +====================================================================== +====================== Fucntion 69 - debugging. ====================== +====================================================================== +A process can load other process as debugged by set of corresponding +bit by call to subfunction 16 of function 58 +or subfunction 7 of function 70. +A process can have only one debugger; one process can debug some +others. The system notifies debugger on events occuring with +debugged process. Messages are written to the buffer defined by +subfunction 0. +Format of a message: + * +0: dword: message code + * +4: dword: PID of debugged process + * +8: there can be additional data depending on message code +Message codes: + * 1 = exception + * in addition dword-number of the exception is given + * process is suspended + * 2 = process has terminated + * comes at any termination: both through the system function -1, + and at "murder" by any other process (including debugger itself) + * 3 = debug exception int 1 = #DB + * 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 + (flag TF is set TF) + * process is suspended +When debugger terminates, all debugged processes are killed. +If debugger does not want this, it must previously detach by +subfunction 3. + +All subfunctions are applicable only to processes/threads started +from the current by function 58 or 70 with set debugging flag. +Debugging of multithreaded programs is not supported yet. +The full list of subfunctions: + * subfunction 0 - define data area for debug messages + * subfunction 1 - get contents of registers of debugged thread + * subfunction 2 - set contents of registers of debugged thread + * subfunction 3 - detach from debugged process + * subfunction 4 - suspend debugged thread + * subfunction 5 - resume debugged thread + * subfunction 6 - read from the memory of debugged process + * subfunction 7 - write to the memory of debugged process + * subfunction 8 - terminate debugged thread + * subfunction 9 - set/clear hardware breakpoint + +====================================================================== += Function 69, subfunction 0 - define data area fror debug messages. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 0 - subfunction number + * ecx = pointer +Format of data area: + * +0: dword: N = buffer size (not including this header) + * +4: dword: occupied place + * +8: N*byte: buffer +Returned value: + * function does not return value +Remarks: + * If the size field is negative, the buffer is considered locked + and at arrival of new message the system will wait. + For synchronization frame all work with the buffer by operations + lock/unlock + neg [bufsize] + * Data in the buffer are considered as array of items with variable + length - messages. Format of a message is explained in + general description. + +====================================================================== +===================== Function 69, subfunction 1 ===================== +============ Get contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 1 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes + * esi = pointer to context structure +Returned value: + * function does not return value +Format of context structure: (FPU is not supported yet) + * +0: dword: eip + * +4: dword: eflags + * +8: dword: eax + * +12 = +0xC: dword: ecx + * +16 = +0x10: dword: edx + * +20 = +0x14: dword: ebx + * +24 = +0x18: dword: esp + * +28 = +0x1C: dword: ebp + * +32 = +0x20: dword: esi + * +36 = +0x24: dword: edi +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===================== Function 69, subfunction 2 ===================== +============ Set contents of registers of debugged thread. =========== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 2 - subfunction number + * ecx = thread identifier + * edx = size of context structure, must be 0x28=40 bytes +Returned value: + * function does not return value +Format of context structure is shown in the description of +subfunction 1. +Remarks: + * If the thread executes code of ring-0, the function returns + contents of registers of ring-3. + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +===== Function 69, subfunction 3 - detach from debugged process. ===== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 3 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * If the process was suspended, it resumes execution. + +====================================================================== +======== Function 69, subfunction 4 - suspend debugged thread. ======= +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 4 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======== Function 69, subfunction 5 - resume debugged thread. ======== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 5 - subfunction number + * ecx = thread identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== += Fucntion 69, subfunction 6 - read from memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 6 - subfunction number + * ecx = identifier + * edx = number of bytes to read + * esi = address in the memory of debugged process + * edi = pointer to buffer for data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of read bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +== Function 69, subfunction 7 - write to memory of debugged process. = +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 7 - subfunction number + * ecx = identifier + * edx = number of bytes to write + * esi = address of memory in debugged process + * edi = pointer to data +Returned value: + * eax = -1 at an error (invalid PID or buffer) + * otherwise eax = number of written bytes (possibly, 0, + if esi is too large) +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + +====================================================================== +======= Function 69, subfunction 8 - terminate debugged thread. ====== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 8 - subfunction number + * ecx = identifier +Returned value: + * function does not return value +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * The function is similar to subfunction 2 of function 18 + with two differences: it requires first remark and + accepts PID rather than slot number. + +====================================================================== +===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== +====================================================================== +Parameters: + * eax = 69 - function number + * ebx = 9 - subfunction number + * ecx = thread identifier + * dl = index of breakpoint, from 0 to 3 inclusively + * dh = flags: + * if high bit is cleared - set breakpoint: + * bits 0-1 - condition: + * 00 = breakpoint on execution + * 01 = breakpoint on read + * 11 = breakpoint on read/write + * bits 2-3 - length; for breakpoints on exception it must be + 00, otherwise one of + * 00 = byte + * 01 = word + * 11 = dword + * esi = breakpoint address; must be aligned according to + the length (i.e. must be even for word breakpoints, + divisible by 4 for dword) + * if high bit is set - clear breakpoint +Returned value: + * eax = 0 - success + * eax = 1 - error in the input data + * eax = 2 - (reserved, is never returned in the current + implementation) a global breakpoint with that index is already set +Remarks: + * Process must be loaded for debugging (as is shown in + general description). + * Hardware breakpoints are implemented through DRx-registers of + the processor, all limitations results from this. + * The function can reinstall the breakpoint, previously set + by it (and it does not inform on this). + Carry on the list of set breakpoints in the debugger. + * Breakpoints generate debug exception #DB, on which the system + notifies debugger. + * Breakpoints on write and read/write act after + execution of the caused it instruction. + +====================================================================== +==== Function 70 - work with file system with long names support. ==== +====================================================================== +Parameters: + * eax = 70 + * ebx = pointer to the information structure +Returned value: + * eax = 0 - success; otherwise file system error code + * some subfunctions return value in other registers too +General format of the information structure: + * +0: dword: subfunction number + * +4: dword: file offset + * +8: dword: high dword of offset (must be 0) or flags field + * +12 = +0xC: dword: size + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: n db: ASCIIZ-string with the filename + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with the filename +Specifications - in documentation on the appropriate subfunction. +Filename is case-insensitive. Russian letters must be written in +the encoding cp866 (DOS). +Format of filename: +/base/number/dir1/dir2/.../dirn/file, +where /base/number identifies device, on which file is located: +one of + * /RD/1 = /RAMDISK/1 to access ramdisk + * /FD/1 = /FLOPPYDISK/1 to access first floppy drive, + /FD/2 = /FLOPPYDISK/2 to access second one + * /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices + IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave); + x - partition number on the selected hard drive, varies from 1 + to 255 (on each hard drive the indexing starts from 1) + * /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to + CD on IDE0 (Primary Master), IDE1 (Primary Slave), + IDE2 (Secondary Master), IDE3 (Secondary Slave) +Examples: + * '/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 +Available subfunctions: + * subfunction 0 - read file + * subfunction 1 - read folder + * subfunction 2 - create/rewrite file + * subfunction 3 - write to existing file + * subfunction 4 - set file size + * subfunction 5 - get attributes of file/folder + * subfunction 6 - set attributes of file/folder + * subfunction 7 - start application +For CD-drives due to hardware limitations only subfunctions +0,1,5 and 7 are available, other subfunctions return error +with code 2. + +====================================================================== +=== Function 70, subfunction 0 - read file with long names support. == +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 0 = subfunction number + * +4: dword: file offset (in bytes) + * +8: dword: 0 (reserved for high dword of offset) + * +12 = +0xC: dword: number of bytes to read + * +16 = +0x10: dword: pointer to buffer for data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of read bytes or -1=0xffffffff if file was not found +Remarks: + * If file was ended before last requested block was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * The function does not allow to read folder (returns eax=10, + access denied). + +====================================================================== +== Function 70, subfunction 1 - read folder with long names support. = +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 1 = subfunction number + * +4: dword: index of starting block (beginning from 0) + * +8: dword: flags field: + * bit 0 (mask 1): in what format to return names, + 0=ANSI, 1=UNICODE + * other bits are reserved and must be set to 0 for the future + compatibility + * +12 = +0xC: dword: number of blocks to read + * +16 = +0x10: dword: pointer to buffer for data, buffer size + must be not less than 32 + [+12]*560 bytes + * +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of files, information on which was written to + the buffer, or -1=0xffffffff, if folder was not found +Structure of the buffer: + * +0: 32*byte: header + * +32 = +0x20: n1*byte: block with information on file 1 + * +32+n1: n2*byte: block with information on file 2 + * ... +Structure of header: + * +0: dword: version of structure (current is 1) + * +4: dword: number of placed blocks; is not greater than requested + in the field +12 of information structure; can be less, if + there are no more files in folder (the same as in ebx) + * +8: dword: total number of files in folder + * +12 = +0xC: 20*byte: reserved (zeroed) +Structure of block of data for folder entry (BDFE): + * +0: dword: attributes of file: + * bit 0 (mask 1): file is read-only + * bit 1 (mask 2): file is hidden + * bit 2 (mask 4): file is system + * bit 3 (mask 8): this is not a file but volume label + (for one partition meets no more than once and + only in root folder) + * bit 4 (mask 0x10): this is a folder + * bit 5 (mask 0x20): file was not archived - many archivation + programs have an option to archive only files with this bit set, + and after archiving this bit is cleared - it can be useful + for automatically creating of backup-archives as at writing + this bit is usually set + * +4: byte: type of name data: + (coincides with bit 0 of flags in the information structure) + * 0 = ASCII = 1-byte representation of each character + * 1 = UNICODE = 2-byte representation of each character + * +5: 3*byte: reserved (zero) + * +8: 4*byte: time of file creation + * +12 = +0xC: 4*byte: date of file creation + * +16 = +0x10: 4*byte: time of last access (read or write) + * +20 = +0x14: 4*byte: date of last access + * +24 = +0x18: 4*byte: time of last modification + * +28 = +0x1C: 4*byte: date of last modification + * +32 = +0x20: qword: file size in bytes (up to 16777216 Tb) + * +40 = +0x28: name + * for ASCII format: maximum length is 263 characters + (263 bytes), byte after the name has value 0 + * для формата UNICODE: maximum length is 259 characters + (518 bytes), 2 bytes after the name have value 0 +Time format: + * +0: byte: seconds + * +1: byte: minutes + * +2: byte: hours + * +3: byte: reserved (0) + * for example, 23.59.59 is written as (in hex) 3B 3B 17 00 +Date format: + * +0: byte: day + * +1: byte: month + * +2: word: year + * for example, 25.11.1979 is written as (in hex) 19 0B BB 07 +Remarks: + * If BDFE contains ASCII name, the length of BDFE is 304 bytes, + if UNICODE name - 560 bytes. Value of length is aligned + on 16-byte bound (to accelerate processing in CPU cache). + * First character after a name is zero (ASCIIZ-string). The further + data contain garbage. + * If files in folder were ended before requested number was read, + the function will read as many as it can, and after that return + eax=6 (EOF). + * Any folder on the disk, except for root, contains two special + entries "." and "..", identifying accordingly the folder itself + and the parent folder. + * The function allows also to read virtual folders "/", "/rd", + "/fd", "/hd[n]", thus attributes of subfolders are set to 0x10, + and times and dates are zeroed. An alternative way to get the + equipment information - subfunction 11 of function 18. + +====================================================================== +===================== Function 70, subfunction 2 ===================== +============ Create/rewrite file with long names support. ============ +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 2 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: number of bytes to read + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of written bytes (possibly 0) +Remarks: + * If a file with given name did not exist, it is created; + if it existed, it is rewritten. + * If there is not enough free space on disk, the function will + write as many as can and then return error code 8. + * The function is not supported for CD (returns error code 2). + +====================================================================== +===================== Function 70, subfunction 3 ===================== +=========== Write to existing file with long names support. ========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 3 = subfunction number + * +4: dword: file offset (in bytes) + * +8: dword: high dword of offset (must be 0 for FAT) + * +12 = +0xC: dword: number of bytes to write + * +16 = +0x10: dword: pointer to data + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx = number of written bytes (possibly 0) +Remarks: + * The file must already exist, otherwise function returns eax=5. + * The only result of write 0 bytes is update in the file attributes + date/time of modification and access to the current date/time. + * If beginning and/or ending position is greater than file size + (except for the previous case), the file is expanded to needed + size with zero characters. + * The function is not supported for CD (returns error code 2). + +====================================================================== +============ Function 70, subfunction 4 - set end of file. =========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 4 = subfunction number + * +4: dword: low dword of new file size + * +8: dword: high dword of new file size (must be 0 for FAT) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Remarks: + * If the new file size is less than old one, file is truncated. + If the new size is greater than old one, file is expanded with + characters with code 0. If the new size is equal to old one, + the only result of call is set date/time of modification and + access to the current date/time. + * If there is not enough free space on disk for expansion, the + function will expand to maximum possible size and then return + error code 8. + * The function is not supported for CD (returns error code 2). + +====================================================================== +==== Function 70, subfunction 5 - get information on file/folder. ==== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 5 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: pointer to buffer for data (40 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +Information on file is returned in the BDFE format (block of data +for folder entry), explained in the description of +subfunction 1, but without filename +(i.e. only first 40 = 0x28 bytes). +Remarks: + * The function does not support virtual folders such as /, /rd and + root folders like /rd/1. + +====================================================================== +===== Function 70, subfunction 6 - set attributes of file/folder. ==== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 6 = subfunction number + * +4: dword: 0 (reserved) + * +8: dword: 0 (reserved) + * +12 = +0xC: dword: 0 (reserved) + * +16 = +0x10: dword: pointer to buffer with attributes (32 bytes) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax = 0 - success, otherwise file system error code + * ebx destroyed +File attributes are first 32 bytes in BDFE (block of data +for folder entry), explained in the description of subfunction 1 +(that is, without name and size of file). Attribute +file/folder/volume label (bits 3,4 in dword +0) is not changed. +Byte +4 (name format) is ignored. +Remarks: + * The function does not support virtual folders such as /, /rd and + root folders like /rd/1. + * The function is not supported for CD (returns error code 2). + +====================================================================== +=========== Function 70, subfunction 7 - start application. ========== +====================================================================== +Parameters: + * eax = 70 - function number + * ebx = pointer to the information structure +Format of the information structure: + * +0: dword: 7 = subfunction number + * +4: dword: flags field: + * бит 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) + * +16 = +0x10: dword: 0 (reserved) + * +20 = +0x14: ASCIIZ-name of file, the rules of names forming are + given in the general description + or + * +20 = +0x14: db 0 + * +21 = +0x15: dd pointer to ASCIIZ-string with file name +Returned value: + * eax > 0 - program is loaded, eax contains PID + * eax < 0 - an error has occured, -eax contains + file system error code + * ebx destroyed +Remarks: + * Command line must be terminated by the character with the code 0 + (ASCIIZ-string); function takes into account either all characters + up to terminating zero inclusively or first 256 character + regarding what is less. + * If the process is started as debugged, it is created in + the suspended state; to run use subfunction 5 of function 69. + +====================================================================== +========== Function 71, subfunction 1 - set window caption. ========== +====================================================================== +Parameters: + * eax = 71 - function number + * ebx = 1 - subfunction number + * ecx = pointer to caption string +Returned value: + * function does not return value +Remarks: + * String must be in the ASCIIZ-format. Disregarding real string + length, no more than 255 characters are drawn. + * Pass NULL in ecx to remove caption. + +====================================================================== +=============== Function -1 - terminate thread/process =============== +====================================================================== +Parameters: + * eax = -1 - function number +Returned value: + * function does not return neither value nor control +Remarks: + * If the process did not create threads obviously, it has only + one thread, which termination results in process termination. + * If the current thread is last in the process, its termination + also results in process terminates. + * This function terminates the current thread. Other thread can be + killed by call to subfunction 2 of function 18. + +====================================================================== +=========================== List of events =========================== +====================================================================== +Next event can be retrieved by the call of one from functions 10 +(to wait for event), 11 (to check without waiting), 23 +(to wait during the given time). +These functions return only those events, which enter into a mask set +by function 40. By default it is first three, +there is enough for most applications. +Codes of events: + * 1 = redraw event (is reset by call to function 0) + * 2 = key on keyboard is pressed (acts, only when the window is + active) or hotkey is pressed; is reset, when all keys from + the buffer are read out by function 2 + * 3 = button is pressed, defined earlier by function 8 + (or close button, created implicitly by function 0; + minimize button is handled by the system and sends no message; + acts, only when the window is active; + is reset when all buttons from the buffer + are read out by function 17) + * 4 = reserved (in current implementation never comes even after + unmasking by function 40) + * 5 = the desktop background is redrawed (is reset automatically + after redraw, so if in redraw time program does not wait and + does not check events, it will not remark this event) + * 6 = mouse event (something happened - button pressing or moving; + is reset at reading) + * 7 = IPC event (see function 60 - + Inter Process Communication; is reset at reading) + * 8 = network event (is reset at reading) + * 9 = debug event (is reset at reading; see + debug subsystem) + * 16..31 = event with appropriate IRQ + (16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data) + +====================================================================== +=================== Error codes of the file system =================== +====================================================================== + * 0 = success + * 1 = base and/or partition of a hard disk is not defined + (by subfunctions 7, 8 of function 21) + * 2 = function is not supported for the given file system + * 3 = unknown file system + * 4 = is returned only from function 'rename' by transmission of + the strongly incorrect parameter and in any way does not + correspond to the description in the kernel sources + "partition not defined at hd" + * 5 = file not found + * 6 = end of file, EOF + * 7 = pointer lies outside of application memory + * 8 = disk is full + * 9 = FAT table is destroyed + * 10 = access denied + * 11 = device error +Application start functions can return also following errors: + * 30 = 0x1E = not enough memory + * 31 = 0x1F = file is not executable + * 32 = 0x20 = too many processes diff --git a/kernel/tags/kolibri0.6.0.0/fs/fat12.inc b/kernel/tags/kolibri0.6.0.0/fs/fat12.inc new file mode 100644 index 0000000000..c11a75f9f1 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/fat12.inc @@ -0,0 +1,2576 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; FAT12.INC ;; +;; (C) 2005 Mario79, License: GPL ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +n_sector dd 0 ; temporary save for sector value +flp_status dd 0 +clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write +path_pointer_flp dd 0 +pointer_file_name_flp dd 0 +save_root_flag db 0 +save_flag db 0 +root_read db 0 ; 0-necessary to load root, 1-not to load root +flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat +flp_number db 0 ; 1- Floppy A, 2-Floppy B +old_track db 0 ; old value track +flp_label rb 15 ; Label and ID of inserted floppy disk + +reserve_flp: + + cli + cmp [flp_status],0 + je reserve_flp_ok + + sti + call change_task + jmp reserve_flp + + reserve_flp_ok: + + push eax + mov eax,[0x3000] + shl eax,5 + mov eax,[eax+0x3000+TASKDATA.pid] + mov [flp_status],eax + pop eax + sti + ret + +floppy_free_space: +;--------------------------------------------- +; +; returns free space in edi +; +;--------------------------------------------- + push eax ebx ecx + call read_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_2 + mov eax,0x282004 + xor edi,edi + mov ecx,2847 ;1448000/512 +rdfs1_1: + mov ebx,[eax] + and ebx,4095 + jne rdfs2_1 + add edi,512 +rdfs2_1: + add eax,2 + loop rdfs1_1 +fdc_status_error_2: + pop ecx ebx eax + ret + + + + +floppy_fileread: +;---------------------------------------------------------------- +; +; fileread - sys floppy +; +; eax points to filename 11 chars - for root directory +; ebx first wanted block ; 1+ ; if 0 then set to 1 +; ecx number of blocks to read ; 1+ ; if 0 then set to 1 +; edx mem location to return data +; esi length of filename 12*X +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; ret ebx = size or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; 10 = access denied +;-------------------------------------------------------------- + + mov [save_flag],0 + mov [path_pointer_flp],edi + cmp esi,0 ; return ramdisk root + jne fr_noroot_1 + cmp ebx,224/16 + jbe fr_do_1 + mov eax,5 + mov ebx,0 + mov [flp_status],0 + ret + +fr_do_1: + push ebx ecx edx + call read_flp_root + pop edx ecx ebx + cmp [FDC_Status],0 + jne fdc_status_error_1 + mov edi,edx + dec ebx + shl ebx,9 + mov esi,0x8000 + add esi,ebx + shl ecx,9 + cld + rep movsb + mov eax,0 ; ok read + mov ebx,0 + mov [flp_status],0 + ret +fdc_status_error_1: + mov [flp_status],0 + mov eax,10 + mov ebx,-1 + ret + +fr_noroot_1: + sub esp,32 + call expand_filename +frfloppy_1: + cmp ebx,0 + jne frfl5_1 + mov ebx,1 +frfl5_1: + cmp ecx,0 + jne frfl6_1 + mov ecx,1 +frfl6_1: + dec ebx + push eax + push eax ebx ecx edx esi edi + 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 ; Сектор + call SeekTrack + mov dh,14 +l.20_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_3_1 + mov dl,16 + mov edi,0xD000 + inc [FDD_Sector] +l.21_1: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifound_1 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + cmp dl,0 + jne l.21_1 + dec dh + cmp dh,0 + jne l.20_1 +fdc_status_error_3: + mov eax,5 ; file not found ? + mov ebx,-1 + add esp,32+28 + mov [flp_status],0 + ret +fdc_status_error_3_2: + cmp [FDC_Status],0 + je fdc_status_error_3 +fdc_status_error_3_1: + add esp,32+28 + jmp fdc_status_error_1 + +fifound_1: + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + je fifound_2 + add edi,0xf + mov eax,[edi] + and eax,65535 + mov ebx,[path_pointer_flp] + add ebx,36 + call get_cluster_of_a_path_flp + jc fdc_status_error_3_2 + mov ebx,[ebx-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + jmp fifound_3 +fifound_2: + mov ebx,[edi-11+28] ;file size + mov [esp+20],ebx + mov [esp+24],ebx + add edi,0xf + mov eax,[edi] +fifound_3: + and eax,65535 + mov [n_sector],eax ;eax=cluster +frnew_1: + add eax,31 ;bootsector+2*fat+filenames + cmp [esp+16],dword 0 ; wanted cluster ? + jne frfl7_1 + call read_chs_sector + cmp [FDC_Status],0 + jne fdc_status_error_5 + mov edi,[esp+8] + call give_back_application_data_1 + add [esp+8],dword 512 + dec dword [esp+12] ; last wanted cluster ? + cmp [esp+12],dword 0 + je frnoread_1 + jmp frfl8_1 +frfl7_1: + dec dword [esp+16] +frfl8_1: + mov edi,[n_sector] + shl edi,1 ;find next cluster from FAT + add edi,0x282000 + mov eax,[edi] + and eax,4095 + mov edi,eax + mov [n_sector],edi + cmp edi,4095 ;eof - cluster + jz frnoread2_1 + cmp [esp+24],dword 512 ;eof - size + jb frnoread_1 + sub [esp+24],dword 512 + jmp frnew_1 + +read_chs_sector: + call calculate_chs + call ReadSectWithRetr + ret + +frnoread2_1: + cmp [esp+16],dword 0 ; eof without read ? + je frnoread_1 + mov [fdc_irq_func],fdc_null + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + mov eax,6 ; end of file + mov [flp_status],0 + ret + +frnoread_1: + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + mov eax,0 + mov [flp_status],0 + ret + +fdc_status_error_5: + pop edi esi edx ecx + add esp,4 + pop ebx ; ebx <- eax : size of file + add esp,36 + jmp fdc_status_error_1 + +read_flp_root: + pusha + call check_label + cmp [FDC_Status],0 + 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 edi,0x8000 + call SeekTrack +read_flp_root_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_root_read + push edi + call give_back_application_data_1 + pop edi + add edi,512 + inc [FDD_Sector] + cmp [FDD_Sector],16 + jne read_flp_root_1 + mov [root_read],1 +unnecessary_root_read: + popa + ret + + +read_flp_fat: + pusha + call check_label + cmp [FDC_Status],0 + 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 edi,0x8000 + call SeekTrack +read_flp_fat_1: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat + push edi + call give_back_application_data_1 + pop edi + add edi,512 + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne read_flp_fat_1 + mov [FDD_Sector],1 + mov [FDD_Head],1 + call ReadSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat + call give_back_application_data_1 + call calculatefatchain_flp + mov [root_read],0 + mov [flp_fat],1 +unnecessary_flp_fat: + popa + ret + +calculatefatchain_flp: + pushad + + mov esi,0x8000 + mov edi,0x282000 + + fcnew_1: + mov eax,dword [esi] + mov ebx,dword [esi+4] + mov ecx,dword [esi+8] + mov edx,ecx + shr edx,4 ;8 ok + shr dx,4 ;7 ok + xor ch,ch + shld ecx,ebx,20 ;6 ok + shr cx,4 ;5 ok + shld ebx,eax,12 + and ebx,0x0fffffff ;4 ok + shr bx,4 ;3 ok + shl eax,4 + and eax,0x0fffffff ;2 ok + shr ax,4 ;1 ok + mov dword [edi],eax + add edi,4 + mov dword [edi],ebx + add edi,4 + mov dword [edi],ecx + add edi,4 + mov dword [edi],edx + add edi,4 + add esi,12 + + cmp edi,0x282000+2856*2 ;2849 clusters + jnz fcnew_1 + + popad + ret + +check_label: + pushad + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],0 ; Сторона + mov [FDD_Sector],1 ; Сектор + call SetUserInterrupts + call FDDMotorON + call RecalibrateFDD + cmp [FDC_Status],0 + jne fdc_status_error + call SeekTrack + cmp [FDC_Status],0 + jne fdc_status_error + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error + mov esi,flp_label + mov edi,0xD000+39 + mov ecx,15 + cld + rep cmpsb + je same_label + mov [root_read],0 + mov [flp_fat],0 +same_label: + mov esi,0xD000+39 + mov edi,flp_label + mov ecx,15 + cld + rep movsb + popad + ret +fdc_status_error: + popad + ret + +save_flp_root: + pusha + call check_label + cmp [FDC_Status],0 + 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 esi,0x8000 + call SeekTrack +save_flp_root_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_root_save + inc [FDD_Sector] + cmp [FDD_Sector],16 + jne save_flp_root_1 +unnecessary_root_save: + mov [fdc_irq_func],fdc_null + popa + ret + +save_flp_fat: + pusha + call check_label + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + 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 esi,0x8000 + call SeekTrack +save_flp_fat_1: + push esi + call take_data_from_application_1 + pop esi + add esi,512 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + inc [FDD_Sector] + cmp [FDD_Sector],19 + jne save_flp_fat_1 + mov [FDD_Sector],1 + mov [FDD_Head],1 + call take_data_from_application_1 + call WriteSectWithRetr + cmp [FDC_Status],0 + jne unnecessary_flp_fat_save + mov [root_read],0 +unnecessary_flp_fat_save: + mov [fdc_irq_func],fdc_null + popa + ret + + +restorefatchain_flp: ; restore fat chain + pushad + + mov esi,0x282000 + mov edi,0x8000 + + fcnew2_1: + mov eax,dword [esi] + mov ebx,dword [esi+4] + shl ax,4 + shl eax,4 + shl bx,4 + shr ebx,4 + shrd eax,ebx,8 + shr ebx,8 + mov dword [edi],eax + add edi,4 + mov word [edi],bx + add edi,2 + add esi,8 + + cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT + jb fcnew2_1 + + mov esi,0x8000 ; duplicate fat chain + mov edi,0x8000+0x1200 + mov ecx,0x1200/4 + cld + rep movsd + + popad + ret + + +floppy_filedelete: +;-------------------------------------------- +; +; filedelete - sys floppy +; in: +; eax - filename 11 chars - for root directory +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; out: +; eax - 0 = successful, 1 = file not found, 10 = access denied +; +;-------------------------------------------- + mov [path_pointer_flp],edi + mov [save_flag],0 + mov ebp,1 ; file not found as default +filedelete_newtry_1: + sub esp,32 + call expand_filename + push eax ebx ecx edx esi edi + call read_flp_fat + cmp [FDC_Status],0 + jne frnoreadd_1 + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],1 ; Сторона + mov [FDD_Sector],2 ; Сектор + call SeekTrack + mov dh,14 +l.20_2: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_4 + mov dl,16 + mov edi,0xD000 + inc [FDD_Sector] +l.21_2: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifoundd_1 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + jne l.21_2 + dec dh + jne l.20_2 + jmp frnoreadd_1 + +fdc_status_error_4: + pop edi esi edx ecx ebx eax + add esp,32 + jmp fdc_status_error_1 + +fifoundd_1: + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + je fifoundd_2 + movzx eax, word [edi+0xf] + mov ebx,[path_pointer_flp] + add ebx,36 + call get_cluster_of_a_path_flp + jc frnoreadd_1_1 + mov edi,ebx + add edi,11 + jmp fifoundd_2_1 +fifoundd_2: + dec [FDD_Sector] +fifoundd_2_1: + mov [edi-11],byte 0xE5 ;mark filename deleted + movzx edi, word [edi+0xf] ;edi = cluster +frnewd_1: + shl edi,1 ;find next cluster from FAT + add edi,0x282000 + mov eax,[edi] + mov [edi],word 0x0 ;clear fat chain cluster + and eax,4095 + mov edi,eax + cmp edi,dword 4095 ;last cluster ? + jz frnoreadd2_1 + jmp frnewd_1 + +frnoreadd2_1: + call WriteSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_4 + call save_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_4 +; pop edi esi edx ecx ebx eax +; add esp,32 + mov ebp,0 ; file found +; jmp filedelete_newtry_1 + jmp frnoreadd_1 + +frnoreadd_1_1: + cmp [FDC_Status],0 + jne fdc_status_error_4 +frnoreadd_1: + pop edi esi edx ecx ebx eax + add esp,32 + mov eax,ebp + ret + +floppy_filesave: +;---------------------------------------------------------- +; +; filesave - sys floppy +; +; eax ; pointer to file name 11 chars - for root directory +; ebx ; buffer +; ecx ; count to write in bytes +; edx ; 0 create new , 1 append +; edi pointer to path /fd/1/...... - for all files in nested directories +; +; output : eax = 0 - ok +; 5 - file not found / directory not found +; 8 - disk full +; 10 - access denied +;----------------------------------------------------------- + mov [path_pointer_flp],edi + sub esp,32 + call expand_filename + cmp edx,0 + jnz fsdel_1 + pusha + call floppy_filedelete + cmp [FDC_Status],0 + jne fdc_status_error_6 + popa + mov [save_flag],1 +fsdel_1: + call floppy_free_space + cmp [FDC_Status],0 + jne fdc_status_error_6 + cmp ecx,edi + jb rd_do_save_1 + add esp,32 + mov eax,8 ; not enough free space + mov [flp_status],0 + ret + +fdc_status_error_6: + popa + add esp,32 + jmp fdc_status_error_1 + +rd_do_save_1: + push eax ebx ecx edx esi edi + call read_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_7 + push eax + mov eax,[path_pointer_flp] + cmp [eax+36],byte 0 + jne fifoundds_2 + pop eax + mov [save_root_flag],1 + call read_flp_root + cmp [FDC_Status],0 + jne fdc_status_error_7 + mov edi,0x8000 ;Point at directory + mov edx,224 +1 + ; find an empty spot for filename in the root dir +l20ds_1: + sub edx,1 + jz frnoreadds_1 +l21ds_1: + cmp [edi],byte 0xE5 + jz fifoundds_1 + cmp [edi],byte 0x0 + jz fifoundds_1 + add edi,32 ; Advance to next entry + jmp l20ds_1 + +fifoundds_2: + pop eax + mov [save_root_flag],0 + mov [FDD_Track],0 ; Цилиндр + mov [FDD_Head],1 ; Сторона + mov [FDD_Sector],2 ; Сектор + call SeekTrack + mov dh,14 +l.20_3: + call ReadSectWithRetr + cmp [FDC_Status],0 + jne fdc_status_error_7 + mov dl,16 + mov edi,0xD000 + inc [FDD_Sector] +l.21_3: + mov esi,eax ;Name of file we want + mov ecx,11 + cld + rep cmpsb ;Found the file? + je fifoundds_3 ;Yes + add ecx,21 + add edi, ecx ;Advance to next entry + dec dl + jne l.21_3 + dec dh + jne l.20_3 +fdc_status_error_8: + pop edi esi edx ecx ebx eax + mov eax,5 ; file not found ? + mov ebx,-1 + add esp,32 + mov [flp_status],0 + ret + +fifoundds_3: + add edi,0xf + mov eax,[edi] + and eax,65535 + mov ebx,[path_pointer_flp] + add ebx,36 + call get_cluster_of_a_path_flp + jc fdc_status_error_7_1 +found_directory_for_writing_flp: + call analyze_directory_to_write_flp + jc fdc_status_error_7_1 + mov edi,ebx +fifoundds_1: + push edi ; move the filename to root dir + mov esi,[esp+4+20] + cmp [save_root_flag],0 + jne fifoundds_4 + mov esi,[pointer_file_name_flp] +fifoundds_4: + mov ecx,11 + cld + rep movsb + pop edi + mov edx,edi + add edx,11+0xf ; edx <- cluster save position + mov ebx,[esp+12] ; save file size + mov [edi+28],ebx + mov [edi+11],byte 0x20 ; attribute + call get_date_for_file ; from FAT32.INC + mov [edi+24],ax ; date + mov [edi+18],ax ; date + call get_time_for_file ; from FAT32.INC + mov [edi+22],ax ; time + xor ax,ax + mov [edi+20],ax + mov ebx,1 ; first cluster + cmp [save_root_flag],0 + jne frnewds_1 + call frnewds_2 + pusha + call WriteSectWithRetr + popa + cmp [FDC_Status],0 + jne fdc_status_error_7 + jmp frnewds_3 + +frnewds_1: + call frnewds_2 +frnewds_3: + pusha ; move save to floppy cluster + add ebx,31 + mov eax,ebx + mov esi,[esp+32+16] + call take_data_from_application_1 + call save_chs_sector + cmp [FDC_Status],0 + jne fdc_status_error_7 + popa + mov eax,[esp+12] + cmp eax,512 + jb flnsa_1 + sub eax,512 + mov [esp+12],eax + mov eax,[esp+16] + add eax,512 + mov [esp+16],eax + jmp frnewds_1 + +frnewds_2: + add ebx,1 + mov edi,ebx ; find free cluster in FAT + shl edi,1 + add edi,0x282000 + mov eax,[edi] + and eax,4095 + jnz frnewds_2 + mov [edx],bx ; save next cluster pos. to prev cl. + mov edx,edi ; next save pos abs mem add + ret + +flnsa_1: + mov [edi],word 4095 ; mark end of file - last cluster + cmp [save_root_flag],1 + jne flnsa_2 + call save_flp_root + cmp [FDC_Status],0 + jne fdc_status_error_7 +flnsa_2: + call save_flp_fat + cmp [FDC_Status],0 + jne fdc_status_error_7 +frnoreadds_1: + pop edi esi edx ecx ebx eax + add esp,32 + mov eax,0 + mov [flp_status],0 + ret + +fdc_status_error_7_1: + cmp [FDC_Status],0 + je fdc_status_error_8 +fdc_status_error_7: + pop edi esi edx ecx ebx eax + add esp,32 + jmp fdc_status_error_1 + +save_chs_sector: + call calculate_chs + call WriteSectWithRetr + ret + +calculate_chs: + mov bl,[FDD_Track] + mov [old_track],bl + mov ebx,18 + xor edx,edx + div ebx + inc edx + mov [FDD_Sector],dl + xor edx,edx + mov ebx,2 + div ebx + mov [FDD_Track],al + mov [FDD_Head],0 + cmp edx,0 + je no_head_2 + inc [FDD_Head] +no_head_2: + mov dl,[old_track] + cmp dl,[FDD_Track] + je no_seek_track_1 + call SeekTrack +no_seek_track_1: + ret + + +get_cluster_of_a_path_flp: +;--------------------------------------------------------- +; input : EBX = pointer to a path string +; (example: the path "/files/data/document" become +; "files......data.......document...0" +; '.' = space char +; '0' = char(0) (ASCII=0) !!! ) +; output : if (CARRY=1) -> ERROR in the PATH +; if (CARRY=0) -> EAX=cluster +;--------------------------------------------------------- + + push edx + mov edx,ebx + +search_end_of_path_flp: + cmp [save_flag],0 + jne search_end_of_path_flp_1 + cmp byte [edx],0 + je found_end_of_path_flp + jmp search_end_of_path_flp_2 +search_end_of_path_flp_1: + cmp byte [edx+12],0 + je found_end_of_path_flp +search_end_of_path_flp_2: + inc edx ; '/' + call analyze_directory_flp + jc directory_not_found_flp + + mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field + mov ax,[ebx+26] ; read the LOW 16bit cluster field + and eax,0xfff ;[fatMASK] + add edx,11 ; 8+3 (name+extension) + jmp search_end_of_path_flp + +found_end_of_path_flp: + inc edx + mov [pointer_file_name_flp],edx + pop edx + clc ; no errors + ret + +directory_not_found_flp: + pop edx + stc ; errors occour + ret + +analyze_directory_flp: +;-------------------------------- +; input : EAX = first cluster of the directory +; EBX = pointer to filename +; output : IF CARRY=0 EAX = sector where th file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,EDI,EDI not changed +; IF CARRY=1 +;-------------------------------- + push ebx ;[esp+16] + push ecx + push edx + push esi + push edi + + +adr56_flp: + mov [clust_tmp_flp],eax + add eax,31 + pusha + call read_chs_sector + popa + cmp [FDC_Status],0 + jne not_found_file_analyze_flp + + mov ecx,512/32 + mov ebx,0xD000 + +adr1_analyze_flp: + mov esi,edx ;[esp+16] + mov edi,ebx + cld + push ecx + mov ecx,11 + rep cmpsb + pop ecx + je found_file_analyze_flp + + add ebx,32 + loop adr1_analyze_flp + + mov eax,[clust_tmp_flp] + shl eax,1 ;find next cluster from FAT + add eax,0x282000 + mov eax,[eax] + and eax,4095 + cmp eax,0x0ff8 + jb adr56_flp +not_found_file_analyze_flp: + pop edi + pop esi + pop edx + pop ecx + add esp,4 + stc ;file not found + ret + +found_file_analyze_flp: + pop edi + pop esi + pop edx + pop ecx + add esp,4 + clc ;file found + ret + + +analyze_directory_to_write_flp: +;-------------------------------- +; input : EAX = first cluster of the directory +; output : IF CARRY=0 EAX = sector where the file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,EDI,EDI not changed +; IF CARRY=1 +;-------------------------------- + + push ecx + push edx + push esi + +adr561: + mov [clust_tmp_flp],eax + add eax,31 + pusha + call read_chs_sector + popa + cmp [FDC_Status],0 + jne error_found_file_analyze1 + + mov ecx,512/32 + mov ebx,0xD000 + +adr1_analyze1: + cmp byte [ebx],0x00 + je found_file_analyze1 + cmp byte [ebx],0xe5 + je found_file_analyze1 + +avanti: + add ebx,32 + loop adr1_analyze1 + + mov eax,[clust_tmp_flp] + shl eax,1 ;find next cluster from FAT + add eax,0x282000 + mov eax,[eax] + and eax,4095 + cmp eax,0x0ff8 + jb adr561 + + call get_free_FAT ;this block of code add a new cluster + ;for the directory because the directory + ;is full + + mov [edi],word 0x0fff + + mov eax,[clust_tmp_flp] + shl eax,1 ;find next cluster from FAT + add eax,0x282000 + sub edi,0x282000 + mov [eax],di + + pusha + mov ecx,512/4 + xor eax,eax + mov edi,0xD000 + cld + rep stosd + popa + + mov eax,edi + add eax,31 + pusha + call save_chs_sector + popa + cmp [FDC_Status],0 + jne error_found_file_analyze1 + mov ebx,0xD000 + +found_file_analyze1: + + pop esi + pop edx + pop ecx + clc ;file found + ret + +error_found_file_analyze1: + pop esi + pop edx + pop ecx + stc + ret + +get_free_FAT_flp: +;------------------------------------------ +; input : EAX = # cluster for start the searching +; output : EAX = # first cluster found free +;------------------------------------------- + push ebx + + mov ebx,1 +check_new_flp: + add ebx,1 + mov edi,ebx ; find free cluster in FAT + shl edi,1 + add edi,0x282000 + mov eax,[edi] + and eax,4095 + cmp eax,0x0 + jnz check_new_flp + + pop ebx + ret + +; \begin{diamond} +fat_find_lfn: +; in: esi->name +; [esp+4] = next +; [esp+8] = first +; [esp+C]... - possibly parameters for first and next +; out: CF=1 - file not found +; else CF=0, esi->next name component, edi->direntry + pusha + lea eax, [esp+0Ch+20h] + call dword [eax-4] + jc .reterr + sub esp, 262*2 ; reserve place for LFN + mov ebp, esp + push 0 ; for fat_get_name: read ASCII name +.l1: + call fat_get_name + jc .l2 + call fat_compare_name + jz .found +.l2: + lea eax, [esp+0Ch+20h+262*2+4] + call dword [eax-8] + jnc .l1 + add esp, 262*2+4 +.reterr: + stc + popa + ret +.found: + add esp, 262*2+4 +; if this is LFN entry, advance to true entry + cmp byte [edi+11], 0xF + jnz @f + lea eax, [esp+0Ch+20h] + call dword [eax-8] + jc .reterr +@@: + add esp, 8 ; CF=0 + push esi + push edi + popa + ret + +flp_root_next: + cmp edi, 0xD200-0x20 + jae @f + add edi, 0x20 + ret ; CF=0 +@@: +; read next sector + inc dword [eax] + cmp dword [eax], 14 + jae flp_root_first.readerr +flp_root_first: + mov eax, [eax] + pusha + add eax, 19 + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .readerr + mov edi, 0xD000 + ret ; CF=0 +.readerr: + stc + ret + +flp_rootmem_first: + mov edi, 0x8000 + clc + ret +flp_rootmem_next: + add edi, 0x20 + cmp edi, 0x8000+14*0x200 + cmc +flp_rootmem_next_write: +flp_rootmem_begin_write: +flp_rootmem_end_write: + ret +flp_rootmem_extend_dir: + stc + ret + +flp_notroot_next: + cmp edi, 0xD200-0x20 + jae flp_notroot_next_sector + add edi, 0x20 + ret ; CF=0 +flp_notroot_next_sector: + push ecx + mov ecx, [eax] + mov ecx, [ecx*2+0x282000] + and ecx, 0xFFF + cmp ecx, 2849 + jae flp_notroot_first.err2 + mov [eax], ecx + pop ecx +flp_notroot_first: + mov eax, [eax] + cmp eax, 2 + jb .err + cmp eax, 2849 + jae .err + pusha + add eax, 31 + call read_chs_sector + popa + mov edi, 0xD000 + cmp [FDC_Status], 0 + jnz .err + ret ; CF=0 +.err2: + pop ecx +.err: + stc + ret +flp_notroot_begin_write: + pusha + mov eax, [eax] + add eax, 31 + call read_chs_sector + popa + ret +flp_notroot_end_write: + pusha + mov eax, [eax] + add eax, 31 + call save_chs_sector + popa + ret +flp_notroot_next_write: + cmp edi, 0xD200 + jae @f + ret +@@: + call flp_notroot_end_write + jmp flp_notroot_next_sector +flp_notroot_extend_dir: +; find free cluster in FAT + pusha + xor eax, eax + mov edi, 0x282000 + mov ecx, 2849 + repnz scasw + jnz .notfound + mov word [edi-2], 0xFFF ; mark as last cluster + sub edi, 0x282000 + shr edi, 1 + dec edi + mov eax, [esp+28] + mov ecx, [eax] + mov [0x282000+ecx*2], di + mov [eax], edi + xor eax, eax + mov edi, 0xD000 + mov ecx, 128 + rep stosd + popa + call flp_notroot_end_write + mov edi, 0xD000 + clc + ret +.notfound: + popa + stc + ret + +fd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and edi->direntry, eax=directory cluster (0 for root) + push esi edi + push 0 + push flp_root_first + push flp_root_next +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found + test byte [edi+11], 10h + jz .notfound + movzx eax, word [edi+26] ; cluster + mov [esp+8], eax + mov dword [esp+4], flp_notroot_first + mov dword [esp], flp_notroot_next + jmp .loop +.notfound: + add esp, 12 + pop edi esi + stc + ret +.found: + mov eax, [esp+8] + add eax, 31 + cmp dword [esp], flp_root_next + jnz @f + add eax, -31+19 +@@: + add esp, 16 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_FloppyRead - LFN variant for reading floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyRead: + call read_flp_fat + cmp byte [esi], 0 + jnz @f + or ebx, -1 + mov eax, 10 ; access denied + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, 5 ; file not found + ret +.found: + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; EOF + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 ; EOF +@@: + movzx edi, word [edi+26] +.new: + jecxz .done + test edi, edi + jz .eof + cmp edi, 0xFF8 + jae .eof + sub ebx, 512 + jae .skip + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err + lea eax, [0xD000+ebx+512] + neg ebx + push ecx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx +.skip: + movzx edi, word [edi*2+0x282000] + jmp .new +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + jmp .reteof +.err: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + mov al, 11 + ret + +;---------------------------------------------------------------- +; +; fs_FloppyReadFolder - LFN variant for reading floppy folders +; +; esi points to filename +; ebx pointer to structure: 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyReadFolder: + call read_flp_fat + push edi + cmp byte [esi], 0 + jz .root + call fd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 ; do not allow read files + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + movzx eax, word [edi+26] + add eax, 31 + push 0 + jmp .doit +.root: + mov eax, 19 + push 14 +.doit: + push ecx ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + mov byte [edx], 1 ; version + mov esi, edi ; esi points to BDFE +.main_loop: + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .error + mov edi, 0xD000 + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + cmp edi, 0xD200 + jb .do_bdfe + pop eax + inc eax + dec byte [esp+262*2+12] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x282000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+12], 0 +@@: + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .error + mov edi, 0xD000 + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec ebx + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + cmp edi, 0xD200 + jb .l1 + pop eax + inc eax + dec byte [esp+262*2+12] + jz .done + jns @f +; read next sector from FAT + mov eax, [(eax-31-1)*2+0x282000] + and eax, 0xFFF + cmp eax, 0xFF8 + jae .done + add eax, 31 + mov byte [esp+262*2+12], 0 +@@: + jmp .main_loop +.error: + add esp, 262*2+4 + pop ebp ecx edi edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.done: + add esp, 262*2+4 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx edi edi + ret + +;---------------------------------------------------------------- +; +; fs_FloppyRewrite - LFN variant for writing sys floppy +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +@@: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +fsfrfe2: + popad +fsfrfe: + mov eax, 11 + xor ebx, ebx + ret + +fs_FloppyRewrite: + cmp byte [esi], 0 + jz @b + call read_flp_fat + cmp [FDC_Status], 0 + jnz fsfrfe + pushad + xor ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + call read_flp_root + cmp [FDC_Status], 0 + jnz fsfrfe2 + push flp_rootmem_extend_dir + push flp_rootmem_end_write + push flp_rootmem_next_write + push flp_rootmem_begin_write + xor ebp, ebp + push ebp + push flp_rootmem_first + push flp_rootmem_next + jmp .common1 +.noroot: +; check existence + mov byte [ebp], 0 + call fd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + movzx ebp, word [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 + cmp ebp, 2849 + jae .ret1 + push flp_notroot_extend_dir + push flp_notroot_end_write + push flp_notroot_next_write + push flp_notroot_begin_write + push ebp + push flp_notroot_first + push flp_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 28 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xchg ax, word [edi+26] ; start cluster + test eax, eax + jz .done1 +@@: + cmp eax, 0xFF8 + jae .done1 + lea edi, [0x282000 + eax*2] ; position in FAT + xor eax, eax + xchg ax, [edi] + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 28 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+28 + popa + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+12+8+12+8] + mov [eax], ebp + call dword [eax-4] + pop eax + jnc .scan_dir +.fsfrfe3: + add esp, 8+8+12+28 + popad + mov eax, 11 + xor ebx, ebx + ret +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+12+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + cmp [FDC_Status], 0 + jnz .fsfrfe3 + push eax + lea eax, [esp+12+8+12+8] + call dword [eax+16] ; extend directory + pop eax + jnc .scan_dir + add esp, 8+8+12+28 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+8+8+12+8] + mov [esp+4], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+8] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+8] +; edi points to first entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + lea eax, [esp+8+8+12+8] + call dword [eax+4] ; begin write + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call fs_RamdiskRewrite.read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call fs_RamdiskRewrite.read_symbols + xor eax, eax + stosw + mov cl, 2 + call fs_RamdiskRewrite.read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+8] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +; lea eax, [esp+8+12+8] +; call dword [eax+12] ; end write +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + and word [edi+20], 0 ; high word of cluster + and word [edi+26], 0 ; low word of cluster - to be filled + and dword [edi+28], 0 ; file size - to be filled +.doit: + lea eax, [esp+8] + call dword [eax+12] ; flush directory + push ecx + push edi + push 0 + mov esi, edx + jecxz .done + mov ecx, 2849 + mov edi, 0x282000 + push 0 ; first cluster +.write_loop: +; allocate new cluster + xor eax, eax + repnz scasw + mov al, ERROR_DISK_FULL + jnz .ret + dec edi + dec edi + lea eax, [edi-0x282000] + shr eax, 1 ; eax = cluster + mov word [edi], 0xFFF ; mark as last cluster + xchg edi, [esp+4] + cmp dword [esp], 0 + jz .first + stosw + jmp @f +.first: + mov [esp], eax +@@: + mov edi, [esp+4] + inc ecx +; write data + push ecx edi + mov ecx, 512 + cmp dword [esp+20], ecx + jae @f + mov ecx, [esp+20] +@@: + push ecx + mov edi, 0xD000 + rep movsb + pop ecx + push ecx + sub ecx, 512 + neg ecx + push eax + xor eax, eax + rep stosb + pop eax + add eax, 31 + pusha + call save_chs_sector + popa + pop ecx + cmp [FDC_Status], 0 + jnz .diskerr + sub [esp+20], ecx + pop edi ecx + jnz .write_loop +.done: + xor eax, eax +.ret: + pop ebx edi edi ecx + mov [esp+28+28], eax + lea eax, [esp+8] + call dword [eax+4] + mov [edi+26], bx + mov ebx, esi + sub ebx, edx + mov [edi+28], ebx + call dword [eax+12] + mov [esp+28+16], ebx + test ebp, ebp + jnz @f + call save_flp_root +@@: + add esp, 28 + cmp [FDC_Status], 0 + jnz .err3 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .err3 + popa + ret +.err3: + popa + mov al, 11 + xor ebx, ebx + ret +.diskerr: + sub esi, ecx + mov eax, 11 + pop edi ecx + jmp .ret + +;---------------------------------------------------------------- +; +; fs_FloppyWrite - LFN variant for writing to floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- + +@@: + push ERROR_ACCESS_DENIED +fs_FloppyWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_FloppyWrite.ret11: + push 11 + jmp fs_FloppyWrite.ret0 + +fs_FloppyWrite: + cmp byte [esi], 0 + jz @b + call read_flp_fat + cmp [FDC_Status], 0 + jnz .ret11 + pushad + call fd_find_lfn + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push eax ; save directory cluster + push 0 ; return value=0 + + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + + push dword [edi+28] ; save current file size + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call floppy_extend_file + jnc .length_ok + mov [esp+4], eax +; floppy_extend_file can return two error codes: FAT table error or disk full. +; First case is fatal error, in second case we may write some data + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + pop eax + mov [esp+4+28], eax + pop eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + pop eax + pop eax + mov [esp+4+28], eax ; eax=return value + pop eax + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: +; save FAT & directory +; note that directory must be saved first because save_flp_fat uses buffer at 0xD000 + mov esi, [edi+28] + movzx edi, word [edi+26] ; starting cluster + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jz @f +.device_err: + mov byte [esp+4], 11 + jmp .ret +@@: + +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret + call SetUserInterrupts +.write_loop: + lea eax, [edi+31] ; current sector +; get length of data in current sector + push ecx + sub ebx, 0x200 + jb .hasdata + neg ebx + xor ecx, ecx + jmp @f +.hasdata: + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: +; load sector if needed + cmp dword [esp+4], 0 ; we don't need to read uninitialized data + jz .noread + cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten + jz .noread + cmp ecx, esi ; (same for the last sector) + jz .noread + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jz @f +.device_err2: + pop ecx + jmp .device_err +@@: +.noread: +; zero uninitialized data if file was extended (because floppy_extend_file does not this) + push eax ecx edi + xor eax, eax + mov ecx, 0x200 + sub ecx, [esp+4+12] + jbe @f + mov edi, 0xD000 + add edi, [esp+4+12] + rep stosb +@@: +; zero uninitialized data in the last sector + mov ecx, 0x200 + sub ecx, esi + jbe @f + mov edi, 0xD000 + add edi, esi + rep stosb +@@: + pop edi ecx eax +; copy new data + push eax + mov eax, edx + neg ebx + jecxz @f + add ebx, 0xD000+0x200 + call memmove + xor ebx, ebx +@@: + pop eax +; save sector + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + add edx, ecx + sub [esp], ecx + pop ecx + jz .done +.next_cluster: + movzx edi, word [edi*2+0x282000] + sub esi, 0x200 + jae @f + xor esi, esi +@@: + sub dword [esp], 0x200 + jae .write_loop + and dword [esp], 0 + jmp .write_loop +.done: + mov [fdc_irq_func], fdc_null + jmp .ret + +floppy_extend_file.zero_size: + xor eax, eax + jmp floppy_extend_file.start_extend + +; extends file on floppy to given size (new data area is undefined) +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) +floppy_extend_file: + push ecx +; find the last cluster of file + movzx eax, word [edi+26] ; first cluster + mov ecx, [edi+28] + jecxz .zero_size +@@: + sub ecx, 0x200 + jbe @f + mov eax, [eax*2+0x282000] + and eax, 0xFFF + jz .fat_err + cmp eax, 0xFF8 + jb @b +.fat_err: + pop ecx + push ERROR_FAT_TABLE + pop eax + stc + ret +@@: + push eax + mov eax, [eax*2+0x282000] + and eax, 0xFFF + cmp eax, 0xFF8 + pop eax + jb .fat_err +; set length to full number of sectors + sub [edi+28], ecx +.start_extend: + pop ecx +; now do extend + push edx esi + mov esi, 0x282000+2*2 ; start scan from cluster 2 + mov edx, 2847 ; number of clusters to scan +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new sector + push ecx + push edi +.scan: + mov ecx, edx + mov edi, esi + jecxz .disk_full + push eax + xor eax, eax + repnz scasw + pop eax + jnz .disk_full + mov word [edi-2], 0xFFF + mov esi, edi + mov edx, ecx + sub edi, 0x282000 + shr edi, 1 + dec edi ; now edi=new cluster + test eax, eax + jz .first_cluster + mov [0x282000+eax*2], di + jmp @f +.first_cluster: + pop eax ; eax->direntry + push eax + mov [eax+26], di +@@: + mov eax, edi ; eax=new cluster + pop edi ; edi->direntry + pop ecx ; ecx=required size + add dword [edi+28], 0x200 + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop esi edx + xor eax, eax ; CF=0 + ret +.disk_full: + pop edi ecx + pop esi edx + stc + push ERROR_DISK_FULL + pop eax + ret + +;---------------------------------------------------------------- +; +; fs_FloppySetFileEnd - set end of file on floppy +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppySetFileEnd: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND +.ret: + pop eax + jmp .doret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + pushad + call save_chs_sector + popad + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: +.doret: + mov [fdc_irq_func], fdc_null + ret +.expand: + push ecx + push dword [edi+28] ; save old size + mov ecx, eax + call floppy_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax ecx ecx edi edi + jmp .doret +.device_err: + pop eax +.device_err2: + pop ecx ecx eax edi + push 11 + jmp .ret +.disk_full: +.expand_ok: +; save directory & FAT + mov eax, [edi+28] + xchg eax, [esp+12] + movzx edi, word [edi+26] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err + call SetUserInterrupts +; now zero new data +; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + cmp dword [esp+4], -0x200 + jz .noread + lea eax, [edi+31] + pusha + call read_chs_sector + popa + cmp [FDC_Status], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, 0xD000+0x200 + add edi, [esp+8] + xor eax, eax + mov [esp+8], eax + rep stosb + pop edi + lea eax, [edi+31] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+12], 0x200 + jbe .expand_done + movzx edi, word [0x282000+edi*2] + jmp .zero_loop +.expand_done: + pop eax ecx ecx edi edi + jmp .doret +.truncate: + mov [edi+28], eax + push ecx + movzx ecx, word [edi+26] + test eax, eax + jz .zero_size +; find new last sector +@@: + sub eax, 0x200 + jbe @f + movzx ecx, word [0x282000+ecx*2] + jmp @b +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + mov word [ecx], 0xFFF + pop ecx + and ecx, 0xFFF + jmp .delete +.zero_size: + and word [edi+26], 0 + push 0 +.delete: +; delete FAT chain starting with ecx +; mark all clusters as free + cmp ecx, 0xFF8 + jae .deleted + lea ecx, [0x282000+ecx+ecx] + push dword [ecx] + and word [ecx], 0 + pop ecx + and ecx, 0xFFF + jmp .delete +.deleted: + mov edi, [edi+28] +; save directory & FAT + mov eax, [esp+8] + pusha + call save_chs_sector + popa + cmp [FDC_Status], 0 + jnz .device_err2 + call save_flp_fat + cmp [FDC_Status], 0 + jnz .device_err2 +; zero last sector, ignore errors + pop eax + add eax, 31 + and edi, 0x1FF + jz .truncate_done + call SetUserInterrupts + pusha + call read_chs_sector + popa + add edi, 0xD000 + mov ecx, 0xD000+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pusha + call save_chs_sector + popa +.truncate_done: + pop ecx eax edi + xor eax, eax + jmp .doret + +fs_FloppyGetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jmp fs_GetFileInfo_finish + +ret11: + mov eax, 11 + ret + +fs_FloppySetFileInfo: + call read_flp_fat + cmp [FDC_Status], 0 + jnz ret11 + cmp byte [esi], 0 + jnz @f + mov eax, 2 ; unsupported + ret +@@: + push edi + call fd_find_lfn + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + pusha + call save_chs_sector + popa + pop edi + xor eax, eax + cmp [FDC_Status], 0 + jz @f + mov al, 11 +@@: + ret + +;---------------------------------------------------------------- +; +; fs_FloppyExecute - LFN variant for executing from floppy +; +; esi points to floppy filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/fd/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_FloppyExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_FloppyExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + call read_flp_fat + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call fd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + ret +.found: + movzx eax, word [edi+26] ; cluster + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 12 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + mov eax, [eax+4] ; cluster + add eax, 31 + call read_chs_sector + cmp [FDC_Status], 0 + jnz .err + pop edi + mov esi, 0xD000 + push edi + mov ecx, 512/4 + rep movsd + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + add edi, ecx + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+4] + mov dx, [edx*2+0x282000] + mov [eax+4], dx ; high word is already zero + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.6.0.0/fs/fat32.inc b/kernel/tags/kolibri0.6.0.0/fs/fat32.inc new file mode 100644 index 0000000000..824e4109b6 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/fat32.inc @@ -0,0 +1,4184 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; FAT32.INC ;; +;; ;; +;; FAT16/32 functions for KolibriOS ;; +;; ;; +;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; +;; ;; +;; See file COPYING for details ;; +;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;; +;; 17.08.2006 LFN write/append to file - diamond ;; +;; 23.06.2006 LFN start application - diamond ;; +;; 15.06.2006 LFN get/set file/folder info - diamond ;; +;; 27.05.2006 LFN create/rewrite file - diamond ;; +;; 04.05.2006 LFN read folder - diamond ;; +;; 29.04.2006 Elimination of hangup after the ;; +;; expiration hd_wait_timeout - Mario79 ;; +;; 23.04.2006 LFN read file - diamond ;; +;; 28.01.2006 find all Fat16/32 partition in all input point ;; +;; to MBR, see file part_set.inc - Mario79 ;; +;; 15.01.2005 get file size/attr/date, file_append - ATV ;; +;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; +;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; +;; 23.11.2004 don't allow overwrite dir with file - ATV ;; +;; 18.11.2004 get_disk_info and more error codes - ATV ;; +;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; +;; 10.11.2004 removedir clear whole directory structure - ATV ;; +;; 08.11.2004 rename - ATV ;; +;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; +;; 20.10.2004 Makedir/Removedir - ATV ;; +;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; +;; 06.9.2004 Fix free space by Mario79 added - MH ;; +;; 24.5.2004 Write back buffer for File_write -VT ;; +;; 20.5.2004 File_read function to work with syscall 58 - VT ;; +;; 30.3.2004 Error parameters at function return - VT ;; +;; 01.5.2002 Bugfix in device write - VT ;; +;; 20.5.2002 Hd status check - VT ;; +;; 29.6.2002 Improved fat32 verification - VT ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 + +ERROR_SUCCESS = 0 +ERROR_DISK_BASE = 1 +ERROR_UNSUPPORTED_FS = 2 +ERROR_UNKNOWN_FS = 3 +ERROR_PARTITION = 4 +ERROR_FILE_NOT_FOUND = 5 +ERROR_END_OF_FILE = 6 +ERROR_MEMORY_POINTER = 7 +ERROR_DISK_FULL = 8 +ERROR_FAT_TABLE = 9 +ERROR_ACCESS_DENIED = 10 + +PUSHAD_EAX equ [esp+28] +PUSHAD_ECX equ [esp+24] +PUSHAD_EDX equ [esp+20] +PUSHAD_EBX equ [esp+16] +PUSHAD_EBP equ [esp+8] +PUSHAD_ESI equ [esp+4] +PUSHAD_EDI equ [esp+0] + +cluster dd 0 ; used by file_write,makedir,append +partition_count dd 0 ; partitions found by set_FAT32_variables +longname_sec1 dd 0 ; used by analyze_directory to save 2 previous +longname_sec2 dd 0 ; directory sectors for delete long filename + +hd_error dd 0 ; set by wait_for_sector_buffer +hd_setup dd 0 +hd_wait_timeout dd 0 + +cluster_tmp dd 0 ; used by analyze_directory + ; and analyze_directory_to_write + +file_size dd 0 ; used by file_read + +sector_tmp dd 0 ; used by rename,append,file_write +entry_pos dd 0 ; used by rename,append,file_write + +old_filesize dd 0 ; used by append +new_filepos dd 0 ; used by append +bytes2write dd 0 ; used by append + +cache_search_start dd 0 ; used by find_empty_slot + +fat_in_cache dd -1 +fat_cache: times 512 db 0 + +uglobal + Sector512: ; label for dev_hdcd.inc + buffer: times 512 db 0 + deltree_buffer: times 512 db 0 + fsinfo_buffer: times 512 db 0 +endg + +iglobal + NewDirEntry1 db ". ",0x10 + times 20 db 0 + NewDirEntry2 db ".. ",0x10 + times 20 db 0 +endg + +uglobal + dir_entry: times 32 db 0 + + startpath: times 255 db 0 + + fat16_root db 0 ; flag for fat16 rootdir + fat_change db 0 ; 1=fat has changed + +endg + +reserve_hd1: + + cli + cmp [hd1_status],0 + je reserve_ok1 + + sti + call change_task + jmp reserve_hd1 + + reserve_ok1: + + push eax + mov eax,[0x3000] + shl eax,5 + mov eax,[eax+0x3000+TASKDATA.pid] + mov [hd1_status],eax + pop eax + sti + ret +;******************************************** +reserve_hd_channel: + cmp [hdbase], 0x1F0 + jne .IDE_Channel_2 +.IDE_Channel_1: + cli + cmp [IDE_Channel_1],0 + je .reserve_ok_1 + sti + call change_task + jmp .IDE_Channel_1 +.IDE_Channel_2: + cli + cmp [IDE_Channel_2],0 + je .reserve_ok_2 + sti + call change_task + jmp .IDE_Channel_1 +.reserve_ok_1: + mov [IDE_Channel_1],1 + ret +.reserve_ok_2: + mov [IDE_Channel_2],1 + ret + +free_hd_channel: + cmp [hdbase], 0x1F0 + jne .IDE_Channel_2 +.IDE_Channel_1: + mov [IDE_Channel_1],0 + ret +.IDE_Channel_2: + mov [IDE_Channel_2],0 + ret +;******************************************** +clear_hd_cache: + + push eax ecx edi + mov edi,0x600000 + mov ecx,16384 + xor eax,eax + cld + rep stosd ; clear hd cache with 0 + mov [cache_search_start],eax + mov [fat_in_cache],-1 + mov [fat_change],0 + pop edi ecx eax + ret + +problem_partition db 0 ; used for partitions search + +include 'part_set.inc' + +set_FAT: +;-------------------------------- +; input : EAX = cluster +; EDX = value to save +; output : EDX = old value +;-------------------------------- + push eax ebx esi + + cmp eax,2 + jb sfc_error + cmp eax,[LAST_CLUSTER] + ja sfc_error + cmp [fat_type],16 + je sfc_1 + add eax,eax + sfc_1: + add eax,eax + mov esi,511 + and esi,eax ; esi = position in fat sector + shr eax,9 ; eax = fat sector + add eax,[FAT_START] + mov ebx,fat_cache + + cmp eax,[fat_in_cache] ; is fat sector already in memory? + je sfc_in_cache ; yes + + cmp [fat_change],0 ; is fat changed? + je sfc_no_change ; no + call write_fat_sector ; yes. write it into disk + cmp [hd_error],0 + jne sfc_error + + sfc_no_change: + mov [fat_in_cache],eax ; save fat sector + call hd_read + cmp [hd_error],0 + jne sfc_error + + + sfc_in_cache: + cmp [fat_type],16 + jne sfc_test32 + + sfc_set16: + xchg [ebx+esi],dx ; save new value and get old value + jmp sfc_write + + sfc_test32: + mov eax,[fatMASK] + + sfc_set32: + and edx,eax + xor eax,-1 ; mask for high bits + and eax,[ebx+esi] ; get high 4 bits + or eax,edx + mov edx,[ebx+esi] ; get old value + mov [ebx+esi],eax ; save new value + + sfc_write: + mov [fat_change],1 ; fat has changed + + sfc_nonzero: + and edx,[fatMASK] + + sfc_error: + pop esi ebx eax + ret + + +get_FAT: +;-------------------------------- +; input : EAX = cluster +; output : EAX = next cluster +;-------------------------------- + push ebx esi + + cmp [fat_type],16 + je gfc_1 + add eax,eax + gfc_1: + add eax,eax + mov esi,511 + and esi,eax ; esi = position in fat sector + shr eax,9 ; eax = fat sector + add eax,[FAT_START] + mov ebx,fat_cache + + cmp eax,[fat_in_cache] ; is fat sector already in memory? + je gfc_in_cache + + cmp [fat_change],0 ; is fat changed? + je gfc_no_change ; no + call write_fat_sector ; yes. write it into disk + cmp [hd_error],0 + jne hd_error_01 + + gfc_no_change: + mov [fat_in_cache],eax + call hd_read + cmp [hd_error],0 + jne hd_error_01 + + gfc_in_cache: + mov eax,[ebx+esi] + and eax,[fatMASK] + hd_error_01: + pop esi ebx + ret + + +get_free_FAT: +;----------------------------------------------------------- +; input : EAX = # cluster for start the searching +; output : if CARRY=0 EAX = # first cluster found free +; if CARRY=1 disk full +; Note : for more speed need to use fat_cache directly +;----------------------------------------------------------- + push ecx + mov ecx,[LAST_CLUSTER] ; counter for full disk + sub ecx,2 + + gff_test: + cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2 + jbe gff_in_range + mov eax,2 + + gff_in_range: + push eax + call get_FAT ; get cluster state + cmp [hd_error],0 + jne gff_not_found_1 + + test eax,eax ; is it free? + pop eax + je gff_found ; yes + inc eax ; next cluster + dec ecx ; is all checked? + jns gff_test ; no + + gff_not_found_1: + add esp,4 + gff_not_found: + pop ecx ; yes. disk is full + stc + ret + + gff_found: + pop ecx + clc + ret + + +write_fat_sector: +;----------------------------------------------------------- +; write changed fat to disk +;----------------------------------------------------------- + push eax ebx ecx + + mov [fat_change],0 + mov eax,[fat_in_cache] + cmp eax,-1 + jz write_fat_not_used + mov ebx,fat_cache + mov ecx,[NUMBER_OF_FATS] + + write_next_fat: + call hd_write + cmp [hd_error],0 + jne write_fat_not_used + + add eax,[SECTORS_PER_FAT] + dec ecx + jnz write_next_fat + + write_fat_not_used: + pop ecx ebx eax + ret + + +analyze_directory: +;----------------------------------------------------------- +; input : EAX = first cluster of the directory +; EBX = pointer to filename +; output : IF CARRY=0 EAX = sector where th file is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,ESI,EDI not changed +; IF CARRY=1 filename not found +; Note : if cluster=0 it's changed to read rootdir +; save 2 previous directory sectors in longname_sec +;----------------------------------------------------------- + push ecx edx esi edi ebx ; ebx = [esp+0] + mov [longname_sec1],0 + mov [longname_sec2],0 + + adr_new_cluster: + mov [cluster_tmp],eax + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja adr_not_found ; too big cluster number, something is wrong + cmp eax,2 + jnb adr_data_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fat_type],16 + jne adr_data_cluster + mov eax,[ROOT_START] + mov edx,[ROOT_SECTORS] + mov [fat16_root],1 ; flag for fat16 rootdir + jmp adr_new_sector + + adr_data_cluster: + sub eax,2 + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + adr_new_sector: + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne adr_not_found + + mov ecx,512/32 ; count of dir entrys per sector = 16 + + adr_analyze: + mov edi,[ebx+11] ; file attribute + and edi,0xf + cmp edi,0xf + je adr_long_filename + test edi,0x8 ; skip over volume label + jne adr_long_filename ; Note: label can be same name as file/dir + + mov esi,[esp+0] ; filename need to be uppercase + mov edi,ebx + push ecx + mov ecx,11 + cld + rep cmpsb ; compare 8+3 filename + pop ecx + je adr_found + + adr_long_filename: + add ebx,32 ; position of next dir entry + dec ecx + jnz adr_analyze + + mov ecx,[longname_sec1] ; save 2 previous directory sectors + mov [longname_sec1],eax ; for delete long filename + mov [longname_sec2],ecx + inc eax ; next sector + dec edx + jne adr_new_sector + cmp [fat16_root],1 ; end of fat16 rootdir + je adr_not_found + + adr_next_cluster: + mov eax,[cluster_tmp] + call get_FAT ; get next cluster + cmp [hd_error],0 + jne adr_not_found + + cmp eax,2 ; incorrect fat chain? + jb adr_not_found ; yes + cmp eax,[fatRESERVED] ; is it end of directory? + jb adr_new_cluster ; no. analyse it + + adr_not_found: + pop edi edi esi edx ecx ; first edi will remove ebx + stc ; file not found + ret + + adr_found: + pop edi edi esi edx ecx ; first edi will remove ebx + clc ; file found + ret + + +analyze_directory_to_write: +;----------------------------------------------------------- +; input : EAX = first cluster of the directory +; output : IF CARRY=0 EAX = sector where the empty pos is found +; EBX = pointer in buffer +; [buffer .. buffer+511] +; ECX,EDX,ESI,EDI not changed +; IF CARRY=1 disk full or fat corrupted +; Note : if cluster=0 it's changed to read rootdir +;----------------------------------------------------------- + push ecx edx edi + + adw_new_cluster: + mov [cluster_tmp],eax + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja adw_not_found ; too big cluster number, something is wrong + cmp eax,2 + jnb adw_data_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fat_type],16 + jne adw_data_cluster + mov eax,[ROOT_START] + mov edx,[ROOT_SECTORS] + mov [fat16_root],1 ; flag for fat16 rootdir + jmp adw_new_sector + + adw_data_cluster: + sub eax,2 + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + adw_new_sector: + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne adw_not_found + + mov ecx,512/32 ; count of dir entrys per sector = 16 + + adw_analyze: + cmp byte [ebx],0x00 ; is free entry? + je adw_found ; yes + cmp byte [ebx],0xe5 ; is deleted entry? + je adw_found ; yes + add ebx,32 ; position of next dir entry + dec ecx + jnz adw_analyze + + inc eax ; next sector + dec edx + jne adw_new_sector + cmp [fat16_root],1 ; end of fat16 rootdir + je adw_not_found + + mov eax,[cluster_tmp] + call get_FAT ; get next cluster + cmp [hd_error],0 + jne adw_not_found + + cmp eax,2 ; incorrect fat chain? + jb adw_not_found ; yes + cmp eax,[fatRESERVED] ; is it end of directory? + jb adw_new_cluster ; no. analyse it + + mov eax,2 ; this block of code add a new cluster + call get_free_FAT ; for the directory because the directory + jc adw_not_found ; is full + + mov edx,[fatEND] ; new end for directory + call set_FAT + cmp [hd_error],0 + jne adw_not_found + + push eax ; save new cluster + mov edx,eax + mov eax,[cluster_tmp] ; change last cluster to point new cluster + call set_FAT + cmp [hd_error],0 + jne adw_not_found_1 + + mov ecx,-1 ; remove 1 cluster from free disk space + call add_disk_free_space + cmp [hd_error],0 + jne adw_not_found_1 + + mov ecx,512/4 + xor eax,eax + mov edi,buffer + cld + rep stosd ; clear new directory cluster + pop eax + + sub eax,2 + mov ecx,[SECTORS_PER_CLUSTER] + imul eax,ecx + add eax,[DATA_START] + mov ebx,buffer + push eax ; save sector number + + adw_set_empty_directory: + call hd_write + cmp [hd_error],0 + jne adw_not_found_1 + + inc eax ; next sector + dec ecx + jnz adw_set_empty_directory + + pop eax + + adw_found: + pop edi edx ecx + clc ; free space found + ret + adw_not_found_1: + add esp,4 + adw_not_found: + pop edi edx ecx + stc ; free space not found + ret + + +get_data_cluster: +;----------------------------------------------------------- +; input : EAX = cluster +; EBX = pointer to buffer +; EDX = # blocks to read in buffer +; ESI = # blocks to skip over +; output : if CARRY=0 ok EBX/EDX/ESI updated +; if CARRY=1 cluster out of range +; Note : if cluster=0 it's changed to read rootdir +;----------------------------------------------------------- + push eax ecx + + mov [fat16_root],0 + cmp eax,[LAST_CLUSTER] + ja gdc_error ; too big cluster number, something is wrong + cmp eax,2 + jnb gdc_cluster + + mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir + cmp [fat_type],16 + jne gdc_cluster + mov eax,[ROOT_START] + mov ecx,[ROOT_SECTORS] ; Note: not cluster size + mov [fat16_root],1 ; flag for fat16 rootdir + jmp gdc_read + + gdc_cluster: + sub eax,2 + mov ecx,[SECTORS_PER_CLUSTER] + imul eax,ecx + add eax,[DATA_START] + + gdc_read: + test esi,esi ; first wanted block + je gdcl1 ; yes, skip count is 0 + dec esi + jmp gdcl2 + + gdcl1: + call hd_read + cmp [hd_error],0 + jne gdc_error + + add ebx,512 ; update pointer + dec edx + + gdcl2: + test edx,edx ; is all read? + je out_of_read + + inc eax ; next sector + dec ecx + jnz gdc_read + + out_of_read: + pop ecx eax + clc + ret + + gdc_error: + pop ecx eax + stc + ret + + +set_data_cluster: +;----------------------------------------------------------- +; input : EAX = cluster +; EBX = pointer to buffer +; output : if CARRY=0 ok +; if CARRY=1 cluster out of range +;----------------------------------------------------------- + push eax ebx edx + + cmp eax,[LAST_CLUSTER] + ja sdc_error ; too big cluster number, something is wrong + sub eax,2 + jb sdc_error ; don't allow rootdir write + + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + + sdc_write: + call hd_write + cmp [hd_error],0 + jne sdc_error + + add ebx,512 ; update pointer + inc eax + dec edx + jnz sdc_write + pop edx ebx eax + clc + ret + + sdc_error: + pop edx ebx eax + stc + ret + + +get_cluster_of_a_path: +;--------------------------------------------------------- +; input : EBX = pointer to a path string +; (example: the path "/files/data/document" become +; "files......data.......document...0" +; '.' = space char +; '0' = char(0) (ASCII=0) !!! ) +; output : if (CARRY=1) -> ERROR in the PATH +; if (CARRY=0) -> EAX=cluster +;--------------------------------------------------------- + push ebx edx + + mov eax,[ROOT_CLUSTER] + mov edx,ebx + +search_end_of_path: + cmp byte [edx],0 + je found_end_of_path + + inc edx ; '/' + mov ebx,edx + call analyze_directory + jc directory_not_found + + mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field + mov ax,[ebx+26] ; read the LOW 16bit cluster field + and eax,[fatMASK] + add edx,11 ; 8+3 (name+extension) + jmp search_end_of_path + +found_end_of_path: + pop edx ebx + clc ; no errors + ret + +directory_not_found: + pop edx ebx + stc ; errors occour + ret + + +bcd2bin: +;---------------------------------- +; input : AL=BCD number (eg. 0x11) +; output : AH=0 +; AL=decimal number (eg. 11) +;---------------------------------- + xor ah,ah + shl ax,4 + shr al,4 + aad + ret + + +get_date_for_file: +;----------------------------------------------------- +; Get date from CMOS and pack day,month,year in AX +; DATE bits 0..4 : day of month 0..31 +; 5..8 : month of year 1..12 +; 9..15 : count of years from 1980 +;----------------------------------------------------- + mov al,0x7 ;day + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,5 + + mov al,0x8 ;month + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,4 + + mov al,0x9 ;year + out 0x70,al + in al,0x71 + call bcd2bin + add ax,20 ;because CMOS return only the two last + ;digit (eg. 2000 -> 00 , 2001 -> 01) and we + rol eax,9 ;need the difference with 1980 (eg. 2001-1980) + ret + + +get_time_for_file: +;----------------------------------------------------- +; Get time from CMOS and pack hour,minute,second in AX +; TIME bits 0..4 : second (the low bit is lost) +; 5..10 : minute 0..59 +; 11..15 : hour 0..23 +;----------------------------------------------------- + mov al,0x0 ;second + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,6 + + mov al,0x2 ;minute + out 0x70,al + in al,0x71 + call bcd2bin + ror eax,6 + + mov al,0x4 ;hour + out 0x70,al + in al,0x71 + call bcd2bin + rol eax,11 + ret + + +set_current_time_for_entry: +;----------------------------------------------------- +; Set current time/date for file entry +; input : ebx = file entry pointer +;----------------------------------------------------- + push eax + call get_time_for_file ; update files date/time + mov [ebx+22],ax + call get_date_for_file + mov [ebx+24],ax + pop eax + ret + + +makedir: +;----------------------------------------------------- +; input : eax = directory name +; edx = path +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 8 - disk full +; 10 - access denied +; Note : can only make one directory at time +;----------------------------------------------------- + cmp [fat_type],0 + jnz make_dir_fat_ok + mov eax,ERROR_UNKNOWN_FS + ret + + make_dir_fat_ok: +; call reserve_hd1 + + pushad + + mov ebx,edx + call get_cluster_of_a_path + jnc make_dir_found_path + cmp [hd_error],0 + jne make_dir_error_1 + + make_dir_path_not_found: + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne make_dir_error_2 + + mov [hd1_status],0 + mov eax,ERROR_FILE_NOT_FOUND + ret + + make_dir_disk_full: + cmp [hd_error],0 + jne make_dir_error_1 + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne make_dir_error_2 + + mov [hd1_status],0 + mov eax,ERROR_DISK_FULL + ret + + make_dir_already_exist: + cmp [hd_error],0 + jne make_dir_error_1 + mov eax,[cluster] ; directory cluster + xor edx,edx ; free + call set_FAT + cmp [hd_error],0 + jne make_dir_error_1 + + popad + call update_disk ; write all of cache and fat to hd + make_dir_error_2: + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + + make_dir_error_1: + popad + jmp make_dir_error_2 + + make_dir_error_3: + add esp,4 + jmp make_dir_error_1 + + make_dir_found_path: + cmp eax,[ROOT_CLUSTER] + jnz make_dir_not_root + xor eax,eax + + make_dir_not_root: + mov ecx,eax ; directorys start cluster + mov word [NewDirEntry2+26],cx ; 16 bits low of cluster + shr ecx,16 + mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16) + + push eax ; save parent directory cluster + mov eax,2 + call get_free_FAT + mov [cluster],eax ; first free cluster + pop eax + jc make_dir_disk_full + + push eax + mov eax,[cluster] ; directory cluster + mov edx,[fatEND] ; end for directory + call set_FAT + cmp [hd_error],0 + jne make_dir_error_3 + pop eax + + mov ebx,PUSHAD_EAX ; dir name + push eax + call analyze_directory ; check if directory already exist + cmp [hd_error],0 + jne make_dir_error_1 + + pop eax + jnc make_dir_already_exist ; need to free allocated cluster! + + call analyze_directory_to_write + jc make_dir_already_exist ; need to free allocated cluster! + + mov esi,PUSHAD_EAX ; dir name + mov edi,ebx ; pointer in buffer + mov ecx,11 + cld + rep movsb + + mov dword [ebx+28],0 ; dir size is always 0 + mov ecx,[cluster] + mov [ebx+26],cx ; 16 bits low of cluster + mov word [NewDirEntry1+26],cx + shr ecx,16 + mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) + mov word [NewDirEntry1+20],cx + mov byte [ebx+11],0x10 ; attribute = directory + + call set_current_time_for_entry + mov ecx,[ebx+22] + mov dword [NewDirEntry1+22],ecx + mov dword [NewDirEntry2+22],ecx + + mov ebx,buffer ; save the directory name,length,cluster + call hd_write + cmp [hd_error],0 + jne make_dir_error_1 + + mov ecx,512/4 + xor eax,eax + mov edi,buffer + cld + rep stosd ; clear new directory cluster + + mov eax,[cluster] ; new directory cluster + sub eax,2 + mov edx,[SECTORS_PER_CLUSTER] + imul eax,edx + add eax,[DATA_START] + mov ebx,buffer + add eax,edx ; start from last sector + + dir_set_empty_directory: + dec eax ; next sector + cmp edx,1 ; is first directory sector? + jnz not_first_sector ; no. write empty sector + mov esi,NewDirEntry1 + mov edi,buffer + mov ecx,64/4 + cld + rep movsd ; copy 2 first directory entrys "." and ".." + + not_first_sector: + call hd_write + cmp [hd_error],0 + jne make_dir_error_1 + + dec edx + jnz dir_set_empty_directory + + mov ecx,-1 ; remove 1 cluster from free disk space + call add_disk_free_space + cmp [hd_error],0 + jne make_dir_error_1 + + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne make_dir_error_2 + mov [hd1_status],0 + xor eax,eax + ret + + +removedir: +;----------------------------------------------------- +; input : eax = file/directory name +; edx = path +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 10 - access denied +;----------------------------------------------------- + cmp [fat_type],0 + jnz remove_dir_fat_ok + mov eax,ERROR_UNKNOWN_FS + ret + + remove_dir_fat_ok: +; call reserve_hd1 + + push edi + mov edi,1 ; allow directory remove + call file_delete + cmp [hd_error],0 + jne @f + + pop edi + + call update_disk ; write all of cache and fat to hd + @@: + mov [hd1_status],0 + ret + + +add_disk_free_space: +;----------------------------------------------------- +; input : ecx = cluster count +; Note : negative = remove clusters from free space +; positive = add clusters to free space +;----------------------------------------------------- + test ecx,ecx ; no change + je add_dfs_no + cmp [fat_type],32 ; free disk space only used by fat32 + jne add_dfs_no + + push eax ebx + mov eax,[ADR_FSINFO] + mov ebx,fsinfo_buffer + call hd_read + cmp [hd_error],0 + jne add_not_fs + + cmp dword [ebx+0x1fc],0xaa550000 ; check sector id + jne add_not_fs + + add [ebx+0x1e8],ecx + call hd_write +; cmp [hd_error],0 +; jne add_not_fs + + add_not_fs: + pop ebx eax + + add_dfs_no: + ret + + +file_write: +;-------------------------------------------------------------------------- +; INPUT : user-reg register-in-this meaning symbol-in-this-routine +; +; EAX EDI system call to write / +; EBX EAX (PAR0) pointer to file-name PAR0 +; EDX ECX (PAR1) pointer to buffer PAR1 +; ECX EBX (PAR2) file size PAR2 +; ESI EDX (PAR3) pointer to path PAR3 +; +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 8 - disk full +; 10 - access denied +;-------------------------------------------------------------------------- + cmp [fat_type],0 + jnz fat_ok_for_writing + mov eax,ERROR_UNKNOWN_FS + ret + + fat_ok_for_writing: +; call reserve_hd1 + + pushad + + xor edi,edi ; don't allow directory remove + call file_delete ; try to delete the file first + cmp [hd_error],0 + jne exit_write_access_1 + + test eax,eax + jz old_deleted ; deleted ok + cmp eax,ERROR_FILE_NOT_FOUND + jnz exit_write_access ; it exist but can't delete + + old_deleted: + mov ebx,PUSHAD_EDX + call get_cluster_of_a_path + jnc found_directory_for_writing + cmp [hd_error],0 + jne exit_write_access + + exit_writing_with_error: + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + + mov [hd1_status],0 + mov eax,ERROR_FILE_NOT_FOUND + ret + + exit_writing_disk_full_clear: + cmp [hd_error],0 + jne exit_write_access_1 + mov eax,[sector_tmp] + mov ebx,buffer + call hd_read ; read directory sector + cmp [hd_error],0 + jne exit_write_access_1 + + mov edx,[entry_pos] + mov byte [edx],0xe5 ; mark as deleted + call hd_write + cmp [hd_error],0 + jne exit_write_access_1 + + mov eax,[edx+20-2] ; FAT entry + mov ax,[edx+26] + and eax,[fatMASK] + call clear_cluster_chain + + exit_writing_disk_full: + cmp [hd_error],0 + jne exit_write_access_1 + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + mov [hd1_status],0 + mov eax,ERROR_DISK_FULL + ret + + exit_write_access: + popad + call update_disk ; write all of cache and fat to hd + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + + exit_write_access_1: + popad + exit_write_access_2: + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + +found_directory_for_writing: + call analyze_directory_to_write + jc exit_writing_disk_full + + mov [sector_tmp],eax + mov [entry_pos],ebx + push eax ; save directory sector + mov eax,2 + call get_free_FAT + mov [cluster],eax ; first free cluster + pop eax + jc exit_writing_disk_full + + mov esi,PUSHAD_EAX ; file name + mov edi,ebx ; pointer in buffer + mov ecx,11 + cld + rep movsb + + mov esi,PUSHAD_EBX ; file size (bytes left) + mov [ebx+28],esi ; file size + mov ecx,[cluster] + mov [ebx+26],cx ; 16 bits low of cluster + shr ecx,16 + mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16) + mov byte [ebx+11],0x20 ; attribute = archive + + call set_current_time_for_entry + + mov ebx,buffer ; save the directory name,length,cluster + call hd_write + cmp [hd_error],0 + jne exit_write_access_1 + + imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes + xor ecx,ecx ; cluster count + mov ebx,PUSHAD_ECX ; ebx = buffer + +hd_new_block_write: + + mov eax,[cluster] ; eax = block + call set_data_cluster + cmp [hd_error],0 + jne exit_write_access_1 + + sub esi,edi ; sub wrote bytes + jbe file_saved_OK ; end if all done + add ebx,edi ; update buffer position + + inc eax + call get_free_FAT ; next free in FAT + jc exit_writing_disk_full_clear + + mov edx,eax + xchg eax,[cluster] ; get old cluster and save new cluster + call set_FAT ; add it in cluster chain + cmp [hd_error],0 + jne exit_write_access_1 + + dec ecx ; update cluster count + jmp hd_new_block_write + +file_saved_OK: + + mov edx,[fatEND] ; new end for cluster chain + call set_FAT + cmp [hd_error],0 + jne exit_write_access_1 + + dec ecx ; update cluster count + + call add_disk_free_space ; remove clusters from free disk space + cmp [hd_error],0 + jne exit_write_access_1 + + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne exit_write_access_2 + mov [hd1_status],0 + xor eax,eax + ret + + +file_read: +;-------------------------------------------------------------------------- +; INPUT : user-register register-in-this meaning symbol-in-this +; +; EAX EDI system call to write / +; EBX EAX (PAR0) pointer to file-name PAR0 +; EDX ECX (PAR1) pointer to buffer PAR1 +; ECX EBX (PAR2) vt file blocks to read PAR2 +; ESI EDX (PAR3) pointer to path PAR3 +; EDI ESI vt first 512 block to read +; EDI if 0 - read root +; +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 6 - end of file +; 9 - fat table corrupted +; 10 - access denied +; ebx = size of file/directory +;-------------------------------------------------------------------------- + cmp [fat_type],0 + jnz fat_ok_for_reading + xor ebx,ebx + mov eax,ERROR_UNKNOWN_FS + mov [hd1_status], ebx + ret + + fat_ok_for_reading: +; call reserve_hd1 + + pushad + + mov ebx,edx + call get_cluster_of_a_path + jc file_to_read_not_found + + test edi,edi ; read rootdir + jne no_read_root + + xor eax,eax + call get_dir_size ; return rootdir size + cmp [hd_error],0 + jne file_access_denied + + mov [file_size],eax + mov eax,[ROOT_CLUSTER] + jmp file_read_start + + no_read_root: + mov ebx,PUSHAD_EAX ; file name + call analyze_directory + jc file_to_read_not_found + + mov eax,[ebx+28] ; file size + test byte [ebx+11],0x10 ; is it directory? + jz read_set_size ; no + + mov eax,[ebx+20-2] ; FAT entry + mov ax,[ebx+26] + and eax,[fatMASK] + call get_dir_size + cmp [hd_error],0 + jne file_access_denied + + read_set_size: + mov [file_size],eax + + mov eax,[ebx+20-2] ; FAT entry + mov ax,[ebx+26] + and eax,[fatMASK] + + file_read_start: + mov ebx,PUSHAD_ECX ; pointer to buffer + mov edx,PUSHAD_EBX ; file blocks to read + mov esi,PUSHAD_ESI ; first 512 block to read + + file_read_new_cluster: + call get_data_cluster + jc file_read_eof ; end of file or cluster out of range + + test edx,edx ; is all read? + je file_read_OK ; yes + + call get_FAT ; get next cluster + cmp [hd_error],0 + jne file_access_denied + + cmp eax,[fatRESERVED] ; end of file + jnb file_read_eof + cmp eax,2 ; incorrect fat chain + jnb file_read_new_cluster + + popad + mov [hd1_status],0 + mov ebx,[file_size] + mov eax,ERROR_FAT_TABLE + ret + + file_read_eof: + cmp [hd_error],0 + jne file_access_denied + popad + mov [hd1_status],0 + mov ebx,[file_size] + mov eax,ERROR_END_OF_FILE + ret + + file_read_OK: + popad + mov [hd1_status],0 + mov ebx,[file_size] + xor eax,eax + ret + + file_to_read_not_found: + cmp [hd_error],0 + jne file_access_denied + popad + mov [hd1_status],0 + xor ebx,ebx + mov eax,ERROR_FILE_NOT_FOUND + ret + + file_access_denied: + popad + mov [hd1_status],0 + xor ebx,ebx + mov eax,ERROR_ACCESS_DENIED + ret + +get_dir_size: +;----------------------------------------------------- +; input : eax = first cluster (0=rootdir) +; output : eax = directory size in bytes +;----------------------------------------------------- + push edx + xor edx,edx ; count of directory clusters + test eax,eax + jnz dir_size_next + + mov eax,[ROOT_SECTORS] + shl eax,9 ; fat16 rootdir size in bytes + cmp [fat_type],16 + je dir_size_ret + mov eax,[ROOT_CLUSTER] + + dir_size_next: + cmp eax,2 ; incorrect fat chain + jb dir_size_end + cmp eax,[fatRESERVED] ; end of directory + ja dir_size_end + call get_FAT ; get next cluster + cmp [hd_error],0 + jne dir_size_ret + + inc edx + jmp dir_size_next + + dir_size_end: + imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes + imul eax,edx + + dir_size_ret: + pop edx + ret + + +file_delete: +;----------------------------------------------------- +; input : eax = file/directory name +; edx = path +; edi = 1 - allow directory remove else don't remove directory +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 10 - access denied +;----------------------------------------------------- + cmp [fat_type],0 + jnz file_del_fat_ok + mov eax,ERROR_UNKNOWN_FS + ret + + file_del_fat_ok: + pushad + + mov ebx,edx + call get_cluster_of_a_path + jc file_to_delete_not_found + + mov ebx,PUSHAD_EAX ; file/directory name + call analyze_directory + jc file_to_delete_not_found + + test byte [ebx+11],0x10 ; is it directory? + jz delete_notdir ; no. it's file + cmp edi,1 ; allow directory remove + jnz delete_no_access ; no + + push eax ; save directory sector + mov eax,[ebx+20-2] ; first cluster of file + mov ax,[ebx+26] ; 0 length files start cluster = 0 + and eax,[fatMASK] + xor ebp,ebp ; counter for directory deepnes + call clear_directory + pop eax + jc delete_no_access + + push ebx ; save directory pointer in buffer + mov ebx,buffer + call hd_read ; read directory sector + cmp [hd_error],0 + jne delete_no_access_1 + pop ebx + + delete_notdir: + call delete_entry_name + cmp [hd_error],0 + jne delete_no_access + + mov eax,ecx ; first cluster of file + call clear_cluster_chain + cmp [hd_error],0 + jne delete_no_access + + popad + xor eax,eax + ret + + delete_no_access_1: + add esp,4 + delete_no_access: + popad + mov eax,ERROR_ACCESS_DENIED + ret + + file_to_delete_not_found: + cmp [hd_error],0 + jne delete_no_access + popad + mov eax,ERROR_FILE_NOT_FOUND + ret + + +clear_cluster_chain: +;----------------------------------------------------- +; input : eax = first cluster +;----------------------------------------------------- + push eax ecx edx + xor ecx,ecx ; cluster count + + clean_new_chain: + cmp eax,[LAST_CLUSTER] ; end of file + ja delete_OK + cmp eax,2 ; unfinished fat chain or zero length file + jb delete_OK + cmp eax,[ROOT_CLUSTER] ; don't remove root cluster + jz delete_OK + + xor edx,edx + call set_FAT ; clear fat entry + cmp [hd_error],0 + jne access_denied_01 + + inc ecx ; update cluster count + mov eax,edx ; old cluster + jmp clean_new_chain + + delete_OK: + call add_disk_free_space ; add clusters to free disk space + access_denied_01: + pop edx ecx eax + ret + + +clear_directory: +;----------------------------------------------------- +; input : eax = directory cluster +; ebp = directory deepnes +; Note : use recursive call +;----------------------------------------------------- + pushad + inc ebp + cmp ebp,64 ; if over 63 directory deep + jnb clear_error ; something must be wrong + + clear_new_cluster: + cmp eax,[LAST_CLUSTER] + ja clear_end + cmp eax,[ROOT_CLUSTER] ; don't remove root cluster + jz clear_end + mov esi,eax ; esi = current directory cluster + sub eax,2 + jb clear_end + mov ecx,[SECTORS_PER_CLUSTER] + imul eax,ecx + add eax,[DATA_START] + + clear_new_sector: + mov edi,eax ; edi = current directory sector + mov ebx,deltree_buffer + call hd_read + cmp [hd_error],0 + jne clear_error + + mov edx,512/32 ; count of dir entrys per sector = 16 + + clear_analyze: + mov al,[ebx+11] ; file attribute + and al,0xf + cmp al,0xf + je clear_long_filename + + cmp byte [ebx],'.' ; parent or current directory + je clear_next_entry + cmp byte [ebx],0xe5 ; deleted + je clear_next_entry + cmp byte [ebx],0 ; empty + je clear_write_last + ;je clear_next_entry + + mov eax,[ebx+20-2] ; first cluster of entry + mov ax,[ebx+26] + and eax,[fatMASK] + + test byte [ebx+11],0x10 ; is it directory? + jz clear_file ; no + + push eax ebx + mov eax,edi + mov ebx,deltree_buffer ; save buffer over recursive call + call hd_write ; write directory sector to disk + cmp [hd_error],0 + jne clear_error + + pop ebx eax + + call clear_directory ; recursive call !!! + jc clear_error ; exit if error found + + push eax ebx + mov eax,edi + mov ebx,deltree_buffer + call hd_read ; read directory sector again + cmp [hd_error],0 + jne clear_error_1 + + pop ebx eax + + clear_file: + call clear_cluster_chain + cmp [hd_error],0 + jne clear_error + + clear_long_filename: + mov byte [ebx],0xe5 + + clear_next_entry: + add ebx,32 ; position of next dir entry + dec edx + jnz clear_analyze + + mov eax,edi + mov ebx,deltree_buffer + call hd_write ; write directory sector to disk + cmp [hd_error],0 + jne clear_error + + inc eax ; next sector + dec ecx + jnz clear_new_sector + + mov eax,esi + call get_FAT ; get next cluster + cmp [hd_error],0 + jne clear_error + + jmp clear_new_cluster ; clear it + + clear_write_last: + mov eax,edi + mov ebx,deltree_buffer + call hd_write ; write directory sector to disk + cmp [hd_error],0 + jne clear_error + + clear_end: + popad + clc + ret +clear_error_1: + add esp,8 + clear_error: + popad + stc + ret + + +delete_entry_name: +;----------------------------------------------------- +; input : eax = directory sector +; ebx = directory pointer in buffer +; longname_sec = 2 previous directory sectors +; output : ecx = first cluster +; change : eax,ebx,edx +;----------------------------------------------------- + mov byte [ebx],0xe5 + mov ecx,[ebx+20-2] ; first cluster of file + mov cx,[ebx+26] ; 0 length files start cluster = 0 + and ecx,[fatMASK] + + delete_empty: + sub ebx,32 + cmp ebx,buffer + jnb delete_test_long + + mov ebx,buffer + call hd_write ; write directory sector back + cmp [hd_error],0 + jne delete_name_end + + xor eax,eax + xchg eax,[longname_sec2] + xchg eax,[longname_sec1] + test eax,eax ; is there previous directory sector? + jz delete_name_end ; no + + mov ebx,buffer + call hd_read ; read previous sector + cmp [hd_error],0 + jne delete_name_end + + mov ebx,buffer+0x1e0 ; start from last entry + + delete_test_long: + mov dh,[ebx+11] ; file attribute + and dh,0xf + cmp dh,0xf + jne delete_write_buffer + + cmp byte [ebx],0x40 ; end of long dir entry? + mov byte [ebx],0xe5 + jb delete_empty + + delete_write_buffer: + mov ebx,buffer + call hd_write ; write directory sector back + + delete_name_end: + ret + + +rename: +;----------------------------------------------------------- +; input : eax = source directory name +; edx = source path +; ebx = dest directory name +; edi = dest path +; output : eax = 0 - ok +; 3 - unknown FS +; 5 - file not found +; 8 - disk full +; 10 - access denied +;----------------------------------------------------------- + cmp [fat_type],0 + jnz fat_ok_for_rename + mov eax,ERROR_UNKNOWN_FS + ret + + fat_ok_for_rename: +; call reserve_hd1 + + pushad + + mov ebx,edx ; source path + call get_cluster_of_a_path + jc rename_entry_not_found + + mov ebx,PUSHAD_EAX ; source directory name + call analyze_directory + jc rename_entry_not_found + + mov [sector_tmp],eax ; save source sector + mov [entry_pos],ebx + mov esi,ebx + mov edi,dir_entry + mov ecx,32/4 + cld + rep movsd ; save entry + + mov ebx,PUSHAD_EDI ; dest path + call get_cluster_of_a_path + jc rename_entry_not_found + + mov edx,eax ; save dest directory cluster + mov ebx,PUSHAD_EBX ; dest directory name + push [longname_sec1] + push [longname_sec2] + call analyze_directory ; check if entry already exist + cmp [hd_error],0 + jne rename_entry_already_exist_1 + + pop [longname_sec2] + pop [longname_sec1] + jnc rename_entry_already_exist + + mov eax,edx + call analyze_directory_to_write + jc rename_disk_full + + mov esi,dir_entry + mov edi,ebx + mov ecx,32/4 + cld + rep movsd ; copy entry + mov esi,PUSHAD_EBX ; dest directory name + mov edi,ebx + mov ecx,11 + rep movsb ; copy name + + mov ebx,buffer ; save the directory name,length,cluster + call hd_write + + test byte [dir_entry+11],0x10 ; is it directory? + jz rename_not_dir ; no + mov eax,[dir_entry+20-2] ; FAT entry + mov ax,[dir_entry+26] + and eax,[fatMASK] + call change_2dot_cluster + cmp [hd_error],0 + jne rename_entry_already_exist + + rename_not_dir: + cmp [hd_error],0 + jne rename_entry_already_exist + mov eax,[sector_tmp] + mov ebx,buffer + call hd_read ; read source directory sector + cmp [hd_error],0 + jne rename_entry_already_exist + + mov ebx,[entry_pos] + call delete_entry_name + cmp [hd_error],0 + jne rename_entry_already_exist + + popad + call update_disk ; write all of cache and fat to hd + cmp [hd_error],0 + jne rename_entry_already_exist_2 + mov [hd1_status],0 + xor eax,eax + ret + + rename_entry_not_found: + cmp [hd_error],0 + jne rename_entry_already_exist + popad + mov [hd1_status],0 + mov eax,ERROR_FILE_NOT_FOUND + ret + + rename_entry_already_exist_1: + add esp,8 + rename_entry_already_exist: + popad + rename_entry_already_exist_2: + mov [hd1_status],0 + mov eax,ERROR_ACCESS_DENIED + ret + + rename_disk_full: + cmp [hd_error],0 + jne rename_entry_already_exist + popad + mov [hd1_status],0 + mov eax,ERROR_DISK_FULL + ret + + +change_2dot_cluster: +;----------------------------------------------------------- +; input : eax = directory cluster +; edx = value to save +; change : eax,ebx,edx +;----------------------------------------------------------- + cmp eax,[LAST_CLUSTER] + ja not_2dot ; too big cluster number, something is wrong + sub eax,2 + jb not_2dot + + imul eax,[SECTORS_PER_CLUSTER] + add eax,[DATA_START] + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne not_2dot + + cmp dword [ebx+32],'.. ' + jnz not_2dot + + cmp edx,[ROOT_CLUSTER] ; is rootdir cluster? + jne not_2dot_root + xor edx,edx ; yes. set it zero + + not_2dot_root: + mov [ebx+32+26],dx ; 16 bits low of cluster + shr edx,16 + mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16) + call hd_write + + not_2dot: + ret + + +get_hd_info: +;----------------------------------------------------------- +; output : eax = 0 - ok +; 3 - unknown FS +; 10 - access denied +; edx = cluster size in bytes +; ebx = total clusters on disk +; ecx = free clusters on disk +;----------------------------------------------------------- + cmp [fat_type],0 + jnz info_fat_ok + xor edx,edx + xor ebx,ebx + xor ecx,ecx + mov eax,ERROR_UNKNOWN_FS + ret + + info_fat_ok: +; call reserve_hd1 + + xor ecx,ecx ; count of free clusters + mov eax,2 + mov ebx,[LAST_CLUSTER] + + info_cluster: + push eax + call get_FAT ; get cluster info + cmp [hd_error],0 + jne info_access_denied + + test eax,eax ; is it free? + jnz info_used ; no + inc ecx + + info_used: + pop eax + inc eax + cmp eax,ebx ; is above last cluster? + jbe info_cluster ; no. test next cluster + + dec ebx ; cluster count + imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes + mov [hd1_status],0 + xor eax,eax + ret + + info_access_denied: + add esp,4 + xor edx,edx + xor ebx,ebx + xor ecx,ecx + mov eax,ERROR_ACCESS_DENIED + ret + +update_disk: +;----------------------------------------------------------- +; write changed fat and cache to disk +;----------------------------------------------------------- + cmp [fat_change],0 ; is fat changed? + je upd_no_change + + call write_fat_sector + cmp [hd_error],0 + jne update_disk_acces_denied + + upd_no_change: + + call write_cache + update_disk_acces_denied: + ret + + +;************************************************************************** +; +; 0x600008 - first entry in cache list +; +; +0 - lba sector +; +4 - state of cache sector +; 0 = empty +; 1 = used for read ( same as in hd ) +; 2 = used for write ( differs from hd ) +; +; +65536 - cache entries +; +;************************************************************************** + + +hd_read: +;----------------------------------------------------------- +; input : eax = block to read +; ebx = destination +;----------------------------------------------------------- + push ecx esi edi ; scan cache + + mov ecx,cache_max ; entries in cache + mov esi,0x600000+8 + mov edi,1 + + hdreadcache: + + cmp dword [esi+4],0 ; empty + je nohdcache + + cmp [esi],eax ; correct sector + je yeshdcache + + nohdcache: + + add esi,8 + inc edi + dec ecx + jnz hdreadcache + + call find_empty_slot ; ret in edi + cmp [hd_error],0 + jne return_01 + + push eax edx + + call disable_ide_int + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_read_error + +; cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al ; ATAFeatures ॣЁбва "®б®ЎҐ­­®б⥩" + inc edx + inc eax + out dx,al ; ATASectorCount бзҐвзЁЄ ᥪв®а®ў + inc edx + mov eax,[esp+4] + out dx,al ; ATASectorNumber ॣЁбва ­®¬Ґа  ᥪв®а  + shr eax,8 + inc edx + out dx,al ; ATACylinder ­®¬Ґа жЁ«Ё­¤а  (¬« ¤иЁ© Ў ©в) + shr eax,8 + inc edx + 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 ; ­®¬Ґа Ј®«®ўЄЁ/­®¬Ґа ¤ЁбЄ  + inc edx + mov al,20h + out dx,al ; ATACommand ॣЁбва Є®¬ ­¤ +; sti + + call wait_for_sector_buffer + + cmp [hd_error],0 + jne hd_read_error + +; cli + push edi + shl edi,9 + add edi,0x600000+65536 + mov ecx,256 + mov edx,[hdbase] + cld + rep insw + pop edi +; sti + + call enable_ide_int + + pop edx eax + blok_read_2: + lea esi,[edi*8+0x600000] + mov [esi],eax ; sector number + mov dword [esi+4],1 ; hd read - mark as same as in hd + + yeshdcache: + + mov esi,edi + shl esi,9 + add esi,0x600000+65536 + mov edi,ebx + mov ecx,512/4 + cld + rep movsd ; move data + return_01: + pop edi esi ecx + ret + +disable_ide_int: + mov edx,[hdbase] + add edx,0x206 + mov al,2 + out dx,al + ret + +enable_ide_int: + mov edx,[hdbase] + add edx,0x206 + mov al,0 + out dx,al + ret + +hd_write: +;----------------------------------------------------------- +; input : eax = block +; ebx = pointer to memory +;----------------------------------------------------------- + push ecx esi edi + + ; check if the cache already has the sector and overwrite it + + mov ecx,cache_max + mov esi,0x600000+8 + mov edi,1 + + hdwritecache: + + cmp dword [esi+4],0 ; if cache slot is empty + je not_in_cache_write + + cmp [esi],eax ; if the slot has the sector + je yes_in_cache_write + + not_in_cache_write: + + add esi,8 + inc edi + dec ecx + jnz hdwritecache + + ; sector not found in cache + ; write the block to a new location + + call find_empty_slot ; ret in edi + cmp [hd_error],0 + jne hd_write_access_denied + + lea esi,[edi*8+0x600000] + mov [esi],eax ; sector number + + yes_in_cache_write: + + mov dword [esi+4],2 ; write - differs from hd + + shl edi,9 + add edi,0x600000+65536 + mov esi,ebx + mov ecx,512/4 + cld + rep movsd ; move data + hd_write_access_denied: + pop edi esi ecx + ret + + +write_cache: +;----------------------------------------------------------- +; write all changed sectors to disk +;----------------------------------------------------------- + push eax ecx edx esi edi + + ; write difference ( 2 ) from cache to hd + + mov ecx,cache_max + mov esi,0x600000+8 + mov edi,1 + + write_cache_more: + + cmp dword [esi+4],2 ; if cache slot is not different + jne does_not_need_writing + + mov dword [esi+4],1 ; same as in hd + mov eax,[esi] ; eax = sector to write + + cmp eax,[PARTITION_START] + jb danger + cmp eax,[PARTITION_END] + ja danger + + call disable_ide_int + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_write_error + +; cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al + inc edx + inc eax + out dx,al + inc edx + mov eax,[esi] ; eax = sector to write + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + 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 + inc edx + mov al,30h + out dx,al +; sti + + call wait_for_sector_buffer + + cmp [hd_error],0 + jne hd_write_error + + push ecx esi + +; cli + mov esi,edi + shl esi,9 + add esi,0x600000+65536 ; esi = from memory position + mov ecx,256 + mov edx,[hdbase] + cld + rep outsw +; sti + + pop esi ecx + + call enable_ide_int + + danger: + does_not_need_writing: + + add esi,8 + inc edi + dec ecx + jnz write_cache_more + return_02: + pop edi esi edx ecx eax + ret + + +find_empty_slot: +;----------------------------------------------------------- +; find empty or read slot, flush cache if next 10% is used by write +; output : edi = cache slot +;----------------------------------------------------------- + push ecx esi + + search_again: + + mov ecx,cache_max*10/100 + mov edi,[cache_search_start] + + search_for_empty: + + inc edi + cmp edi,cache_max + jbe inside_cache + mov edi,1 + + inside_cache: + + cmp dword [edi*8+0x600000+4],2 ; get cache slot info + jb found_slot ; it's empty or read + dec ecx + jnz search_for_empty + + call write_cache ; no empty slots found, write all + cmp [hd_error],0 + jne found_slot_access_denied + + jmp search_again ; and start again + + found_slot: + + mov [cache_search_start],edi + found_slot_access_denied: + pop esi ecx + ret + + +save_hd_wait_timeout: + + push eax + mov eax,[timer_ticks];[0xfdf0] + add eax,300 ; 3 sec timeout + mov [hd_wait_timeout],eax + pop eax + ret + + +check_hd_wait_timeout: + + push eax + mov eax,[hd_wait_timeout] + cmp [timer_ticks], eax ;[0xfdf0],eax + jg hd_timeout_error + pop eax + mov [hd_error],0 + ret + +iglobal + hd_timeout_str db 'K : FS - HD timeout',13,10,0 + hd_read_str db 'K : FS - HD read error',13,10,0 + hd_write_str db 'K : FS - HD write error',13,10,0 + hd_lba_str db 'K : FS - HD LBA error',13,10,0 +endg + +hd_timeout_error: + + call clear_hd_cache + call clear_application_table_status + mov esi,hd_timeout_str + call sys_msg_board_str +; jmp $ + mov [hd_error],1 + pop eax + ret + +hd_read_error: + + call clear_hd_cache + call clear_application_table_status + mov esi,hd_read_str + call sys_msg_board_str + pop edx eax + jmp return_01 +; jmp $ + +hd_write_error: + + call clear_hd_cache + call clear_application_table_status + mov esi,hd_write_str + call sys_msg_board_str + jmp return_02 +; jmp $ + +hd_lba_error: + call clear_hd_cache + call clear_application_table_status + mov esi,hd_lba_str + call sys_msg_board_str + jmp LBA_read_ret + + +wait_for_hd_idle: + + push eax edx + + call save_hd_wait_timeout + + mov edx,[hdbase] + add edx,0x7 + + wfhil1: + + call check_hd_wait_timeout + cmp [hd_error],0 + jne @f + + in al,dx + test al,128 + jnz wfhil1 + + @@: + + pop edx eax + ret + + + +wait_for_sector_buffer: + + push eax edx + + mov edx,[hdbase] + add edx,0x7 + + call save_hd_wait_timeout + + hdwait_sbuf: ; wait for sector buffer to be ready + + call check_hd_wait_timeout + cmp [hd_error],0 + jne @f + + in al,dx + test al,8 + jz hdwait_sbuf + + mov [hd_error],0 + + cmp [hd_setup],1 ; do not mark error for setup request + je buf_wait_ok + + test al,1 ; previous command ended up with an error + jz buf_wait_ok + @@: + mov [hd_error],1 + + buf_wait_ok: + + pop edx eax + ret + + + +read_hd_file: +;----------------------------------------------------------------- +; +; Converting old reading function for hd-application start. +; +; IN: +; +; eax - pointer to file (0 = read only first sector of drive: eg 'label') +; ebx - file lenght +; ecx - start 512 byte block number +; edx - number of blocks to read +; esi - pointer to return/work area (atleast 20 000 bytes) +; +; For new read function +; +; EAX (PAR0) pointer to file-name +; ECX (PAR1) pointer to buffer +; EBX (PAR2) vt file blocks to read +; EDX (PAR3) pointer to path +; ESI vt first 512 block to read +; EDI if 0 - return root +;-------------------------------------------------------------------------- + + push ecx esi edi + mov esi,eax + mov edi,startpath + mov ecx,250 + cld + rep movsb + pop edi esi ecx + + mov eax,startpath + mov [eax+ebx-12],byte 0 + + push eax ebx ecx edx esi + + pop ecx ; pointer to buffer + add ecx,1024 + pop ebx ; number of blocks to read + pop esi ; first block to read + dec esi + pop eax ; file length + pop edx ; pointer to path + + mov edi,12 + lea eax,[eax+edx-12+1] + call file_read + + ret + +; \begin{diamond} +hd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and edi->direntry, eax=sector +; destroys eax + push esi edi + push 0 + push 0 + push fat16_root_first + push fat16_root_next + mov eax, [ROOT_CLUSTER] + cmp [fat_type], 32 + jz .fat32 +.loop: + call fat_find_lfn + jc .notfound + cmp byte [esi], 0 + jz .found + test byte [edi+11], 10h + jz .notfound + and dword [esp+12], 0 + mov eax, [edi+20-2] + mov ax, [edi+26] ; cluster +.fat32: + mov [esp+8], eax + mov dword [esp+4], fat_notroot_first + mov dword [esp], fat_notroot_next + jmp .loop +.notfound: + add esp, 16 + pop edi esi + stc + ret +.found: + lea eax, [esp+8] + cmp dword [eax], 0 + jz .root + call fat_get_sector + jmp .cmn +.root: + mov eax, [eax+4] + add eax, [ROOT_START] +.cmn: + add esp, 20 ; CF=0 + pop esi + ret + +;---------------------------------------------------------------- +; +; fs_HdRead - LFN variant for reading hard disk +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_HdRead: + cmp [fat_type], 0 + jnz @f + or ebx, -1 + mov eax, ERROR_UNKNOWN_FS + ret +@@: + push edi + cmp byte [esi], 0 + jnz @f +.noaccess: + pop edi +.noaccess_2: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret + +.noaccess_3: + add esp,4 +.noaccess_1: + add esp,4 +.noaccess_4: + add esp,4*5 + jmp .noaccess_2 + +@@: + call hd_find_lfn + jnc .found + pop edi + cmp [hd_error],0 + jne .noaccess_2 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + +.found: + test byte [edi+11], 0x10 ; do not allow read directories + jnz .noaccess + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+28] + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 +@@: + mov eax, [edi+20-2] + mov ax, [edi+26] +; now eax=cluster, ebx=position, ecx=count, edx=buffer for data +.new_cluster: + jecxz .new_sector + test eax, eax + jz .eof + cmp eax, [fatRESERVED] + jae .eof + mov [cluster_tmp], eax + dec eax + dec eax + mov edi, [SECTORS_PER_CLUSTER] + imul eax, edi + add eax, [DATA_START] +.new_sector: + test ecx, ecx + jz .done + sub ebx, 512 + jae .skip + add ebx, 512 + jnz .force_buf + cmp ecx, 512 + jb .force_buf +; we may read directly to given buffer + push ebx + mov ebx, edx + call hd_read + cmp [hd_error],0 + jne .noaccess_1 + pop ebx + add edx, 512 + sub ecx, 512 + jmp .skip +.force_buf: +; we must read sector to temporary buffer and then copy it to destination + push eax ebx + mov ebx, buffer + call hd_read + cmp [hd_error],0 + jne .noaccess_3 + + mov eax, ebx + pop ebx + add eax, ebx + push ecx + add ecx, ebx + cmp ecx, 512 + jbe @f + mov ecx, 512 +@@: + sub ecx, ebx + mov ebx, edx + call memmove + add edx, ecx + sub [esp], ecx + pop ecx + pop eax + xor ebx, ebx +.skip: + inc eax + dec edi + jnz .new_sector + mov eax, [cluster_tmp] + call get_FAT + cmp [hd_error],0 + jne .noaccess_4 + + jmp .new_cluster +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof + +;---------------------------------------------------------------- +; +; fs_HdReadFolder - LFN variant for reading hard disk folder +; +; esi points to filename +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_HdReadFolder: + mov eax, [ROOT_CLUSTER] + push edi + cmp byte [esi], 0 + jz .doit + call hd_find_lfn + jnc .found + pop edi + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + test byte [edi+11], 0x10 ; do not allow read files + jnz .found_dir + pop edi + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + mov eax, [edi+20-2] + mov ax, [edi+26] ; eax=cluster +.doit: + push esi ecx + push ebp + sub esp, 262*2 ; reserve space for LFN + mov ebp, esp + push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name + mov ebx, [ebx] +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + mov byte [edx], 1 ; version + mov esi, edi ; esi points to BDFE +.new_cluster: + mov [cluster_tmp], eax + test eax, eax + jnz @f + cmp [fat_type], 32 + jz .notfound + mov eax, [ROOT_START] + push [ROOT_SECTORS] + push ebx + jmp .new_sector +@@: + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + push [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + push ebx +.new_sector: + mov ebx, buffer + mov edi, ebx + call hd_read + cmp [hd_error], 0 + jnz .notfound2 + add ebx, 512 + push eax +.l1: + call fat_get_name + jc .l2 + cmp byte [edi+11], 0xF + jnz .do_bdfe + add edi, 0x20 + cmp edi, ebx + jb .do_bdfe + pop eax + inc eax + dec dword [esp+4] + jnz @f + mov eax, [cluster_tmp] + test eax, eax + jz .done + call get_FAT + cmp [hd_error], 0 + jnz .notfound2 + cmp eax, 2 + jb .done + cmp eax, [fatRESERVED] + jae .done + push eax + mov eax, [SECTORS_PER_CLUSTER] + mov [esp+8], eax + pop eax + mov [cluster_tmp], eax + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] +@@: + mov ebx, buffer + mov edi, ebx + call hd_read + cmp [hd_error], 0 + jnz .notfound2 + add ebx, 512 + push eax +.do_bdfe: + inc dword [edx+8] ; new file found + dec dword [esp+4] + jns .l2 + dec ecx + js .l2 + inc dword [edx+4] ; new file block copied + call fat_entry_to_bdfe +.l2: + add edi, 0x20 + cmp edi, ebx + jb .l1 + pop eax + inc eax + dec dword [esp+4] + jnz .new_sector + mov eax, [cluster_tmp] + test eax, eax + jz .done + call get_FAT + cmp [hd_error], 0 + jnz .notfound2 + cmp eax, 2 + jb .done + cmp eax, [fatRESERVED] + jae .done + push eax + mov eax, [SECTORS_PER_CLUSTER] + mov [esp+8], eax + pop eax + pop ebx + add esp, 4 + jmp .new_cluster +.notfound2: + add esp, 8 +.notfound: + add esp, 262*2+4 + pop ebp ecx esi edi + mov eax, ERROR_FILE_NOT_FOUND + or ebx, -1 + ret +.done: + add esp, 262*2+4+8 + pop ebp + mov ebx, [edx+4] + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + pop ecx esi edi + ret + +fat16_root_next: + cmp edi, buffer+0x200-0x20 + jae fat16_root_next_sector + add edi, 0x20 + ret ; CF=0 +fat16_root_next_sector: +; read next sector + push ecx + mov ecx, [eax+4] + inc ecx + mov [eax+4], ecx + cmp ecx, [ROOT_SECTORS] + pop ecx + jae fat16_root_first.readerr +fat16_root_first: + mov eax, [eax+4] + add eax, [ROOT_START] + push ebx + mov edi, buffer + mov ebx, edi + call hd_read + pop ebx + cmp [hd_error], 0 + jnz .readerr + ret ; CF=0 +.readerr: + stc + ret +fat16_root_begin_write: + push edi eax + call fat16_root_first + pop eax edi + ret +fat16_root_end_write: + pusha + mov eax, [eax+4] + add eax, [ROOT_START] + mov ebx, buffer + call hd_write + popa + ret +fat16_root_next_write: + cmp edi, buffer+0x200 + jae @f + ret +@@: + call fat16_root_end_write + jmp fat16_root_next_sector +fat16_root_extend_dir: + stc + ret + +fat_notroot_next: + cmp edi, buffer+0x200-0x20 + jae fat_notroot_next_sector + add edi, 0x20 + ret ; CF=0 +fat_notroot_next_sector: + push ecx + mov ecx, [eax+4] + inc ecx + cmp ecx, [SECTORS_PER_CLUSTER] + jae fat_notroot_next_cluster + mov [eax+4], ecx + jmp @f +fat_notroot_next_cluster: + push eax + mov eax, [eax] + call get_FAT + mov ecx, eax + pop eax + cmp [hd_error], 0 + jnz fat_notroot_next_err + cmp ecx, [fatRESERVED] + jae fat_notroot_next_err + mov [eax], ecx + and dword [eax+4], 0 +@@: + pop ecx +fat_notroot_first: + call fat_get_sector + push ebx + mov edi, buffer + mov ebx, edi + call hd_read + pop ebx + cmp [hd_error], 0 + jnz @f + ret ; CF=0 +fat_notroot_next_err: + pop ecx +@@: + stc + ret +fat_notroot_begin_write: + push eax edi + call fat_notroot_first + pop edi eax + ret +fat_notroot_end_write: + call fat_get_sector + push ebx + mov ebx, buffer + call hd_write + pop ebx + ret +fat_notroot_next_write: + cmp edi, buffer+0x200 + jae @f + ret +@@: + push eax + call fat_notroot_end_write + pop eax + jmp fat_notroot_next_sector +fat_notroot_extend_dir: + push eax + mov eax, [eax] + call get_free_FAT + jnc .found + pop eax + ret ; CF=1 +.found: + push edx + mov edx, [fatEND] + call set_FAT + mov edx, eax + mov eax, [esp+4] + mov eax, [eax] + push edx + call set_FAT + pop edx + cmp [hd_error], 0 + jz @f + pop edx + pop eax + stc + ret +@@: + push ecx + or ecx, -1 + call add_disk_free_space +; zero new cluster + mov ecx, 512/4 + mov edi, buffer + push edi + xor eax, eax + rep stosd + pop edi + pop ecx + mov eax, [esp+4] + mov [eax], edx + and dword [eax+4], 0 + pop edx + mov eax, [eax] + dec eax + dec eax + push ebx ecx + mov ecx, [SECTORS_PER_CLUSTER] + imul eax, ecx + add eax, [DATA_START] + mov ebx, edi +@@: + call hd_write + inc eax + loop @b + pop ecx ebx eax + clc + ret + +fat_get_sector: + push ecx + mov ecx, [eax] + dec ecx + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + add ecx, [eax+4] + mov eax, ecx + pop ecx + ret + +;---------------------------------------------------------------- +; +; fs_HdRewrite - LFN variant for writing hard disk +; +; esi points to filename +; ebx ignored (reserved) +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = number of written bytes +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fshrad: + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +fshrfs: + mov eax, ERROR_UNKNOWN_FS + xor ebx, ebx + ret + +fs_HdRewrite: + cmp [fat_type], 0 + jz fshrfs + cmp byte [esi], 0 + jz fshrad + pushad + xor ebp, ebp + push esi +@@: + lodsb + test al, al + jz @f + cmp al, '/' + jnz @b + lea ebp, [esi-1] + jmp @b +@@: + pop esi + test ebp, ebp + jnz .noroot + mov ebp, [ROOT_CLUSTER] + cmp [fat_type], 32 + jz .pushnotroot + push fat16_root_extend_dir + push fat16_root_end_write + push fat16_root_next_write + push fat16_root_begin_write + xor ebp, ebp + push ebp + push ebp + push fat16_root_first + push fat16_root_next + jmp .common1 +.noroot: +; check existence + mov byte [ebp], 0 + call hd_find_lfn + mov byte [ebp], '/' + lea esi, [ebp+1] + jnc @f + mov eax, ERROR_FILE_NOT_FOUND +.ret1: + mov [esp+28], eax + popad + xor ebx, ebx + ret +@@: + test byte [edi+11], 0x10 ; must be directory + mov eax, ERROR_ACCESS_DENIED + jz .ret1 + mov ebp, [edi+20-2] + mov bp, [edi+26] ; ebp=cluster + mov eax, ERROR_FAT_TABLE + cmp ebp, 2 + jb .ret1 +.pushnotroot: + push fat_notroot_extend_dir + push fat_notroot_end_write + push fat_notroot_next_write + push fat_notroot_begin_write + push 0 + push ebp + push fat_notroot_first + push fat_notroot_next +.common1: + call fat_find_lfn + jc .notfound +; found; must not be directory + test byte [edi+11], 10h + jz @f + add esp, 32 + popad + mov eax, ERROR_ACCESS_DENIED + xor ebx, ebx + ret +@@: +; delete FAT chain + push edi + xor eax, eax + mov dword [edi+28], eax ; zero size + xor ecx, ecx + mov eax, [edi+20-2] + mov ax, [edi+26] + mov word [edi+20], cx + mov word [edi+26], cx + test eax, eax + jz .done1 +@@: + cmp eax, [fatRESERVED] + jae .done1 + push edx + xor edx, edx + call set_FAT + mov eax, edx + pop edx + inc ecx + jmp @b +.done1: + pop edi + call get_time_for_file + mov [edi+22], ax + call get_date_for_file + mov [edi+24], ax + mov [edi+18], ax + or byte [edi+11], 20h ; set 'archive' attribute + jmp .doit +.notfound: +; file is not found; generate short name + call fat_name_is_legal + jc @f + add esp, 32 + popad + mov eax, ERROR_FILE_NOT_FOUND + xor ebx, ebx + ret +@@: + sub esp, 12 + mov edi, esp + call fat_gen_short_name +.test_short_name_loop: + push esi edi ecx + mov esi, edi + lea eax, [esp+12+12+8] + mov [eax], ebp + and dword [eax+4], 0 + call dword [eax-4] + jc .found +.test_short_name_entry: + cmp byte [edi+11], 0xF + jz .test_short_name_cont + mov ecx, 11 + push esi edi + repz cmpsb + pop edi esi + jz .short_name_found +.test_short_name_cont: + lea eax, [esp+12+12+8] + call dword [eax-8] + jnc .test_short_name_entry + jmp .found +.short_name_found: + pop ecx edi esi + call fat_next_short_name + jnc .test_short_name_loop +.disk_full: + add esp, 12+32 + popa + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.found: + pop ecx edi esi +; now find space in directory +; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' + mov al, '~' + push ecx edi + mov ecx, 8 + repnz scasb + push 1 + pop eax ; 1 entry + jnz .notilde +; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total + xor eax, eax +@@: + cmp byte [esi], 0 + jz @f + inc esi + inc eax + jmp @b +@@: + sub esi, eax + add eax, 12+13 + mov ecx, 13 + push edx + cdq + div ecx + pop edx +.notilde: + push -1 + push -1 + push -1 +; find successive entries in directory + xor ecx, ecx + push eax + lea eax, [esp+16+8+12+8] + mov [eax], ebp + and dword [eax+4], 0 + call dword [eax-4] + pop eax + jnc .scan_dir +.fsfrfe3: + add esp, 12+8+12+32 + popad + mov eax, 11 + xor ebx, ebx + ret +.scan_dir: + cmp byte [edi], 0 + jz .free + cmp byte [edi], 0xE5 + jz .free + xor ecx, ecx +.scan_cont: + push eax + lea eax, [esp+16+8+12+8] + call dword [eax-8] + pop eax + jnc .scan_dir + cmp [hd_error], 0 + jnz .fsfrfe3 + push eax + lea eax, [esp+16+8+12+8] + call dword [eax+20] ; extend directory + pop eax + jnc .scan_dir + add esp, 12+8+12+32 + popad + mov eax, ERROR_DISK_FULL + xor ebx, ebx + ret +.free: + test ecx, ecx + jnz @f + mov [esp], edi + mov ecx, [esp+12+8+12+8] + mov [esp+4], ecx + mov ecx, [esp+12+8+12+12] + mov [esp+8], ecx + xor ecx, ecx +@@: + inc ecx + cmp ecx, eax + jb .scan_cont +; found! +; calculate name checksum + push esi ecx + mov esi, [esp+8+12] + mov ecx, 11 + xor eax, eax +@@: + ror al, 1 + add al, [esi] + inc esi + loop @b + pop ecx esi + pop edi + pop dword [esp+8+12+12] + pop dword [esp+8+12+12] +; edi points to first entry in free chunk + dec ecx + jz .nolfn + push esi + push eax + lea eax, [esp+8+8+12+8] + call dword [eax+8] ; begin write + mov al, 40h +.writelfn: + or al, cl + mov esi, [esp+4] + push ecx + dec ecx + imul ecx, 13 + add esi, ecx + stosb + mov cl, 5 + call fs_RamdiskRewrite.read_symbols + mov ax, 0xF + stosw + mov al, [esp+4] + stosb + mov cl, 6 + call fs_RamdiskRewrite.read_symbols + xor eax, eax + stosw + mov cl, 2 + call fs_RamdiskRewrite.read_symbols + pop ecx + lea eax, [esp+8+8+12+8] + call dword [eax+12] ; next write + xor eax, eax + loop .writelfn + pop eax + pop esi +; lea eax, [esp+8+12+8] +; call dword [eax+16] ; end write +.nolfn: + xchg esi, [esp] + mov ecx, 11 + rep movsb + mov word [edi], 20h ; attributes + sub edi, 11 + pop esi ecx + add esp, 12 + mov byte [edi+13], 0 ; tenths of a second at file creation time + call get_time_for_file + mov [edi+14], ax ; creation time + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+16], ax ; creation date + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + xor ecx, ecx + mov word [edi+20], cx ; high word of cluster + mov word [edi+26], cx ; low word of cluster - to be filled + mov dword [edi+28], ecx ; file size - to be filled +.doit: + lea eax, [esp+8] + call dword [eax+16] ; flush directory + push ecx + mov ecx, [esp+4+32+24] + push ecx + push edi + mov esi, edx + test ecx, ecx + jz .done + mov eax, 2 + call get_free_FAT + jc .diskfull + push eax + mov [edi+26], ax + shr eax, 16 + mov [edi+20], ax + lea eax, [esp+16+8] + call dword [eax+16] ; flush directory + pop eax + push edx + mov edx, [fatEND] + call set_FAT + pop edx +.write_cluster: + push eax + dec eax + dec eax + mov ebp, [SECTORS_PER_CLUSTER] + imul eax, ebp + add eax, [DATA_START] +; write data +.write_sector: + mov ecx, 512 + cmp dword [esp+8], ecx + jb .writeshort +; we can write directly from given buffer + mov ebx, esi + add esi, ecx + jmp .writecommon +.writeshort: + mov ecx, [esp+8] + push ecx + mov edi, buffer + mov ebx, edi + rep movsb + mov ecx, buffer+0x200 + sub ecx, edi + push eax + xor eax, eax + rep stosb + pop eax + pop ecx +.writecommon: + call hd_write + cmp [hd_error], 0 + jnz .writeerr + inc eax + sub dword [esp+8], ecx + jz .writedone + dec ebp + jnz .write_sector +; allocate new cluster + pop eax + mov ecx, eax + call get_free_FAT + jc .diskfull + push edx + mov edx, [fatEND] + call set_FAT + xchg eax, ecx + mov edx, ecx + call set_FAT + pop edx + xchg eax, ecx + jmp .write_cluster +.diskfull: + mov eax, ERROR_DISK_FULL + jmp .ret +.writeerr: + pop eax + sub esi, ecx + mov eax, 11 + jmp .ret +.writedone: + pop eax +.done: + xor eax, eax +.ret: + pop edi ecx + mov ebx, esi + sub ebx, edx + pop ebp + mov [esp+32+28], eax + lea eax, [esp+8] + call dword [eax+8] + mov [edi+28], ebx + call dword [eax+16] + mov [esp+32+16], ebx + lea eax, [ebx+511] + shr eax, 9 + mov ecx, [SECTORS_PER_CLUSTER] + lea eax, [eax+ecx-1] + xor edx, edx + div ecx + mov ecx, ebp + sub ecx, eax + call add_disk_free_space + add esp, 32 + call update_disk + popad + ret + +;---------------------------------------------------------------- +; +; fs_HdWrite - LFN variant for writing to floppy +; +; esi points to filename +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +fs_HdWrite.access_denied: + push ERROR_ACCESS_DENIED +fs_HdWrite.ret0: + pop eax + xor ebx, ebx + ret + +fs_HdWrite.ret11: + push 11 + jmp fs_HdWrite.ret0 + +fs_HdWrite: + cmp [fat_type], 0 + jnz @f + push ERROR_UNKNOWN_FS + jmp .ret0 +@@: + cmp byte [esi], 0 + jz .access_denied + pushad + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + popad + push 11 + jmp .ret0 +@@: + popfd + jnc .found + popad + push ERROR_FILE_NOT_FOUND + jmp .ret0 +.found: +; FAT does not support files larger than 4GB + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f +.eof: + popad + push ERROR_END_OF_FILE + jmp .ret0 +@@: + mov ebx, [ebx] +.l1: +; now edi points to direntry, ebx=start byte to write, +; ecx=number of bytes to write, edx=data pointer + +; extend file if needed + add ecx, ebx + jc .eof ; FAT does not support files larger than 4GB + push eax ; save directory sector + push 0 ; return value=0 + + call get_time_for_file + mov [edi+22], ax ; last write time + call get_date_for_file + mov [edi+24], ax ; last write date + mov [edi+18], ax ; last access date + + push dword [edi+28] ; save current file size + cmp ecx, [edi+28] + jbe .length_ok + cmp ecx, ebx + jz .length_ok + call hd_extend_file + jnc .length_ok + mov [esp+4], eax +; hd_extend_file can return three error codes: FAT table error, device error or disk full. +; First two cases are fatal errors, in third case we may write some data + cmp al, ERROR_DISK_FULL + jz .disk_full + pop eax + pop eax + mov [esp+4+28], eax + pop eax + popad + xor ebx, ebx + ret +.disk_full: +; correct number of bytes to write + mov ecx, [edi+28] + cmp ecx, ebx + ja .length_ok +.ret: + call update_disk + cmp [hd_error], 0 + jz @f + mov byte [esp+4], 11 +@@: + pop eax + pop eax + mov [esp+4+28], eax ; eax=return value + pop eax + sub edx, [esp+20] + mov [esp+16], edx ; ebx=number of written bytes + popad + ret +.length_ok: + mov esi, [edi+28] + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax ; edi=current cluster + xor ebp, ebp ; ebp=current sector in cluster +; save directory + mov eax, [esp+8] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jz @f +.device_err: + mov byte [esp+4], 11 + jmp .ret +@@: + +; now ebx=start pos, ecx=end pos, both lie inside file + sub ecx, ebx + jz .ret +.write_loop: +; get length of data in current sector + push ecx + sub ebx, 0x200 + jb .hasdata + neg ebx + xor ecx, ecx + jmp @f +.hasdata: + neg ebx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: +; get current sector number + mov eax, edi + dec eax + dec eax + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp +; load sector if needed + cmp dword [esp+4], 0 ; we don't need to read uninitialized data + jz .noread + cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten + jz .noread + cmp ecx, esi ; (same for the last sector) + jz .noread + push ebx + mov ebx, buffer + call hd_read + pop ebx + cmp [hd_error], 0 + jz @f +.device_err2: + pop ecx + jmp .device_err +@@: +.noread: +; zero uninitialized data if file was extended (because hd_extend_file does not this) + push eax ecx edi + xor eax, eax + mov ecx, 0x200 + sub ecx, [esp+4+12] + jbe @f + mov edi, buffer + add edi, [esp+4+12] + rep stosb +@@: +; zero uninitialized data in the last sector + mov ecx, 0x200 + sub ecx, esi + jbe @f + mov edi, buffer + add edi, esi + rep stosb +@@: + pop edi ecx eax +; copy new data + push eax + mov eax, edx + neg ebx + jecxz @f + add ebx, buffer+0x200 + call memmove + xor ebx, ebx +@@: + pop eax +; save sector + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err2 + add edx, ecx + sub [esp], ecx + pop ecx + jz .ret +; next sector + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb @f + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .device_err +@@: + sub esi, 0x200 + jae @f + xor esi, esi +@@: + sub dword [esp], 0x200 + jae @f + and dword [esp], 0 +@@: jmp .write_loop + +hd_extend_file.zero_size: + xor eax, eax + jmp hd_extend_file.start_extend + +; extends file on hd to given size (new data area is undefined) +; in: edi->direntry, ecx=new size +; out: CF=0 => OK, eax=0 +; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) +hd_extend_file: + push ebp + mov ebp, [SECTORS_PER_CLUSTER] + imul ebp, [BYTES_PER_SECTOR] + push ecx +; find the last cluster of file + mov eax, [edi+20-2] + mov ax, [edi+26] + mov ecx, [edi+28] + jecxz .zero_size +.last_loop: + sub ecx, ebp + jbe .last_found + call get_FAT + cmp [hd_error], 0 + jz @f +.device_err: + pop ecx +.device_err2: + pop ebp + push 11 +.ret_err: + pop eax + stc + ret +@@: + cmp eax, 2 + jb .fat_err + cmp eax, [fatRESERVED] + jb .last_loop +.fat_err: + pop ecx ebp + push ERROR_FAT_TABLE + jmp .ret_err +.last_found: + push eax + call get_FAT + cmp [hd_error], 0 + jz @f + pop eax + jmp .device_err +@@: + cmp eax, [fatRESERVED] + pop eax + jb .fat_err +; set length to full number of clusters + sub [edi+28], ecx +.start_extend: + pop ecx +; now do extend + push edx + mov edx, 2 ; start scan from cluster 2 +.extend_loop: + cmp [edi+28], ecx + jae .extend_done +; add new cluster + push eax + mov eax, edx + call get_free_FAT + jc .disk_full + mov edx, [fatEND] + call set_FAT + mov edx, eax + pop eax + test eax, eax + jz .first_cluster + push edx + call set_FAT + pop edx + jmp @f +.first_cluster: + ror edx, 16 + mov [edi+20], dx + ror edx, 16 + mov [edi+26], dx +@@: + push ecx + mov ecx, -1 + call add_disk_free_space + pop ecx + mov eax, edx + cmp [hd_error], 0 + jnz .device_err3 + add [edi+28], ebp + jmp .extend_loop +.extend_done: + mov [edi+28], ecx + pop edx ebp + xor eax, eax ; CF=0 + ret +.device_err3: + pop edx + jmp .device_err2 +.disk_full: + pop eax edx ebp + push ERROR_DISK_FULL + pop eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: stc + ret + +;---------------------------------------------------------------- +; +; fs_HdSetFileEnd - set end of file on hard disk +; +; esi points to filename +; ebx points to 64-bit number = new file size +; ecx ignored (reserved) +; edx ignored (reserved) +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdSetFileEnd: + cmp [fat_type], 0 + jnz @f + push ERROR_UNKNOWN_FS +.ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +.access_denied: + push ERROR_ACCESS_DENIED + jmp .ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + push 11 + jmp .ret +@@: + popfd + jnc @f + pop edi + push ERROR_FILE_NOT_FOUND + jmp .ret +@@: +; must not be directory + test byte [edi+11], 10h + jz @f + pop edi + jmp .access_denied +@@: +; file size must not exceed 4 Gb + cmp dword [ebx+4], 0 + jz @f + pop edi + push ERROR_END_OF_FILE + jmp .ret +@@: + push eax ; save directory sector +; set file modification date/time to current + call fat_update_datetime + mov eax, [ebx] + cmp eax, [edi+28] + jb .truncate + ja .expand + pop eax + mov ebx, buffer + call hd_write + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret +.expand: + push ebx ebp ecx + push dword [edi+28] ; save old size + mov ecx, eax + call hd_extend_file + push eax ; return code + jnc .expand_ok + cmp al, ERROR_DISK_FULL + jz .disk_full +.pop_ret: + call update_disk + pop eax ecx ebp ebx ecx edi edi + ret +.expand_ok: +.disk_full: +; save directory + mov eax, [edi+28] + xchg eax, [esp+20] + mov ebx, buffer + call hd_write + mov eax, [edi+20-2] + mov ax, [edi+26] + mov edi, eax + cmp [hd_error], 0 + jz @f +.pop_ret11: + mov byte [esp], 11 + jmp .pop_ret +@@: +; now zero new data + xor ebp, ebp +; edi=current cluster, ebp=sector in cluster +; [esp+20]=new size, [esp+4]=old size, [esp]=return code +.zero_loop: + sub dword [esp+4], 0x200 + jae .next_cluster + lea eax, [edi-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ebp + cmp dword [esp+4], -0x200 + jz .noread + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err_next +.noread: + mov ecx, [esp+4] + neg ecx + push edi + mov edi, buffer+0x200 + add edi, [esp+8] + push eax + xor eax, eax + mov [esp+12], eax + rep stosb + pop eax + pop edi + call hd_write + cmp [hd_error], 0 + jz .next_cluster +.err_next: + mov byte [esp], 11 +.next_cluster: + sub dword [esp+20], 0x200 + jbe .pop_ret + inc ebp + cmp ebp, [SECTORS_PER_CLUSTER] + jb .zero_loop + xor ebp, ebp + mov eax, edi + call get_FAT + mov edi, eax + cmp [hd_error], 0 + jnz .pop_ret11 + jmp .zero_loop +.truncate: + mov [edi+28], eax + push ecx + mov ecx, [edi+20-2] + mov cx, [edi+26] + push eax + test eax, eax + jz .zero_size +; find new last cluster +@@: + mov eax, [SECTORS_PER_CLUSTER] + shl eax, 9 + sub [esp], eax + jbe @f + mov eax, ecx + call get_FAT + mov ecx, eax + cmp [hd_error], 0 + jz @b +.device_err3: + pop eax ecx eax edi + push 11 + pop eax + ret +@@: +; we will zero data at the end of last sector - remember it + push ecx +; terminate FAT chain + push edx + mov eax, ecx + mov edx, [fatEND] + call set_FAT + mov eax, edx + pop edx + cmp [hd_error], 0 + jz @f +.device_err4: + pop ecx + jmp .device_err3 +.zero_size: + and word [edi+20], 0 + and word [edi+26], 0 + push 0 + mov eax, ecx +@@: +; delete FAT chain + call clear_cluster_chain + cmp [hd_error], 0 + jnz .device_err4 +; save directory + mov eax, [esp+12] + push ebx + mov ebx, buffer + call hd_write + pop ebx + cmp [hd_error], 0 + jnz .device_err4 +; zero last sector, ignore errors + pop ecx + pop eax + dec ecx + imul ecx, [SECTORS_PER_CLUSTER] + add ecx, [DATA_START] + push eax + sar eax, 9 + add ecx, eax + pop eax + and eax, 0x1FF + jz .truncate_done + push ebx eax + mov eax, ecx + mov ebx, buffer + call hd_read + pop eax + lea edi, [buffer+eax] + push ecx + mov ecx, 0x200 + sub ecx, eax + xor eax, eax + rep stosb + pop eax + call hd_write + pop ebx +.truncate_done: + pop ecx eax edi + call update_disk + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret + +fs_HdGetFileInfo: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jmp fs_GetFileInfo_finish + +fs_HdSetFileInfo: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi + call hd_find_lfn + pushfd + cmp [hd_error], 0 + jz @f + popfd + pop edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + push eax + call bdfe_to_fat_entry + pop eax + mov ebx, buffer + call hd_write + call update_disk + pop edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_HdExecute - LFN variant for executing from harddisk +; +; esi points to hd filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/hd0/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_HdExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_HdExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp [fat_type], 0 + jnz @f + mov eax, ERROR_UNKNOWN_FS + ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call hd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + cmp [hd_error], 0 + jz @f + mov al, -11 +@@: + ret +.found: + mov eax, [edi+20-2] + mov ax, [edi+26] + push 0 + push eax + push dword [edi+28] ; size + push .DoRead + call fs_execute + add esp, 16 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + add eax, 4 + call fat_get_sector + mov ebx, edi + call hd_read + cmp [hd_error], 0 + jnz .err + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + lea edi, [edi+ecx+512] + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+8] + inc edx + cmp edx, [SECTORS_PER_CLUSTER] + jb @f + push eax + mov eax, [eax+4] + call get_FAT + cmp [hd_error], 0 + jnz .err + mov ecx, eax + pop eax + mov [eax+4], ecx + xor edx, edx +@@: + mov [eax+8], edx + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + +; \end{diamond} diff --git a/kernel/tags/kolibri0.6.0.0/fs/fs.inc b/kernel/tags/kolibri0.6.0.0/fs/fs.inc new file mode 100644 index 0000000000..449c385833 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/fs.inc @@ -0,0 +1,939 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; System service for filesystem call ;; +;; (C) 2004 Ville Turjanmaa, License: GPL ;; +;; 29.04.2006 Elimination of hangup after the ;; +;; expiration hd_wait_timeout (for LBA) - Mario79 ;; +;; xx.04.2006 LFN support - diamond ;; +;; 15.01.2005 get file size/attr/date, file_append (only for hd) - ATV ;; +;; 23.11.2004 test if hd/partition is set - ATV ;; +;; 18.11.2004 get_disk_info and more error codes - ATV ;; +;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;; +;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +iglobal +dir0: db 'HARDDISK ' + db 'RAMDISK ' + db 'FLOPPYDISK ' + db 0 + +dir1: db 'FIRST ' + db 'SECOND ' + db 'THIRD ' + db 'FOURTH ' + db 0 + +not_select_IDE db 0 + +hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 + dd 0x170,0x00,0x170,0x10 +endg + +file_system: + +; IN: +; +; eax = 0 ; read file /RamDisk/First 6 +; eax = 1 ; write file /RamDisk/First 33 /HardDisk/First 56 +; eax = 2 ; delete file /RamDisk/First 32 +; eax = 4 ; makedir +; eax = 5 ; rename file/directory +; eax = 8 ; lba read +; eax = 15 ; get_disk_info +; +; OUT: +; +; eax = 0 : read ok +; eax = 1 : no hd base and/or partition defined +; eax = 2 : function is unsupported for this FS +; eax = 3 : unknown FS +; eax = 4 : partition not defined at hd +; eax = 5 : file not found +; eax = 6 : end of file +; eax = 7 : memory pointer not in application area +; eax = 8 : disk full +; eax = 9 : fat table corrupted +; eax = 10 : access denied +; eax = 11 : disk error +; +; ebx = size + +; \begin{diamond}[18.03.2006] +; for subfunction 16 (start application) error codes must be negative +; because positive values are valid PIDs +; so possible return values are: +; eax > 0 : process created, eax=PID + +; -0x10 <= eax < 0 : -eax is filesystem error code: +; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined +; eax = -3 = 0xFFFFFFFD : unknown FS +; eax = -5 = 0xFFFFFFFB : file not found +; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file) +; eax = -9 = 0xFFFFFFF7 : fat table corrupted +; eax = -10 = 0xFFFFFFF6 : access denied + +; -0x20 <= eax < -0x10: eax is process creation error code: +; eax = -0x20 = 0xFFFFFFE0 : too many processes +; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable +; eax = -0x1E = 0xFFFFFFE2 : no memory + +; ebx is not changed + +; \end{diamond}[18.03.2006] + + ; Extract parameters + add eax, std_application_base_address ; abs start of info block + + cmp dword [eax+0],15 ; GET_DISK_INFO + je fs_info + cmp dword [eax+0],5 ; RENAME - dont care about read&write blocks + je fs_read + cmp dword [eax+0],4 ; MAKEDIR - dont care about read&write blocks + je fs_read + cmp dword [eax+0],2 ; DELETE - dont care about read&write blocks + je fs_read + + cmp dword [0x3000],1 ; no memory checks for kernel requests + jz no_checks_for_kernel + mov edx,eax + cmp dword [eax+0],1 + jnz .usual_check + mov ebx,[eax+12] + add ebx,std_application_base_address + mov ecx,[eax+8] + call check_region + test eax,eax + jnz area_in_app_mem + +.error_output: + mov esi,buffer_failed + call sys_msg_board_str +; mov eax,7 + mov dword [esp+36],7 + ret +iglobal + buffer_failed db 'K : Buffer check failed',13,10,0 +endg +.usual_check: + cmp dword [eax+0],0 + mov ecx,512 + jnz .small_size + mov ecx,[eax+8] + shl ecx,9 +.small_size: + mov ebx,[eax+12] + add ebx,std_application_base_address + call check_region + test eax,eax + jz .error_output + area_in_app_mem: + mov eax,edx + no_checks_for_kernel: + + fs_read: + + mov ebx,[eax+20] ; program wants root directory ? + test bl,bl + je fs_getroot + test bh,bh + jne fs_noroot + fs_getroot: +; \begin{diamond}[18.03.2006] +; root - only read is allowed +; other operations return "access denied", eax=10 +; (execute operation returns eax=-10) + cmp dword [eax], 0 + jz .read_root + mov dword [esp+36], 10 + ret +.read_root: +; \end{diamond}[18.03.2006] + mov esi,dir0 + mov edi,[eax+12] + add edi,std_application_base_address + mov ecx,11 + push ecx +; cld ; already is + rep movsb + mov al,0x10 + stosb + add edi,32-11-1 + pop ecx + rep movsb + stosb + and dword [esp+36],0 ; ok read + mov dword [esp+24],32*2 ; size of root + ret + + fs_info: ;start of code - Mihasik + push eax + cmp [eax+21],byte 'h' + je fs_info_h + cmp [eax+21],byte 'H' + je fs_info_h + cmp [eax+21],byte 'r' + je fs_info_r + cmp [eax+21],byte 'R' + je fs_info_r + mov eax,3 ;if unknown disk + xor ebx,ebx + xor ecx,ecx + xor edx,edx + jmp fs_info1 + fs_info_r: + call ramdisk_free_space ;if ramdisk + mov ecx,edi ;free space in ecx + shr ecx,9 ;free clusters + mov ebx,2847 ;total clusters + mov edx,512 ;cluster size + xor eax,eax ;always 0 + jmp fs_info1 + fs_info_h: ;if harddisk + call get_hd_info + fs_info1: + pop edi + mov [esp+36],eax + mov [esp+24],ebx ; total clusters on disk + mov [esp+32],ecx ; free clusters on disk + mov [edi],edx ; cluster size in bytes + ret ;end of code - Mihasik + + fs_noroot: + + push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run + push dword [eax+4] ; 512 block number to read + push dword [eax+8] ; bytes to write/append or 512 blocks to read + mov ebx,[eax+12] + add ebx,std_application_base_address + push ebx ; abs start of return/save area + + lea esi,[eax+20] ; abs start of dir + filename + mov edi,[eax+16] + add edi,std_application_base_address ; abs start of work area + + call expand_pathz + + push edi ; dir start + push ebx ; name of file start + + mov eax,[edi+1] + cmp eax,'RD ' + je fs_yesramdisk + cmp eax,'RAMD' + jne fs_noramdisk + + fs_yesramdisk: + + cmp byte [edi+1+11],0 + je fs_give_dir1 + + mov eax,[edi+1+12] + cmp eax,'1 ' + je fs_yesramdisk_first + cmp eax,'FIRS' + jne fs_noramdisk + + fs_yesramdisk_first: + + cmp dword [esp+20],8 ; LBA read ramdisk + jne fs_no_LBA_read_ramdisk + + mov eax,[esp+16] ; LBA block to read + mov ecx,[esp+8] ; abs pointer to return area + + call LBA_read_ramdisk + jmp file_system_return + + + fs_no_LBA_read_ramdisk: + + cmp dword [esp+20],0 ; READ + jne fs_noramdisk_read + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+16] ; block start + inc ebx + mov ecx,[esp+12] ; block count + mov edx,[esp+8] ; return + mov esi,[esp+0] + sub esi,eax + add esi,12+1 ; file name length + call fileread + + jmp file_system_return + + + fs_noramdisk_read: + + cmp dword [esp+20],1 ; WRITE + jne fs_noramdisk_write + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+8] ; buffer + mov ecx,[esp+12] ; count to write + mov edx,0 ; create new + call filesave + + ; eax=0 ok - eax=1 not enough free space + + jmp file_system_return + + fs_noramdisk_write: + + cmp dword [esp+20],2 ;DELETE + jne fs_noramdisk_delete + mov eax,[esp+4] ; fname + add eax,2*12+1 + call filedelete + jmp file_system_return + + fs_noramdisk_delete: + fs_noramdisk: + + ;******************************************************************** + mov eax,[edi+1] + cmp eax,'FD ' + je fs_yesflpdisk + cmp eax,'FLOP' + jne fs_noflpdisk + + fs_yesflpdisk: + call reserve_flp + + cmp byte [edi+1+11],0 + je fs_give_dir1 + + mov eax,[edi+1+12] + cmp eax,'1 ' + je fs_yesflpdisk_first + cmp eax,'FIRS' + je fs_yesflpdisk_first + cmp eax,'2 ' + je fs_yesflpdisk_second + cmp eax,'SECO' + jne fs_noflpdisk + jmp fs_yesflpdisk_second + + fs_yesflpdisk_first: + mov [flp_number],1 + jmp fs_yesflpdisk_start + fs_yesflpdisk_second: + mov [flp_number],2 + fs_yesflpdisk_start: + cmp dword [esp+20],0 ; READ + jne fs_noflpdisk_read + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+16] ; block start + inc ebx + mov ecx,[esp+12] ; block count + mov edx,[esp+8] ; return + mov esi,[esp+0] + sub esi,eax + add esi,12+1 ; file name length + call floppy_fileread + + jmp file_system_return + + + fs_noflpdisk_read: + + cmp dword [esp+20],1 ; WRITE + jne fs_noflpdisk_write + + mov eax,[esp+4] ; fname + add eax,2*12+1 + mov ebx,[esp+8] ; buffer + mov ecx,[esp+12] ; count to write + mov edx,0 ; create new + call floppy_filesave + + ; eax=0 ok - eax=1 not enough free space + + jmp file_system_return + + fs_noflpdisk_write: + + cmp dword [esp+20],2 ; DELETE + jne fs_noflpdisk_delete + + mov eax,[esp+4] ; fname + add eax,2*12+1 + call floppy_filedelete + mov [flp_status],0 + jmp file_system_return + + fs_noflpdisk_delete: + + fs_noflpdisk: + ;***************************************************************** + + mov eax,[edi+1] + cmp eax,'HD0 ' + je fs_yesharddisk_IDE0 + cmp eax,'HD1 ' + je fs_yesharddisk_IDE1 + cmp eax,'HD2 ' + je fs_yesharddisk_IDE2 + cmp eax,'HD3 ' + je fs_yesharddisk_IDE3 + jmp old_path_harddisk +fs_yesharddisk_IDE0: + call reserve_hd1 + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE1: + call reserve_hd1 + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE2: + call reserve_hd1 + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 + jmp fs_yesharddisk_partition +fs_yesharddisk_IDE3: + call reserve_hd1 + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 +fs_yesharddisk_partition: +; call choice_necessity_partition +; jmp fs_yesharddisk_all + jmp fs_for_new_semantic + +choice_necessity_partition: + mov eax,[edi+1+12] + call StringToNumber + mov [fat32part],eax +choice_necessity_partition_1: + mov ecx,[hdpos] + xor eax,eax + mov [0xfe10], eax ; entries in hd cache + mov edx,0x40002 + search_partition_array: + mov bl,[edx] + movzx ebx,bl + add eax,ebx + inc edx + loop search_partition_array + sub eax,ebx + add eax,[fat32part] + dec eax + xor edx,edx + imul eax,100 + add eax,0x4000a + mov [transfer_adress],eax + call partition_data_transfer_1 + ret + + old_path_harddisk: + mov eax,[edi+1] + cmp eax,'HD ' + je fs_yesharddisk + cmp eax,'HARD' + jne fs_noharddisk + + fs_yesharddisk: + cmp dword [esp+20],8 ; LBA read + jne fs_no_LBA_read + mov eax,[esp+16] ; LBA block to read + lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH + mov ecx,[esp+8] ; abs pointer to return area + call LBA_read + jmp file_system_return + + fs_no_LBA_read: + + cmp byte [edi+1+11],0 ; directory read + je fs_give_dir1 + call reserve_hd1 + fs_for_new_semantic: + call choice_necessity_partition + + fs_yesharddisk_all: + mov eax,1 + mov ebx, [esp+24+24] + cmp [hdpos],0 ; is hd base set? + jz hd_err_return + cmp [fat32part],0 ; is partition set? + jnz @f +hd_err_return: + and [hd1_status], 0 + jmp file_system_return +@@: + + cmp dword [esp+20],0 ; READ + jne fs_noharddisk_read + + mov eax,[esp+0] ; /fname + lea edi,[eax+12] + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + + mov ebx,[esp+12] ; count to read + mov ecx,[esp+8] ; buffer + mov edx,[esp+4] + add edx,12*2 ; dir start + sub edi,edx ; path length + mov esi,[esp+16] ; blocks to read + + call file_read + + mov edi,[esp+0] + mov byte [edi],'/' + + jmp file_system_return + + fs_noharddisk_read: + + + cmp dword [esp+20],1 ; WRITE + jne fs_noharddisk_write + + mov eax,[esp+0] ; /fname + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + + mov ebx,[esp+12] ; count to write + mov ecx,[esp+8] ; buffer + mov edx,[esp+4] + add edx,12*2 ; path start + + call file_write + + mov edi,[esp+0] + mov byte [edi],'/' + + ; eax=0 ok - eax=1 not enough free space + + jmp file_system_return + + + fs_noharddisk_write: + + cmp dword [esp+20],2 ; DELETE + jne fs_noharddisk_delete + + mov eax,[esp+0] ; /dirname or /filename + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + mov edx,[esp+4] + add edx,12*2 ; path start + + call removedir + + mov edi,[esp+0] + mov byte [edi],'/' + + jmp file_system_return + + fs_noharddisk_delete: + + cmp dword [esp+20],4 ; MAKEDIR + jne fs_noharddisk_makedir + + mov eax,[esp+0] ; /dirname + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + mov edx,[esp+4] + add edx,12*2 ; path start + + call makedir + + mov edi,[esp+0] + mov byte [edi],'/' + + jmp file_system_return + + fs_noharddisk_makedir: + + cmp dword [esp+20],5 ; RENAME + jne fs_noharddisk_rename + + mov edi,[esp+0] ; start of source file name + add edi,12+1 ; continue after name + call expand_pathz ; convert destination name + + mov eax,[edi+1] + cmp eax,'HD ' + je fs_rename_test1 + cmp eax,'HARD' + jne fs_rename_error + + fs_rename_test1: + mov eax,[edi+1+12] + cmp eax,'1 ' + je fs_rename_start + cmp eax,'FIRS' + jne fs_rename_error + + fs_rename_start: + mov byte [ebx],0 ; path to asciiz + inc ebx ; filename start + add edi,12*2 ; path start + cmp byte [ebx],0 + je fs_rename_error + cmp byte [ebx],32 + je fs_rename_error + + mov eax,[esp+0] ; /filename + mov byte [eax],0 ; path to asciiz + inc eax ; filename start + mov edx,[esp+4] + add edx,12*2 ; path start + + call rename + + mov edi,[esp+0] + mov byte [edi],'/' + + jmp file_system_return + + fs_rename_error: + mov eax,4 ; partition not defined at hd + jmp file_system_return + + fs_noharddisk_rename: + + 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] + + file_system_return: + + add esp,24 + + mov [esp+36],eax + mov [esp+24],ebx + ret + + + fs_give_dir1: + +; \begin{diamond}[18.03.2006] +; /RD,/FD,/HD - only read is allowed +; other operations return "access denied", eax=10 +; (execute operation returns eax=-10) + cmp dword [esp+20], 0 + jz .read + add esp, 20 + pop ecx + mov dword [esp+36], 10 + ret +.read: +; \end{diamond}[18.03.2006] + mov al,0x10 + mov ebx,1 + mov edi,[esp+8] + mov esi,dir1 + fs_d1_new: + mov ecx,11 +; cld + rep movsb + stosb + add edi,32-11-1 + dec ebx + jne fs_d1_new + + add esp,24 + + and dword [esp+36],0 ; ok read + mov dword [esp+24],32*1 ; dir/data size + ret + + + +LBA_read_ramdisk: + + cmp [lba_read_enabled],1 + je lbarrl1 + + xor ebx,ebx + mov eax,2 + ret + + lbarrl1: + + cmp eax,18*2*80 + jb lbarrl2 + xor ebx,ebx + mov eax,3 + ret + + lbarrl2: + + pushad + + call restorefatchain + + mov edi,ecx + mov esi,eax + + shl esi,9 + add esi,0x100000 + mov ecx,512/4 +; cld + rep movsd + + popad + + xor ebx,ebx + xor eax,eax + ret + +LBA_read: + +; IN: +; +; eax = LBA block to read +; ebx = pointer to FIRST/SECOND/THIRD/FOURTH +; ecx = abs pointer to return area + + cmp [lba_read_enabled],1 + je lbarl1 + mov eax,2 + ret + + lbarl1: + + call reserve_hd1 + + push eax + push ecx + + mov edi,hd_address_table + mov esi,dir1 + mov eax,[ebx] + mov edx,'1 ' + mov ecx,4 + blar0: + cmp eax,[esi] + je blar2 + cmp eax,edx + je blar2 + inc edx + add edi,8 + add esi,11 + dec ecx + jnz blar0 + + mov eax,1 + mov ebx,1 + jmp LBA_read_ret + + blar2: + mov eax,[edi+0] + mov ebx,[edi+4] + + mov [hdbase],eax + mov [hdid],ebx + + call wait_for_hd_idle + cmp [hd_error],0 + jne hd_lba_error + + ; eax = hd port + ; ebx = set for primary (0x00) or slave (0x10) + + cli + + mov edx,eax + inc edx + xor eax,eax + out dx,al + inc edx + inc eax + out dx,al + inc edx + mov eax,[esp+4] + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + and al,1+2+4+8 + add al,bl + add al,128+64+32 + out dx,al + + inc edx + mov al,20h + out dx,al + + sti + + call wait_for_sector_buffer + cmp [hd_error],0 + jne hd_lba_error + + cli + + mov edi,[esp+0] + mov ecx,256 + sub edx,7 + cld + rep insw + + sti + + xor eax,eax + xor ebx,ebx + + LBA_read_ret: + mov [hd_error],0 + mov [hd1_status],0 + add esp,2*4 + + ret + + +expand_pathz: +; IN: +; esi = asciiz path & file +; edi = buffer for path & file name +; OUT: +; edi = directory & file : / 11 + / 11 + / 11 - zero terminated +; ebx = /file name - zero terminated +; esi = pointer after source + + push eax + push ecx + push edi ;[esp+0] + + pathz_start: + mov byte [edi],'/' + inc edi + mov al,32 + mov ecx,11 + cld + rep stosb ; clear filename area + sub edi,11 + mov ebx,edi ; start of dir/file name + + pathz_new_char: + mov al,[esi] + inc esi + cmp al,0 + je pathz_end + + cmp al,'/' + jne pathz_not_path + cmp edi,ebx ; skip first '/' + jz pathz_new_char + lea edi,[ebx+11] ; start of next directory + jmp pathz_start + + pathz_not_path: + cmp al,'.' + jne pathz_not_ext + lea edi,[ebx+8] ; start of extension + jmp pathz_new_char + + pathz_not_ext: + cmp al,'a' + jb pathz_not_low + cmp al,'z' + ja pathz_not_low + sub al,0x20 ; char to uppercase + + pathz_not_low: + mov [edi],al + inc edi + mov eax,[esp+0] ; start_of_dest_path + add eax,512 ; keep maximum path under 512 bytes + cmp edi,eax + jb pathz_new_char + + pathz_end: + cmp ebx,edi ; if path end with '/' + jnz pathz_put_zero ; go back 1 level + sub ebx,12 + + pathz_put_zero: + mov byte [ebx+11],0 + dec ebx ; include '/' char into file name + pop edi + pop ecx + pop eax + ret + +;******************************************* +;* string to number +;* input eax - 4 byte string +;* output eax - number +;******************************************* +StringToNumber: +; ПЕРЕВОД СТРОКОВОГО ЧИСЛА В ЧИСЛОВОЙ ВИД +; Вход: +; EDI - адрес строки с числом. Конец числа отмечен кодом 0Dh +; Выход: +; CF - индикатор ошибок: +; 0 - ошибок нет; +; 1 - ошибка +; Если CF=0, то AX - число. + + push bx + push cx + push dx + push edi + mov [partition_string],eax + mov edi,partition_string + xor cx,cx +i1: + mov al,[edi] + cmp al,32 ;13 + je i_exit +; cmp al,'0' +; jb err +; cmp al,'9' +; ja err + sub al,48 + shl cx,1 + jc err + mov bx,cx + shl cx,1 + jc err + shl cx,1 + jc err + add cx,bx + jc err + cbw + add cx,ax + jc err +i3: + inc edi + jmp i1 +i_exit: + mov ax,cx + clc +i4: + movzx eax,ax + pop edi + pop dx + pop cx + pop bx + ret + +err: + stc + jmp i4 + +partition_string: dd 0 + db 32 diff --git a/kernel/tags/kolibri0.6.0.0/fs/fs_lfn.inc b/kernel/tags/kolibri0.6.0.0/fs/fs_lfn.inc new file mode 100644 index 0000000000..8890209800 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/fs_lfn.inc @@ -0,0 +1,661 @@ +; System function 70 - files with long names (LFN) +; diamond, 2006 + +iglobal +; in this table names must be in lowercase +rootdirs: + db 2,'rd' + dd fs_OnRamdisk + dd fs_NextRamdisk + db 7,'ramdisk' + dd fs_OnRamdisk + dd fs_NextRamdisk + db 2,'fd' + dd fs_OnFloppy + dd fs_NextFloppy + db 10,'floppydisk' + dd fs_OnFloppy + dd fs_NextFloppy + db 3,'hd0' + dd fs_OnHd0 + dd fs_NextHd0 + db 3,'hd1' + dd fs_OnHd1 + dd fs_NextHd1 + db 3,'hd2' + dd fs_OnHd2 + dd fs_NextHd2 + db 3,'hd3' + dd fs_OnHd3 + dd fs_NextHd3 +;********************************************** + db 3,'cd0' + dd fs_OnCd0 + dd fs_NextCd + db 3,'cd1' + dd fs_OnCd1 + dd fs_NextCd + db 3,'cd2' + dd fs_OnCd2 + dd fs_NextCd + db 3,'cd3' + dd fs_OnCd3 + dd fs_NextCd +;*********************************************** + db 0 + + +virtual_root_query: + dd fs_HasRamdisk + db 'rd',0 + dd fs_HasFloppy + db 'fd',0 + dd fs_HasHd0 + db 'hd0',0 + dd fs_HasHd1 + db 'hd1',0 + dd fs_HasHd2 + db 'hd2',0 + dd fs_HasHd3 + db 'hd3',0 +;********************************************** + dd fs_HasCd0 + db 'cd0',0 + dd fs_HasCd1 + db 'cd1',0 + dd fs_HasCd2 + db 'cd2',0 + dd fs_HasCd3 + db 'cd3',0 +;********************************************** + dd 0 +endg + +file_system_lfn: +; in: eax->fileinfo block +; operation codes: +; 0 : read file +; 1 : read folder +; 2 : create/rewrite file +; 3 : write/append to file +; 4 : set end of file +; 5 : get file/directory attributes structure +; 6 : set file/directory attributes structure +; 7 : start application +; 8 : delete file - not implemented yet +; 9 : create directory - not implemented yet +; 10: rename file/directory - not implemented yet + + add eax, std_application_base_address +; parse file name + xchg ebx, eax + lea esi, [ebx+20] + mov ebp, esi ; for 'start app' function full path must be known + lodsb + test al, al + jnz @f + mov esi, [esi] + add esi, std_application_base_address + mov ebp, esi + lodsb +@@: + cmp al, '/' + jz @f +.notfound: + mov dword [esp+36], 5 ; file not found + ret +@@: + cmp byte [esi], 0 + jz .rootdir + mov edi, rootdirs-8 + xor ecx, ecx + push esi +.scan1: + pop esi + add edi, ecx + scasd + scasd + mov cl, byte [edi] + jecxz .notfound + inc edi + push esi +@@: + lodsb + or al, 20h + scasb + loopz @b + jnz .scan1 + lodsb + cmp al, '/' + jz .found1 + test al, al + jnz .scan1 + pop eax +; directory /xxx +.maindir: + cmp dword [ebx], 1 + jnz .access_denied + xor eax, eax + mov ebp, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + push dword [ebx+4] ; first block + mov ebx, [ebx+8] ; flags + mov esi, [edi+4] +; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler + mov edi, edx + mov ecx, 32/4 + rep stosd + mov byte [edx], 1 ; version +.maindir_loop: + call esi + jc .maindir_done + inc dword [edx+8] + dec dword [esp] + jns .maindir_loop + dec ebp + js .maindir_loop + inc dword [edx+4] + mov dword [edi], 0x10 ; attributes: folder + mov dword [edi+4], 1 ; name type: UNICODE + push eax + xor eax, eax + add edi, 8 + mov ecx, 40/4-2 + rep stosd + pop eax + push eax edx +; convert number in eax to decimal UNICODE string + push edi + push -'0' + mov cl, 10 +@@: + xor edx, edx + div ecx + push edx + test eax, eax + jnz @b +@@: + pop eax + add al, '0' + stosb + test bl, 1 ; UNICODE name? + jz .ansi2 + mov byte [edi], 0 + inc edi +.ansi2: + test al, al + jnz @b + mov byte [edi-1], 0 + pop edi +; UNICODE name length is 520 bytes, ANSI - 264 + add edi, 520 + test bl, 1 + jnz @f + sub edi, 520-264 +@@: + pop edx eax + jmp .maindir_loop +.maindir_done: + pop eax + mov ebx, [edx+4] + xor eax, eax + dec ebp + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+36], eax + mov [esp+24], ebx + ret +; directory / +.rootdir: + cmp dword [ebx], 1 ; read folder? + jz .readroot +.access_denied: + mov dword [esp+36], 10 ; access denied + ret + +.readroot: +; virtual root folder - special handler + mov esi, virtual_root_query + mov ebp, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + push dword [ebx+4] ; first block + mov ebx, [ebx+8] ; flags + xor eax, eax +; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area + mov edi, edx + mov ecx, 32/4 + rep stosd + mov byte [edx], 1 ; version +.readroot_loop: + cmp dword [esi], eax + jz .readroot_done + call dword [esi] + add esi, 4 + test eax, eax + jnz @f +.readroot_next: + or ecx, -1 + xchg esi, edi + repnz scasb + xchg esi, edi + jmp .readroot_loop +@@: + xor eax, eax + inc dword [edx+8] + dec dword [esp] + jns .readroot_next + dec ebp + js .readroot_next + inc dword [edx+4] + mov dword [edi], 0x10 ; attributes: folder + mov dword [edi+4], 1 ; name type: UNICODE + add edi, 8 + mov ecx, 40/4-2 + rep stosd + push edi +@@: + lodsb + stosb + test bl, 1 + jz .ansi + mov byte [edi], 0 + inc edi +.ansi: + test eax, eax + jnz @b + pop edi + add edi, 520 + test bl, 1 + jnz .readroot_loop + sub edi, 520-264 + jmp .readroot_loop +.readroot_done: + pop eax + mov ebx, [edx+4] + xor eax, eax + dec ebp + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+36], eax + mov [esp+24], ebx + ret + +.found1: + pop eax + cmp byte [esi], 0 + jz .maindir +; read partition number + xor ecx, ecx + xor eax, eax +@@: + lodsb + cmp al, '/' + jz .done1 + test al, al + jz .done1 + sub al, '0' + cmp al, 9 + ja .notfound + imul ecx, 10 + add ecx, eax + jmp @b +.done1: + test ecx, ecx + jz .notfound + test al, al + jnz @f + dec esi +@@: +; now [edi] contains handler address, ecx - partition number, +; esi points to ASCIIZ string - rest of name + jmp dword [edi] + +; handlers for devices +; in: ecx = 0 => query virtual directory /xxx +; in: ecx = partition number +; esi -> relative (for device) name +; ebx -> fileinfo +; out: [esp+36]=image of eax, [esp+24]=image of ebx + +fs_OnRamdisk: + cmp ecx, 1 + jnz file_system_lfn.notfound + mov eax, [ebx] + cmp eax, fs_NumRamdiskServices + jae .not_impl + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + add ebx, 4 + call dword [fs_RamdiskServices + eax*4] + mov [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + mov dword [esp+36], 2 ; not implemented + ret + +fs_NotImplemented: + mov eax, 2 + ret + +fs_RamdiskServices: + dd fs_RamdiskRead + dd fs_RamdiskReadFolder + dd fs_RamdiskRewrite + dd fs_RamdiskWrite + dd fs_RamdiskSetFileEnd + dd fs_RamdiskGetFileInfo + dd fs_RamdiskSetFileInfo + dd fs_RamdiskExecute +fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 + +fs_OnFloppy: + cmp ecx, 2 + ja file_system_lfn.notfound + mov eax, [ebx] + cmp eax, fs_NumFloppyServices + jae fs_OnRamdisk.not_impl + call reserve_flp + mov [flp_number], cl + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + add ebx, 4 + call dword [fs_FloppyServices + eax*4] + and [flp_status], 0 + mov [esp+36], eax + mov [esp+24], ebx + ret + +fs_FloppyServices: + dd fs_FloppyRead + dd fs_FloppyReadFolder + dd fs_FloppyRewrite + dd fs_FloppyWrite + dd fs_FloppySetFileEnd + dd fs_FloppyGetFileInfo + dd fs_FloppySetFileInfo + dd fs_FloppyExecute +fs_NumFloppyServices = ($ - fs_FloppyServices)/4 + +fs_OnHd0: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0 + push 1 + jmp fs_OnHd +fs_OnHd1: + call reserve_hd1 + mov [hdbase], 0x1F0 + mov [hdid], 0x10 + push 2 + jmp fs_OnHd +fs_OnHd2: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0 + push 3 + jmp fs_OnHd +fs_OnHd3: + call reserve_hd1 + mov [hdbase], 0x170 + mov [hdid], 0x10 + push 4 +fs_OnHd: + call reserve_hd_channel + pop eax + mov [hdpos], eax + cmp ecx, 0x100 + jae .nf + cmp cl, [0x40001+eax] + jbe @f +.nf: + call free_hd_channel + and [hd1_status], 0 + mov dword [esp+36], 5 ; not found + ret +@@: + mov [fat32part], ecx + push ebx esi + call choice_necessity_partition_1 + pop esi ebx + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + mov eax, [ebx] + cmp eax, fs_NumHdServices + jae .not_impl + add ebx, 4 + call dword [fs_HdServices + eax*4] + call free_hd_channel + and [hd1_status], 0 + mov [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + call free_hd_channel + and [hd1_status], 0 + mov dword [esp+36], 2 ; not implemented + ret + +fs_HdServices: + dd fs_HdRead + dd fs_HdReadFolder + dd fs_HdRewrite + dd fs_HdWrite + dd fs_HdSetFileEnd + dd fs_HdGetFileInfo + dd fs_HdSetFileInfo + dd fs_HdExecute +fs_NumHdServices = ($ - fs_HdServices)/4 + +;******************************************************* +fs_OnCd0: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],0 + push 6 + jmp fs_OnCd +fs_OnCd1: + call reserve_cd + mov [ChannelNumber],1 + mov [DiskNumber],1 + push 4 + jmp fs_OnCd +fs_OnCd2: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],0 + push 2 + jmp fs_OnCd +fs_OnCd3: + call reserve_cd + mov [ChannelNumber],2 + mov [DiskNumber],1 + push 0 +fs_OnCd: + call reserve_cd_channel + pop eax + mov [hdpos], eax + cmp ecx, 0x100 + jae .nf + push ecx ebx + mov cl,al + mov bl,[0x40001] + shr bl,cl + test bl,2 + pop ebx ecx + + jnz @f +.nf: + call free_cd_channel + and [cd_status], 0 + mov dword [esp+36], 5 ; not found + ret +@@: + mov ecx, [ebx+12] + mov edx, [ebx+16] + add edx, std_application_base_address + mov eax, [ebx] + cmp eax,fs_NumCdServices + jae .not_impl + add ebx, 4 + call dword [fs_CdServices + eax*4] + call free_cd_channel + and [cd_status], 0 + mov [esp+36], eax + mov [esp+24], ebx + ret +.not_impl: + call free_cd_channel + and [cd_status], 0 + mov dword [esp+36], 2 ; not implemented + ret + +fs_CdServices: + dd fs_CdRead + dd fs_CdReadFolder + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_NotImplemented + dd fs_CdGetFileInfo + dd fs_NotImplemented + dd fs_CdExecute +fs_NumCdServices = ($ - fs_CdServices)/4 + +;******************************************************* + +fs_HasRamdisk: + mov al, 1 ; we always have ramdisk + ret + +fs_HasFloppy: + cmp byte [0x40000], 0 + setnz al + ret + +fs_HasHd0: + mov al, [0x40001] + and al, 11000000b + cmp al, 01000000b + setz al + ret +fs_HasHd1: + mov al, [0x40001] + and al, 00110000b + cmp al, 00010000b + setz al + ret +fs_HasHd2: + mov al, [0x40001] + and al, 00001100b + cmp al, 00000100b + setz al + ret +fs_HasHd3: + mov al, [0x40001] + and al, 00000011b + cmp al, 00000001b + setz al + ret + +;******************************************************* +fs_HasCd0: + mov al, [0x40001] + and al, 11000000b + cmp al, 10000000b + setz al + ret +fs_HasCd1: + mov al, [0x40001] + and al, 00110000b + cmp al, 00100000b + setz al + ret +fs_HasCd2: + mov al, [0x40001] + and al, 00001100b + cmp al, 00001000b + setz al + ret +fs_HasCd3: + mov al, [0x40001] + and al, 00000011b + cmp al, 00000010b + setz al + ret +;******************************************************* + +; fs_NextXXX functions: +; in: eax = partition number, from which start to scan +; out: CF=1 => no more partitions +; CF=0 => eax=next partition number + +fs_NextRamdisk: +; we always have /rd/1 + test eax, eax + stc + jnz @f + mov al, 1 + clc +@@: + ret + +fs_NextFloppy: +; we have /fd/1 iff (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0) + test byte [0x40000], 0xF0 + jz .no1 + test eax, eax + jnz .no1 + inc eax + ret ; CF cleared +.no1: + test byte [0x40000], 0x0F + jz .no2 + cmp al, 2 + jae .no2 + mov al, 2 + clc + ret +.no2: + stc + ret + +; on hdx, we have partitions from 1 to [0x40002+x] +fs_NextHd0: + push 0 + jmp fs_NextHd +fs_NextHd1: + push 1 + jmp fs_NextHd +fs_NextHd2: + push 2 + jmp fs_NextHd +fs_NextHd3: + push 3 +fs_NextHd: + pop ecx + movzx ecx, byte [0x40002+ecx] + cmp eax, ecx + jae fs_NextFloppy.no2 + inc eax + clc + ret + +;******************************************************* +fs_NextCd: +; we always have /cdX/1 + test eax, eax + stc + jnz @f + mov al, 1 + clc +@@: + ret +;******************************************************* + diff --git a/kernel/tags/kolibri0.6.0.0/fs/fs_phys.inc b/kernel/tags/kolibri0.6.0.0/fs/fs_phys.inc new file mode 100644 index 0000000000..418945d02b --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/fs_phys.inc @@ -0,0 +1,111 @@ +hd_phys_read: +;eax - sector number +;ebx - destination + pushad + call wait_for_hd_idle + popad + push edx + push eax + cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al + inc edx + inc eax + out dx,al + inc edx +;write sector number. + mov eax,[esp] + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + and al,1+2+4+8 + add al,byte [hdid] ;+0 or +16 + or al,32+64+128 + out dx,al + inc edx + mov al,0x20 + out dx,al + sti + + call wait_for_sector_buffer + cmp [hd_error],0 + jnz hd_read_error + cli + push edi + mov edi,ebx + mov ecx,256 + mov edx,[hdbase] + cld + rep insw + pop edi + sti + pop edx + pop eax + ret + +hd_phys_write: +;eax - sector number +;ebx - destination + cmp eax,[partition_start] + jb .ret + cmp eax,[partition_end] + ja .ret + pushad + call wait_for_hd_idle + popad + push edx + push eax + cli + xor eax,eax + mov edx,[hdbase] + inc edx + out dx,al + inc edx + inc eax + out dx,al +;write sector number + inc edx + mov eax,[esp] + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + out dx,al + shr eax,8 + inc edx + and al,1+2+4+8 + add al,byte [hdid] ;+0 or +16 + or al,32+64+128 + out dx,al + + inc edx + mov al,0x30 + out dx,al + sti + + call wait_for_sector_buffer + cmp [hd_error],0 + jnz hd_write_error + cli + push esi + mov esi,ebx + mov ecx,256 + mov edx,[hdbase] + cld + rep outsw + pop esi + sti + pop edx + pop eax +.ret: + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/fs/iso9660.inc b/kernel/tags/kolibri0.6.0.0/fs/iso9660.inc new file mode 100644 index 0000000000..196d6ef1cf --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/iso9660.inc @@ -0,0 +1,826 @@ + +uglobal +cd_current_pointer_of_input dd 0 +cd_current_pointer_of_input_2 dd 0 +cd_mem_location dd 0 +cd_counter_block dd 0 +IDE_Channel_1 db 0 +IDE_Channel_2 db 0 +endg + +CDDataBuf equ 0x7000 + +reserve_cd: + + cli + cmp [cd_status],0 + je reserve_ok2 + + sti + call change_task + jmp reserve_cd + + reserve_ok2: + + push eax + mov eax,[0x3000] + shl eax,5 + mov eax,[eax+0x3000+TASKDATA.pid] + mov [cd_status],eax + pop eax + sti + ret + +reserve_cd_channel: + cmp [ChannelNumber],1 + jne .IDE_Channel_2 +.IDE_Channel_1: + cli + cmp [IDE_Channel_1],0 + je .reserve_ok_1 + sti + call change_task + jmp .IDE_Channel_1 +.IDE_Channel_2: + cli + cmp [IDE_Channel_2],0 + je .reserve_ok_2 + sti + call change_task + jmp .IDE_Channel_1 +.reserve_ok_1: + mov [IDE_Channel_1],1 + ret +.reserve_ok_2: + mov [IDE_Channel_2],1 + ret + +free_cd_channel: + cmp [ChannelNumber],1 + jne .IDE_Channel_2 +.IDE_Channel_1: + mov [IDE_Channel_1],0 + ret +.IDE_Channel_2: + mov [IDE_Channel_2],0 + ret + +cd_status dd 0 + +;---------------------------------------------------------------- +; +; fs_CdRead - LFN variant for reading CD disk +; +; esi points to filename /dir1/dir2/.../dirn/file,0 +; ebx pointer to 64-bit number = first wanted byte, 0+ +; may be ebx=0 - start from first byte +; ecx number of bytes to read, 0+ +; edx mem location to return data +; +; ret ebx = bytes read or 0xffffffff file not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_CdRead: + push edi + cmp byte [esi], 0 + jnz @f +.noaccess: + pop edi +.noaccess_2: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret + +.noaccess_3: + pop eax edx ecx edi + jmp .noaccess_2 + +@@: + call cd_find_lfn + jnc .found + pop edi + cmp [DevErrorCode],0 + jne .noaccess_2 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret + +.found: + mov edi,[cd_current_pointer_of_input] + test byte [edi+25],10b ; do not allow read directories + jnz .noaccess + test ebx, ebx + jz .l1 + cmp dword [ebx+4], 0 + jz @f + xor ebx, ebx +.reteof: + mov eax, 6 ; end of file + pop edi + ret +@@: + mov ebx, [ebx] +.l1: + push ecx edx + push 0 + mov eax, [edi+10] ; реальный размер файловой секции + sub eax, ebx + jb .eof + cmp eax, ecx + jae @f + mov ecx, eax + mov byte [esp], 6 +@@: + mov eax,[edi+2] + mov [CDSectorAddress],eax +; now eax=cluster, ebx=position, ecx=count, edx=buffer for data +.new_sector: + test ecx, ecx + jz .done + sub ebx, 2048 + jae .new_sector + add ebx, 2048 + jnz .incomplete_sector + cmp ecx, 2048 + jb .incomplete_sector +; we may read and memmove complete sector + mov [CDDataBuf_pointer],edx + call ReadCDWRetr ; читаем сектор файла + cmp [DevErrorCode],0 + jne .noaccess_3 + inc dword [CDSectorAddress] + add edx, 2048 + sub ecx, 2048 + jmp .new_sector +.incomplete_sector: +; we must read and memmove incomplete sector + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr ; читаем сектор файла + cmp [DevErrorCode],0 + jne .noaccess_3 + inc dword [CDSectorAddress] + mov eax,CDDataBuf + add eax, ebx + push ecx + add ecx, ebx + cmp ecx, 2048 + jbe @f + mov ecx, 2048 +@@: + sub ecx, ebx + push edi esi ecx + mov edi,edx + mov esi,eax ;0x7000 ; CD data buffer + cld + rep movsb + pop ecx esi edi + add edx, ecx + sub [esp], ecx + pop ecx + xor ebx, ebx + jmp .new_sector + +.done: + mov ebx, edx + pop eax edx ecx edi + sub ebx, edx + ret +.eof: + mov ebx, edx + pop eax edx ecx + sub ebx, edx + jmp .reteof + +;---------------------------------------------------------------- +; +; fs_CdReadFolder - LFN variant for reading CD disk folder +; +; esi points to filename /dir1/dir2/.../dirn/file,0 +; ebx pointer to structure 32-bit number = first wanted block, 0+ +; & flags (bitfields) +; flags: bit 0: 0=ANSI names, 1=UNICODE names +; ecx number of blocks to read, 0+ +; edx mem location to return data +; +; ret ebx = blocks read or 0xffffffff folder not found +; eax = 0 ok read or other = errormsg +; +;-------------------------------------------------------------- +fs_CdReadFolder: + push edi + call cd_find_lfn + jnc .found + pop edi + cmp [DevErrorCode],0 + jne .noaccess_1 + or ebx, -1 + mov eax, ERROR_FILE_NOT_FOUND + ret +.found: + mov edi,[cd_current_pointer_of_input] + test byte [edi+25],10b ; do not allow read directories + jnz .found_dir + pop edi +.noaccess_1: + or ebx, -1 + mov eax, ERROR_ACCESS_DENIED + ret +.found_dir: + mov eax,[edi+2] ; eax=cluster + mov [CDSectorAddress],eax + mov eax,[edi+10] ; размер директрории +.doit: +; init header + push eax ecx + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + pop ecx eax + 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] + push ecx +.read_to_buffer: + inc dword [CDSectorAddress] + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr ; читаем сектор директории + cmp [DevErrorCode],0 + jne .noaccess_1 + call .get_names_from_buffer + sub eax,2048 +; директория закончилась? + cmp eax,0 + ja .read_to_buffer + mov edi,[cd_counter_block] + mov [edx+8],edi + mov edi,[ebx] + sub [edx+4],edi + pop ecx edi + mov ebx, [edx+4] + mov eax,ERROR_SUCCESS + ret + +.get_names_from_buffer: + mov [cd_current_pointer_of_input_2],CDDataBuf + push eax esi edi edx +.get_names_from_buffer_1: + call cd_get_name + jc .end_buffer + inc dword [cd_counter_block] + mov eax,[cd_counter_block] + cmp [ebx],eax + jae .get_names_from_buffer_1 + test ecx, ecx + jz .get_names_from_buffer_1 + mov edi,[cd_counter_block] + mov [edx+4],edi + dec ecx + mov esi,ebp + mov edi,[cd_mem_location] + add edi,40 + test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE + jnz .unicode +; jmp .unicode +.ansi: + cmp [cd_counter_block],2 + jbe .ansi_parent_directory + cld + lodsw + xchg ah,al + call uni2ansi_char + cld + stosb +; проверка конца файла + mov ax,[esi] + 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 + jb .ansi +.cd_get_parameters_of_file_1: + mov [edi],byte 0 + call cd_get_parameters_of_file + add [cd_mem_location],304 + jmp .get_names_from_buffer_1 + +.ansi_parent_directory: + cmp [cd_counter_block],2 + je @f + mov [edi],byte '.' + inc edi + jmp .cd_get_parameters_of_file_1 +@@: + mov [edi],word '..' + add edi,2 + jmp .cd_get_parameters_of_file_1 + +.unicode: + cmp [cd_counter_block],2 + jbe .unicode_parent_directory + cld + movsw +; проверка конца файла + mov ax,[esi] + 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 + jb .unicode +.cd_get_parameters_of_file_2: + mov [edi],word 0 + call cd_get_parameters_of_file + add [cd_mem_location],560 + jmp .get_names_from_buffer_1 + +.unicode_parent_directory: + cmp [cd_counter_block],2 + je @f + mov [edi],word 2E00h ; '.' + add edi,2 + jmp .cd_get_parameters_of_file_2 +@@: + mov [edi],dword 2E002E00h ; '..' + add edi,4 + jmp .cd_get_parameters_of_file_2 + +.end_buffer: + pop edx edi esi eax + ret + +cd_get_parameters_of_file: + mov edi,[cd_mem_location] +cd_get_parameters_of_file_1: +; получаем атрибуты файла + xor eax,eax +; файл не архивировался + inc al + shl eax,1 +; это каталог? + test [ebp-8],byte 2 + jz .file + inc al +.file: +; метка тома не как в FAT, в этом виде отсутсвует +; файл не является системным + shl eax,3 +; файл является скрытым? (атрибут существование) + test [ebp-8],byte 1 + jz .hidden + inc al +.hidden: + shl eax,1 +; файл всегда только для чтения, так как это CD + inc al + 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 + mov [edi+4],eax + jmp @f +.unicode_1: + inc eax + mov [edi+4],eax +@@: +; получаем размер файла в байтах + xor eax,eax + mov [edi+32+4],eax + mov eax,[ebp-23] + mov [edi+32],eax + ret + +;---------------------------------------------------------------- +; +; fs_CdGetFileInfo - LFN variant for CD +; get file/directory attributes structure +; +;---------------------------------------------------------------- +fs_CdGetFileInfo: + cmp byte [esi], 0 + jnz @f + mov eax, 2 + ret +@@: + push edi ebp + call cd_find_lfn + pushfd + cmp [DevErrorCode], 0 + jz @f + popfd + pop ebp edi + mov eax, 11 + ret +@@: + popfd + jnc @f + pop ebp edi + mov eax, ERROR_FILE_NOT_FOUND + ret +@@: + + mov edi, edx + call cd_get_parameters_of_file_1 + and dword [edi+4], 0 + pop ebp + pop ebp edi + xor eax, eax + ret + +;---------------------------------------------------------------- +; +; fs_CdExecute - LFN variant for executing from CD +; +; esi points to hd filename (e.g. 'dir1/name') +; ebp points to full filename (e.g. '/hd0/1/dir1/name') +; dword [ebx] = flags +; dword [ebx+4] = cmdline +; +; ret ebx,edx destroyed +; eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- +fs_CdExecute: + mov edx, [ebx] + mov ebx, [ebx+4] + test ebx, ebx + jz @f + add ebx, std_application_base_address +@@: + +;---------------------------------------------------------------- +; +; fs_CdExecute.flags - second entry +; +; esi points to floppy filename (kernel address) +; ebp points to full filename +; edx flags +; ebx cmdline (kernel address) +; +; ret eax > 0 - PID, < 0 - error +; +;-------------------------------------------------------------- + +.flags: + cmp byte [esi], 0 + jnz @f +; cannot execute root! + mov eax, -ERROR_ACCESS_DENIED + ret +@@: + push edi + call cd_find_lfn + jnc .found + pop edi + mov eax, -ERROR_FILE_NOT_FOUND + cmp [DevErrorCode], 0 + jz @f + mov al, -11 +@@: + ret +.found: + mov edi,[cd_current_pointer_of_input] + mov eax,[edi+2] + push 0 + push eax + push dword [edi+10] ; size + push .DoRead + call fs_execute + add esp, 16 + pop edi + ret + +.DoRead: +; read next block +; in: eax->parameters, edi->buffer +; out: eax = error code + pushad + cmp dword [eax], 0 ; file size + jz .eof + cmp [eax+8],dword 0 + jne @f + mov ecx,[eax+4] + inc dword [eax+4] + mov [CDSectorAddress],ecx + mov [CDDataBuf_pointer],CDDataBuf ;edi + call ReadCDWRetr + cmp [DevErrorCode], 0 + jnz .err +@@: + push esi edi ecx + mov esi,512 + imul esi,[eax+8] + add esi,CDDataBuf + mov ecx,512/4 + cld + rep movsd + pop ecx edi esi + + mov eax, [esp+28] + mov ecx, [eax] + sub ecx, 512 + jae @f + lea edi, [edi+ecx+512] + neg ecx + push eax + xor eax, eax + rep stosb + pop eax +@@: + mov [eax], ecx + mov edx, [eax+8] + inc edx + cmp edx, 4 ; 2048/512=4 + jb @f + xor edx, edx +@@: + mov [eax+8], edx + popad + xor eax, eax + ret +.eof: + popad + mov eax, 6 + ret +.err: + popad + mov eax, 11 + ret + +cd_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0 and [cd_current_pointer_of_input] direntry + push eax esi +; 16 сектор начало набора дескрипторов томов + mov [CDSectorAddress],dword 15 +.start: + inc dword [CDSectorAddress] + mov [CDDataBuf_pointer],CDDataBuf + call ReadCDWRetr + cmp [DevErrorCode],0 + jne .access_denied +; проверка на вшивость + 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 директрории + mov [CDSectorAddress],eax + 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 ; читаем сектор директории + cmp [DevErrorCode],0 + jne .access_denied + call cd_find_name_in_buffer + jnc .found + sub eax,2048 +; директория закончилась? + cmp eax,0 + ja .read_to_buffer +; нет искомого элемента цепочки +.access_denied: + pop esi eax + stc + ret +; искомый элемент цепочки найден + .found: +; конец пути файла + cmp byte [esi-1], 0 + jz .done + mov eax,[cd_current_pointer_of_input] + add eax,2 + mov eax,[eax] + mov [CDSectorAddress],eax ; начало директории + add eax,8 + mov eax,[eax] ; размер директории + jmp .mainloop +; указатель файла найден + .done: + pop esi eax + clc + ret + +cd_find_name_in_buffer: + mov [cd_current_pointer_of_input_2],CDDataBuf +.start: + call cd_get_name + jc .not_found + call cd_compare_name + jc .start +.found: + clc + ret +.not_found: + stc + ret + +cd_get_name: + push eax + mov ebp,[cd_current_pointer_of_input_2] + mov [cd_current_pointer_of_input],ebp + mov eax,[ebp] + cmp eax,0 ; входы закончились? + je .next_sector + cmp ebp,CDDataBuf+2048 ; буфер закончился? + jae .next_sector + movzx eax, byte [ebp] + add [cd_current_pointer_of_input_2],eax ; следующий вход каталога + add ebp,33 ; указатель установлен на начало имени + pop eax + clc + ret +.next_sector: + pop eax + stc + ret + +cd_compare_name: +; compares ASCIIZ-names, case-insensitive (cp866 encoding) +; in: esi->name, ebp->name +; out: if names match: ZF=1 and esi->next component of name +; else: ZF=0, esi is not changed +; destroys eax + push esi eax edi + mov edi,ebp +.loop: + cld + lodsb + push ax + call char_todown + call ansi2uni_char + xchg ah,al + cld + scasw + pop ax + je .coincides + call char_toupper + call ansi2uni_char + xchg ah,al + cld + sub edi,2 + scasw + jne .name_not_coincide +.coincides: + cmp [esi],byte '/' ; разделитель пути, конец имени текущего элемента + je .done + cmp [esi],byte 0 ; разделитель пути, конец имени текущего элемента + je .done + jmp .loop +.name_not_coincide: + pop edi eax esi + stc + ret +.done: +; проверка конца файла + 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 + jne .name_not_coincide +.done_1: + pop edi eax + add esp,4 + inc esi + clc + ret + +char_todown: +; convert character to uppercase, using cp866 encoding +; in: al=symbol +; out: al=converted symbol + cmp al, 'A' + jb .ret + cmp al, 'Z' + jbe .az + cmp al, 'Ђ' + jb .ret + cmp al, 'ђ' + jb .rus1 + cmp al, 'џ' + ja .ret +; 0x90-0x9F -> 0xE0-0xEF + add al, 'а'-'ђ' +.ret: + ret +.rus1: +; 0x80-0x8F -> 0xA0-0xAF +.az: + add al, 0x20 + ret + +uni2ansi_char: +; convert UNICODE character in al to ANSI character in ax, using cp866 encoding +; in: ax=UNICODE character +; out: al=converted ANSI character + cmp ax, 0x80 + jb .ascii + cmp ax, 0x401 + jz .yo1 + cmp ax, 0x451 + jz .yo2 + cmp ax, 0x410 + jb .unk + cmp ax, 0x440 + jb .rus1 + cmp ax, 0x450 + jb .rus2 +.unk: + mov al, '_' + jmp .doit +.yo1: + mov al, 'р' + jmp .doit +.yo2: + mov al, 'с' + jmp .doit +.rus1: +; 0x410-0x43F -> 0x80-0xAF + add al, 0x70 + jmp .doit +.rus2: +; 0x440-0x44F -> 0xE0-0xEF + add al, 0xA0 +.ascii: +.doit: + ret diff --git a/kernel/tags/kolibri0.6.0.0/fs/part_set.inc b/kernel/tags/kolibri0.6.0.0/fs/part_set.inc new file mode 100644 index 0000000000..aa9fea0134 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/fs/part_set.inc @@ -0,0 +1,351 @@ +;************************************************************* +;* 29.04.2006 Elimination of hangup after the * +;* expiration hd_wait_timeout - Mario79 * +;* 28.01.2006 find all Fat16/32 partition in all input point * +;* to MBR - Mario79 * +;************************************************************* + +align 4 +;****************************************************** +; Please do not change this place - variables in text +; Mario79 +; START place +;****************************************************** +PARTITION_START dd 0x3f +PARTITION_END dd 0 +SECTORS_PER_FAT dd 0x1f3a +NUMBER_OF_FATS dd 0x2 +SECTORS_PER_CLUSTER dd 0x8 +BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes +ROOT_CLUSTER dd 2 ; first rootdir cluster +FAT_START dd 0 ; start of fat table +ROOT_START dd 0 ; start of rootdir (only fat16) +ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) +DATA_START dd 0 ; start of data area (=first cluster 2) +LAST_CLUSTER dd 0 ; last availabe cluster +ADR_FSINFO dd 0 ; used only by fat32 + +fatRESERVED dd 0x0FFFFFF6 +fatBAD dd 0x0FFFFFF7 +fatEND dd 0x0FFFFFF8 +fatMASK dd 0x0FFFFFFF + +fat_type db 0 ; 0=none, 16=fat16, 32=fat32 +;*************************************************************************** +; End place +; Mario79 +;*************************************************************************** + +iglobal + partition_types: ; list of fat16/32 partitions + db 0x04 ; DOS: fat16 <32M + db 0x06 ; DOS: fat16 >32M + db 0x0b ; WIN95: fat32 + db 0x0c ; WIN95: fat32, LBA-mapped + db 0x0e ; WIN95: fat16, LBA-mapped + db 0x14 ; Hidden DOS: fat16 <32M + db 0x16 ; Hidden DOS: fat16 >32M + db 0x1b ; Hidden WIN95: fat32 + db 0x1c ; Hidden WIN95: fat32, LBA-mapped + db 0x1e ; Hidden WIN95: fat16, LBA-mapped + db 0xc4 ; DRDOS/secured: fat16 <32M + db 0xc6 ; DRDOS/secured: fat16 >32M + db 0xcb ; DRDOS/secured: fat32 + db 0xcc ; DRDOS/secured: fat32, LBA-mapped + db 0xce ; DRDOS/secured: fat16, LBA-mapped + db 0xd4 ; Old Multiuser DOS secured: fat16 <32M + db 0xd6 ; Old Multiuser DOS secured: fat16 >32M + partition_types_end: + + + extended_types: ; list of extended partitions + db 0x05 ; DOS: extended partition + db 0x0f ; WIN95: extended partition, LBA-mapped + db 0xc5 ; DRDOS/secured: extended partition + db 0xd5 ; Old Multiuser DOS secured: extended partition + extended_types_end: + +endg + +; Partition chain used: +; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4 +;========================================================== +; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +-- +; extended --+ extended --+ extended --+ extended --+ +; 0 0 0 0 +; 0 0 0 0 +; Notes: +; - extended partition need to be in second entry on table +; - it will skip over removed partitions + +set_FAT32_variables: + mov [0xfe10],dword 0 ; entries in hd cache + mov [problem_partition],0 + call reserve_hd1 + call clear_hd_cache + + cmp dword [hdpos],0 + je problem_hd + + pushad + xor ecx,ecx ; partition count + mov edx,-1 ; flag for partition + xor eax,eax ; read MBR + xor ebp,ebp ; extended partition start + +new_partition: + test ebp,ebp ; is there extended partition? + jnz extended_already_set ; yes + xchg ebp,eax ; no. set it now + +extended_already_set: + add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start + mov ebx,buffer + call hd_read + cmp [hd_error],0 + jne problem_hd + + cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? + jnz end_partition_chain + cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition + jz next_partition + + push eax + mov al,[ebx+0x1be+4] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition ; no + + mov edx,eax ; start sector + add edx,[ebx+0x1be+8] ; add relative start + +next_primary_partition: + push eax + mov al,[ebx+0x1be+4+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition_1 ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition_1 ; no + + mov edx,eax ; start sector + add edx,[ebx+0x1be+8+16] ; add relative start + +next_primary_partition_1: + push eax + mov al,[ebx+0x1be+4+16+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_primary_partition_2 ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_primary_partition_2 ; no + + mov edx,eax ; start sector + add edx,[ebx+0x1be+8+16+16] ; add relative start + +next_primary_partition_2: + push eax + mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type + call scan_partition_types + pop eax + jnz next_partition ; no. skip over + + inc ecx + cmp ecx,[fat32part] ; is it wanted partition? + jnz next_partition ; no + + mov edx,eax ; start sector + add edx,[ebx+0x1be+8+16+16+16] ; add relative start + +next_partition: + push eax + mov al,[ebx+0x1be+4] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_1 + + mov eax,[ebx+0x1be+8] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_1: + push eax + mov al,[ebx+0x1be+4+16] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_2 + + mov eax,[ebx+0x1be+8+16] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_2: + push eax + mov al,[ebx+0x1be+4+16+16] ; get extended partition type + call scan_extended_types + pop eax + jnz next_partition_3 + + mov eax,[ebx+0x1be+8+16+16] ; add relative start + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +next_partition_3: + push eax + mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type + call scan_extended_types + pop eax + jnz end_partition_chain ; no. end chain + + mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition + test eax,eax ; is there extended partition? + jnz new_partition ; yes. read it + +end_partition_chain: + mov [partition_count],ecx + + cmp edx,-1 ; found wanted partition? + jnz hd_and_partition_ok ; yes. install it + jmp problem_partition_or_fat + +scan_partition_types: + push ecx + mov edi,partition_types + mov ecx,partition_types_end-partition_types + cld + repne scasb ; is partition type ok? + pop ecx + ret + +scan_extended_types: + push ecx + mov edi,extended_types + mov ecx,extended_types_end-extended_types + cld + repne scasb ; is it extended partition? + pop ecx + ret + +problem_fat_dec_count: ; bootsector is missing or another problem + dec [partition_count] ; remove it from partition_count + +problem_partition_or_fat: + popad + +problem_hd: + mov [fat_type],0 + mov [hd1_status],0 ; free + mov [problem_partition],1 + ret + +hd_and_partition_ok: + mov eax,edx + mov [PARTITION_START],eax + + mov [hd_setup],1 + mov ebx,buffer + call hd_read ; read boot sector of partition + cmp [hd_error],0 + jne problem_fat_dec_count + + mov [hd_setup],0 + + cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? + jnz problem_fat_dec_count + + movzx eax,word [ebx+0xe] ; sectors reserved + add eax,[PARTITION_START] + mov [FAT_START],eax ; fat_start = partition_start + reserved + + movzx eax,byte [ebx+0xd] ; sectors per cluster + mov [SECTORS_PER_CLUSTER],eax + + movzx ecx,word [ebx+0xb] ; bytes per sector + mov [BYTES_PER_SECTOR],ecx + + movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32) + mov edx,32 + mul edx + dec ecx + add eax,ecx ; round up if not equal count + inc ecx ; bytes per sector + div ecx + mov [ROOT_SECTORS],eax ; count of rootdir sectors + + movzx eax,word [ebx+0x16] ; sectors per fat <65536 + test eax,eax + jnz fat16_fatsize + mov eax,[ebx+0x24] ; sectors per fat + fat16_fatsize: + mov [SECTORS_PER_FAT],eax + + movzx eax,byte [ebx+0x10] ; number of fats + test eax,eax ; if 0 it's not fat partition + jz problem_fat_dec_count + mov [NUMBER_OF_FATS],eax + imul eax,[SECTORS_PER_FAT] + add eax,[FAT_START] + mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count + add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32 + mov [DATA_START],eax ; data area = rootdir + rootdir_size + + movzx eax,word [ebx+0x13] ; total sector count <65536 + test eax,eax + jnz fat16_total + mov eax,[ebx+0x20] ; total sector count + fat16_total: + add eax,[PARTITION_START] + dec eax + mov [PARTITION_END],eax + inc eax + sub eax,[DATA_START] ; eax = count of data sectors + xor edx,edx + div dword [SECTORS_PER_CLUSTER] + inc eax + mov [LAST_CLUSTER],eax + dec eax ; cluster count + + ; limits by Microsoft Hardware White Paper v1.03 + cmp eax,4085 ; 0xff5 + jb problem_fat_dec_count ; fat12 not supported + cmp eax,65525 ; 0xfff5 + jb fat16_partition + +fat32_partition: + mov eax,[ebx+0x2c] ; rootdir cluster + mov [ROOT_CLUSTER],eax + movzx eax,word [ebx+0x30] ; fs info sector + add eax,[PARTITION_START] + mov [ADR_FSINFO],eax + + popad + + mov [fatRESERVED],0x0FFFFFF6 + mov [fatBAD],0x0FFFFFF7 + mov [fatEND],0x0FFFFFF8 + mov [fatMASK],0x0FFFFFFF + mov [fat_type],32 ; Fat32 + mov [hd1_status],0 ; free + ret + +fat16_partition: + xor eax,eax + mov [ROOT_CLUSTER],eax + + popad + + mov [fatRESERVED],0x0000FFF6 + mov [fatBAD],0x0000FFF7 + mov [fatEND],0x0000FFF8 + mov [fatMASK],0x0000FFFF + mov [fat_type],16 ; Fat16 + mov [hd1_status],0 ; free + ret diff --git a/kernel/tags/kolibri0.6.0.0/gui/button.inc b/kernel/tags/kolibri0.6.0.0/gui/button.inc new file mode 100644 index 0000000000..4d7492c2d9 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/button.inc @@ -0,0 +1,648 @@ +max_buttons=4095 +dececx: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0x20 + jae @f + mov [esp+edx],byte 0x20 + @@: + sub [esp+edx],byte 0x20 + + dec edx + jns .loop + + pop ecx + pop edx + ret + +incecx: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0xdf + jbe @f + mov [esp+edx],byte 0xdf + @@: + add [esp+edx],byte 0x20 + + dec edx + jns .loop + pop ecx + pop edx + ret + +incecx2: + push edx + push ecx + + mov edx,2 + .loop: + + cmp byte [esp+edx],0xeb + jbe @f + mov [esp+edx],byte 0xeb + @@: + add [esp+edx],byte 0x14 + + dec edx + jns .loop + pop ecx + pop edx + ret + +drawbuttonframes: + + push esi + push edi + push eax + push ebx + push ecx + push edx + + shr eax,16 + shr ebx,16 + mov edx,[0x3010] + + add eax,[edx-twdw + WDATA.box.left] + add ebx,[edx-twdw + WDATA.box.top] + mov cx,ax + mov dx,bx + shl eax,16 + shl ebx,16 + mov ax,cx + mov bx,dx + add ax,word [esp+12] + mov esi,ebx + mov edi,0 + mov ecx,[esp+0] + call incecx + call [draw_line] + + movzx edx,word [esp+8] + add ebx,edx + shl edx,16 + add ebx,edx + mov ecx,[esp+0] + call dececx + call [draw_line] + + mov ebx,esi + push edx + mov edx,eax + shr edx,16 + mov ax,dx + mov edx,ebx + shr edx,16 + mov bx,dx + mov dx,[esp+8+4] + add bx,dx + pop edx + mov edi,0 + mov ecx,[esp+0] + call incecx + call [draw_line] + + mov esi,edx + mov dx,[esp+12] + add ax,dx + shl edx,16 + add eax,edx + add ebx,1*65536 + mov edx,esi + mov ecx,[esp+0] + call dececx + call [draw_line] + + pop edx + pop ecx + pop ebx + pop eax + pop edi + pop esi + + ret + +button_dececx: + + cmp [buttontype],dword 1 + jne .finish +; je bdece +; ret +; bdece: + push eax + mov eax,0x01 + cmp edi,20 + jg @f + mov eax,0x02 + @@: + test ecx,0xff + jz @f + sub ecx,eax + @@: + shl eax,8 + test ecx,0xff00 + jz @f + sub ecx,eax + @@: + shl eax,8 + test ecx,0xff0000 + jz @f + sub ecx,eax + @@: + pop eax + .finish: + ret + + +sys_button: + + push edi + mov edi,[0x3000] + shl edi,8 + rol eax,16 + add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] + rol eax,16 + rol ebx,16 + add bx,word[edi+0x80000+APPDATA.wnd_clientbox.top] + rol ebx,16 + pop edi + .forced: + + test ecx,0x80000000 + jnz remove_button + + push esi + push edi + push eax ; + push ebx ; + push ecx ; + push edx + + or ax,ax + jle noaddbutt + or bx,bx + jle noaddbutt + + test ecx,0x40000000 + jnz button_no_draw + + pushad ; button body + push ebx + shr eax,16 + shr ebx,16 + mov edx,[0x3010] + mov esi,[edx-twdw + WDATA.box.left] + mov edi,[edx-twdw + WDATA.box.top] + add eax,esi + add ebx,edi + mov cx,ax + mov dx,bx + shl eax,16 + shl ebx,16 + mov ax,cx + mov bx,dx + movzx ecx,word [4+32+esp+12] + add eax,ecx + mov ecx,[4+32+esp+0] + cmp [buttontype],dword 0 + je @f + call incecx2 + @@: + movzx edi,word [esp] + + pop edx + and edx, 0xFFFF + + .newline: + call button_dececx + push edi + xor edi, edi + call [draw_line] + pop edi + add ebx,1*65536+1 ; [ y start | y end ] + dec edx + jnz .newline + popad + + call drawbuttonframes + + button_no_draw: + + and ecx,0xffff + + mov edi,[0xfe88] + movzx eax,word [edi] + cmp eax,max_buttons + jge noaddbutt + inc eax + mov [edi],ax + + shl eax,4 + add eax,edi + + mov bx,[0x3000] + mov [eax],bx + + add eax,2 ; save button id number + mov ebx,[esp+4] + mov [eax],bx ; bits 0-15 + shr ebx,16 + mov [eax-2+0xc],bx; bits 16-31 + add eax,2 ; x start + mov bx,[esp+12+2] + mov [eax],bx + add eax,2 ; x size + mov bx,[esp+12+0] + mov [eax],bx + add eax,2 ; y start + mov bx,[esp+8+2] + mov [eax],bx + add eax,2 ; y size + mov bx,[esp+8+0] + mov [eax],bx + + noaddbutt: + + pop edx + pop ecx + pop ebx + pop eax + pop edi + pop esi + + ret + + +remove_button: + + and ecx,0x7fffffff + + rnewba2: + + mov edi,[0xfe88] + mov eax,edi + movzx ebx,word [edi] + inc bx + + rnewba: + + dec bx + jz rnmba + + add eax,0x10 + + mov dx,[0x3000] + cmp dx,[eax] + jnz rnewba + + cmp cx,[eax+2] + jnz rnewba + + pushad + mov ecx,ebx + inc ecx + shl ecx,4 + mov ebx,eax + add eax,0x10 + call memmove + dec dword [edi] + popad + + jmp rnewba2 + + rnmba: + + ret + +find_pressed_button_frames: + + pushad + + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+ WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add ecx,edx + push ecx + + mov dx,[eax+6] ; button x size + add cx,dx + mov esi,ecx + inc esi + mov ecx, [ebx+WDATA.box.top] ; window y start + mov dx,[eax+8] ; button y start + add ecx,edx + mov ebx,ecx + mov dx,[eax+10] ; button y size + add dx,cx + inc dx + + pop eax + + ; eax x beginning + ; ebx y beginning + ; esi x end + ; edx y end + ; ecx color + + mov [pressed_button_eax],eax + mov [pressed_button_ebx],ebx + mov [pressed_button_ecx],ecx + mov [pressed_button_edx],edx + mov [pressed_button_esi],esi + + popad + ret + +uglobal + pressed_button_eax dd 0 + pressed_button_ebx dd 0 + pressed_button_ecx dd 0 + pressed_button_edx dd 0 + pressed_button_esi dd 0 +endg + +; negative button image + +negativebutton: + ; If requested, do not display button + ; boarder on press. + test ebx,0x20000000 + jz draw_negative_button + ret + draw_negative_button: + + pushad + + mov eax,[pressed_button_eax] + mov ebx,[pressed_button_ebx] + mov ecx,[pressed_button_ecx] + mov edx,[pressed_button_edx] + mov esi,[pressed_button_esi] + mov ecx,0x01000000 + + dec edx + push edx + inc edx + dec esi + push esi + inc esi + + push eax + push ebx + push ecx + push edx + push edi + + call [disable_mouse] + + bdbnewline: + mov edi,1 ; force + cmp eax,[esp+16] + jz bneg + cmp eax,[esp+20] + jz bneg + cmp ebx,[esp+12] + jz bneg + cmp ebx,[esp+24] + jnz nbneg +; jz bneg +; jmp nbneg + + bneg: + + ;;;call [disable_mouse] + call [putpixel] + + nbneg: + + inc eax + cmp eax,esi + jnz bdbnewline + mov eax,[esp+16] + inc ebx + cmp ebx,edx + jnz bdbnewline + + add esp,28 + + popad + + ret + +; check buttons + + +; 0000 word process number +; 0002 word button id number : bits 0-15 +; 0004 word x start +; 0006 word x size +; 0008 word y start +; 000A word y size +; 000C word button id number : bits 16-31 +; +; button table in 0x10 increments +; +; first at 0x10 + + +checkbuttons: + + cmp [0xfb40],byte 0 ; mouse buttons pressed + jnz @f + ret + @@: + + pushad + + xor esi, esi + mov edi, [0xfe88] + movzx edx, word [edi] + test edx, edx + jne @f + popad + ret + + @@: + + push esi + inc edx + push edx + + buttonnewcheck: + + pop edx + pop esi + inc esi + cmp edx,esi + jge bch + + popad ; no button pressed + ret + + bch: + + push esi + push edx + mov eax,esi + shl eax,4 + add eax,edi + +;......................start 1/2 : modified by vhanla ............................. + mov [buttonid],eax +;......................end 1/2 : modified by vhanla ............................. + + ; check that button is at top of windowing stack + + movzx ebx,word [eax] + movzx ecx,word [0xC000 + ebx * 2] + cmp ecx,[0x3004] + jne buttonnewcheck + + ; check that button start is inside window x/y end + + movzx ebx,word [eax+0] + shl ebx,5 + + test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED + jnz buttonnewcheck + +; add ebx,window_data +; mov ecx,[window_data+ebx+8] ; window end X + movzx edx,word [eax+4] ; button start X + cmp edx, [window_data+ebx+WDATA.box.width] ;ecx + jge buttonnewcheck + +; mov ecx,[window_data+ebx+12] ; window end Y + movzx edx, word [eax+8] ; button start Y + cmp edx, [window_data+ebx+WDATA.box.height] ;ecx + jge buttonnewcheck + + ; check coordinates + ; mouse x >= button x ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add edx,ecx + mov cx,[0xfb0a] + cmp edx,ecx + jg buttonnewcheck + + movzx ebx,word [eax+6] ; button x size + add edx,ebx + cmp ecx,edx + jg buttonnewcheck + + ; mouse y >= button y ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.top] ; window y start + movzx edx,word [eax+8] ; button y start + add edx,ecx + mov cx,[0xfb0c] + cmp edx,ecx + jg buttonnewcheck + + movzx ebx,word [eax+10] ; button y size + add edx,ebx + cmp ecx,edx + jg buttonnewcheck + + ; mouse on button + + pop edx + pop esi + + mov bx,[eax+0xc] ; button id : bits 16-31 + shl ebx,16 + mov bx,[eax+2] ; button id : bits 00-16 + push ebx + + mov [0xfb44],byte 1 ; no mouse down checks + call find_pressed_button_frames + call negativebutton + + pushad + cbwaitmouseup: + + call checkidle + + call [draw_pointer] + + pushad + call stack_handler + popad + + cmp [0xfb40],byte 0 ; mouse buttons pressed ? + jnz cbwaitmouseup + popad + + call negativebutton + mov [0xfff4],byte 0 ; no mouse background + mov [0xfff5],byte 0 ; draw mouse +;..................................... start 2/2 : modified by vhanla ............................. + ; check coordinates + jmp afterbuttonid + buttonid dd 0x0 ;here a will backup the eax value + afterbuttonid: + + pusha + ; mouse x >= button x ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.left] ; window x start + movzx edx,word [eax+4] ; button x start + add edx,ecx + mov cx,[0xfb0a] + cmp edx,ecx + jg no_on_button ;if we release the pointer out of the button area + + movzx ebx,word [eax+6] ; button x size + add edx,ebx + cmp ecx,edx + jg no_on_button + + ; mouse y >= button y ? + movzx ebx,word [eax+0] + shl ebx,5 + add ebx,window_data + mov ecx, [ebx+WDATA.box.top] ; window y start + movzx edx,word [eax+8] ; button y start + add edx,ecx + mov cx,[0xfb0c] + cmp edx,ecx + jg no_on_button + + movzx ebx,word [eax+10] ; button y size + add edx,ebx + cmp ecx,edx + jg no_on_button + popa + mov [0xf500],byte 1 ; no of buttons in buffer + pop ebx + mov [0xf501],ebx ; lets put the button id in buffer + push ebx + pusha + jmp yes_on_button +no_on_button: + mov [0xf500],byte 0 ; no of buttons in buffer +yes_on_button: + mov [0xfb44],byte 0 ; mouse down -> do not draw + popa + pop ebx + popa + ret + +;..................................... end 2/2 : modified by vhanla ................................ diff --git a/kernel/tags/kolibri0.6.0.0/gui/event.inc b/kernel/tags/kolibri0.6.0.0/gui/event.inc new file mode 100644 index 0000000000..ebd8000872 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/event.inc @@ -0,0 +1,215 @@ +sys_getevent: + + call get_event_for_app + mov [esp+36],eax + ret + + +align 4 + +sys_wait_event_timeout: + + mov ebx,[timer_ticks] + add ebx,eax + cmp ebx,[timer_ticks] + jna .swfet2 + .swfet1: + call get_event_for_app + test eax,eax + jne .eventoccur_time + call change_task + cmp ebx,[timer_ticks] + jg .swfet1 + .swfet2: + xor eax,eax + .eventoccur_time: + mov [esp+36],eax + ret + + +align 4 + +sys_waitforevent: + + call get_event_for_app + test eax,eax + jne eventoccur + newwait: + + mov eax, [0x3010] + mov [eax+TASKDATA.state], byte 5 + call change_task + + mov eax, [event_sched] + + eventoccur: + mov [esp+36],eax + ret + + +get_event_for_app: + + pushad + + mov edi,[0x3010] ; WINDOW REDRAW + test [edi+TASKDATA.event_mask],dword 1 + jz no_eventoccur1 + ;mov edi,[0x3010] + cmp [edi-twdw+WDATA.fl_redraw],byte 0 + je no_eventoccur1 + popad + mov eax,1 + ret + no_eventoccur1: + + ;mov edi,[0x3010] ; KEY IN BUFFER + test [edi+TASKDATA.event_mask],dword 2 + jz no_eventoccur2 + mov ecx, [0x3000] + movzx edx,word [0xC000+ecx*2] + mov eax, [0x3004] + cmp eax,edx + jne no_eventoccur2x + cmp [0xf400],byte 0 + je no_eventoccur2x + eventoccur2: + popad + mov eax,2 + ret + no_eventoccur2x: + mov eax, hotkey_buffer +@@: + cmp [eax], ecx + jz eventoccur2 + add eax, 8 + cmp eax, hotkey_buffer+120*8 + jb @b + no_eventoccur2: + + ;mov edi,[0x3010] ; BUTTON IN BUFFER + test [edi+TASKDATA.event_mask],dword 4 + jz no_eventoccur3 + cmp [0xf500],byte 0 + je no_eventoccur3 + mov ecx, [0x3000] + movzx edx, word [0xC000+ecx*2] + mov eax, [0x3004] + cmp eax,edx + jnz no_eventoccur3 + popad + mov eax,[0xf501] + cmp eax,65535 + je no_event_1 + mov eax,3 + ret + + no_event_1: + mov [window_minimize],1 + mov [0xf500],byte 0 + xor eax, eax + ret + + no_eventoccur3: + + + ;mov edi,[0x3010] ; mouse event + test [edi+TASKDATA.event_mask],dword 00100000b + jz no_mouse_event + mov eax,[0x3000] + shl eax,8 + test [eax+0x80000+APPDATA.event_mask],dword 00100000b + jz no_mouse_event + and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-00100000b + popad + mov eax,6 + ret + no_mouse_event: + + + ;mov edi,[0x3010] ; DESKTOP BACKGROUND REDRAW + test [edi+TASKDATA.event_mask],dword 16 + jz no_eventoccur5 + cmp [0xfff0],byte 2 + jnz no_eventoccur5 + popad + mov eax,5 + ret + no_eventoccur5: + + ;mov edi,[0x3010] ; IPC + test [edi+TASKDATA.event_mask],dword 01000000b + jz no_ipc + mov eax,[0x3000] + shl eax,8 + test [eax+0x80000+APPDATA.event_mask],dword 01000000b + jz no_ipc + and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-01000000b + popad + mov eax,7 + ret + no_ipc: + + + ;mov edi,[0x3010] ; STACK + test [edi+TASKDATA.event_mask],dword 10000000b + jz no_stack_event + mov eax,[0x3000] + shl eax,8 + test [eax+0x80000+APPDATA.event_mask],dword 10000000b + jz no_stack_event + and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-10000000b + popad + mov eax,8 + ret + no_stack_event: + + test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG + jz no_debug_event + mov eax, [0x3000] + shl eax, 8 + test byte [eax+0x80000+APPDATA.event_mask+1], byte 1 + jz no_debug_event + and byte [eax+0x80000+APPDATA.event_mask+1], not 1 + popad + mov eax, 9 + ret + no_debug_event: + + cmp dword [edi+TASKDATA.event_mask], 0xFFFF + jbe no_events + + mov esi,0x2e0000 ; IRQ'S AND DATA + mov ebx,0x00010000 + xor ecx, ecx + irq_event_test: + mov edi,[0x3010] + test [edi+TASKDATA.event_mask],ebx + jz no_irq_event + mov edi,ecx + shl edi,2 + add edi,irq_owner + mov edx,[edi] + mov eax,[0x3010] + mov eax,[eax+TASKDATA.pid] + cmp edx,eax + jne no_irq_event + cmp [esi],dword 0 + jz no_irq_event + mov eax,ecx + add eax,16 + mov [esp+28],eax + popad + ret + no_irq_event: + add esi,0x1000 + shl ebx,1 + inc ecx + cmp ecx,16 + jb irq_event_test + + no_events: + popad + xor eax, eax + ret + + diff --git a/kernel/tags/kolibri0.6.0.0/gui/font.inc b/kernel/tags/kolibri0.6.0.0/gui/font.inc new file mode 100644 index 0000000000..cd62e2dac6 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/font.inc @@ -0,0 +1,107 @@ +align 4 +dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) + ; eax x & y + ; ebx style ( 0xX0000000 ) & color ( 0x00RRGGBB ) + ; X = ABnnb: + ; nn = font + ; A = 0 <=> output edx characters; otherwise output ASCIIZ string + ; B = 1 <=> fill background with color esi + ; ecx start of text + ; edi 1 force + + pushad + call [disable_mouse] + + mov ebp, ecx ; ebp=pointer to text + mov ecx, ebx ; ecx=color + movsx ebx, ax ; ebx=y + sar eax, 16 ; eax=x + cmp edx, 255 + jb .loop + mov edx, 255 +.loop: + test ecx, ecx + js .test_asciiz + dec edx + js .end + jmp @f +.test_asciiz: + cmp byte [ebp], 0 + jz .end +@@: + push edx + movzx edx, byte [ebp] + inc ebp + test ecx, 0x10000000 + jnz .font2 + pushad + mov esi, 9 + lea ebp, [0x3F600+8*edx+edx] +.symloop1: + mov dl, byte [ebp] + or dl, 1 shl 6 +.pixloop1: + shr dl, 1 + jz .pixloop1end + jnc .nopix + call [putpixel] + jmp .pixloop1cont +.nopix: + test ecx, 0x40000000 + jz .pixloop1cont + push ecx + mov ecx, [esp+4+4] + call [putpixel] + pop ecx +.pixloop1cont: + inc eax + jmp .pixloop1 +.pixloop1end: + sub eax, 6 + inc ebx + inc ebp + dec esi + jnz .symloop1 + popad + add eax, 6 + pop edx + jmp .loop +.font2: + pushad + add edx, edx + lea ebp, [0x3EC00+4*edx+edx+1] + push 9 + movzx esi, byte [ebp-1] +.symloop2: + mov dl, byte [ebp] + push esi +.pixloop2: + shr dl, 1 + jnc .nopix2 + call [putpixel] + jmp .pixloop2cont +.nopix2: + test ecx, 0x40000000 + jz .pixloop2cont + push ecx + mov ecx, [esp+12+4] + call [putpixel] + pop ecx +.pixloop2cont: + inc eax + dec esi + jnz .pixloop2 + pop esi + sub eax, esi + inc ebx + inc ebp + dec dword [esp] + jnz .symloop2 + pop eax + add dword [esp+28], esi + popad + pop edx + jmp .loop +.end: + popad + ret diff --git a/kernel/tags/kolibri0.6.0.0/gui/mouse.inc b/kernel/tags/kolibri0.6.0.0/gui/mouse.inc new file mode 100644 index 0000000000..8c6d18e7b5 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/mouse.inc @@ -0,0 +1,243 @@ +;mouseunder: +; times 16*24 dd 0 +label mouseunder dword at 0x6900 + +iglobal + +mousepointer: +db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f +db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 +db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 +db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 +db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 +db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 +db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 +db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 +db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f +db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 +db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e +db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a +db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 +db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e +db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 +db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 +db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c +db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff +db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 +db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d +db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 +db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e +db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e +db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 +db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 +db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d +db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d +db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 +db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a +db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c +db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 +db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 +db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 +db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 +db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 +db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 +db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff +db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 +db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 +db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d +db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 +db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 +db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 +db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 +db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d +db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a +db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff +db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 +db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 +db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 +db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 +db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff +db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 +db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f +db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 +db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e +db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 +db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 +db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 +db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c +db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f +db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 +db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d +db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e +db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 +db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 +db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b +db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f +db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 +db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 +db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 +db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 +db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 +db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b +db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c +db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a +db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f +db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e +db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e +db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 +db 0x80,0x80 + +mousepointer1: +db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a +db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 +db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e +db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f +db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 +db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 +db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c +db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c +db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 +db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff +db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c +db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 +db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 +db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 +db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 +db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 +db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 +db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 +db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 +db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff +db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e +db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e +db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 +db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff +db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 +db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 +db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a +db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 +db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 +db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d +db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 +db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 +db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +db 0x00,0x00,0x00,0x00 + +endg \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/gui/skincode.inc b/kernel/tags/kolibri0.6.0.0/gui/skincode.inc new file mode 100644 index 0000000000..60f28fdd1a --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/skincode.inc @@ -0,0 +1,438 @@ +include "skindata.inc" + +skin_data = 0x00778000 + +load_skin_file: +; eax = filename +; edx = destination + mov ebx,1 + or ecx,-1 + mov esi,12 + call fileread + ret + +struct SKIN_HEADER + .ident dd ? + .version dd ? + .params dd ? + .buttons dd ? + .bitmaps dd ? +ends + +struct SKIN_PARAMS + .skin_height dd ? + .margin.right dw ? + .margin.left dw ? + .margin.bottom dw ? + .margin.top dw ? + .colors.inner dd ? + .colors.outer dd ? + .colors.frame dd ? + .colors_1.inner dd ? + .colors_1.outer dd ? + .colors_1.frame dd ? + .dtp.size dd ? + .dtp.data db 40 dup (?) +ends + +struct SKIN_BUTTONS + .type dd ? + .pos: + .left dw ? + .top dw ? + .size: + .width dw ? + .height dw ? +ends + +struct SKIN_BITMAPS + .kind dw ? + .type dw ? + .data dd ? +ends + +load_skin: + pushad + mov [_skinh],22 + mov eax,_skin_file + mov edx,skin_data + mov [edx+SKIN_HEADER.ident],'????' + call load_skin_file + cmp eax,ERROR_SUCCESS + je @f + cmp eax,ERROR_END_OF_FILE + jne .exit + @@: call parse_skin_data + .exit: + popad + ret + +parse_skin_data: + mov ebp,skin_data + cmp [ebp+SKIN_HEADER.ident],'SKIN' + jne .exit + + mov edi,skin_udata + mov ecx,(skin_udata.end-skin_udata)/4 + xor eax,eax + cld + rep stosd + + mov ebx,[ebp+SKIN_HEADER.params] + add ebx,skin_data + mov eax,[ebx+SKIN_PARAMS.skin_height] + mov [_skinh],eax + mov eax,[ebx+SKIN_PARAMS.colors.inner] + mov [skin_active.colors.inner],eax + mov eax,[ebx+SKIN_PARAMS.colors.outer] + mov [skin_active.colors.outer],eax + mov eax,[ebx+SKIN_PARAMS.colors.frame] + mov [skin_active.colors.frame],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.inner] + mov [skin_inactive.colors.inner],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.outer] + mov [skin_inactive.colors.outer],eax + mov eax,[ebx+SKIN_PARAMS.colors_1.frame] + mov [skin_inactive.colors.frame],eax + lea esi,[ebx+SKIN_PARAMS.dtp.data] + mov edi,common_colours + mov ecx,[ebx+SKIN_PARAMS.dtp.size] + and ecx,127 + rep movsb + mov eax,dword[ebx+SKIN_PARAMS.margin.right] + mov dword[_skinmargins+0],eax + mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] + mov dword[_skinmargins+4],eax + + mov ebx,[ebp+SKIN_HEADER.bitmaps] + add ebx,skin_data + .lp1: cmp dword[ebx],0 + je .end_bitmaps + movzx eax,[ebx+SKIN_BITMAPS.kind] + movzx ecx,[ebx+SKIN_BITMAPS.type] + dec eax + jnz .not_left + xor eax,eax + mov edx,skin_active.left.data + or ecx,ecx + jnz @f + mov edx,skin_inactive.left.data + @@: jmp .next_bitmap + .not_left: + dec eax + jnz .not_oper + mov esi,[ebx+SKIN_BITMAPS.data] + add esi,skin_data + mov eax,[esi+0] + neg eax + mov edx,skin_active.oper.data + or ecx,ecx + jnz @f + mov edx,skin_inactive.oper.data + @@: jmp .next_bitmap + .not_oper: + dec eax + jnz .not_base + mov eax,[skin_active.left.width] + mov edx,skin_active.base.data + or ecx,ecx + jnz @f + mov eax,[skin_inactive.left.width] + mov edx,skin_inactive.base.data + @@: jmp .next_bitmap + .not_base: + add ebx,8 + jmp .lp1 + .next_bitmap: + mov ecx,[ebx+SKIN_BITMAPS.data] + add ecx,skin_data + mov [edx+4],eax + mov eax,[ecx+0] + mov [edx+8],eax + add ecx,8 + mov [edx+0],ecx + add ebx,8 + jmp .lp1 + .end_bitmaps: + + mov ebx,[ebp+SKIN_HEADER.buttons] + add ebx,skin_data + .lp2: cmp dword[ebx],0 + je .end_buttons + mov eax,[ebx+SKIN_BUTTONS.type] + dec eax + jnz .not_close + mov edx,skin_btn_close + jmp .next_button + .not_close: + dec eax + jnz .not_minimize + mov edx,skin_btn_minimize + jmp .next_button + .not_minimize: + add ebx,12 + jmp .lp2 + .next_button: + movsx eax,[ebx+SKIN_BUTTONS.left] + mov [edx+SKIN_BUTTON.left],eax + movsx eax,[ebx+SKIN_BUTTONS.top] + mov [edx+SKIN_BUTTON.top],eax + movsx eax,[ebx+SKIN_BUTTONS.width] + mov [edx+SKIN_BUTTON.width],eax + movsx eax,[ebx+SKIN_BUTTONS.height] + mov [edx+SKIN_BUTTON.height],eax + add ebx,12 + jmp .lp2 + .end_buttons: + + .exit: + ret + +sys_putimage_with_check: + or ebx,ebx + jz @f + call sys_putimage.forced + @@: ret + +drawwindow_IV_caption: + + mov ebp,skin_active + or al,al + jnz @f + mov ebp,skin_inactive + @@: + + mov esi,[esp+4] + mov eax,[esi+WDATA.box.width] ; window width + mov edx,[ebp+SKIN_DATA.left.left] + shl edx,16 + mov ecx,[ebp+SKIN_DATA.left.width] + shl ecx,16 + add ecx,[_skinh] + + mov ebx, [ebp+SKIN_DATA.left.data] + call sys_putimage_with_check + + mov esi,[esp+4] + mov eax,[esi+WDATA.box.width] + sub eax,[ebp+SKIN_DATA.left.width] + sub eax,[ebp+SKIN_DATA.oper.width] + cmp eax,[ebp+SKIN_DATA.base.left] + jng .non_base + xor edx,edx + mov ecx,[ebp+SKIN_DATA.base.width] + jecxz .non_base + div ecx + + inc eax + + mov ebx,[ebp+SKIN_DATA.base.data] + mov ecx,[ebp+SKIN_DATA.base.width] + shl ecx,16 + add ecx,[_skinh] + mov edx,[ebp+SKIN_DATA.base.left] + sub edx,[ebp+SKIN_DATA.base.width] + shl edx,16 + .baseskinloop: + shr edx,16 + add edx,[ebp+SKIN_DATA.base.width] + shl edx,16 + + push eax ebx ecx edx + call sys_putimage_with_check + pop edx ecx ebx eax + + dec eax + jnz .baseskinloop + .non_base: + + mov esi,[esp+4] + mov edx,[esi+WDATA.box.width] + sub edx,[ebp+SKIN_DATA.oper.width] + inc edx + shl edx,16 + mov ebx,[ebp+SKIN_DATA.oper.data] + + mov ecx,[ebp+SKIN_DATA.oper.width] + shl ecx,16 + add ecx,[_skinh] + call sys_putimage_with_check + + ret + +;//mike.dld, 2006-08-02 ] + + +drawwindow_IV: +;param1 - aw_yes + + pusha + + push edx + + mov edi,[esp] ; RECTANGLE + + mov ebp,skin_active + cmp byte [esp+32+4+4],0 + jne @f + mov ebp,skin_inactive + @@: + + mov eax,[edi+WDATA.box.left] + shl eax,16 + mov ax,word [edi+WDATA.box.left] + add ax,word [edi+WDATA.box.width] + mov ebx,[edi+WDATA.box.top] + shl ebx,16 + mov bx,word [edi+WDATA.box.top] + add bx,word [edi+WDATA.box.height] +; mov esi,[edi+24] +; shr esi,1 +; and esi,0x007f7f7f + mov esi,[ebp+SKIN_DATA.colors.outer] + call draw_rectangle + mov ecx,3 + _dw3l: + add eax,1*65536-1 + add ebx,1*65536-1 + test ax,ax + js no_skin_add_button + test bx,bx + js no_skin_add_button + mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24] + call draw_rectangle + dec ecx + jnz _dw3l + mov esi,[ebp+SKIN_DATA.colors.inner] + add eax,1*65536-1 + add ebx,1*65536-1 + test ax,ax + js no_skin_add_button + test bx,bx + js no_skin_add_button + call draw_rectangle + + cmp dword[skin_data],'SKIN' + je @f + xor eax,eax + xor ebx,ebx + mov esi,[esp] + mov ecx,[esi+WDATA.box.width] + inc ecx + mov edx,[_skinh] + mov edi,[common_colours+4] ; standard grab color + call [drawbar] + jmp draw_clientbar + @@: + + mov al,[esp+32+4+4] + call drawwindow_IV_caption + + draw_clientbar: + + mov esi,[esp] + + mov edx,[esi+WDATA.box.top] ; WORK AREA + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg _noinside2 + mov eax,5 + mov ebx,[_skinh] + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + sub ecx,4 + sub edx,4 + mov edi,[esi+WDATA.cl_workarea] + call [drawbar] + _noinside2: + + cmp dword[skin_data],'SKIN' + jne no_skin_add_button + +;* close button + mov edi,[0xfe88] + movzx eax,word [edi] + cmp eax,1000 + jge no_skin_add_button + inc eax + mov [edi],ax + + shl eax,4 + add eax,edi + + mov bx,[0x3000] + mov [eax],bx + + add eax,2 ; save button id number + mov bx,1 + mov [eax],bx + add eax,2 ; x start + xor ebx,ebx + cmp [skin_btn_close.left],0 + jge _bCx_at_right + mov ebx,[esp] + mov ebx,[ebx+WDATA.box.width] + inc ebx + _bCx_at_right: + add ebx,[skin_btn_close.left] + mov [eax],bx + add eax,2 ; x size + mov ebx,[skin_btn_close.width] + dec ebx + mov [eax],bx + add eax,2 ; y start + mov ebx,[skin_btn_close.top] + mov [eax],bx + add eax,2 ; y size + mov ebx,[skin_btn_close.height] + dec ebx + mov [eax],bx + +;* minimize button + mov edi,[0xfe88] + movzx eax,word [edi] + cmp eax,1000 + jge no_skin_add_button + inc eax + mov [edi],ax + + shl eax,4 + add eax,edi + + mov bx,[0x3000] + mov [eax],bx + + add eax,2 ; save button id number + mov bx,65535 ;999 + mov [eax],bx + add eax,2 ; x start + xor ebx,ebx + cmp [skin_btn_minimize.left],0 + jge _bMx_at_right + mov ebx,[esp] + mov ebx,[ebx+WDATA.box.width] + inc ebx + _bMx_at_right: + add ebx,[skin_btn_minimize.left] + mov [eax],bx + add eax,2 ; x size + mov ebx,[skin_btn_minimize.width] + dec ebx + mov [eax],bx + add eax,2 ; y start + mov ebx,[skin_btn_minimize.top] + mov [eax],bx + add eax,2 ; y size + mov ebx,[skin_btn_minimize.height] + dec ebx + mov [eax],bx + + no_skin_add_button: + + add esp,4 + popa + + ret 4 + diff --git a/kernel/tags/kolibri0.6.0.0/gui/skindata.inc b/kernel/tags/kolibri0.6.0.0/gui/skindata.inc new file mode 100644 index 0000000000..5faffc1b88 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/skindata.inc @@ -0,0 +1,56 @@ +; +; WINDOW SKIN DATA +; + +iglobal + _skin_file_default db 'DEFAULT SKN',0 +endg + +struct SKIN_DATA + .colors.inner dd ? + .colors.outer dd ? + .colors.frame dd ? + .left.data dd ? + .left.left dd ? + .left.width dd ? + .oper.data dd ? + .oper.left dd ? + .oper.width dd ? + .base.data dd ? + .base.left dd ? + .base.width dd ? +ends + +struct SKIN_BUTTON + .left dd ? + .top dd ? + .width dd ? + .height dd ? +ends + +uglobal + +align 4 + +skin_udata: + _skinh dd ? + + _skinmargins: ; rw 4 + .right dw ? + .left dw ? + .bottom dw ? + .top dw ? + + skin_btn_close SKIN_BUTTON + skin_btn_minimize SKIN_BUTTON + + skin_active SKIN_DATA + skin_inactive SKIN_DATA + + _skin_file rb 256 + +align 4 + +skin_udata.end: + +endg diff --git a/kernel/tags/kolibri0.6.0.0/gui/window.inc b/kernel/tags/kolibri0.6.0.0/gui/window.inc new file mode 100644 index 0000000000..7437d92b45 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/gui/window.inc @@ -0,0 +1,1751 @@ +get_titlebar_height: ; edi = window draw_data pointer + mov al,[edi+WDATA.fl_wstyle] + and al,0x0F + cmp al,0x03 + jne @f + mov eax,[_skinh] + ret + @@: mov eax,21 + ret + +get_rolledup_height: ; edi = window draw_data pointer + mov al,[edi+WDATA.fl_wstyle] + and al,0x0F + cmp al,0x03 + jne @f + mov eax,[_skinh] + add eax,3 + ret + @@: or al,al + jnz @f + mov eax,21 + ret + @@: mov eax,21+2 + ret + + +setwindowdefaults: + pushad + + xor eax,eax + mov ecx,0xc000 + @@: + inc eax + add ecx,2 + mov [ecx+0x000],ax ; process no + mov [ecx+0x400],ax ; positions in stack + cmp ecx,0xc400-2 ; the more high, the more surface + jnz @b + + popad + ret + + + +; eax = cx +; ebx = cy +; ecx = ex +; edx = ey +; идея: перебрать все окна, начиная с самого нижнего, +; и для попавших в заданную область +; частей окон вызвать setscreen +align 4 +calculatescreen: + pushad + pushfd + cli + + push edx ecx ebx eax + + mov esi, 1 + call setscreen + + mov ebp, [0x3004] ; number of processes + cmp ebp, 1 + jbe .finish + align 4 + .new_wnd: + movzx edi, word [0xC400 + esi * 2] + shl edi, 5 + + cmp [0x3000+edi+TASKDATA.state], byte 9 + je .not_wnd + + add edi, window_data + test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .not_wnd + + mov eax,[edi+WDATA.box.left] + cmp eax, [esp+RECT.right] + ja .out_of_bounds + mov ebx,[edi+WDATA.box.top] + cmp ebx, [esp+RECT.bottom] + ja .out_of_bounds + mov ecx,[edi+WDATA.box.width] + add ecx, eax + cmp ecx, [esp+RECT.left] + jb .out_of_bounds + mov edx,[edi+WDATA.box.height] + add edx, ebx + cmp edx, [esp+RECT.top] + jb .out_of_bounds + + cmp eax, [esp+RECT.left] + jae @f + mov eax, [esp+RECT.left] + @@: + cmp ebx, [esp+RECT.top] + jae @f + mov ebx, [esp+RECT.top] + @@: + cmp ecx, [esp+RECT.right] + jbe @f + mov ecx, [esp+RECT.right] + @@: + cmp edx, [esp+RECT.bottom] + jbe @f + mov edx, [esp+RECT.bottom] + @@: + + push esi + movzx esi, word [0xC400 + esi * 2] + call setscreen + pop esi + + .not_wnd: + .out_of_bounds: + inc esi + dec ebp + jnz .new_wnd + .finish: + + pop eax ebx ecx edx + + popfd + popad +ret + + + +virtual at esp + ff_x dd ? + ff_y dd ? + ff_width dd ? + ff_xsz dd ? + ff_ysz dd ? + ff_scale dd ? +end virtual + +align 4 +; резервирует место под окно заданного процесса +setscreen: +; eax x start +; ebx y start +; ecx x end +; edx y end +; esi process number +pushad +; \begin{diamond}[29.08.2006] + cmp esi, 1 + jz @f + mov edi, esi + shl edi, 5 + cmp [edi+window_data+WDATA.box.width], 0 + jnz @f + cmp [edi+window_data+WDATA.box.height], 0 + jz .ret +@@: +; \end{diamond}[29.08.2006] + mov edi, esi ;;;word [esi*2+0xc400] + shl edi, 8 + add edi, 0x80000 ; address of random shaped window area + cmp [edi+APPDATA.wnd_shape], dword 0 + jne .free_form + + ; get x&y size + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + ; get WinMap start + mov edi, [0xFE00] ; screen_sx + inc edi + imul edi, ebx + add edi, eax + add edi, WinMapAddress + + .new_y: + push ecx ; sx + push edx + + mov edx, esi + align 4 + .new_x: + mov byte [edi], dl + inc edi + dec ecx + jnz .new_x + + pop edx + pop ecx + add edi, [0xFE00] + inc edi + sub edi, ecx + dec edx + jnz .new_y +.ret: + popad + ret + .read_byte: + ;eax - address + ;esi - slot + push eax + push ebx + push ecx + push edx + mov edx,eax + mov eax,esi + lea ebx,[esp+12] + mov ecx,1 + call read_process_memory + pop edx + pop ecx + pop ebx + pop eax + ret + .free_form: + + ; for (y=0; y <= x_size; y++) + ; for (x=0; x <= x_size; x++) + ; if (shape[coord(x,y,scale)]==1) + ; set_pixel(x, y, process_number); + + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + push dword [edi+APPDATA.wnd_shape_scale] ; push scale first -> for loop + + ; get WinMap start -> ebp + push eax + mov eax, [0xFE00] ; screen_sx + inc eax + imul eax, ebx + add eax, [esp] + add eax, WinMapAddress + mov ebp, eax + + mov edi, [edi+APPDATA.wnd_shape] + pop eax + + ; eax = x_start + ; ebx = y_start + ; ecx = x_size + ; edx = y_size + ; esi = process_number + ; edi = &shape + ; [scale] + push edx ecx ; for loop - x,y size + + mov ecx, esi + shl ecx, 5 + mov edx, [window_data+ecx+WDATA.box.top] + push [window_data+ecx+WDATA.box.width] ; for loop - width + mov ecx, [window_data+ecx+WDATA.box.left] + sub ebx, edx + sub eax, ecx + push ebx eax ; for loop - x,y + + add [ff_xsz], eax + add [ff_ysz], ebx + + mov ebx, [ff_y] + + .ff_new_y: + mov edx, [ff_x] + + .ff_new_x: + ; -- body -- + mov ecx, [ff_scale] + mov eax, [ff_width] + inc eax + shr eax, cl + push ebx edx + shr ebx, cl + shr edx, cl + imul eax, ebx + add eax, edx + pop edx ebx + add eax, edi + call .read_byte + test al,al + jz @f + mov eax, esi + mov [ebp], al + @@: + ; -- end body -- + inc ebp + inc edx + cmp edx, [ff_xsz] + jb .ff_new_x + sub ebp, [ff_xsz] + add ebp, [ff_x] + add ebp, [0xFE00] ; screen.x + inc ebp + inc ebx + cmp ebx, [ff_ysz] + jb .ff_new_y + + add esp, 24 +popad +ret + + +display_settings: + +; eax = 0 ; DISPLAY redraw +; ebx = 0 ; all +; +; eax = 1 ; BUTTON type +; ebx = 0 ; flat +; ebx = 1 ; 3D +; eax = 2 ; set WINDOW colours +; ebx = pointer to table +; ecx = number of bytes define +; eax = 3 ; get WINDOW colours +; ebx = pointer to table +; ecx = number of bytes wanted +; eax = 4 ; get skin height +; input : nothing +; output : eax = skin height in pixel +; eax = 5 ; get screen workarea +; input : nothing +; output : eax = [left]*65536+[right] +; ebx = [top]*65536+[bottom] +; eax = 6 ; set screen workarea +; input : ecx = [left]*65536+[right] +; edx = [top]*65536+[bottom] +; output : nothing +; eax = 7 ; get skin margins +; input : nothing +; output : eax = [left]*65536+[right] +; ebx = [top]*65536+[bottom] +; eax = 8 ; set window skin +; input : ecx = pointer to file info block +; output : eax = FS error code + + + pushad + + test eax, eax ; redraw display + jnz dspl0 + test ebx, ebx + jnz dspl0 + cmp [windowtypechanged],dword 1 + jne dspl00 + mov [windowtypechanged],dword 0 + redraw_screen_direct: + mov [dlx],dword 0 + mov [dly],dword 0 + mov eax,[0xfe00] + mov [dlxe],eax + mov eax,[0xfe04] + mov [dlye],eax + mov eax,window_data + call redrawscreen + dspl00: + popad + ret + dspl0: + + cmp eax,1 ; button type + jne dspl1 + and ebx,1 + cmp ebx,[buttontype] + je dspl9 + mov [buttontype],ebx + mov [windowtypechanged],dword 1 + dspl9: + popad + ret + dspl1: + + cmp eax,2 ; set common window colours + jne no_com_colours + mov [windowtypechanged],dword 1 + mov esi,[0x3010] + add esi,TASKDATA.mem_start + add ebx,[esi] + mov esi,ebx + mov edi,common_colours + and ecx,127 + cld + rep movsb + popad + ret + no_com_colours: + + cmp eax,3 ; get common window colours + jne no_get_com + mov esi,[0x3010] + add esi,TASKDATA.mem_start + add ebx,[esi] + mov edi,ebx + mov esi,common_colours + and ecx,127 + cld + rep movsb + popad + ret + no_get_com: + + cmp eax,4 ; get skin height + jne no_skin_height + popad + mov eax,[_skinh] + mov [esp+36],eax + ret + no_skin_height: + + cmp eax,5 ; get screen workarea + jne no_get_workarea + popad + mov eax,[screen_workarea.left-2] + mov ax,word[screen_workarea.right] + mov [esp+36],eax + mov eax,[screen_workarea.top-2] + mov ax,word[screen_workarea.bottom] + mov [esp+24],eax + ret + no_get_workarea: + + cmp eax,6 ; set screen workarea + jne no_set_workarea + movsx eax,word[esp+16+2] + movsx ebx,word[esp+16] + cmp eax,ebx + jge .lp1 + or eax,eax;[0xFE00] + jl @f + mov [screen_workarea.left],eax + @@: cmp ebx,[0xFE00] + jg .lp1 + mov [screen_workarea.right],ebx + .lp1: movsx eax,word[esp+24+2] + movsx ebx,word[esp+24] + cmp eax,ebx + jge .lp2 + or eax,eax;[0xFE04] + jl @f + mov [screen_workarea.top],eax + @@: cmp ebx,[0xFE04] + jg .lp2 + mov [screen_workarea.bottom],ebx + .lp2: call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [0xfe00] + mov edx, [0xfe04] + call calculatescreen +; jmp redraw_screen_direct + .exit: + popad + ret + no_set_workarea: + + cmp eax,7 ; get skin margins + jne no_get_skinmargins + popad + mov eax,dword[_skinmargins+0] + mov [esp+36],eax + mov eax,dword[_skinmargins+4] + mov [esp+24],eax + ret + no_get_skinmargins: + + cmp eax,8 ; set window skin + jne no_set_skin + mov eax,ebx + mov edi,[0x3010] + add ebx,[edi+TASKDATA.mem_start] ; abs start of info block + pushd [ebx+0] [ebx+4] [ebx+8] [ebx+12] + mov dword[ebx+0],0 ; read + mov dword[ebx+4],0 ; from the beginning + mov dword[ebx+8],64 ; 32 KBytes maximum + mov ecx,skin_data+64*512 + sub ecx,[edi+0x10] + mov dword[ebx+12],ecx ; destination + push eax + pushad + call file_system + popad + pop eax + popd [ebx+12] [ebx+8] [ebx+4] [ebx+0] + cmp eax,ERROR_SUCCESS + je @f + cmp eax,ERROR_END_OF_FILE + jne .exit + @@: cmp [skin_data+64*512+SKIN_HEADER.ident],'SKIN' + mov eax,ERROR_UNKNOWN_FS + jne .exit + mov esi,skin_data+64*512 + mov edi,skin_data + mov ecx,(64*512)/4 + rep movsd + call parse_skin_data + pushad + mov eax, 0 + mov ebx, 0 + mov ecx, [0xfe00] + mov edx, [0xfe04] + call calculatescreen + popad + mov dword[esp+32+36],0 + jmp redraw_screen_direct + .exit: + mov [esp+32+36],eax + popad + ret + no_set_skin: + + popad + ret + + +repos_windows: + mov ecx,[0x3004] + mov esi,0x20*2 + mov byte[0x0000fff0],1 + dec ecx + jge @f + ret + @@: mov [esi+WDATA.fl_redraw],1 + test [esi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jz .lp2 + mov eax,[screen_workarea.left] + mov [esi+WDATA.box.left],eax + sub eax,[screen_workarea.right] + neg eax + mov [esi+WDATA.box.width],eax + mov eax,[screen_workarea.top] + mov [esi+WDATA.box.top],eax + test [esi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .lp1 + sub eax,[screen_workarea.bottom] + neg eax + mov [esi+WDATA.box.height],eax + .lp1: add esi,0x20 + loop @b + ret + .lp2: mov eax,[esi+WDATA.box.left] + add eax,[esi+WDATA.box.width] + mov ebx,[0x0000fe00] +; inc ebx + cmp eax,ebx + jle .lp4 + mov eax,[esi+WDATA.box.width] + sub eax,ebx + jle .lp3 + mov [esi+WDATA.box.width],ebx + .lp3: sub ebx,[esi+WDATA.box.width] + mov [esi+WDATA.box.left],ebx + .lp4: mov eax,[esi+WDATA.box.top] + add eax,[esi+WDATA.box.height] + mov ebx,[0x0000fe04] +; inc ebx + cmp eax,ebx + jle .lp6 + mov eax,[esi+WDATA.box.height] + sub eax,ebx + jle .lp5 + mov [esi+WDATA.box.height],ebx + .lp5: sub ebx,[esi+WDATA.box.height] + mov [esi+WDATA.box.top],ebx + .lp6: add esi,0x20 + loop @b + ret + +uglobal + common_colours: + times 128 db 0x0 +endg + + + + +check_window_position: + + pushad ; window inside screen ? + + movzx eax,word [edi+WDATA.box.left] + movzx ebx,word [edi+WDATA.box.top] + movzx ecx,word [edi+WDATA.box.width] + movzx edx,word [edi+WDATA.box.height] + + mov esi,ecx ; check x pos + add esi,eax + cmp esi,[0xfe00] + jbe x_pos_ok + mov [edi+WDATA.box.left],dword 0 + xor eax, eax + x_pos_ok: + + mov esi,edx ; check y pos + add esi,ebx + cmp esi,[0xfe04] + jbe y_pos_ok + mov [edi+WDATA.box.top],dword 0 + mov ebx,0 + y_pos_ok: + + mov esi,ecx ; check x size + add esi,eax + cmp esi,[0xfe00] + jbe x_size_ok + mov ecx,[0xfe00] + mov [edi+WDATA.box.width],ecx + x_size_ok: + + mov esi,edx ; check y size + add esi,ebx + cmp esi,[0xfe04] + jbe y_size_ok + mov edx,[0xfe04] + mov [edi+WDATA.box.height],edx + y_size_ok: + + popad + + ret + + +uglobal + new_window_starting dd 0 +endg + + +sys_window_mouse: + + push eax + + mov eax,[timer_ticks] + cmp [new_window_starting],eax + jb swml1 + + mov [0xfff4],byte 0 ; no mouse background + mov [0xfff5],byte 0 ; draw mouse + + mov [new_window_starting],eax + + swml1: + + pop eax + + ret + + + + +drawwindow_I_caption: + + mov ecx,[edx+WDATA.cl_titlebar] ; grab bar + push ecx + mov esi,edx + mov edx,[esi+WDATA.box.top] + add edx,1 + mov ebx,[esi+WDATA.box.top] + add ebx,21 + mov eax,[esi+WDATA.box.top] + add eax,[esi+WDATA.box.height] + cmp ebx,eax + jb .wdsizeok + mov ebx,eax + .wdsizeok: + push ebx + .drwi: + mov ebx,edx + shl ebx,16 + add ebx,edx + mov eax,[esi+WDATA.box.left] + inc eax + shl eax,16 + add eax,[esi+WDATA.box.left] + add eax,[esi+WDATA.box.width] + sub eax,1 + push edx + mov edx,0x80000000 + mov ecx,[esi+WDATA.cl_titlebar] + and ecx,edx + cmp ecx,edx + jnz .nofa + mov ecx,[esi+WDATA.cl_titlebar] + sub ecx,0x00040404 + mov [esi+WDATA.cl_titlebar],ecx + and ecx,0x00ffffff + jmp .faj + .nofa: + mov ecx,[esi+WDATA.cl_titlebar] + and ecx,0x00ffffff + .faj: + pop edx + mov edi,0 + call [draw_line] + inc edx + cmp edx,[esp] + jb .drwi + add esp,4 + pop ecx + mov [esi+WDATA.cl_titlebar],ecx + + ret + + +drawwindow_I: + + pushad + + mov esi,[edx+WDATA.cl_frames] ; rectangle + mov eax,[edx+WDATA.box.left] + shl eax,16 + add eax,[edx+WDATA.box.left] + add eax,[edx+WDATA.box.width] + mov ebx,[edx+WDATA.box.top] + shl ebx,16 + add ebx,[edx+WDATA.box.top] + add ebx,[edx+WDATA.box.height] + call draw_rectangle + + call drawwindow_I_caption + + mov edx,[esi+WDATA.box.top] ; inside work area + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg noinside + mov eax,1 + mov ebx,21 + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + mov edi,[esi+WDATA.cl_workarea] + call [drawbar] + noinside: + + popad + + ret + + +draw_rectangle: + +r_eax equ [esp+28] ; x start +r_ax equ [esp+30] ; x end +r_ebx equ [esp+16] ; y start +r_bx equ [esp+18] ; y end +;esi ; color + + pushad + + mov ecx,esi ; yb,xb -> yb,xe + mov eax, r_eax + rol eax, 16 + mov ebx,r_ebx + shl ebx,16 + mov bx,r_ebx + xor edi, edi + call [draw_line] + + mov ebx,r_bx ; ye,xb -> ye,xe + shl ebx,16 + mov bx,r_bx + call [draw_line] + + mov ecx,esi ; ya,xa -> ye,xa + mov eax,r_eax + shl eax,16 + mov ax,r_eax + mov ebx,r_ebx + shl ebx,16 + mov bx,r_bx + mov edi,0 + call [draw_line] + + mov eax,r_ax ; ya,xe -> ye,xe + shl eax,16 + mov ax,r_ax + call [draw_line] + + popad + ret + + +drawwindow_III_caption: + + mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR + push ecx + mov esi,edx + mov edx,[esi+WDATA.box.top] + add edx,4 + mov ebx,[esi+WDATA.box.top] + add ebx,20 + mov eax,[esi+WDATA.box.top] + add eax,[esi+WDATA.box.height] + cmp ebx,eax + jb .wdsizeok + mov ebx,eax + .wdsizeok: + push ebx + .drwi: + mov ebx,edx + shl ebx,16 + add ebx,edx + mov eax,[esi+WDATA.box.left] + shl eax,16 + add eax,[esi+WDATA.box.left] + add eax,[esi+WDATA.box.width] + add eax,4*65536-4 + mov ecx,[esi+WDATA.cl_titlebar] + test ecx,0x40000000 + jz .nofa + add ecx,0x040404 + .nofa: + test ecx,0x80000000 + jz .nofa2 + sub ecx,0x040404 + .nofa2: + mov [esi+WDATA.cl_titlebar],ecx + and ecx,0xffffff + xor edi, edi + call [draw_line] + inc edx + cmp edx,[esp] + jb .drwi + add esp,4 + pop ecx + mov [esi+WDATA.cl_titlebar],ecx + + ret + + +drawwindow_III: + + pushad + + mov edi,edx ; RECTANGLE + mov eax,[edi+WDATA.box.left] + shl eax,16 + mov ax, word [edi+WDATA.box.left] + add ax, word [edi+WDATA.box.width] + mov ebx,[edi+WDATA.box.top] + shl ebx,16 + mov bx, word [edi+WDATA.box.top] + add bx, word [edi+WDATA.box.height] + mov esi,[edi+WDATA.cl_frames] + shr esi,1 + and esi,0x007f7f7f + push esi + call draw_rectangle + mov ecx,3 + dw3l: + add eax,1*65536-1 + add ebx,1*65536-1 + mov esi,[edi+WDATA.cl_frames] + call draw_rectangle + dec ecx + jnz dw3l + pop esi + add eax,1*65536-1 + add ebx,1*65536-1 + call draw_rectangle + + call drawwindow_III_caption + + mov edx,[esi+WDATA.box.top] ; WORK AREA + add edx,21+5 + mov ebx,[esi+WDATA.box.top] + add ebx,[esi+WDATA.box.height] + cmp edx,ebx + jg noinside2 + mov eax,5 + mov ebx,20 + mov ecx,[esi+WDATA.box.width] + mov edx,[esi+WDATA.box.height] + sub ecx,4 + sub edx,4 + mov edi,[esi+WDATA.cl_workarea] + call [drawbar] + noinside2: + + popad + + ret + + + +; activate window +align 4 +windowactivate: + + ; esi = abs mem position in stack 0xC400+ + + pushad + + ; if type of current active window is 3, + ; it must be redrawn + mov eax, [0x3004] + movzx eax, word [0xC400 + eax*2] + shl eax, 5 + add eax, window_data + mov ebx, [eax + WDATA.cl_workarea] + and ebx, 0x0f000000 + cmp ebx, 0x03000000 + jne @f + mov [eax + WDATA.fl_redraw], byte 1 + @@: + + push esi + movzx eax, word [esi] ; ax <- process no + movzx eax, word [0xC000+eax*2] ; ax <- position in window stack + + xor esi, esi ; drop others + waloop: + cmp esi, dword [0x3004] + jae wacont + inc esi + lea edi, [0xC000 + esi*2] + mov bx, [edi] ; position of the current process + cmp bx, ax + jbe @f + dec bx ; upper? => drop! + mov [edi], bx + @@: + jmp waloop + wacont: + ; set to no 1 + pop esi ; esi = pointer at 0xC400 + + movzx eax, word [esi] + mov bx, [0x3004] ; number of processes + mov [0xC000+eax*2], bx ; this is the last (and the upper) + + ; update on screen -window stack + xor esi, esi + waloop2: + mov edi, [0x3004] + cmp esi, edi + jae wacont2 + inc esi + movzx ebx, word [esi*2 + 0xC000] + mov [ebx*2 + 0xC400], si + jmp waloop2 + wacont2: + mov [0xf400], byte 0 ; empty keyboard buffer + mov [0xf500], byte 0 ; empty button buffer + popad + ret + + +; check if window is necessary to draw + +checkwindowdraw: + + ; edi = position in window_data+ + + mov eax, [edi + WDATA.cl_workarea] + and eax, 0x0f000000 + cmp eax, 0x03000000 + je .return_yes ; window type 3 + + mov esi, edi + sub esi, window_data + shr esi, 5 + + ; esi = process number + + movzx eax, word [0xC000 + esi * 2] ; get value of the curr process + lea esi, [0xC400 + eax * 2] ; get address of this process at 0xC400 + + push esi + + .new_check: + + pop esi + add esi, 2 + push esi + + mov eax, [0x3004] + lea eax, word [0xC400 + eax * 2] ; number of the upper window + + cmp esi, eax + ja .all_wnds_to_top + + movzx eax, word [esi] + shl eax, 5 + cmp [0x3000 + eax + TASKDATA.state], byte 9 + je .new_check ; skip dead windows + + lea esi, [eax+window_data] + + mov ebx, [edi+WDATA.box.top] ; y0 + mov edx, [edi+WDATA.box.height] + add edx, ebx ; y0e + + mov ecx, [esi+WDATA.box.top] ; y ; y check + cmp ecx, edx + jae .new_check ; y < y0e + mov eax, [esi+WDATA.box.height] + add ecx, eax ; ye + cmp ebx, ecx ; y0 >= ye + ja .new_check + + mov eax, [edi+WDATA.box.left] ; x0 + mov ecx, [edi+WDATA.box.width] + add ecx, eax ; x0e + + mov edx, [esi+WDATA.box.left] ; x ; x check + cmp edx, ecx + jae .new_check ; x < x0e + mov ecx, [esi+WDATA.box.width] + add edx, ecx + cmp eax, edx + ja .new_check + + pop esi + .return_yes: + mov ecx,1 ; overlap some window + ret + + .all_wnds_to_top: + + pop esi + + xor ecx, ecx ; passed all windows to top + ret + + + + +waredraw: ; if redraw necessary at activate + + pushad + + call checkwindowdraw ; draw window on activation ? + test ecx, ecx + jz .do_not_draw + + popad + mov [0xfb44], byte 1 ; do draw mouse + call windowactivate + + ; update screen info + pushad + mov edi, [0x3004] ; the last process (number) + movzx esi, word [0xC400 + edi * 2] + shl esi, 5 + add esi, window_data + + ; coordinates of the upper window + mov eax, [esi + WDATA.box.left] ; cx + mov ebx, [esi + WDATA.box.top] ; cy + mov ecx, [esi + WDATA.box.width] ; sx + mov edx, [esi + WDATA.box.height] ; sy + + add ecx, eax ; ecx = x_end + add edx, ebx ; edx = y_end + + mov edi, [0x3004] + movzx esi, word [0xC400 + edi * 2] + call setscreen + popad + + mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app + mov [0xfb44],byte 0 ; mouse down checks + + ret + + .do_not_draw: + + popad + + call windowactivate + mov [0xfb44],byte 0 ; mouse down checks + mov [0xfff4],byte 0 ; no mouse background + mov [0xfff5],byte 0 ; draw mouse + ret + + +; eax = window number on screen +; corrupts registers and [dl*] +minimize_window: + movzx eax, word [0xC400+eax*2] + shl eax, 5 + add eax, window_data + test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .skip_redrawings + pushfd + cli + or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED + mov edi, eax + ;call calculatescreen + mov eax, [edi+WDATA.box.left] + mov [dlx], eax + mov ecx, eax + add ecx, [edi+WDATA.box.width] + mov [dlxe], ecx + mov ebx, [edi+WDATA.box.top] + mov [dly], ebx + mov edx, ebx + add edx, [edi+WDATA.box.height] + mov [dlye], edx + call calculatescreen + xor esi, esi + xor eax, eax + call redrawscreen + popfd +.skip_redrawings: + ret + +; eax = window number on screen +; corrupts registers and [dl*] +restore_minimized_window: + pushfd + cli + movzx esi, word [0xC400+eax*2] + mov edi, esi + shl edi, 5 + add edi, window_data + test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED + jz .skip_redrawings + mov [edi+WDATA.fl_redraw], 1 + and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED + cmp eax, [0x3004] ; the uppermost window + jnz .no_uppermost + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, eax + mov edx, ebx + add ecx, [edi+WDATA.box.width] + add edx, [edi+WDATA.box.height] + call setscreen + jmp .done +.no_uppermost: + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, eax + mov edx, ebx + add ecx, [edi+WDATA.box.width] + add edx, [edi+WDATA.box.height] + call calculatescreen +.done: + mov [0xfff4],byte 0 ; no mouse under +.skip_redrawings: + popfd + ret + + +iglobal + window_moving db 'K : Window - move/resize',13,10,0 + window_moved db 'K : Window - done',13,10,0 +endg + +; check window touch +align 4 +checkwindows: + pushad + + cmp [window_minimize], 0 + je .no_minimizing + mov eax, [0x3004] ; the uppermost window + mov bl, 0 + xchg [window_minimize], bl + cmp bl, 1 + jne .restore + call minimize_window + jmp .continue + .restore: + call restore_minimized_window + .continue: + .no_minimizing: + + cmp [0xfb40],byte 0 ; mouse buttons pressed ? + jne .mouse_buttons_pressed + popad + ret + .mouse_buttons_pressed: + + mov esi,[0x3004] + inc esi + + cwloop: + cmp esi,2 + jb .exit + + dec esi + movzx edi, word [0xC400 + esi * 2] ; ebx + shl edi, 5 + add edi, window_data +; mov edi, ebx + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + + mov eax,ecx + mov ebx,edx + test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED + jnz cwloop + + movzx eax, word [0xfb0a] + movzx ebx, word [0xfb0c] + + cmp ecx, eax + jae cwloop + cmp edx, ebx + jae cwloop + add ecx, [edi + WDATA.box.width] + add edx, [edi + WDATA.box.height] + cmp eax, ecx + jae cwloop + cmp ebx, edx + jae cwloop + + pushad + mov eax, esi + mov ebx, [0x3004] + cmp eax, ebx ; is this window active? + jz .move_resize_window + + ; eax = position in windowing stack + ; redraw must ? + lea esi, [0xC400 + esi * 2] + call waredraw + add esp, 32 + + .exit: + popad + ret + + .move_resize_window: ; MOVE OR RESIZE WINDOW + + popad + + ; Check for user enabled fixed window + mov edx, [edi + WDATA.cl_titlebar] + and edx, 0x0f000000 + cmp edx, 0x01000000 + jne .window_move_enabled_for_user + popad + ret + .window_move_enabled_for_user: + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .no_resize_2 + + mov [do_resize_from_corner],byte 0 ; resize for skinned window + mov edx, [edi + WDATA.cl_workarea] + and edx, 0x0f000000 + cmp edx, 0x02000000 + jb .no_resize_2 ; not type 2 wnd + + mov edx, [edi + WDATA.box.top] + add edx, [edi + WDATA.box.height] + sub edx, 6 ; edx = y_end - 6 + cmp ebx, edx ; ebx = mouse_y + jb .no_resize_2 + mov [do_resize_from_corner],byte 1 + jmp .continue + .no_resize_2: + + push eax + call get_titlebar_height + add eax,[edi + WDATA.box.top] + cmp ebx,eax + pop eax + jae .exit + + .continue: + + push esi + mov esi, window_moving + call sys_msg_board_str + pop esi + + mov ecx, [timer_ticks] ; double-click ? + mov edx, ecx + sub edx, [latest_window_touch] + mov [latest_window_touch], ecx + mov [latest_window_touch_delta], edx + + mov cl, [0xfb40] ; save for shade check + mov [do_resize], cl + no_emulation_righ_button: + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + + push eax ecx edx + mov [dlx], ecx ; save for drawlimits + mov [dly], edx + mov eax, [edi + WDATA.box.width] + add ecx, eax + mov eax, [edi + WDATA.box.height] + add edx, eax + mov [dlxe], ecx + mov [dlye], edx + pop edx ecx eax + + sub eax, ecx + sub ebx, edx + + mov esi, [0xfb0a] + mov [0xf300], esi + + pushad ; wait for putimages to finish +; mov eax,5 +; call delay_hs + mov eax,[edi + WDATA.box.left] + mov [npx],eax + mov eax,[edi + WDATA.box.top] + mov [npy],eax + popad + + push eax ; save old coordinates + mov ax, word [edi + WDATA.box.left] + mov word [oldc+BOX.left],ax + mov ax, word [edi + WDATA.box.top] + mov word [oldc+BOX.top],ax + mov ax, word [edi + WDATA.box.width] + mov word [oldc+BOX.width],ax + mov word [npxe],ax + mov ax, word [edi + WDATA.box.height] + mov word [oldc+BOX.height],ax + mov word [npye],ax + pop eax + + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz @f + call drawwindowframes + @@: + + mov [reposition],0 + mov [0xfb44],byte 1 ; no reaction to mouse up/down + + ; move window + + newchm: + + mov [0xfff5],byte 1 + + call checkidle + + call checkVga_N13 + + mov [0xfff4],byte 0 + + call [draw_pointer] + + pushad + call stack_handler + popad + + mov esi,[0xf300] + cmp esi,[0xfb0a] + je cwb + + mov cx,[0xfb0a] + mov dx,[0xfb0c] + sub cx,ax + sub dx,bx + + push ax + push bx + + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz @f + call drawwindowframes + @@: + + mov ax,[0xfe00] + mov bx,[0xfe04] + + cmp [do_resize_from_corner],1 + je no_new_position + + mov word [npx],word 0 ; x repos ? + cmp ax,cx + jb noreposx + mov [reposition],1 + sub ax,word [npxe] + mov word [npx],ax + cmp ax,cx + jb noreposx + mov word [npx],cx + noreposx: + + mov word [npy],word 0 ; y repos ? + cmp bx,dx + jb noreposy + mov [reposition],1 + sub bx,word [npye] + mov word [npy],bx + cmp bx,dx + jb noreposy + mov word [npy],dx + noreposy: + + no_new_position: + + cmp [do_resize_from_corner],0 ; resize from right corner + je norepos_size + pushad + + mov edx,edi + sub edx,window_data + ;shr edx,5 + ;shl edx,8 + ;add edx,0x80000 ; process base at 0x80000+ + lea edx, [0x80000 + edx*8] + + movzx eax,word [0xfb0a] + cmp eax,[edi + WDATA.box.left] + jb nnepx + sub eax,[edi + WDATA.box.left] + cmp eax,32 ; [edx+0x90+8] + jge nnepx2 + mov eax,32 ; [edx+0x90+8] + nnepx2: + mov [npxe],eax + nnepx: + + call get_rolledup_height + mov ebx,eax + movzx eax,word [0xfb0c] + cmp eax,[edi + WDATA.box.top] + jb nnepy + sub eax,[edi + WDATA.box.top] + cmp eax,ebx ; [edx+0x90+12] + jge nnepy2 + mov eax,ebx ; [edx+0x90+12] + nnepy2: + mov [npye],eax + nnepy: + + mov [reposition],1 + + popad + norepos_size: + + pop bx + pop ax + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz @f + call drawwindowframes + @@: + + mov esi,[0xfb0a] + mov [0xf300],esi + + cwb: + cmp [0xfb40],byte 0 + jne newchm + ; new position done + mov [0xfff5],byte 1 + mov cl,0 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz @f + mov cl,[reposition] + call drawwindowframes + + mov eax,[npx] + mov [edi + WDATA.box.left],eax + mov eax,[npy] + mov [edi + WDATA.box.top],eax + mov eax,[npxe] + mov [edi + WDATA.box.width],eax + mov eax,[npye] + mov [edi + WDATA.box.height],eax + + @@: mov [reposition],cl + + cmp [reposition],1 ; save new position and size + jne no_bounds_save + push esi edi ecx + mov esi,edi + mov ecx,2 + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED + jnz @f + add ecx,2 + @@: sub edi,window_data + shr edi,5 + shl edi,8 + add edi,0x80000+APPDATA.saved_box + cld + rep movsd + pop ecx edi esi + no_bounds_save: + + pushad ; WINDOW SHADE/FULLSCREEN + + cmp [reposition],1 + je no_window_sizing + mov edx,edi + sub edx,window_data + shr edx,5 + shl edx,8 + add edx,0x80000 ; process base at 0x80000+ + + cmp [do_resize],2 ; window shade ? + jne no_window_shade + mov [reposition],1 + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz wnd_rolldown + wnd_rollup: + or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + call get_rolledup_height + jmp @f + wnd_rolldown: + and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP + mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jz @f + mov eax,[screen_workarea.bottom] + sub eax,[screen_workarea.top] + @@: mov [edi+WDATA.box.height],eax + + no_window_shade: + + cmp [do_resize],1 ; fullscreen/restore ? + jne no_fullscreen_restore + cmp [latest_window_touch_delta],dword 50 + jg no_fullscreen_restore + mov [reposition],1 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz restore_from_fullscreen + or [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + mov eax,[screen_workarea.left] + mov [edi+WDATA.box.left],eax + sub eax,[screen_workarea.right] + neg eax + mov [edi+WDATA.box.width],eax + mov eax,[screen_workarea.top] + mov [edi+WDATA.box.top],eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz @f + sub eax,[screen_workarea.bottom] + neg eax + mov [edi+WDATA.box.height],eax + @@: + jmp no_fullscreen_restore + restore_from_fullscreen: + and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED + push [edi+WDATA.box.height] + push edi ; restore + lea esi, [edx + APPDATA.saved_box] + mov ecx,4 + cld + rep movsd + pop edi + pop eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jz @f + mov [edi+WDATA.box.height],eax + @@: + + no_fullscreen_restore: + + mov eax,[edi+WDATA.box.top] ; check Y inside screen + add eax,[edi+WDATA.box.height] + cmp eax,[0xfe04] + jbe no_window_sizing + mov eax,[edi+WDATA.box.left] ; check X inside screen + add eax,[edi+WDATA.box.width] + cmp eax,[0xfe00] + jbe no_window_sizing + mov eax,[0xfe00] + sub eax,[edi+WDATA.box.width] + mov [edi+WDATA.box.left],eax + mov eax,[0xfe04] + sub eax,[edi+WDATA.box.height] + mov [edi+WDATA.box.top],eax + no_window_sizing: + + popad + + cmp [reposition],0 + je retwm + + mov [0xfff5],byte 1 ; no mouse + + + push eax ebx ecx edx + mov eax,[edi+WDATA.box.left] + mov ebx,[edi+WDATA.box.top] + mov ecx,[edi+WDATA.box.width] + mov edx,[edi+WDATA.box.height] + add ecx,eax + add edx,ebx + call calculatescreen + + mov eax,[oldc+BOX.left] + mov ebx,[oldc+BOX.top] + mov ecx,[oldc+BOX.width] + mov edx,[oldc+BOX.height] + add ecx,eax + add edx,ebx + call calculatescreen + pop edx ecx ebx eax + + mov eax,edi + call redrawscreen + + + mov [edi+WDATA.fl_redraw],1 + + mov ecx,100 ; wait to avoid mouse residuals + waitre2: + mov [0xfff5],byte 1 + call checkidle + cmp [edi+WDATA.fl_redraw],0 + jz retwm + loop waitre2 + + retwm: + + mov [0xfff5],byte 0 ; mouse pointer + mov [0xfff4],byte 0 ; no mouse under + mov [0xfb44],byte 0 ; react to mouse up/down + + mov esi,window_moved + call sys_msg_board_str + + popad + + ret + + +uglobal + add_window_data dd 0 + do_resize_from_corner db 0x0 + reposition db 0x0 + latest_window_touch dd 0x0 + latest_window_touch_delta dd 0x0 + + do_resize db 0x0 + + oldc dd 0x0,0x0,0x0,0x0 + + dlx dd 0x0 + dly dd 0x0 + dlxe dd 0x0 + dlye dd 0x0 + + npx dd 0x0 + npy dd 0x0 + npxe dd 0x0 + npye dd 0x0 + + mpx dd 0x0 + mpy dd 0x0 +endg + + +; draw negative window frames + +drawwindowframes: + + pushad + + mov eax,[npx] + shl eax,16 + add eax,[npx] + add eax,[npxe] + add eax,65536*1-1 + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + mov ecx,0x01000000 + push edi + mov edi,1 + call [draw_line] + pop edi + + mov eax,[npx] + shl eax,16 + add eax,[npx] + add eax,[npxe] + add eax,65536*1-1 + mov ebx,[npy] + add ebx,[npye] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + mov ecx,0x01000000 + push edi + mov edi,1 + call [draw_line] + pop edi + + mov eax,[npx] + shl eax,16 + add eax,[npx] + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + mov ecx,0x01000000 + push edi + mov edi,1 + call [draw_line] + pop edi + + mov eax,[npx] + add eax,[npxe] + shl eax,16 + add eax,[npx] + add eax,[npxe] + mov ebx,[npy] + shl ebx,16 + add ebx,[npy] + add ebx,[npye] + mov ecx,0x01000000 + push edi + mov edi,1 + call [draw_line] + mov edi,[0x3000] + shl edi,5 + add edi,window_data + mov [edi+WDATA.fl_wdrawn],byte 1 + pop edi + + popad + + ret + + + +random_shaped_window: + +; +; eax = 0 giving address of data area +; ebx address +; eax = 1 shape area scale +; ebx 2^ebx scale + + test eax, eax + jne rsw_no_address + mov eax,[0x3000] + shl eax,8 + + mov [eax+0x80000+APPDATA.wnd_shape],ebx + rsw_no_address: + + cmp eax,1 + jne rsw_no_scale + mov eax,[0x3000] + shl eax,8 + mov byte [eax+0x80000+APPDATA.wnd_shape_scale], bl + rsw_no_scale: + + ret + + diff --git a/kernel/tags/kolibri0.6.0.0/hid/keyboard.inc b/kernel/tags/kolibri0.6.0.0/hid/keyboard.inc new file mode 100644 index 0000000000..8b293843ce --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/keyboard.inc @@ -0,0 +1,293 @@ +;// mike.dld [ + +VKEY_LSHIFT = 0000000000000001b +VKEY_RSHIFT = 0000000000000010b +VKEY_LCONTROL = 0000000000000100b +VKEY_RCONTROL = 0000000000001000b +VKEY_LALT = 0000000000010000b +VKEY_RALT = 0000000000100000b +VKEY_CAPSLOCK = 0000000001000000b +VKEY_NUMLOCK = 0000000010000000b +VKEY_SCRLOCK = 0000000100000000b + +VKEY_SHIFT = 0000000000000011b +VKEY_CONTROL = 0000000000001100b +VKEY_ALT = 0000000000110000b + +uglobal + align 4 + kb_state dd 0 + ext_code db 0 + + keyboard_mode db 0 + keyboard_data db 0 + + altmouseb db 0 + ctrl_alt_del db 0 + + kb_lights db 0 + +align 4 + hotkey_scancodes rd 256 ; we have 256 scancodes + hotkey_list rd 256*4 ; max 256 defined hotkeys + hotkey_buffer rd 120*2 ; buffer for 120 hotkeys +endg + +iglobal +hotkey_tests dd hotkey_test0 + dd hotkey_test1 + dd hotkey_test2 + dd hotkey_test3 + dd hotkey_test4 +hotkey_tests_num = 5 +endg + +hotkey_test0: + test al, al + setz al + ret +hotkey_test1: + test al, al + setnp al + ret +hotkey_test2: + cmp al, 3 + setz al + ret +hotkey_test3: + cmp al, 1 + setz al + ret +hotkey_test4: + cmp al, 2 + setz al + ret + +hotkey_do_test: + push eax + mov edx, [kb_state] + shr edx, cl + add cl, cl + mov eax, [eax+4] + shr eax, cl + and eax, 15 + cmp al, hotkey_tests_num + jae .fail + xchg eax, edx + and al, 3 + call [hotkey_tests + edx*4] + cmp al, 1 + pop eax + ret +.fail: + stc + pop eax + ret + +align 4 +irq1: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + + mov eax, [0x3004] ; top window process + movzx eax,word[0xC400+eax*2] + shl eax,8 + mov al,[0x80000+eax+APPDATA.keyboard_mode] + mov [keyboard_mode],al + + in al,0x60 + mov [keyboard_data],al + +; ch = scancode +; cl = ext_code +; bh = 0 - normal key +; bh = 1 - modifier (Shift/Ctrl/Alt) +; bh = 2 - extended code + + mov ch,al + cmp al,0xE0 + je @f + cmp al,0xE1 + jne .normal_code + @@: + mov bh, 2 + mov [ext_code], al + jmp .writekey + .normal_code: + mov cl, 0 + xchg cl, [ext_code] + and al,0x7F + mov bh, 1 + @@: cmp al,0x2A + jne @f + cmp cl,0xE0 + je .writekey + mov eax,VKEY_LSHIFT + jmp .modifier + @@: cmp al,0x36 + jne @f + cmp cl,0xE0 + je .writekey + mov eax,VKEY_RSHIFT + jmp .modifier + @@: cmp al,0x38 + jne @f + mov eax, VKEY_LALT + test cl, cl + jz .modifier + mov al, VKEY_RALT + jmp .modifier + @@: cmp al,0x1D + jne @f + mov eax, VKEY_LCONTROL + test cl, cl + jz .modifier + mov al, VKEY_RCONTROL + cmp cl, 0xE0 + jz .modifier + mov [ext_code], cl + jmp .writekey + @@: cmp al,0x3A + jne @f + mov bl,4 + mov eax,VKEY_CAPSLOCK + jmp .no_key.xor + @@: cmp al,0x45 + jne @f + test cl, cl + jnz .writekey + mov bl,2 + mov eax,VKEY_NUMLOCK + jmp .no_key.xor + @@: cmp al,0x46 + jne @f + mov bl,1 + mov eax,VKEY_SCRLOCK + jmp .no_key.xor + @@: + test ch,ch + js .writekey + movzx eax,ch ; plain key + mov bl,[keymap+eax] + mov edx,[kb_state] + test dl,VKEY_CONTROL ; ctrl alt del + jz .noctrlaltdel + test dl,VKEY_ALT + jz .noctrlaltdel + cmp ch,53h + jne .noctrlaltdel + mov [ctrl_alt_del],1 + .noctrlaltdel: + test dl,VKEY_CONTROL ; ctrl on ? + jz @f + sub bl,0x60 + @@: test dl,VKEY_SHIFT ; shift on ? + jz @f + mov bl,[keymap_shift+eax] + @@: test dl,VKEY_ALT ; alt on ? + jz @f + mov bl,[keymap_alt+eax] + @@: + mov bh, 0 + jmp .writekey +.modifier: + test ch, ch + js .modifier.up + or [kb_state], eax + jmp .writekey +.modifier.up: + not eax + and [kb_state], eax + jmp .writekey +.no_key.xor: + mov bh, 0 + test ch, ch + js .writekey + xor [kb_state], eax + xor [kb_lights], bl + call set_lights + +.writekey: +; test for system hotkeys + movzx eax, ch + cmp bh, 1 + ja .nohotkey + jb @f + xor eax, eax +@@: + mov eax, [hotkey_scancodes + eax*4] +.hotkey_loop: + test eax, eax + jz .nohotkey + mov cl, 0 + call hotkey_do_test + jc .hotkey_cont + mov cl, 2 + call hotkey_do_test + jc .hotkey_cont + mov cl, 4 + call hotkey_do_test + jnc .hotkey_found +.hotkey_cont: + mov eax, [eax] + jmp .hotkey_loop +.hotkey_found: + mov eax, [eax+8] +; put key in buffer for process in slot eax + mov edi, hotkey_buffer +@@: + cmp dword [edi], 0 + jz .found_free + add edi, 8 + cmp edi, hotkey_buffer+120*8 + jb @b +; no free space - replace first entry + mov edi, hotkey_buffer +.found_free: + mov [edi], eax + movzx eax, ch + cmp bh, 1 + jnz @f + xor eax, eax +@@: + mov [edi+4], ax + mov eax, [kb_state] + mov [edi+6], ax + jmp .exit.irq1 +.nohotkey: + cmp [keyboard_mode],0 ; return from keymap + jne .scancode + test bh, bh + jnz .exit.irq1 + test bl, bl + jz .exit.irq1 + jmp .dowrite +.scancode: + mov bl, ch +.dowrite: + movzx eax,byte[0xF400] + cmp al,120 + jae .exit.irq1 + inc eax + mov [0xF400],al + mov [0xF400+eax],bl + + .exit.irq1: + mov [check_idle_semaphore],5 + + mov al,0x20 ; ready for next irq + out 0x20,al + + restore_ring3_context + iret + +set_lights: + mov al,0xED + call kb_write + mov al,[kb_lights] + call kb_write + ret + +;// mike.dld ] diff --git a/kernel/tags/kolibri0.6.0.0/hid/m_com1.inc b/kernel/tags/kolibri0.6.0.0/hid/m_com1.inc new file mode 100644 index 0000000000..193b00caae --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/m_com1.inc @@ -0,0 +1,130 @@ +; Номер принимаемого от мыши байта +MouseByteNumber DB 0 +; Трехбайтовая структура данных, передаваемая мышью +FirstByte DB 0 +SecondByte DB 0 +ThirdByte DB 0 +timer_ticks_com dd 0 +;*************************************** +;* НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ * +;*************************************** +check_mouse_data_com1: +; cmp [com1_mouse_detected],0 +; je @@EndMouseInterrupt +; Проверить наличие данных + mov DX,3F8h ;[COMPortBaseAddr] + add DX,5 ;xFDh + in AL,DX + test AL,1 ;Данные готовы? + jz @@Error +; Ввести данные + mov DX,3F8h ;[COMPortBaseAddr] ;xF8h + in AL,DX +; Сбросить старший незначащий бит + and AL,01111111b + +; Определить порядковый номер принимаемого байта + cmp [MouseByteNumber],0 + je @@FirstByte + cmp [MouseByteNumber],1 + je @@SecondByte + cmp [MouseByteNumber],2 + je @@ThirdByte + jmp @@Error + +; Сохранить первый байт данных +@@FirstByte: + test AL,1000000b ;Первый байт посылки? + jz @@Error + mov [FirstByte],AL + inc [MouseByteNumber] ;увеличить счетчик + jmp @@EndMouseInterrupt +; Сохранить второй байт данных +@@SecondByte: + test AL,1000000b + jnz @@Error + mov [SecondByte],AL + inc [MouseByteNumber] ;увеличить счетчик + jmp @@EndMouseInterrupt +; Сохранить третий байт данных +@@ThirdByte: + test AL,1000000b + jnz @@Error + mov [ThirdByte],AL ;увеличить счетчик + mov [MouseByteNumber],0 +; (Пакет данных от мыши принят полностью). +; Записать новое значение состояния кнопок мыши + mov al,[FirstByte] ;[0xfb01] + mov ah,al + shr al,3 + and al,2 + shr ah,5 + and ah,1 + add al,ah + mov [0xfb40],al + mov [mouse_active],1 +; Прибавить перемещение по X к координате X + mov AL,[FirstByte] + shl AL,6 + or AL,[SecondByte] + cbw + call mouse_acceleration_com1 + add AX,[0xFB0A] ;[XCoordinate] + ; Курсор не должен выходить за левую или + ; правую границу экрана + js @@X1 + cmp AX,[0xFE00] ;ScreenLength + jb @@X2 + ; Установить координату X по правой границе + mov AX,[0xFE00] ;ScreenLength-1 + dec ax + jmp @@X2 +@@X1: + ; Установить координату X по левой границе + xor AX,AX +@@X2: + mov [0xFB0A],AX ;[XCoordinate] + ; Прибавить перемещение по Y к координате Y + mov AL,[FirstByte] + and AL,00001100b + shl AL,4 + or AL,[ThirdByte] + cbw + call mouse_acceleration_com1 + add AX,[0xFB0C] ;[YCoordinate] + ; Курсор не должен выходить за верхнюю или + ; нижнюю границу экрана + js @@Y1 + cmp AX,[0xFE04] ;ScreenHeigth + jb @@Y2 + ; Установить координату X по нижней границе + mov AX,[0xFE04] ;ScreenHeigth-1 + dec ax + jmp @@Y2 +@@Y1: + ; Установить координату X по верхней границе + xor AX,AX +@@Y2: + mov [0xFB0C],AX ;[YCoordinate] + mov eax,[timer_ticks] + mov [timer_ticks_com],eax + jmp @@EndMouseInterrupt + +@@Error: +; Произошел сбой в порядке передачи информации от +; мыши, обнулить счетчик байтов пакета данных + mov [MouseByteNumber],0 +@@EndMouseInterrupt: + call ready_for_next_irq + ret + +mouse_acceleration_com1: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_com] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret diff --git a/kernel/tags/kolibri0.6.0.0/hid/m_com2.inc b/kernel/tags/kolibri0.6.0.0/hid/m_com2.inc new file mode 100644 index 0000000000..a84b5663c6 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/m_com2.inc @@ -0,0 +1,130 @@ +; Номер принимаемого от мыши байта +MouseByteNumber_1 DB 0 +; Трехбайтовая структура данных, передаваемая мышью +FirstByte_1 DB 0 +SecondByte_1 DB 0 +ThirdByte_1 DB 0 +timer_ticks_com_1 dd 0 +;*************************************** +;* НОВЫЙ ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ * +;*************************************** +check_mouse_data_com2: +; cmp [com2_mouse_detected],0 +; je @@EndMouseInterrupt_1 +; Проверить наличие данных + mov DX,2F8h ;[COMPortBaseAddr] + add DX,5 ;xFDh + in AL,DX + test AL,1 ;Данные готовы? + jz @@Error_1 +; Ввести данные + mov DX,2F8h ;[COMPortBaseAddr] ;xF8h + in AL,DX +; Сбросить старший незначащий бит + and AL,01111111b + +; Определить порядковый номер принимаемого байта + cmp [MouseByteNumber_1],0 + je @@FirstByte_1 + cmp [MouseByteNumber_1],1 + je @@SecondByte_1 + cmp [MouseByteNumber_1],2 + je @@ThirdByte_1 + jmp @@Error_1 + +; Сохранить первый байт данных +@@FirstByte_1: + test AL,1000000b ;Первый байт посылки? + jz @@Error_1 + mov [FirstByte_1],AL + inc [MouseByteNumber_1] ;увеличить счетчик + jmp @@EndMouseInterrupt_1 +; Сохранить второй байт данных +@@SecondByte_1: + test AL,1000000b + jnz @@Error_1 + mov [SecondByte_1],AL + inc [MouseByteNumber_1] ;увеличить счетчик + jmp @@EndMouseInterrupt_1 +; Сохранить третий байт данных +@@ThirdByte_1: + test AL,1000000b + jnz @@Error_1 + mov [ThirdByte_1],AL ;увеличить счетчик + mov [MouseByteNumber_1],0 +; (Пакет данных от мыши принят полностью). +; Записать новое значение состояния кнопок мыши + mov al,[FirstByte_1] ;[0xfb01] + mov ah,al + shr al,3 + and al,2 + shr ah,5 + and ah,1 + add al,ah + mov [0xfb40],al + mov [mouse_active],1 +; Прибавить перемещение по X к координате X + mov AL,[FirstByte_1] + shl AL,6 + or AL,[SecondByte_1] + cbw + call mouse_acceleration_com2 + add AX,[0xFB0A] ;[XCoordinate] + ; Курсор не должен выходить за левую или + ; правую границу экрана + js @@X1_1 + cmp AX,[0xFE00] ;ScreenLength + jb @@X2_1 + ; Установить координату X по правой границе + mov AX,[0xFE00] ;ScreenLength-1 + dec ax + jmp @@X2_1 +@@X1_1: + ; Установить координату X по левой границе + xor AX,AX +@@X2_1: + mov [0xFB0A],AX ;[XCoordinate] + ; Прибавить перемещение по Y к координате Y + mov AL,[FirstByte_1] + and AL,00001100b + shl AL,4 + or AL,[ThirdByte_1] + cbw + call mouse_acceleration_com2 + add AX,[0xFB0C] ;[YCoordinate] + ; Курсор не должен выходить за верхнюю или + ; нижнюю границу экрана + js @@Y1_1 + cmp AX,[0xFE04] ;ScreenHeigth + jb @@Y2_1 + ; Установить координату X по нижней границе + mov AX,[0xFE04] ;ScreenHeigth-1 + dec ax + jmp @@Y2_1 +@@Y1_1: + ; Установить координату X по верхней границе + xor AX,AX +@@Y2_1: + mov [0xFB0C],AX ;[YCoordinate] + mov eax,[timer_ticks] + mov [timer_ticks_com_1],eax + jmp @@EndMouseInterrupt_1 + +@@Error_1: +; Произошел сбой в порядке передачи информации от +; мыши, обнулить счетчик байтов пакета данных + mov [MouseByteNumber_1],0 +@@EndMouseInterrupt_1: + call ready_for_next_irq + ret + +mouse_acceleration_com2: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_com_1] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret diff --git a/kernel/tags/kolibri0.6.0.0/hid/m_ps2.inc b/kernel/tags/kolibri0.6.0.0/hid/m_ps2.inc new file mode 100644 index 0000000000..460d27385f --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/m_ps2.inc @@ -0,0 +1,170 @@ +; Номер принимаемого от мыши байта +MouseByteNumber_2 DB 0 +; Трехбайтовая структура данных, передаваемая мышью +FirstByte_2 DB 0 +SecondByte_2 DB 0 +ThirdByte_2 DB 0 +timer_ticks_ps2 dd 0 + +;************************************** +;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ МЫШИ PS/2 * +;************************************** +check_mouse_data_ps2: + cmp [ps2_mouse_detected],0 + je @@EndMouseInterrupt_2 + call Wait8042BufferEmpty ;очистка буфера + in AL,0x60 ;получить скэн-код +; Выбирать порядковый номер принимаемого байта + cmp [MouseByteNumber_2],0 + je @@SaveFirstByte + cmp [MouseByteNumber_2],1 + je @@SaveSecondByte + cmp [MouseByteNumber_2],2 + je @@SaveThirdByte + jmp @@Error_2 +; Записать первый байт посылки +@@SaveFirstByte: + test AL,1000b ;первый байт посылки? + jz @@Error_2 ;сбой синхронизации + mov [FirstByte_2],AL + inc [MouseByteNumber_2] + jmp @@EndMouseInterrupt_2 +; Записать второй байт посылки +@@SaveSecondByte: + mov [SecondByte_2],AL + inc [MouseByteNumber_2] + jmp @@EndMouseInterrupt_2 +; Записать третий байт посылки +@@SaveThirdByte: + mov [ThirdByte_2],AL + mov [MouseByteNumber_2],0 +; (пакет данных от мыши принят полностью) +; Записать новое значение байта состояния кнопок + mov al,[FirstByte_2] ;[0xfb01] + and eax,3 + mov [0xfb40],al + mov [mouse_active],1 +; Вычислить новую X-координату курсора + ; Занести в AX перемещение по X + mov AH,0 ;дублируем знак во все разряды AH + mov AL,[FirstByte_2] + test AL,10000b + jz @@M0 + mov AH,0FFh + ; Занести в AL младший байт +@@M0: + mov AL,[SecondByte_2] + call mouse_acceleration_ps2 + ; Вычислить новое значение координаты + ; курсора по X + add AX,[0xFB0A] ;[XCoordinate] + cmp AX,0 + jge @@M1 + mov AX,0 + jmp @@M2 +@@M1: + cmp AX,[0xFE00] ;ScreenLength + jl @@M2 + mov AX,[0xFE00] ;ScreenLength-1 + dec ax +@@M2: + mov [0xFB0A],AX ;[XCoordinate] + +; Вычисляем новую Y-координату курсора + ; Занести в AX перемещение по Y + mov AH,0 ;дублируем знак во все разряды AH + mov AL,[FirstByte_2] + test AL,100000b + jz @@M3 + mov AH,0FFh + ; Занести в AL младший байт +@@M3: + mov AL,[ThirdByte_2] + call mouse_acceleration_ps2 + ; Вычислить новое значение координаты курсора + ; по Y (Y-координата мыши PS/2 направлена + ; противоположно экранной) + neg AX + add AX,[0xFB0C] ;[YCoordinate] + cmp AX,0 + jge @@M4 + mov AX,0 + jmp @@M5 +@@M4: + cmp AX,[0xFE04] ;ScreenHeigth + jl @@M5 + mov AX,[0xFE04] ;ScreenHeigth-1 + dec ax +@@M5: + mov [0xFB0C],AX ;[YCoordinate] + +; Показать курсор в новой позиции + mov eax,[timer_ticks] + mov [timer_ticks_ps2],eax + jmp @@EndMouseInterrupt_2 + +; Обнаружен сбой в порядке передачи информации от мыши +@@Error_2: + mov [MouseByteNumber_2],0 +; Нормальное завершение прерывания +@@EndMouseInterrupt_2: + call ready_for_next_irq_1 + ret + +mouse_acceleration_ps2: + push eax + mov eax,[timer_ticks] + sub eax,[timer_ticks_ps2] + cmp eax,[mouse_delay] + pop eax + ja @f + imul ax,[mouse_speed_factor] +@@: + ret +;*********************************************** +;* ОЖИДАНИЕ ОЧИСТКИ ВХОДНОГО БУФЕРА I8042 * +;* При выходе из процедуры: * +;* флаг ZF установлен - нормальное завершение, * +;* флаг ZF сброшен - ошибка тайм-аута. * +;*********************************************** +Wait8042BufferEmpty: +; push CX +; mov CX,0FFFFh ;задать число циклов ожидания +;@@kb: +; in AL,64h ;получить статус +; test AL,10b ;буфер i8042 свободен? +; loopnz @@kb ;если нет, то цикл +; pop CX + push ecx + xor ecx,ecx + @@: + in al,64h + test al,00000010b + loopnz @b + pop ecx + ;Если при выходе из подпрограммы сброшен + ;флаг ZF - ошибка + ret ;возврат в подпрограмму + +;*************************************** +;* ОЖИДАНИЕ ПОСТУПЛЕНИЯ ДАННЫХ ОТ МЫШИ * +;*************************************** +WaitMouseData: +; push CX +; mov CX,0FFFFh ;задать число циклов ожидания +;@@mouse: +; in AL,64h ;опросить регистр статуса +; test AL,100000b ;данные поступили? +; loopz @@mouse ;если нет, то цикл +; pop CX + push ecx + mov ECX,0FFFFh + @@: + in al,64h + test al,100000b + loopz @b + pop ecx + ;Если при выходе из подпрограммы установлен + ;флаг ZF - ошибка + ret + diff --git a/kernel/tags/kolibri0.6.0.0/hid/mousedrv.inc b/kernel/tags/kolibri0.6.0.0/hid/mousedrv.inc new file mode 100644 index 0000000000..8fa684ea48 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/mousedrv.inc @@ -0,0 +1,331 @@ +; check mouse +; +; +; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y +; FB10 -> FB17 mouse color mem +; FB21 x move +; FB22 y move +; FB30 color temp +; FB28 high bits temp +; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under +; FC00 -> FCFE com1/ps2 buffer +; FCFF com1/ps2 buffer count starting from FC00 + +uglobal + mousecount dd 0x0 + mousedata dd 0x0 +endg + +mouse_delay dd 10 +mouse_speed_factor dw 3 + +include 'm_ps2.inc' +include 'm_com1.inc' +include 'm_com2.inc' + + +;test_mario79: +; push esi +; push eax +; mov [write_error_to],process_test_m79+43 +; movzx eax,al ;[DevErrorCode] +; call writehex +; mov esi,process_test_m79 +; call sys_msg_board_str +; pop eax +; pop esi +; ret +;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0 + +draw_mouse_under: + ; return old picture + pushad + xor ecx,ecx + xor edx,edx + align 4 +mres: + movzx eax,word [0xfb4a] + movzx ebx,word [0xfb4c] + add eax,ecx + add ebx,edx + push ecx + push edx + push eax + push ebx + mov eax,edx + shl eax,6 + shl ecx,2 + add eax,ecx + add eax,mouseunder + mov ecx,[eax] + pop ebx + pop eax + mov edi, 1 ;force + call [putpixel] + pop edx + pop ecx + inc ecx + cmp ecx, 16 + jnz mres + xor ecx, ecx + inc edx + cmp edx, 24 + jnz mres + popad + ret + +save_draw_mouse: + pushad + ; save & draw + mov [0xfb4a],ax + mov [0xfb4c],bx + push eax + push ebx + mov ecx,0 + mov edx,0 + align 4 +drm: + push eax + push ebx + push ecx + push edx + ; helloworld + push ecx + add eax,ecx ; save picture under mouse + add ebx,edx + push ecx + call getpixel + mov [0xfb30],ecx + pop ecx + mov eax,edx + shl eax,6 + shl ecx,2 + add eax,ecx + add eax,mouseunder + mov ebx,[0xfb30] + mov [eax],ebx + pop ecx + mov edi,edx ; y cycle + shl edi,4 ; *16 bytes per row + add edi,ecx ; x cycle + mov esi, edi + add edi, esi + add edi, esi ; *3 + add edi,[0xf200] ; we have our str address + mov esi, edi + add esi, 16*24*3 + push ecx + mov ecx, [0xfb30] + call combine_colors + mov [0xfb10], ecx + pop ecx + pop edx + pop ecx + pop ebx + pop eax + add eax,ecx ; we have x coord+cycle + add ebx,edx ; and y coord+cycle + push ecx + mov ecx, [0xfb10] + mov edi, 1 + call [putpixel] + pop ecx + mov ebx,[esp+0] ; pure y coord again + mov eax,[esp+4] ; and x + inc ecx ; +1 cycle + cmp ecx,16 ; if more than 16 + jnz drm + xor ecx, ecx + inc edx + cmp edx,24 + jnz drm + add esp,8 + popad + ret + + +combine_colors: + ; in + ; ecx - color ( 00 RR GG BB ) + ; edi - ref to new color byte + ; esi - ref to alpha byte + ; + ; out + ; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) + push eax + push ebx + push edx + push ecx + xor ecx, ecx + ; byte 2 + mov eax, 0xff + sub al, [esi+0] + mov ebx, [esp] + shr ebx, 16 + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+0] + mov bl, [esi+0] + mul ebx + shr eax, 8 + add ecx, eax + shl ecx, 8 + ; byte 1 + mov eax, 0xff + sub al, [esi+1] + mov ebx, [esp] + shr ebx, 8 + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+1] + mov bl, [esi+1] + mul ebx + shr eax, 8 + add ecx, eax + shl ecx, 8 + ; byte 2 + mov eax, 0xff + sub al, [esi+2] + mov ebx, [esp] + and ebx, 0xff + mul ebx + shr eax, 8 + add ecx, eax + xor eax, eax + xor ebx, ebx + mov al, [edi+2] + mov bl, [esi+2] + mul ebx + shr eax, 8 + add ecx, eax + pop eax + pop edx + pop ebx + pop eax + ret + + +__sys_disable_mouse: + cmp dword [0xf204],dword 0 + je @f + ret +@@: + pushad + cmp [0x3000],dword 1 + je disable_m + mov edx,[0x3000] + shl edx,5 + add edx,window_data + movzx eax, word [0xfb0a] + movzx ebx, word [0xfb0c] + mov ecx,[0xfe00] + inc ecx + imul ecx,ebx + add ecx,eax + add ecx, display_data + mov eax, [0x3000] + movzx ebx, byte [ecx] + cmp eax,ebx + je yes_mouse_disable + movzx ebx, byte [ecx+16] + cmp eax,ebx + je yes_mouse_disable + mov ebx,[0xfe00] + inc ebx + imul ebx,10 + add ecx,ebx + movzx ebx, byte [ecx] + cmp eax,ebx + je yes_mouse_disable + movzx ebx, byte [ecx+16] + cmp eax,ebx + je yes_mouse_disable + jmp no_mouse_disable +yes_mouse_disable: + mov edx,[0x3000] + shl edx,5 + add edx,window_data + movzx eax, word [0xfb0a] + movzx ebx, word [0xfb0c] + mov ecx,[edx+0] ; mouse inside the area ? + add eax,14 + cmp eax,ecx + jb no_mouse_disable + sub eax,14 + add ecx,[edx+8] + cmp eax,ecx + jg no_mouse_disable + mov ecx,[edx+4] + add ebx,20 + cmp ebx,ecx + jb no_mouse_disable + sub ebx,20 + add ecx,[edx+12] + cmp ebx,ecx + jg no_mouse_disable +disable_m: + cmp dword [0xf204],dword 0 + jne no_mouse_disable + cli + call draw_mouse_under + sti + mov [0xf204],dword 1 +no_mouse_disable: + popad + ret + +__sys_draw_pointer: + cmp [mouse_pause],0 + je @f + ret +@@: + push eax + mov eax,[timer_ticks] + sub eax,[MouseTickCounter] + cmp eax,1 + ja @f + pop eax + ret +@@: + mov eax,[timer_ticks] + mov [MouseTickCounter],eax + pop eax + pushad + cmp dword [0xf204],dword 0 ; mouse visible ? + je chms00 + mov [0xf204], dword 0 + movzx ebx,word [0xfb0c] + movzx eax,word [0xfb0a] + cli + call save_draw_mouse + sti +nodmu2: + popad + ret +chms00: + movzx ecx,word [0xfb4a] + movzx edx,word [0xfb4c] + movzx ebx,word [0xfb0c] + movzx eax,word [0xfb0a] + cmp eax,ecx + jne redrawmouse + cmp ebx,edx + jne redrawmouse + jmp nodmp +redrawmouse: + cli + call draw_mouse_under + call save_draw_mouse + sti +nodmp: + popad + ret + diff --git a/kernel/tags/kolibri0.6.0.0/hid/set_dtc.inc b/kernel/tags/kolibri0.6.0.0/hid/set_dtc.inc new file mode 100644 index 0000000000..479ebce80c --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/hid/set_dtc.inc @@ -0,0 +1,191 @@ +;setting date,time,clock and alarm-clock +;add sys_settime at servetable as for ex. 22 fcn: +; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK +; ebx =0 - set time ecx - 00SSMMHH +; ebx =1 - set date ecx=00DDMMYY +; ebx =2 - set day of week ecx- 1-7 +; ebx =3 - set alarm-clock ecx - 00SSMMHH +; out: 0 -Ok 1 -wrong format 2 -battery low +sys_settime: + mov ecx,eax + cli + mov al,0x0d + out 0x70,al + in al,0x71 + bt ax,7 + jnc bat_low + cmp ecx,2 ;day of week + jne nosetweek + test ebx,ebx ;test day of week + je wrongtime + cmp ebx,7 + ja wrongtime + mov dx,0x70 + call startstopclk + dec edx + mov al,6 + out dx,al + inc edx + mov al,bl + out dx,al + jmp endsettime + nosetweek: ;set date + cmp ecx,1 + jne nosetdate + cmp bl,0x99 ;test year + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + cmp bh,0x99 ;test month + ja wrongtime + shr ebx,4 + test bh,bh + je wrongtime + cmp bh,0x12 + ja wrongtime + shl ebx,8 + bswap ebx ;ebx=00YYMMDD + test bl,bl ;test day + je wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + shr ebx,4 + cmp bh,2 ;February + jne testday + cmp bl,0x29 + ja wrongtime + jmp setdate + testday: + cmp bh,8 + jb testday1 ;Aug-Dec + bt bx,8 + jnc days31 + jmp days30 + testday1: + bt bx,8 ;Jan-Jul ex.Feb + jnc days30 + days31: + cmp bl,0x31 + ja wrongtime + jmp setdate + days30: + cmp bl,0x30 + ja wrongtime + setdate: + mov dx,0x70 + call startstopclk + dec edx + mov al,7 ;set days + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,8 ;set months + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,9 ;set years + out dx,al + inc edx + shr ebx,8 + mov al,bh + out dx,al + jmp endsettime + nosetdate: ;set time or alarm-clock + cmp ecx,3 + ja wrongtime + cmp bl,0x23 + ja wrongtime + cmp bh,0x59 + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + cmp bh,0x92 + ja wrongtime + shl ebx,4 + bswap ebx ;00HHMMSS + cmp bl,0x59 + ja wrongtime + shl ebx,4 + cmp bl,0x90 + ja wrongtime + shr ebx,4 + mov dx,0x70 + call startstopclk + dec edx + cmp ecx,3 + je setalarm + xor eax,eax ;al=0-set seconds + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,2 ;set minutes + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,4 ;set hours + out dx,al + inc edx + shr ebx,8 + mov al,bh + out dx,al + jmp endsettime + setalarm: + mov al,1 ;set seconds for al. + out dx,al + inc edx + mov al,bl + out dx,al + dec edx + mov al,3 ;set minutes for al. + out dx,al + inc edx + mov al,bh + out dx,al + dec edx + mov al,5 ;set hours for al. + out dx,al + inc edx + shr ebx,8 + mov al,bh + out dx,al + dec edx + mov al,0x0b ;enable irq's + out dx,al + inc dx + in al,dx + bts ax,5 ;set bit 5 + out dx,al + endsettime: + dec edx + call startstopclk + sti + mov [esp+36],dword 0 + ret + bat_low: + sti + mov [esp+36],dword 2 + ret + wrongtime: + sti + mov [esp+36],dword 1 + ret + +startstopclk: + mov al,0x0b + out dx,al + inc dx + in al,dx + btc ax,7 + out dx,al + ret diff --git a/kernel/tags/kolibri0.6.0.0/kernel.asm b/kernel/tags/kolibri0.6.0.0/kernel.asm new file mode 100644 index 0000000000..5cc32ee5ff --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/kernel.asm @@ -0,0 +1,5241 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Kolibri OS - based on source code Menuet OS, but not 100% compatible. +;; +;; See file COPYING or GNU.TXT for details with these additional details: +;; - All code written in 32 bit x86 assembly language +;; - No external code (eg. bios) at process execution time +;; +;; +;; Compile with last version FASM +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +include "kglobals.inc" +include "lang.inc" + +WinMapAddress equ 0x460000 +display_data = 0x460000 + +max_processes equ 255 + +window_data equ 0x0000 +tss_data equ 0xD20000 +;tss_step equ (128+2048) ; tss & i/o - 16384 ports, * 256=557056 +tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 +draw_data equ 0xC00000 +sysint_stack_data equ 0xC03000 + + +twdw equ (0x3000-window_data) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Included files: +;; +;; Kernel16.inc +;; - Booteng.inc English text for bootup +;; - Bootcode.inc Hardware setup +;; - Pci16.inc PCI functions +;; +;; Kernel32.inc +;; - Sys32.inc Process management +;; - Shutdown.inc Shutdown and restart +;; - Fat32.inc Read / write hd +;; - Vesa12.inc Vesa 1.2 driver +;; - Vesa20.inc Vesa 2.0 driver +;; - Vga.inc VGA driver +;; - Stack.inc Network interface +;; - Mouse.inc Mouse pointer +;; - Scincode.inc Window skinning +;; - Pci32.inc PCI functions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 16 BIT ENTRY FROM BOOTSECTOR ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +use16 + org 0x0 + jmp start_of_code + +; mike.dld { + org $+0x10000 +db 0 +dd servetable-0x10000 +draw_line dd __sys_draw_line +disable_mouse dd __sys_disable_mouse +draw_pointer dd __sys_draw_pointer +;//mike.dld, 2006-08-02 [ +;drawbar dd __sys_drawbar +drawbar dd __sys_drawbar.forced +;//mike.dld, 2006-08-02 ] +putpixel dd __sys_putpixel +; } mike.dld + +version db 'Kolibri OS version 0.6.0.0 ',13,10,13,10,0 + ;dd endofcode-0x10000 + + ;db 'Boot02' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +include "boot/preboot.inc" +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +preboot_lfb db 0 +preboot_bootlog db 0 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 16 BIT INCLUDED FILES ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +include "kernel16.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SWITCH TO 32 BIT PROTECTED MODE ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +os_data = os_data_l-gdts ; GDTs +os_code = os_code_l-gdts +int_code equ int_code_l-gdts +int_data equ int_data_l-gdts +tss0sys equ tss0sys_l-gdts +graph_data equ 3+graph_data_l-gdts +tss0 equ tss0_l-gdts +app_code equ 3+app_code_l-gdts +app_data equ 3+app_data_l-gdts + + + +; CR0 Flags - Protected mode and Paging + + mov ecx,0x00000001 + ;and ebx,65535 + ;cmp ebx,00100000000000000b ; lfb -> paging + ;jb no_paging + ;mov ax,0x0000 + ;mov es,ax + ;mov al,[es:0x901E] + ;cmp al,1 + ;je no_paging + ;or ecx, 0x80000000 + ;no_paging: + +; Enabling 32 bit protected mode + + sidt [cs:old_ints_h-0x10000] + + cli ; disable all irqs + cld + mov al,255 ; mask all irqs + out 0xa1,al + out 0x21,al + l.5: in al, 0x64 ; Enable A20 + test al, 2 + jnz l.5 + mov al, 0xD1 + out 0x64, al + l.6: in al, 0x64 + test al, 2 + jnz l.6 + mov al, 0xDF + out 0x60, al + lgdt [cs:gdts-0x10000] ; Load GDT + mov eax, cr0 ; Turn on paging // protected mode + or eax, ecx + and eax, 10011111b *65536*256 + 0xffffff ; caching enabled + mov cr0, eax + jmp $+2 +org $+0x10000 + mov ax,os_data ; Selector for os + mov ds,ax + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + mov esp,0x3ec00 ; Set stack + jmp pword os_code:B32 ; jmp to enable 32 bit mode + +use32 + +iglobal + boot_memdetect db 'Determining amount of memory',0 + boot_fonts db 'Fonts loaded',0 + boot_tss db 'Setting TSSs',0 + boot_cpuid db 'Reading CPUIDs',0 + boot_devices db 'Detecting devices',0 + boot_timer db 'Setting timer',0 + boot_irqs db 'Reprogramming IRQs',0 + boot_setmouse db 'Setting mouse',0 + boot_windefs db 'Setting window defaults',0 + boot_bgr db 'Calculating background',0 + boot_resirqports db 'Reserving IRQs & ports',0 + boot_setrports db 'Setting addresses for IRQs',0 + boot_setostask db 'Setting OS task',0 + boot_allirqs db 'Unmasking all IRQs',0 + boot_tsc db 'Reading TSC',0 + boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 + boot_pal_vga db 'Setting VGA 640x480 palette',0 + boot_mtrr db 'Setting MTRR',0 + boot_tasking db 'All set - press ESC to start',0 +endg + +iglobal + boot_y dd 10 +endg + +boot_log: + pushad + + mov eax,10*65536 + mov ax,word [boot_y] + add [boot_y],dword 10 + mov ebx,0x80ffffff ; ASCIIZ string with white color + mov ecx,esi + mov edi,1 + call dtext + + mov [novesachecksum],1000 + call checkVga_N13 + + cmp [preboot_blogesc],byte 1 + je .bll2 + + cmp esi,boot_tasking + jne .bll2 + ; begin ealex 04.08.05 +; in al,0x61 +; and al,01111111b +; out 0x61,al + ; end ealex 04.08.05 +.bll1: in al,0x60 ; wait for ESC key press + cmp al,129 + jne .bll1 + +.bll2: popad + + ret + +uglobal + cpuid_0 dd 0,0,0,0 + cpuid_1 dd 0,0,0,0 + cpuid_2 dd 0,0,0,0 + cpuid_3 dd 0,0,0,0 +endg + +iglobal + firstapp db '/rd/1/LAUNCHER',0 + char db 'CHAR MT ' + char2 db 'CHAR2 MT ' + bootpath db '/KOLIBRI ' + bootpath2 db 0 + vmode db 'VMODE MDR' + vrr_m db '/rd/1/VRR_M',0 +endg + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 32 BIT ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 + +B32: +; CLEAR 0x280000-0xF00000 + + xor eax,eax + mov edi,0x280000 + mov ecx,(0x100000*0xF-0x280000) / 4 + cld + rep stosd +; CLEAR 0x80000-0x90000 +; xor eax,eax + mov edi,0x80000 + mov ecx,(0x90000-0x80000)/4 +; cld + rep stosd + +; CLEAR KERNEL UNDEFINED GLOBALS + mov edi, endofcode + mov ecx, (uglobals_size/4)+4 + rep stosd + +; SAVE & CLEAR 0-0xffff + + mov esi,0x0000 + mov edi,0x2F0000 + mov ecx,0x10000 / 4 + cld + rep movsd + xor eax,eax + mov edi,0 + mov ecx,0x10000 / 4 + cld + rep stosd + +; SAVE REAL MODE VARIABLES +; --------------- APM --------------------- + mov eax, [0x2f0000 + 0x9040] ; entry point + mov dword[apm_entry], eax + mov word [apm_entry + 4], apm_code_32 - gdts + + mov eax, [0x2f0000 + 0x9044] ; version & flags + mov [apm_vf], eax +; ----------------------------------------- +; movzx eax,byte [0x2f0000+0x9010] ; mouse port +; mov [0xF604],byte 1 ;al + mov al,[0x2f0000+0x9000] ; bpp + mov [0xFBF1],al + movzx eax,word [0x2f0000+0x900A] ; X max + dec eax + mov [0xfe00],eax + mov [screen_workarea.right],eax + movzx eax,word [0x2f0000+0x900C] ; Y max + dec eax + mov [0xfe04],eax + mov [screen_workarea.bottom],eax + movzx eax,word [0x2f0000+0x9008] ; screen mode + mov [0xFE0C],eax + mov eax,[0x2f0000+0x9014] ; Vesa 1.2 bnk sw add + mov [0xE030],eax + mov [0xfe08],word 640*4 ; Bytes PerScanLine + cmp [0xFE0C],word 0x13 ; 320x200 + je @f + cmp [0xFE0C],word 0x12 ; VGA 640x480 + je @f + mov ax,[0x2f0000+0x9001] ; for other modes + mov [0xfe08],ax + @@: + +; GRAPHICS ADDRESSES + + ;mov eax,0x100000*8 ; LFB address + ;cmp [0xfe0c],word 0x13 + ;je no_d_lfb + ;cmp [0xfe0c],word 0x12 + ;je no_d_lfb + ;cmp [0x2f0000+0x901e],byte 1 + ;jne no_d_lfb + mov byte [0x2f0000+0x901e],0x0 + mov eax,[0x2f0000+0x9018] + ;no_d_lfb: + mov [0xfe80],eax + + cmp [0xfe0c],word 0100000000000000b + jge setvesa20 + cmp [0xfe0c],word 0x13 + je v20ga32 + mov [0xe020],dword Vesa12_putpixel24 ; Vesa 1.2 + mov [0xe024],dword Vesa12_getpixel24 + cmp [0xfbf1],byte 24 + jz ga24 + mov [0xe020],dword Vesa12_putpixel32 + mov [0xe024],dword Vesa12_getpixel32 + ga24: + jmp v20ga24 + setvesa20: + mov [0xe020],dword Vesa20_putpixel24 ; Vesa 2.0 + mov [0xe024],dword Vesa20_getpixel24 + cmp [0xfbf1],byte 24 + jz v20ga24 + v20ga32: + mov [0xe020],dword Vesa20_putpixel32 + mov [0xe024],dword Vesa20_getpixel32 + v20ga24: + cmp [0xfe0c],word 0x12 ; 16 C VGA 640x480 + jne no_mode_0x12 + mov [0xe020],dword VGA_putpixel + mov [0xe024],dword Vesa20_getpixel32 + no_mode_0x12: + +; MEMORY MODEL + +; mov [0xfe84],dword 0x100000*16 ; apps mem base address +; movzx ecx,byte [0x2f0000+0x9030] +; dec ecx +; mov eax,16*0x100000 ; memory-16 +; shl eax,cl +; mov [0xfe8c],eax ; memory for use +; cmp eax,16*0x100000 +; jne no16mb +; mov [0xfe84],dword 0xD80000 ; !!! 10 !!! +; no16mb: + +; init: +; 1) 0xFE84 - applications base +; 2) 0xFE8C - total amount of memory + + xor edi, edi + m_GMS_loop: + add edi, 0x400000 + mov eax, dword [edi] + mov dword [edi], 'TEST' + wbinvd + cmp dword [edi], 'TEST' + jne m_GMS_exit + cmp dword [0], 'TEST' + je m_GMS_exit + mov dword [es:edi], eax + jmp m_GMS_loop + m_GMS_exit: + mov [edi], eax + ; now edi contains the EXACT amount of memory + + mov eax, 0x100000*16 + cmp edi, eax ;0x100000*16 + jb $ ; less than 16 Mb + + mov dword [0xFE84], eax ;0x100000*16 + cmp edi, eax ;0x100000*16 + jne @f + mov dword [0xFE84], 0xD80000 ; =0x100000*13.5 + @@: + mov dword [0xFE8C], edi + +;!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'detect/disks.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!! + +; CHECK EXTRA REGION +; ENABLE PAGING + mov eax,cr0 + or eax,0x80000000 + mov cr0,eax + jmp $+2 + + call MEM_Init +;add 0x800000-0xc00000 area + cmp word [0xfe0c],0x13 + jle .less_memory + mov eax,0x800000 ;linear address + mov ebx,0x400000 shr 12 ;size in pages (4Mb) + mov ecx,0x800000 ;physical address + jmp .end_first_block +.less_memory: + mov eax,0x980000 ;linear address + mov ebx,0x280000 shr 12 ;size in pages (2.5Mb) + mov ecx,0x980000 ;physical address +.end_first_block: + call MEM_Add_Heap ;nobody can lock mutex yet + + call create_general_page_table +;add 0x1000000(0xd80000)-end_of_memory area + mov eax,second_base_address + mov ebx,[0xfe8c] + mov ecx,[0xfe84] + sub ebx,ecx + shr ebx,12 + add eax,ecx + call MEM_Add_Heap +;init physical memory manager. + call Init_Physical_Memory_Manager + + mov dword [0xfe80],0x80000000 ;0x800000 + +;Set base of graphic segment to linear address of LFB + mov eax,[0xfe80] ; set for gs + mov [graph_data_l+2],ax + shr eax,16 + mov [graph_data_l+4],al + mov [graph_data_l+7],ah + +; READ RAMDISK IMAGE FROM HD + +;!!!!!!!!!!!!!!!!!!!!!!! +include 'boot/rdload.inc' +;!!!!!!!!!!!!!!!!!!!!!!! +; mov [dma_hdd],1 +; CALCULATE FAT CHAIN FOR RAMDISK + + call calculatefatchain + +; LOAD VMODE DRIVER + +;!!!!!!!!!!!!!!!!!!!!!!! +include 'vmodeld.inc' +;!!!!!!!!!!!!!!!!!!!!!!! + +; LOAD FONTS I and II + + mov [0x3000],dword 1 + mov [0x3004],dword 1 + mov [0x3010],dword 0x3020 + + mov eax,char + mov esi,12 + xor ebx,ebx + mov ecx,2560;26000 + mov edx,0x3F600;0x37000 + call fileread + + mov eax,char2 + mov esi,12 + xor ebx,ebx + mov ecx,2560;26000 + mov edx,0x3EC00;0x30000 + call fileread + + mov esi,boot_fonts + call boot_log + +; PRINT AMOUNT OF MEMORY + mov esi, boot_memdetect + call boot_log + + movzx ecx, word [boot_y] + or ecx, (10+29*6) shl 16 ; "Determining amount of memory" + sub ecx, 10 + mov edx, 0xFFFFFF + mov ebx, [0xFE8C] + shr ebx, 20 + mov edi, 1 + mov eax, 0x00040000 + call display_number + +; CHECK EXTENDED REGION +; mov dword [0x80000000],0x12345678 +; cmp dword [0x80000000],0x12345678 +; jz extended_region_found +; mov esi,boot_ext_region +; call boot_log +; jmp $ +;extended_region_found: + + + +; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f + + mov esi,boot_irqs + call boot_log + call rerouteirqs + + mov esi,boot_tss + call boot_log + +; BUILD SCHEDULER + + call build_scheduler ; sys32.inc + +; LOAD IDT + lidt [cs:idtreg] + +; READ CPUID RESULT + + mov esi,boot_cpuid + call boot_log + pushfd ; get current flags + pop eax + mov ecx,eax + xor eax,0x00200000 ; attempt to toggle ID bit + push eax + popfd + pushfd ; get new EFLAGS + pop eax + push ecx ; restore original flags + popfd + and eax,0x00200000 ; if we couldn't toggle ID, + and ecx,0x00200000 ; then this is i486 + cmp eax,ecx + jz nopentium + ; It's Pentium or later. Use CPUID + mov edi,cpuid_0 + mov esi,0 + cpuid_new_read: + mov eax,esi + cpuid + call cpuid_save + add edi,4*4 + cmp esi,3 + jge cpuid_done + cmp esi,[cpuid_0] + jge cpuid_done + inc esi + jmp cpuid_new_read + cpuid_save: + mov [edi+00],eax + mov [edi+04],ebx + mov [edi+8],ecx + mov [edi+12],edx + ret + cpuid_done: + nopentium: + +; CR4 flags - enable fxsave / fxrstore +; +; finit +; mov eax,1 +; cpuid +; test edx,1000000h +; jz fail_fpu +; mov eax,cr4 +; or eax,200h ; Enable fxsave/fxstor +; mov cr4,eax +; fail_fpu: + +;The CPU to this moment should be already in PM, +;and bit MP of the register cr0 should be installed in 1. +finit ;reset of the FPU (finit, instead of fninit) +fsetpm ;enable PM of the FPU +finit ;reset the registers, contents which are still equal RM +;Now FPU too in PM +; DETECT DEVICES + + mov esi,boot_devices + call boot_log + call detect_devices + + ; TIMER SET TO 1/100 S + + mov esi,boot_timer + call boot_log + mov al,0x34 ; set to 100Hz + out 0x43,al + mov al,0x9b ; lsb 1193180 / 1193 + out 0x40,al + mov al,0x2e ; msb + out 0x40,al + +; SET MOUSE + + mov esi,boot_setmouse + call boot_log + call setmouse + +; SET PRELIMINARY WINDOW STACK AND POSITIONS + + mov esi,boot_windefs + call boot_log + call setwindowdefaults + +; SET BACKGROUND DEFAULTS + + mov esi,boot_bgr + call boot_log + call calculatebackground + +; RESERVE SYSTEM IRQ'S JA PORT'S + + mov esi,boot_resirqports + call boot_log + call reserve_irqs_ports + +; SET PORTS FOR IRQ HANDLERS + + mov esi,boot_setrports + call boot_log + call setirqreadports + +; SET UP OS TASK + + mov esi,boot_setostask + call boot_log + ; name for OS/IDLE process + mov dword [0x80000+256+APPDATA.app_name], dword 'OS/I' + mov dword [0x80000+256+APPDATA.app_name+4], dword 'DLE ' + ; task list + mov [0x3020+TASKDATA.wnd_number], 1 ; on screen number + mov [0x3020+TASKDATA.pid], 1 ; process id number + mov [0x3020+TASKDATA.mem_start], 0 ; process base address + + ; set default flags & stacks + mov [l.eflags],dword 0x11202 ; sti and resume + mov [l.ss0], os_data + ; osloop - TSS + mov eax,cr3 + mov [l.cr3],eax + mov [l.eip],osloop + mov [l.esp],sysint_stack_data + 4096*2 ; uses slot 1 stack + mov [l.cs],os_code + mov [l.ss],os_data + mov [l.ds],os_data + mov [l.es],os_data + mov [l.fs],os_data + mov [l.gs],os_data + ; move tss to tss_data+tss_step + mov esi,tss_sceleton + mov edi,tss_data+tss_step + mov ecx,120/4 + cld + rep movsd + + mov ax,tss0 + ltr ax + + +; READ TSC / SECOND + + mov esi,boot_tsc + call boot_log + call _rdtsc + mov ecx,eax + mov esi,250 ; wait 1/4 a second + call delay_ms + call _rdtsc + sub eax,ecx + shl eax,2 + mov [0xf600],eax ; save tsc / sec + +; SET VARIABLES + + call set_variables + +; STACK AND FDC + + call stack_init + call fdc_init + +; PALETTE FOR 320x200 and 640x480 16 col + + cmp [0xfe0c],word 0x12 + jne no_pal_vga + mov esi,boot_pal_vga + call boot_log + call paletteVGA + no_pal_vga: + + cmp [0xfe0c],word 0x13 + jne no_pal_ega + mov esi,boot_pal_ega + call boot_log + call palette320x200 + no_pal_ega: + +; LOAD DEFAULT SKIN + + mov esi,_skin_file_default + mov edi,_skin_file + movsd + movsd + movsd + call load_skin + +; MTRR'S + + call enable_mtrr + + +; LOAD FIRST APPLICATION + mov [0x3000],dword 1 + mov [0x3004],dword 1 + cli + cmp byte [0x2f0000+0x9030],1 + jne no_load_vrr_m + mov ebp,vrr_m + lea esi,[ebp+6] ; skip '/rd/1/' + xor ebx,ebx ; no parameters + xor edx,edx ; no flags + call fs_RamdiskExecute.flags + cmp eax,2 ; if vrr_m app found (PID=2) + je first_app_found + + no_load_vrr_m: + mov ebp,firstapp + lea esi,[ebp+6] + xor ebx,ebx ; no parameters + xor edx,edx ; no flags + call fs_RamdiskExecute.flags + + cmp eax,2 ; continue if a process has been loaded + je first_app_found + mov eax, 0xDEADBEEF ; otherwise halt + hlt + first_app_found: + cli + + ;mov [0x3004],dword 2 + mov [0x3000],dword 1 ; set OS task fisrt + + +; SET KEYBOARD PARAMETERS + mov al, 0xf6 ; reset keyboard, scan enabled + call kb_write + + ; wait until 8042 is ready +; xor ecx,ecx +; @@: +; in al,64h +; and al,00000010b +; loopnz @b + call Wait8042BufferEmpty + + ; mov al, 0xED ; svetodiody - only for testing! + ; call kb_write + ; call kb_read + ; mov al, 111b + ; call kb_write + ; call kb_read + + mov al, 0xF3 ; set repeat rate & delay + call kb_write + call kb_read + mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 + call kb_write + call kb_read + ;// mike.dld [ + call set_lights + ;// mike.dld ] + +; START MULTITASKING + + mov esi,boot_tasking + call boot_log + + mov [0xe000],byte 1 ; multitasking enabled + +; UNMASK ALL IRQ'S + + mov esi,boot_allirqs + call boot_log + + cli ;guarantee forbidance of interrupts. + mov al,0 ; unmask all irq's + out 0xA1,al + out 0x21,al + + mov ecx,32 + + ready_for_irqs: + + mov al,0x20 ; ready for irqs + out 0x20,al + out 0xa0,al + + loop ready_for_irqs ; flush the queue + +; mov [dma_hdd],1 + + sti + jmp $ ; wait here for timer to take control + + ; Fly :) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MAIN OS LOOP START ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +osloop: + + call [draw_pointer] + call checkbuttons + call checkwindows +; call check_window_move_request + call checkmisc + call checkVga_N13 + call stack_handler + call checkidle + call check_fdd_motor_status + jmp osloop +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; MAIN OS LOOP END ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +checkidle: + pushad + + cmp [check_idle_semaphore],0 + jne no_idle_state + + call change_task + mov eax,[idlemem] + mov ebx,[timer_ticks] ;[0xfdf0] + cmp eax,ebx + jnz idle_exit + call _rdtsc + mov ecx,eax + idle_loop: + hlt + cmp [check_idle_semaphore],0 + jne idle_loop_exit + mov eax,[timer_ticks] ;[0xfdf0] + cmp ebx,eax + jz idle_loop + idle_loop_exit: + mov [idlemem],eax + call _rdtsc + sub eax,ecx + mov ebx,[idleuse] + add ebx,eax + mov [idleuse],ebx + + popad + ret + + idle_exit: + + mov ebx,[timer_ticks] ;[0xfdf0] + mov [idlemem],ebx + call change_task + + popad + ret + + no_idle_state: + + dec [check_idle_semaphore] + + mov ebx,[timer_ticks] ;[0xfdf0] + mov [idlemem],ebx + call change_task + + popad + ret + +uglobal + idlemem dd 0x0 + idleuse dd 0x0 + idleusesec dd 0x0 + check_idle_semaphore dd 0x0 +endg + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; INCLUDED SYSTEM FILES ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +include "kernel32.inc" + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ; +; KERNEL FUNCTIONS ; +; ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +enable_mtrr: + + pushad + + cmp [0x2f0000+0x901c],byte 2 + je no_mtrr + mov eax,[0xFE0C] ; if no LFB then no MTRR + test eax,0100000000000000b + jz no_mtrr + mov edx,[cpuid_1+3*4] ; edx - MTRR's supported ? + test edx,1000000000000b + jz no_mtrr + call find_empty_mtrr + cmp ecx,0 + jz no_mtrr + mov esi,boot_mtrr ; 'setting mtrr' + call boot_log + mov edx,0x0 ; LFB , +8 M , write combine + mov eax,[0x2f9018] + or eax,1 + wrmsr + inc ecx + mov edx,0xf + mov eax,0xff800800 + wrmsr + mov ecx,0x2ff ; enable mtrr's + rdmsr + or eax,100000000000b ; set + wrmsr + no_mtrr: + + popad + ret + + +find_empty_mtrr: ; 8 pairs checked + + mov ecx,0x201-2 + mtrr_find: + add ecx,2 + cmp ecx,0x200+8*2 + jge no_free_mtrr + rdmsr + test eax,0x0800 + jnz mtrr_find + dec ecx + ret + no_free_mtrr: + mov ecx,0 + ret + +reserve_irqs_ports: + + pushad + + mov [irq_owner+4*0],byte 1 ; timer + mov [irq_owner+4*1],byte 1 ; keyboard + mov [irq_owner+4*5],byte 1 ; sound blaster + mov [irq_owner+4*6],byte 1 ; floppy diskette + mov [irq_owner+4*13],byte 1 ; math co-pros + mov [irq_owner+4*14],byte 1 ; ide I + mov [irq_owner+4*15],byte 1 ; ide II +; movzx eax,byte [0xf604] ; mouse irq +; dec eax +; add eax,mouseirqtable +; movzx eax,byte [eax] +; shl eax,2 +; mov [irq_owner+eax],byte 1 + + + ; RESERVE PORTS + mov edi,1 ; 0x00-0xff + mov [0x2d0000],edi + shl edi,4 + mov [0x2d0000+edi+0],dword 1 + mov [0x2d0000+edi+4],dword 0x0 + mov [0x2d0000+edi+8],dword 0xff +; cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff +; jne ripl1 +; inc dword [0x2d0000] +; mov edi,[0x2d0000] +; shl edi,4 +; mov [0x2d0000+edi+0],dword 1 +; mov [0x2d0000+edi+4],dword 0x3f0 +; mov [0x2d0000+edi+8],dword 0x3ff +; ripl1: +; cmp [0xf604],byte 3 ; com2 mouse -> 0x2f0-0x2ff +; jne ripl2 +; inc dword [0x2d0000] +; mov edi,[0x2d0000] +; shl edi,4 +; mov [0x2d0000+edi+0],dword 1 +; mov [0x2d0000+edi+4],dword 0x2f0 +; mov [0x2d0000+edi+8],dword 0x2ff +; ripl2: + + popad + ret + +iglobal +mouseirqtable db 12 ; ps2 + db 4 ; com1 + db 3 ; com2 +endg + +setirqreadports: + + mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte + mov [irq12read+4],dword 0 ; end of port list + mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte + mov [irq04read+4],dword 0 ; end of port list + mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte + mov [irq03read+4],dword 0 ; end of port list + + ret + +iglobal + process_number dd 0x1 +endg + +set_variables: + + mov ecx,0x100 ; flush port 0x60 +.fl60: in al,0x60 + loop .fl60 + mov [0xfcff],byte 0 ; mouse buffer + mov [0xf400],byte 0 ; keyboard buffer + mov [0xf500],byte 0 ; button buffer +; mov [0xfb0a],dword 100*65536+100 ; mouse x/y + + push eax + mov ax,[0x2f0000+0x900c] + shr ax,1 + shl eax,16 + mov ax,[0x2f0000+0x900A] + shr ax,1 + mov [0xfb0a],eax + pop eax + + mov byte [SB16_Status],0 ; Minazzi Paolo + mov [display_data-12],dword 1 ; tiled background + mov [0xfe88],dword 0x2C0000 ; address of button list + + ;!! IP 04.02.2005: + mov [next_usage_update], 100 + mov byte [0xFFFF], 0 ; change task if possible + + ret + +;* mouse centered - start code- Mario79 +mouse_centered: + push eax + mov eax,[0xFE00] + shr eax,1 + mov [0xFB0A],ax + mov eax,[0xFE04] + shr eax,1 + mov [0xFB0C],ax + pop eax + ret +;* mouse centered - end code- Mario79 + +align 4 + +sys_outport: + + mov edi,ebx ; separate flag for read / write + and ebx,65535 + + mov ecx,[0x2d0000] + test ecx,ecx + jne sopl8 + mov [esp+36],dword 1 + ret + + sopl8: + mov edx,[0x3010] + mov edx,[edx+0x4] + and ebx,65535 + cld + sopl1: + + mov esi,ecx + shl esi,4 + add esi,0x2d0000 + cmp edx,[esi+0] + jne sopl2 + cmp ebx,[esi+4] + jb sopl2 + cmp ebx,[esi+8] + jg sopl2 + jmp sopl3 + + sopl2: + + dec ecx + jnz sopl1 + mov [esp+36],dword 1 + ret + + sopl3: + + test edi,0x80000000 ; read ? + jnz sopl4 + + mov dx,bx ; write + out dx,al + mov [esp+36],dword 0 + ret + + sopl4: + + mov dx,bx ; read + in al,dx + and eax,0xff + mov [esp+36],dword 0 + mov [esp+24],eax + ret + + + +align 4 +sys_sb16: + + cmp word [sb16],word 0 + jnz sb16l1 + mov [esp+36],dword 1 + ret + sb16l1: + mov [esp+36],dword 0 + cmp eax,1 ; set volume - main + jnz sb16l2 + mov dx,word [sb16] + add dx,4 + mov al,0x22 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + inc edx + out dx,al + ret + sb16l2: + + cmp eax,2 ; set volume - cd + jnz sb16l3 + mov dx,word [sb16] + add dx,4 + mov al,0x28 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + add edx,1 + out dx,al + ret + sb16l3: + mov [esp+36],dword 2 + ret + + +align 4 + +sys_sb16II: + + cmp word [sb16],word 0 + jnz IIsb16l1 + mov [esp+36],dword 1 + ret + IIsb16l1: + + cmp eax,1 ; set volume - main + jnz IIsb16l2 + ; L + mov dx,word [sb16] + add dx,4 + mov al,0x30 + out dx,al + mov eax,ebx + inc edx + out dx,al + ; R + mov dx,word [sb16] + add dx,4 + mov al,0x31 + out dx,al + mov eax,ebx + inc edx + out dx,al + mov [esp+36],dword 0 + ret + IIsb16l2: + + cmp eax,2 ; set volume - cd + jnz IIsb16l3 + ; L + mov dx,word [sb16] + add dx,4 + mov al,0x36 + out dx,al + mov eax,ebx + inc edx + out dx,al + ; R + mov dx,word [sb16] + add dx,4 + mov al,0x37 + out dx,al + mov eax,ebx + inc edx + out dx,al + mov [esp+36],dword 0 + ret + IIsb16l3: + + mov [esp+36],dword 2 + ret + + +align 4 + +sys_wss: + + cmp word [wss],word 0 + jnz wssl1 + mov [esp+36],dword 1 + ret + wssl1: + + cmp eax,1 ; set volume - main + jnz wssl2 + mov [esp+36],dword 0 + ret + wssl2: + + cmp eax,2 ; set volume - cd + jnz wssl3 + ; L + mov dx,word [wss] + add dx,4 + mov al,0x2 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + inc edx + out dx,al + ; R + mov dx,word [wss] + add dx,4 + mov al,0x3 + out dx,al + mov esi,1 + call delay_ms + mov eax,ebx + inc edx + out dx,al + mov [esp+36],dword 0 + ret + wssl3: + mov [esp+36],dword 2 + ret + +display_number: + +; eax = print type, al=0 -> ebx is number +; al=1 -> ebx is pointer +; ah=0 -> display decimal +; ah=1 -> display hexadecimal +; ah=2 -> display binary +; eax bits 16-21 = number of digits to display (0-32) +; eax bits 22-31 = reserved +; +; ebx = number or pointer +; ecx = x shl 16 + y +; edx = color + + cmp eax,0xffff ; length > 0 ? + jge cont_displ + ret + cont_displ: + + cmp eax,61*0x10000 ; length <= 60 ? + jb cont_displ2 + ret + cont_displ2: + + pushad + + cmp al,1 ; ecx is a pointer ? + jne displnl1 + mov ebx,[ebx+std_application_base_address] + displnl1: + sub esp,64 + + cmp ah,0 ; DECIMAL + jne no_display_desnum + shr eax,16 + and eax,0x3f + push eax + mov edi,esp + add edi,4+64 + mov ecx,eax + mov eax,ebx + mov ebx,10 + d_desnum: + xor edx,edx + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_desnum + pop eax + call draw_num_text + add esp,64 + popad + ret + no_display_desnum: + + cmp ah,0x01 ; HEXADECIMAL + jne no_display_hexnum + shr eax,16 + and eax,0x3f + push eax + mov edi,esp + add edi,4+64 + mov ecx,eax + mov eax,ebx + mov ebx,16 + d_hexnum: + xor edx,edx + div ebx + add edx,hexletters + mov dl,[edx] + mov [edi],dl + dec edi + loop d_hexnum + pop eax + call draw_num_text + add esp,64 + popad + ret + no_display_hexnum: + + cmp ah,0x02 ; BINARY + jne no_display_binnum + shr eax,16 + and eax,0x3f + push eax + mov edi,esp + add edi,4+64 + mov ecx,eax + mov eax,ebx + mov ebx,2 + d_binnum: + xor edx,edx + div ebx + add dl,48 + mov [edi],dl + dec edi + loop d_binnum + pop eax + call draw_num_text + add esp,64 + popad + ret + no_display_binnum: + + add esp,64 + popad + ret + + +draw_num_text: + + ; dtext + ; + ; eax x & y + ; ebx color + ; ecx start of text + ; edx length + ; edi 1 force + + mov edi,[0x3000] + shl edi,8 + add ax,word[edi+0x80000+APPDATA.wnd_clientbox.top] + rol eax,16 + add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] + rol eax,16 + + mov edx,eax + mov ecx,65 + sub ecx,eax + add ecx,esp + add ecx,4 + mov eax,[esp+64+32-8+4] + push edx ; add window start x & y + mov edx,[0x3010] + mov ebx,[edx-twdw+WDATA.box.left] + shl ebx,16 + add ebx,[edx-twdw+WDATA.box.top] + add eax,ebx + pop edx + mov ebx,[esp+64+32-12+4] + and ebx, not 0x80000000 ; force counted string + mov esi, [esp+64+4+4] + xor edi,edi + jmp dtext + +read_string: + + ; eax read_area + ; ebx color of letter + ; ecx color of background + ; edx number of letters to read + ; esi [x start]*65536 + [y_start] + + ret + + +align 4 + +sys_setup: + +; 1=roland mpu midi base , base io address +; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 4=sb16 base , base io address +; 5=system language, 1eng 2fi 3ger 4rus +; 6=wss base , base io address +; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 8=fat32 partition in hd +; 9 +; 10 = sound dma channel +; 11 = enable lba read +; 12 = enable pci access + + + mov [esp+36],dword 0 + cmp eax,1 ; MIDI + jnz nsyse1 + cmp ebx,0x100 + jb nsyse1 + mov edx,65535 + cmp edx,ebx + jb nsyse1 + mov [midi_base],bx + mov word [mididp],bx + inc bx + mov word [midisp],bx + ret + +midi_base dw 0 + + nsyse1: + + cmp eax,2 ; KEYBOARD + jnz nsyse2 + cmp ebx,1 + jnz kbnobase + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap + mov ecx,128 + call memmove + ret + kbnobase: + cmp ebx,2 + jnz kbnoshift + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap_shift + mov ecx,128 + call memmove + ret + kbnoshift: + cmp ebx,3 + jne kbnoalt + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov eax,ecx + mov ebx,keymap_alt + mov ecx,128 + call memmove + ret + kbnoalt: + cmp ebx,9 + jnz kbnocountry + mov word [keyboard],cx + ret + kbnocountry: + mov [esp+36],dword 1 + ret + nsyse2: + cmp eax,3 ; CD + jnz nsyse3 + test ebx,ebx + jz nosesl + cmp ebx, 4 + ja nosesl + mov [cd_base],bl + cmp ebx,1 + jnz noprma + mov [cdbase],0x1f0 + mov [cdid],0xa0 + noprma: + cmp ebx,2 + jnz noprsl + mov [cdbase],0x1f0 + mov [cdid],0xb0 + noprsl: + cmp ebx,3 + jnz nosema + mov [cdbase],0x170 + mov [cdid],0xa0 + nosema: + cmp ebx,4 + jnz nosesl + mov [cdbase],0x170 + mov [cdid],0xb0 + nosesl: + ret + +cd_base db 0 + + nsyse3: + + cmp eax,4 ; SB + jnz nsyse4 + cmp ebx,0x100 + jb nsyse4 + mov edx,65535 + cmp edx,ebx + jb nsyse4 + mov word [sb16],bx + ret + nsyse4: + + cmp eax,5 ; SYSTEM LANGUAGE + jnz nsyse5 + mov [syslang],ebx + ret + nsyse5: + + cmp eax,6 ; WSS + jnz nsyse6 + cmp ebx,0x100 + jb nsyse6 + mov [wss],ebx + ret + +wss_temp dd 0 + + nsyse6: + + cmp eax,7 ; HD BASE + jne nsyse7 + test ebx,ebx + jz nosethd + cmp ebx,4 + ja nosethd + mov [hd_base],bl + cmp ebx,1 + jnz noprmahd + mov [hdbase],0x1f0 + mov [hdid],0x0 + mov [hdpos],1 +; call set_FAT32_variables + noprmahd: + cmp ebx,2 + jnz noprslhd + mov [hdbase],0x1f0 + mov [hdid],0x10 + mov [hdpos],2 +; call set_FAT32_variables + noprslhd: + cmp ebx,3 + jnz nosemahd + mov [hdbase],0x170 + mov [hdid],0x0 + mov [hdpos],3 +; call set_FAT32_variables + nosemahd: + cmp ebx,4 + jnz noseslhd + mov [hdbase],0x170 + mov [hdid],0x10 + mov [hdpos],4 +; call set_FAT32_variables + noseslhd: + mov [0xfe10],dword 0 + call reserve_hd1 + call clear_hd_cache + mov [hd1_status],0 ; free + nosethd: + ret + +hd_base db 0 + + nsyse7: + + cmp eax,8 ; HD PARTITION + jne nsyse8 + mov [fat32part],ebx +; call set_FAT32_variables + call reserve_hd1 + call clear_hd_cache + pusha + call choice_necessity_partition_1 + popa + mov [hd1_status],0 ; free + ret + nsyse8: + + cmp eax,10 ; SOUND DMA CHANNEL + jne no_set_sound_dma + cmp ebx,3 + ja sys_setup_err + mov [sound_dma],ebx + ret + no_set_sound_dma: + + cmp eax,11 ; ENABLE LBA READ + jne no_set_lba_read + and ebx,1 + mov [lba_read_enabled],ebx + ret + no_set_lba_read: + + cmp eax,12 ; ENABLE PCI ACCESS + jne no_set_pci_access + and ebx,1 + mov [pci_access_enabled],ebx + ret + no_set_pci_access: + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'vmodeint.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +sys_setup_err: + mov [esp+36],dword -1 + ret + + +align 4 + +sys_getsetup: + +; 1=roland mpu midi base , base io address +; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus +; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 4=sb16 base , base io address +; 5=system language, 1eng 2fi 3ger 4rus +; 6=wss base +; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave +; 8=fat32 partition in hd +; 9=get hs timer tic + + cmp eax,1 + jne ngsyse1 + movzx eax,[midi_base] + mov [esp+36],eax + ret + ngsyse1: + + cmp eax,2 + jne ngsyse2 + cmp ebx,1 + jnz kbnobaseret + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap + mov ecx,128 + call memmove + ret + kbnobaseret: + cmp ebx,2 + jnz kbnoshiftret + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap_shift + mov ecx,128 + call memmove + ret + kbnoshiftret: + cmp ebx,3 + jne kbnoaltret + mov edi,[0x3010] + add ecx,[edi+TASKDATA.mem_start] + mov ebx,ecx + mov eax,keymap_alt + mov ecx,128 + call memmove + ret + kbnoaltret: + cmp ebx,9 + jnz ngsyse2 + movzx eax,word [keyboard] + mov [esp+36],eax + ret + ngsyse2: + + cmp eax,3 + jnz ngsyse3 + movzx eax,[cd_base] + mov [esp+36],eax + ret + ngsyse3: + + cmp eax,4 + jne ngsyse4 + mov eax,[sb16] + mov [esp+36],eax + ret + ngsyse4: + + cmp eax,5 + jnz ngsyse5 + mov eax,[syslang] + mov [esp+36],eax + ret + ngsyse5: + cmp eax,6 + jnz ngsyse6 + mov eax,[wss] + mov [esp+36],eax + ret + ngsyse6: + cmp eax,7 + jnz ngsyse7 + movzx eax,[hd_base] + mov [esp+36],eax + ret + ngsyse7: + cmp eax,8 + jnz ngsyse8 + mov eax,[fat32part] + mov [esp+36],eax + ret + ngsyse8: + cmp eax,9 + jne ngsyse9 + mov eax,[timer_ticks] ;[0xfdf0] + mov [esp+36],eax + ret + ngsyse9: + cmp eax,10 + jnz ngsyse10 + mov eax,[sound_dma] + mov [esp+36],eax + ret + ngsyse10: + cmp eax,11 + jnz ngsyse11 + mov eax,[lba_read_enabled] + mov [esp+36],eax + ret + ngsyse11: + cmp eax,12 + jnz ngsyse12 + mov eax,[pci_access_enabled] + mov [esp+36],eax + ret + ngsyse12: + mov [esp+36],dword 1 + ret + + +align 4 + +readmousepos: + +; eax=0 screen relative +; eax=1 window relative +; eax=2 buttons pressed + + test eax,eax + jnz nosr + mov eax,[0xfb0a] + shl eax,16 + mov ax,[0xfb0c] + mov [esp+36],eax + ret + nosr: + + cmp eax,1 + jnz nowr + mov eax,[0xfb0a] + shl eax,16 + mov ax,[0xfb0c] + mov esi,[0x3010] + mov bx, word [esi-twdw+WDATA.box.left] + shl ebx,16 + mov bx, word [esi-twdw+WDATA.box.top] + sub eax,ebx + + mov edi,[0x3000] + shl edi,8 + sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.top] + rol eax,16 + sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] + rol eax,16 + + mov [esp+36],eax + ret + nowr: + + cmp eax,2 + jnz nomb + movzx eax,byte [0xfb40] + nomb: + mov [esp+36],eax + + ret + +is_input: + + push edx + mov dx,word [midisp] + in al,dx + and al,0x80 + pop edx + ret + + +is_output: + + push edx + mov dx,word [midisp] + in al,dx + and al,0x40 + pop edx + ret + + +get_mpu_in: + + push edx + mov dx,word [mididp] + in al,dx + pop edx + ret + + +put_mpu_out: + + push edx + mov dx,word [mididp] + out dx,al + pop edx + ret + + +setuart: + + su1: + call is_output + cmp al,0 + jnz su1 + mov dx,word [midisp] + mov al,0xff + out dx,al + su2: + mov dx,word [midisp] + mov al,0xff + out dx,al + call is_input + cmp al,0 + jnz su2 + call get_mpu_in + cmp al,0xfe + jnz su2 + su3: + call is_output + cmp al,0 + jnz su3 + mov dx,word [midisp] + mov al,0x3f + out dx,al + + ret + + +align 4 + +sys_midi: + + cmp [mididp],0 + jnz sm0 + mov [esp+36],dword 1 + ret + sm0: + + cmp eax,1 + mov [esp+36],dword 0 + jnz smn1 + call setuart + ret + smn1: + + cmp eax,2 + jnz smn2 + sm10: + call get_mpu_in + call is_output + test al,al + jnz sm10 + mov al,bl + call put_mpu_out + ret + smn2: + + ret + + +detect_devices: +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'detect/commouse.inc' +include 'detect/ps2mouse.inc' +;include 'detect/dev_fd.inc' +;include 'detect/dev_hdcd.inc' +;include 'detect/sear_par.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ret + + +sys_end: + + mov eax,[0x3010] + mov [eax+TASKDATA.state], 3 ; terminate this program + + waitterm: ; wait here for termination + mov eax,5 + call delay_hs + jmp waitterm + +iglobal +sys_system_table: + dd sysfn_shutdown ; 1 = system shutdown + dd sysfn_terminate ; 2 = terminate thread + dd sysfn_activate ; 3 = activate window + dd sysfn_getidletime ; 4 = get idle time + dd sysfn_getcpuclock ; 5 = get cpu clock + dd sysfn_saveramdisk ; 6 = save ramdisk + dd sysfn_getactive ; 7 = get active window + dd sysfn_sound_flag ; 8 = get/set sound_flag + dd sysfn_shutdown_param ; 9 = shutdown with parameter + dd sysfn_minimize ; 10 = minimize window + dd sysfn_getdiskinfo ; 11 = get disk subsystem info + dd sysfn_lastkey ; 12 = get last pressed key + dd sysfn_getversion ; 13 = get kernel version + dd sysfn_waitretrace ; 14 = wait retrace + dd sysfn_centermouse ; 15 = center mouse cursor + dd sysfn_getfreemem ; 16 = get free memory size + dd sysfn_getallmem ; 17 = get total memory size + dd sysfn_terminate2 ; 18 = terminate thread using PID + ; instead of slot + dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration +sysfn_num = ($ - sys_system_table)/4 +endg + +sys_system: + dec eax + cmp eax, sysfn_num + jae @f + jmp dword [sys_system_table + eax*4] +@@: + ret + +sysfn_shutdown: ; 18.1 = BOOT + mov [0x2f0000+0x9030],byte 0 + for_shutdown_parameter: + mov eax,[0x3004] + add eax,2 + mov [shutdown_processes],eax + mov [0xFF00],al + and dword [esp+36], 0 + ret + uglobal + shutdown_processes: dd 0x0 + endg + +sysfn_terminate: ; 18.2 = TERMINATE + cmp ebx,2 + jb noprocessterminate + mov edx,[0x3004] + cmp ebx,edx + ja noprocessterminate + mov eax,[0x3004] + shl ebx,5 + mov edx,[ebx+0x3000+TASKDATA.pid] + add ebx,0x3000+TASKDATA.state + cmp byte [ebx], 9 + jz noprocessterminate + + ;call MEM_Heap_Lock ;guarantee that process isn't working with heap + mov [ebx],byte 3 ; clear possible i40's + ;call MEM_Heap_UnLock + + cmp edx,[application_table_status] ; clear app table stat + jne noatsc + mov [application_table_status],0 + noatsc: + noprocessterminate: + ret + +sysfn_terminate2: +;lock application_table_status mutex +.table_status: + cli + cmp [application_table_status],0 + je .stf + sti + call change_task + jmp .table_status +.stf: + call set_application_table_status + mov eax,ebx + call pid_to_slot + test eax,eax + jz .not_found + mov ebx,eax + cli + call sysfn_terminate + mov [application_table_status],0 + sti + and dword [esp+36],0 + ret +.not_found: + mov [application_table_status],0 + or dword [esp+36],-1 + ret + +sysfn_activate: ; 18.3 = ACTIVATE WINDOW + cmp ebx,2 + jb .nowindowactivate + cmp ebx,[0x3004] + ja .nowindowactivate + + mov [window_minimize], 2 ; restore window if minimized + + movzx esi, word [0xC000 + ebx*2] + cmp esi, [0x3004] + je .nowindowactivate ; already active + + mov edi, ebx + shl edi, 5 + add edi, window_data + movzx esi, word [0xC000 + ebx * 2] + lea esi, [0xC400 + esi * 2] + call waredraw +.nowindowactivate: + ret + +sysfn_getidletime: ; 18.4 = GET IDLETIME + mov eax,[idleusesec] + mov [esp+36], eax + ret + +sysfn_getcpuclock: ; 18.5 = GET TSC/SEC + mov eax,[0xf600] + mov [esp+36], eax + ret + +; SAVE ramdisk to /hd/1/menuet.img +;!!!!!!!!!!!!!!!!!!!!!!!! + include 'blkdev/rdsave.inc' +;!!!!!!!!!!!!!!!!!!!!!!!! + +sysfn_getactive: ; 18.7 = get active window + mov eax, [0x3004] + movzx eax, word [0xC400 + eax*2] + mov [esp+36],eax + ret + +sysfn_sound_flag: ; 18.8 = get/set sound_flag + cmp ebx,1 + jne nogetsoundflag + movzx eax,byte [sound_flag] ; get sound_flag + mov [esp+36],eax + ret + nogetsoundflag: + cmp ebx,2 + jnz nosoundflag + xor byte [sound_flag], 1 + nosoundflag: + ret + +sysfn_shutdown_param: ; 18.9 = system shutdown with param + cmp ebx,1 + jl exit_for_anyone + cmp ebx,4 + jg exit_for_anyone + mov [0x2f0000+0x9030],bl + jmp for_shutdown_parameter + +sysfn_minimize: ; 18.10 = minimize window + mov [window_minimize],1 + exit_for_anyone: + ret + +sysfn_getdiskinfo: ; 18.11 = get disk info table + cmp ebx,1 + jnz full_table + small_table: + call for_all_tables + mov ecx,10 + cld + rep movsb + ret + for_all_tables: + mov edi,[0x3010] + mov edi,[edi+TASKDATA.mem_start] + add edi,ecx + mov esi,0x40000 + ret + full_table: + cmp ebx,2 + jnz exit_for_anyone + call for_all_tables + mov ecx,16384 + cld + rep movsd + ret + +sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) + and dword [esp+36], 0 + ret + +sysfn_getversion: ; 18.13 = get kernel ID and version + mov edi,[0x3010] + mov edi,[edi+TASKDATA.mem_start] + add edi,ebx + mov esi,version_inf + mov ecx,version_end-version_inf + cld + rep movsb + ret + +sysfn_waitretrace: ; 18.14 = sys wait retrace + ;wait retrace functions + sys_wait_retrace: + mov edx,0x3da + WaitRetrace_loop: + in al,dx + test al,1000b + jz WaitRetrace_loop + mov [esp+36],dword 0 + ret + +sysfn_centermouse: ; 18.15 = mouse centered + call mouse_centered + mov [esp+36],dword 0 + ret + +sysfn_mouse_acceleration: ; 18.19 = set/get mouse features + cmp ebx,0 ; get mouse speed factor + jnz .set_mouse_acceleration + xor eax,eax + mov ax,[mouse_speed_factor] + mov [esp+36],eax + ret + .set_mouse_acceleration: + cmp ebx,1 ; set mouse speed factor + jnz .get_mouse_delay + mov [mouse_speed_factor],cx + ret + .get_mouse_delay: + cmp ebx,2 ; get mouse delay + jnz .set_mouse_delay + mov eax,[mouse_delay] + mov [esp+36],eax + ret + .set_mouse_delay: + cmp ebx,3 ; set mouse delay + jnz .set_pointer_position + mov [mouse_delay],ecx + ret + .set_pointer_position: + cmp ebx,4 ; set mouse pointer position + jnz .end + mov [0xFB0C],cx ;y + ror ecx,16 + mov [0xFB0A],cx ;x + rol ecx,16 + .end: + ret + +sysfn_getfreemem: + mov eax,[MEM_FreeSpace] + shl eax,2 + mov [esp+36],eax + ret + +sysfn_getallmem: + mov eax,[0xFE8C] + shr eax,10 +; mov eax,[MEM_AllSpace] +; shl eax,2 + mov [esp+36],eax + ret + +uglobal +;// mike.dld, 2006-29-01 [ +screen_workarea RECT +;// mike.dld, 2006-29-01 ] +window_minimize db 0 +sound_flag db 0 +endg + +iglobal +version_inf: + db 0,6,0,0 ; version 0.6.0.0 + db UID_KOLIBRI + db 'Kolibri',0 +version_end: +endg + +UID_NONE=0 +UID_MENUETOS=1 ;official +UID_KOLIBRI=2 ;russian + +sys_cachetodiskette: +; pushad +; cmp eax,1 +; jne no_write_all_of_ramdisk +; call fdc_writeramdisk +; popad +; ret +; no_write_all_of_ramdisk: +; cmp eax,2 +; jne no_write_part_of_ramdisk +; call fdc_commitflush +; popad +; ret +; no_write_part_of_ramdisk: +; cmp eax,3 +; jne no_set_fdc +; call fdc_set +; popad +; ret +; no_set_fdc: +; cmp eax,4 +; jne no_get_fdc +; popad +; call fdc_get +; mov [esp+36],ecx +; ret +; no_get_fdc: +; popad +; ret + cmp eax,1 + jne no_floppy_a_save + mov [flp_number],1 + jmp save_image_on_floppy + no_floppy_a_save: + cmp eax,2 + jne no_floppy_b_save + mov [flp_number],2 + save_image_on_floppy: + call save_image + mov [esp+36],dword 0 + cmp [FDC_Status],0 + je yes_floppy_save + no_floppy_b_save: + mov [esp+36],dword 1 + yes_floppy_save: + ret + +uglobal +; bgrchanged dd 0x0 +endg + +sys_background: + + cmp eax,1 ; BACKGROUND SIZE + jnz nosb1 + cmp ebx,0 + je sbgrr + cmp ecx,0 + je sbgrr + mov [display_data-8],ebx + mov [display_data-4],ecx +; mov [bgrchanged],1 + sbgrr: + ret + nosb1: + + cmp eax,2 ; SET PIXEL + jnz nosb2 + mov edx,0x160000-16 + cmp edx,ebx + jbe nosb2 + mov edx,[ebx] + and edx,0xFF000000 ;255*256*256*256 + and ecx,0x00FFFFFF ;255*256*256+255*256+255 + add edx,ecx + mov [ebx+0x300000],edx +; mov [bgrchanged],1 + ret + nosb2: + + cmp eax,3 ; DRAW BACKGROUND + jnz nosb3 +draw_background_temp: +; cmp [bgrchanged],1 ;0 +; je nosb31 +;draw_background_temp: +; mov [bgrchanged],1 ;0 + mov [0xfff0],byte 1 + mov [background_defined], 1 + nosb31: + ret + nosb3: + + cmp eax,4 ; TILED / STRETCHED + jnz nosb4 + cmp ebx,[display_data-12] + je nosb41 + mov [display_data-12],ebx +; mov [bgrchanged],1 + nosb41: + ret + nosb4: + + cmp eax,5 ; BLOCK MOVE TO BGR + jnz nosb5 + ; bughere + mov edi, [0x3010] + add ebx, [edi+TASKDATA.mem_start] + ; mov esi, ebx + ; mov edi, ecx + mov eax, ebx + mov ebx, ecx + add ecx, edx + cmp ecx, 0x160000-16 + ja .fin + ; add edi, 0x300000 + add ebx, 0x300000 + mov ecx, edx + cmp ecx, 0x160000-16 + ja .fin +; mov [bgrchanged],1 + ; cld + ; rep movsb + call memmove + .fin: + ret + nosb5: + + ret + + +align 4 + +sys_getbackground: + + cmp eax,1 ; SIZE + jnz nogb1 + mov eax,[display_data-8] + shl eax,16 + mov ax,[display_data-4] + mov [esp+36],eax + ret + nogb1: + + cmp eax,2 ; PIXEL + jnz nogb2 + mov edx,0x160000-16 + cmp edx,ebx + jbe nogb2 + mov eax, [ebx+0x300000] + and eax, 0xFFFFFF + mov [esp+36],eax + ret + nogb2: + + cmp eax,4 ; TILED / STRETCHED + jnz nogb4 + mov eax,[display_data-12] + nogb4: + mov [esp+36],eax + ret + + +align 4 + +sys_getkey: + mov [esp+36],dword 1 +; test main buffer + mov ebx, [0x3000] ; TOP OF WINDOW STACK + movzx ecx,word [0xC000 + ebx * 2] + mov edx,[0x3004] + cmp ecx,edx + jne .finish + cmp [0xf400],byte 0 + je .finish + movzx eax,byte [0xf401] + shl eax,8 + push eax + dec byte [0xf400] + and byte [0xf400],127 + movzx ecx,byte [0xf400] + add ecx,2 + ; mov esi,0xf402 + ; mov edi,0xf401 + ; cld + ; rep movsb + mov eax, 0xF402 + mov ebx, 0xF401 + call memmove + pop eax +.ret_eax: + mov [esp+36],eax + ret + .finish: +; test hotkeys buffer + mov ecx, hotkey_buffer +@@: + cmp [ecx], ebx + jz .found + add ecx, 8 + cmp ecx, hotkey_buffer+120*8 + jb @b + ret +.found: + mov ax, [ecx+6] + shl eax, 16 + mov ah, [ecx+4] + mov al, 2 + and dword [ecx+4], 0 + and dword [ecx], 0 + jmp .ret_eax + +align 4 + +sys_getbutton: + + mov ebx, [0x3000] ; TOP OF WINDOW STACK + mov [esp+36],dword 1 + movzx ecx, word [0xC000 + ebx * 2] + mov edx, [0x3004] ; less than 256 processes + cmp ecx,edx + jne .exit + movzx eax,byte [0xf500] + test eax,eax + jz .exit + mov eax,[0xf501] + shl eax,8 + mov [0xf500],byte 0 + mov [esp+36],eax + .exit: + ret + + +align 4 + +sys_cpuusage: + +; RETURN: +; +; +00 dword process cpu usage +; +04 word position in windowing stack +; +06 word windowing stack value at current position (cpu nro) +; +10 12 bytes name +; +22 dword start in mem +; +26 dword used mem +; +30 dword PID , process idenfification number +; + + mov edi,[0x3010] ; eax = return area + add eax,[edi + TASKDATA.mem_start] + + cmp ebx,-1 ; who am I ? + jne no_who_am_i + mov ebx,[0x3000] + no_who_am_i: + + push eax ; return area + push ebx ; process number + + push ebx + push ebx + push eax + + ; return memory usage + + xor edx,edx + mov eax,0x20 + mul ebx + add eax,0x3000+TASKDATA.cpu_usage + mov ebx,eax + pop eax + mov ecx,[ebx] + mov [eax],ecx + pop ebx + mov cx, [0xC000 + ebx * 2] + mov [eax+4],cx + mov cx, [0xC400 + ebx * 2] + mov [eax+6],cx + push eax + mov eax,ebx + shl eax,8 + add eax,0x80000+APPDATA.app_name + pop ebx + add ebx,10 + mov ecx,11 + call memmove + + ; memory usage + + xor eax,eax + mov edx,0x100000*16 + pop ecx ; get gdt of tss + cmp ecx,1 + je os_mem + shl ecx,8 + mov edx,[0x80000+ecx+APPDATA.mem_size] ;0x8c + mov eax,std_application_base_address + ; eax run base -> edx used memory + os_mem: + dec edx + mov [ebx+12],eax + mov [ebx+16],edx + + ; PID (+30) + + mov eax,[esp] + shl eax,5 + add eax,0x3000+TASKDATA.pid + mov eax,[eax] + mov [ebx+20],eax + + ; window position and size + + mov esi,[esp] + shl esi,5 + add esi,window_data + WDATA.box + mov edi,[esp+4] + add edi,34 + mov ecx,4 + cld + rep movsd + + ; Process state (+50) + + mov eax,[esp] + shl eax,5 + add eax,0x3000+TASKDATA.state + mov eax,[eax] + mov [ebx+40],ax + + ; Window client area box + + mov esi,[esp] + shl esi,8 + add esi,0x80000+APPDATA.wnd_clientbox + lea edi,[ebx+44] + mov ecx,4 + rep movsd + + ; Window state + + mov esi,[esp] + shl esi,5 + add esi,window_data + WDATA.box + mov al,[esi+window_data+WDATA.fl_wstate] + mov [edi],al + + pop ebx + pop eax + + ; return number of processes + + mov eax,[0x3004] + mov [esp+36],eax + ret + + + + +align 4 +sys_clock: + cli + ; Mikhail Lisovin xx Jan 2005 + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b + @@: + ; end Lisovin's fix + + xor al,al ; seconds + out 0x70,al + in al,0x71 + movzx ecx,al + mov al,02 ; minutes + shl ecx,16 + out 0x70,al + in al,0x71 + movzx edx,al + mov al,04 ; hours + shl edx,8 + out 0x70,al + in al,0x71 + add ecx,edx + movzx edx,al + add ecx,edx + sti + mov [esp+36],ecx + ret + + +align 4 + +sys_date: + + cli + + @@: mov al, 10 + out 0x70, al + in al, 0x71 + test al, al + jns @f + mov esi, 1 + call delay_ms + jmp @b + @@: + + mov ch,0 + mov al,7 ; date + out 0x70,al + in al,0x71 + mov cl,al + mov al,8 ; month + shl ecx,16 + out 0x70,al + in al,0x71 + mov ch,al + mov al,9 ; year + out 0x70,al + in al,0x71 + mov cl,al + sti + mov [esp+36],ecx + ret + + +; redraw status + +sys_redrawstat: + + cmp eax,1 + jne no_widgets_away + + ; buttons away + + mov ecx,[0x3000] + + sys_newba2: + + mov edi,[0xfe88] + cmp [edi],dword 0 ; empty button list ? + je end_of_buttons_away + + movzx ebx,word [edi] + inc ebx + + mov eax,edi + + sys_newba: + + dec ebx + jz end_of_buttons_away + + add eax,0x10 + cmp cx,[eax] + jnz sys_newba + + push eax ebx ecx + mov ecx,ebx + inc ecx + shl ecx,4 + mov ebx,eax + add eax,0x10 + call memmove + dec dword [edi] + pop ecx ebx eax + + jmp sys_newba2 + + end_of_buttons_away: + + ret + + no_widgets_away: + + cmp eax,2 + jnz srl1 + + mov edx,[0x3010] ; return whole screen draw area for this app + add edx,draw_data-0x3000 + mov [edx+RECT.left], 0 + mov [edx+RECT.top], 0 + mov eax,[0xfe00] + mov [edx+RECT.right],eax + mov eax,[0xfe04] + mov [edx+RECT.bottom],eax + + mov edi,[0x3010] + mov [edi-twdw+WDATA.fl_wdrawn], 1 ; no new position & buttons from app + + call sys_window_mouse + + ret + + srl1: + + ret + + +sys_drawwindow: + + mov edi,ecx + shr edi,16+8 + and edi,15 + + cmp edi,0 ; type I - original style + jne nosyswI + inc [mouse_pause] + call [disable_mouse] + call sys_set_window + call [disable_mouse] + call drawwindow_I + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswI: + + cmp edi,1 ; type II - only reserve area, no draw + jne nosyswII + inc [mouse_pause] + call [disable_mouse] + call sys_set_window + call [disable_mouse] + call sys_window_mouse + dec [mouse_pause] + call [draw_pointer] + ret + nosyswII: + + cmp edi,2 ; type III - new style + jne nosyswIII + inc [mouse_pause] + call [disable_mouse] + call sys_set_window + call [disable_mouse] + call drawwindow_III + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswIII: + + cmp edi,3 ; type IV - skinned window + jne nosyswIV + + ; parameter for drawwindow_IV + push 0 + mov edi, [0x3004] + movzx edi, word [0xC400 + edi*2] + cmp edi, [0x3000] + jne @f + inc dword [esp] + @@: + + inc [mouse_pause] + call [disable_mouse] + call sys_set_window + call [disable_mouse] + call drawwindow_IV + ;dec [mouse_pause] + ;call [draw_pointer] + ;ret + jmp draw_window_caption.2 + nosyswIV: + + ret + + +draw_window_caption: + inc [mouse_pause] + call [disable_mouse] + + xor eax,eax + mov edx,[0x3004] + movzx edx,word[0xC400+edx*2] + cmp edx,[0x3000] + jne @f + inc eax + @@: mov edx,[0x3000] + shl edx,5 + add edx,window_data + movzx ebx,[edx+WDATA.fl_wstyle] + and bl,0x0F + cmp bl,3 + jne .not_style_3 + + push edx + call drawwindow_IV_caption + add esp,4 + jmp .2 + + .not_style_3: + cmp bl,2 + jne .not_style_2 + + call drawwindow_III_caption + jmp .2 + + .not_style_2: + cmp bl,0 + jne .2 + + call drawwindow_I_caption + +;-------------------------------------------------------------- + .2: ;jmp @f + mov edi,[0x3000] + shl edi,5 + test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + jz @f + mov ecx,[edi*8+0x80000+APPDATA.wnd_caption] + or ecx,ecx + jz @f + add ecx,[edi+twdw+TASKDATA.mem_start] + + movzx eax,[edi+window_data+WDATA.fl_wstyle] + and al,0x0F + cmp al,3 + jne .not_skinned + + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub ax,[_skinmargins.left] + sub ax,[_skinmargins.right] + cwde + cdq + mov ebx,6 + idiv ebx + or eax,eax + js @f + mov edx,eax + mov eax,dword[_skinmargins.left-2] + mov ax,word[_skinh] + sub ax,[_skinmargins.bottom] + sub ax,[_skinmargins.top] + sar ax,1 + adc ax,0 + add ax,[_skinmargins.top] + add ax,-3 + add eax,ebp + jmp .dodraw + + .not_skinned: + cmp al,1 + je @f + + mov ebp,[edi+window_data+WDATA.box.left-2] + mov bp,word[edi+window_data+WDATA.box.top] + movzx eax,word[edi+window_data+WDATA.box.width] + sub eax,16 + cwde + cdq + mov ebx,6 + idiv ebx + or eax,eax + js @f + mov edx,eax + mov eax,0x00080007 + add eax,ebp +.dodraw: + mov ebx,[common_colours+16];0x00FFFFFF + or ebx, 0x80000000 + xor edi,edi + call dtext + + @@: +;-------------------------------------------------------------- + dec [mouse_pause] + call [draw_pointer] + ret + +iglobal +align 4 +window_topleft dd \ + 1, 21,\ + 0, 0,\ + 5, 20,\ + 5, ? +endg + +set_window_clientbox: + push eax ecx edi + + mov eax,[_skinh] + mov [window_topleft+4*7],eax + + mov ecx,edi + sub edi,window_data + shl edi,3 + test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE + jz @f + + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + mov eax,[eax*8+window_topleft+0] + mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax + shl eax,1 + neg eax + add eax,[ecx+WDATA.box.width] + mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax + + movzx eax,[ecx+WDATA.fl_wstyle] + and eax,0x0F + push [eax*8+window_topleft+0] + mov eax,[eax*8+window_topleft+4] + mov [edi+0x80000+APPDATA.wnd_clientbox.top],eax + neg eax + sub eax,[esp] + add eax,[ecx+WDATA.box.height] + mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax + add esp,4 + + pop edi ecx eax + ret + @@: + xor eax,eax + mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax + mov [edi+0x80000+APPDATA.wnd_clientbox.top],eax + mov eax,[ecx+WDATA.box.width] + mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax + mov eax,[ecx+WDATA.box.height] + mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax + + pop edi ecx eax + ret + +sys_set_window: + + mov edi,[0x3000] + shl edi,5 + add edi,window_data + + ; colors + mov [edi+WDATA.cl_workarea],ecx + mov [edi+WDATA.cl_titlebar],edx + mov [edi+WDATA.cl_frames],esi + + ; check flag (?) + cmp [edi+WDATA.fl_wdrawn],1 + jz newd + + push eax + mov eax,[timer_ticks] ;[0xfdf0] + add eax,100 + mov [new_window_starting],eax + pop eax + + mov word[edi+WDATA.box.width],ax + mov word[edi+WDATA.box.height],bx + sar eax,16 + sar ebx,16 + mov word[edi+WDATA.box.left],ax + mov word[edi+WDATA.box.top],bx + + call set_window_clientbox + + call check_window_position + + + push ecx esi edi ; save for window fullscreen/resize + ;mov esi,edi + + mov cl,[edi+WDATA.fl_wstyle] + + sub edi,window_data + shl edi,3 + add edi,0x80000 + + and cl,0x0F + mov [edi+APPDATA.wnd_caption],0 + cmp cl,3 + jne @f + mov [edi+APPDATA.wnd_caption],esi + @@: mov esi,[esp+0] + + add edi, APPDATA.saved_box + mov ecx,4 + cld + rep movsd + pop edi esi ecx + + push eax ebx ecx edx +;;; mov eax, 1 +;;; call delay_hs + mov eax, [edi+WDATA.box.left] + mov ebx, [edi+WDATA.box.top] + mov ecx, [edi+WDATA.box.width] + mov edx, [edi+WDATA.box.height] + add ecx, eax + add edx, ebx + call calculatescreen + pop edx ecx ebx eax + + mov [0xf400],byte 0 ; empty keyboard buffer + mov [0xf500],byte 0 ; empty button buffer + + newd: + mov [edi+WDATA.fl_redraw],byte 0 ; no redraw + mov edx,edi + + ret + +syscall_windowsettings: + + .set_window_caption: + dec eax ; subfunction #1 - set window caption + jnz .get_window_caption + + ; NOTE: only window owner thread can set its caption, + ; so there's no parameter for PID/TID + + mov edi,[0x3000] + shl edi,5 + + ; have to check if caption is within application memory limit + ; check is trivial, and if application resizes its memory, + ; caption still can become over bounds + mov ecx,[edi*8+0x80000+APPDATA.mem_size] + add ecx,255 ; max caption length + cmp ebx,ecx + ja .exit_fail + + mov [edi*8+0x80000+APPDATA.wnd_caption],ebx + or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION + + call draw_window_caption + + xor eax,eax ; eax = 0 (success) + ret + + .get_window_caption: + dec eax ; subfunction #2 - get window caption + jnz .exit_fail + + ; not implemented yet + + .exit_fail: + xor eax,eax + inc eax ; eax = 1 (fail) + ret + + +sys_window_move: + + mov edi,[0x3000] + shl edi,5 + add edi,window_data + + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED + jnz .window_move_return + + push dword [edi + WDATA.box.left] ; save old coordinates + push dword [edi + WDATA.box.top] + push dword [edi + WDATA.box.width] + push dword [edi + WDATA.box.height] + + cmp eax,-1 ; set new position and size + je .no_x_reposition + mov [edi + WDATA.box.left], eax + .no_x_reposition: + cmp ebx,-1 + je .no_y_reposition + mov [edi + WDATA.box.top], ebx + .no_y_reposition: + + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP + jnz .no_y_resizing + + cmp ecx,-1 + je .no_x_resizing + mov [edi + WDATA.box.width], ecx + .no_x_resizing: + cmp edx,-1 + je .no_y_resizing + mov [edi + WDATA.box.height], edx + .no_y_resizing: + + call check_window_position + + pushad ; save for window fullscreen/resize + mov esi,edi + sub edi,window_data + shr edi,5 + shl edi,8 + add edi, 0x80000 + APPDATA.saved_box + mov ecx,4 + cld + rep movsd + popad + + pushad ; calculcate screen at new position + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + call calculatescreen + popad + + pop edx ; calculcate screen at old position + pop ecx + pop ebx + pop eax + add ecx,eax + add edx,ebx + mov [dlx],eax ; save for drawlimits + mov [dly],ebx + mov [dlxe],ecx + mov [dlye],edx + call calculatescreen + + mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw + + mov eax,edi ; redraw screen at old position + xor esi,esi + call redrawscreen + + mov [0xfff5],byte 0 ; mouse pointer + mov [0xfff4],byte 0 ; no mouse under + mov [0xfb44],byte 0 ; react to mouse up/down + + mov ecx,10 ; wait 1/10 second + .wmrl3: + call [draw_pointer] + mov eax,1 + call delay_hs + loop .wmrl3 + + mov [window_move_pr],0 + + .window_move_return: + + ret + +;type_background_1: +; cmp [0xfff0],byte 0 ; background update ? +; jz temp_nobackgr +; mov [0xfff0],byte 2 +; call change_task +; mov [draw_data+32+0],dword 0 +; mov [draw_data+32+4],dword 0 +; mov eax,[0xfe00] +; mov ebx,[0xfe04] +; mov [draw_data+32+8],eax +; mov [draw_data+32+12],ebx +; call drawbackground +; mov [0xfff0],byte 0 +; mov [0xfff4],byte 0 +;temp_nobackgr: +; ret + +uglobal + window_move_pr dd 0x0 + window_move_eax dd 0x0 + window_move_ebx dd 0x0 + window_move_ecx dd 0x0 + window_move_edx dd 0x0 +endg + +;ok - 100% work +;nt - not tested +;--------------------------------------------------------------------------------------------- +;eax +;0 - task switch counter. Ret switch counter in eax. Block. ok. +;1 - change task. Ret nothing. Block. ok. +;2 - performance control +; ebx +; 0 - enable or disable (inversion) PCE flag on CR4 for rdmpc in user mode. +; returned new cr4 in eax. Ret cr4 in eax. Block. ok. +; 1 - is cache enabled. Ret cr0 in eax if enabled else zero in eax. Block. ok. +; 2 - enable cache. Ret 1 in eax. Ret nothing. Block. ok. +; 3 - disable cache. Ret 0 in eax. Ret nothing. Block. ok. +;eax +;3 - rdmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. +;4 - wrmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok. +;--------------------------------------------------------------------------------------------- +sys_sheduler: ;noname & halyavin + cmp eax,0 + je shed_counter + cmp eax,2 + je perf_control + cmp eax,3 + je rdmsr_instr + cmp eax,4 + je wrmsr_instr + cmp eax,1 + jne not_supported + call change_task ;delay,0 +ret +shed_counter: + mov eax,[context_counter] + mov [esp+36],eax +not_supported: +ret +perf_control: + inc eax ;now eax=3 + cmp ebx,eax + je cache_disable + dec eax + cmp ebx,eax + je cache_enable + dec eax + cmp ebx,eax + je is_cache_enabled + dec eax + cmp ebx,eax + je modify_pce +ret + +rdmsr_instr: +;now counter in ecx +;(edx:eax) esi:edi => edx:esi +mov eax,esi +rdmsr +mov [esp+36],eax +mov [esp+24],edx ;ret in ebx? +ret + +wrmsr_instr: +;now counter in ecx +;(edx:eax) esi:edi => edx:esi +mov eax,esi +wrmsr +mov [esp+36],eax +mov [esp+24],edx ;ret in ebx? +ret + +cache_disable: + mov eax,cr0 + or eax,01100000000000000000000000000000b + mov cr0,eax + wbinvd ;set MESI +ret + +cache_enable: + mov eax,cr0 + and eax,10011111111111111111111111111111b + mov cr0,eax +ret + +is_cache_enabled: + mov eax,cr0 + mov ebx,eax + and eax,01100000000000000000000000000000b + jz cache_disabled + mov [esp+36],ebx +cache_disabled: + mov dword [esp+36],eax ;0 +ret + +modify_pce: + mov eax,cr4 +; mov ebx,0 +; or bx,100000000b ;pce +; xor eax,ebx ;invert pce + bts eax,8 ;pce=cr4[8] + mov cr4,eax + mov [esp+36],eax +ret +;--------------------------------------------------------------------------------------------- + + +; check if pixel is allowed to be drawn + +checkpixel: + push eax edx + + mov edx,[0xfe00] ; screen x size + inc edx + imul edx, ebx + mov dl, [eax+edx+display_data] ; lea eax, [...] + + xor ecx, ecx + mov eax, [0x3000] + cmp al, dl + setne cl + + pop edx eax + ret + +uglobal + mouse_active db 0 +endg +iglobal + cpustring db '/RD/1/CPU',0 +endg + +uglobal +background_defined db 0 ; diamond, 11.04.2006 +endg + +align 4 +; check misc + +checkmisc: + + cmp [ctrl_alt_del], 1 + jne nocpustart + mov ebp, cpustring + lea esi,[ebp+6] + xor ebx,ebx ; no parameters + xor edx,edx ; no flags + call fs_RamdiskExecute.flags + mov [ctrl_alt_del], 0 + nocpustart: + cmp [mouse_active], 1 + jne mouse_not_active + mov [mouse_active], 0 + xor edi, edi + mov ecx, [0x3004] + set_mouse_event: + add edi, 256 + or [edi+0x80000+APPDATA.event_mask], dword 00100000b + loop set_mouse_event + mouse_not_active: + + + cmp [0xfff0],byte 0 ; background update ? + jz nobackgr + cmp [background_defined], 0 + jz nobackgr + mov [0xfff0],byte 2 + call change_task + mov [draw_data+32 + RECT.left],dword 0 + mov [draw_data+32 + RECT.top],dword 0 + mov eax,[0xfe00] + mov ebx,[0xfe04] + mov [draw_data+32 + RECT.right],eax + mov [draw_data+32 + RECT.bottom],ebx + call drawbackground + mov [0xfff0],byte 0 + mov [0xfff4],byte 0 + + nobackgr: + + + ; system shutdown request + + cmp [0xFF00],byte 0 + je noshutdown + + mov edx,[shutdown_processes] + sub dl,2 + + cmp [0xff00],dl + jne no_mark_system_shutdown + + mov edx,0x3040 + movzx ecx,byte [0xff00] + add ecx,5 + markz: + mov [edx+TASKDATA.state],byte 3 + add edx,0x20 + loop markz + + no_mark_system_shutdown: + + call [disable_mouse] + + dec byte [0xff00] + + cmp [0xff00],byte 0 + je system_shutdown + + noshutdown: + + + mov eax,[0x3004] ; termination + mov ebx,0x3020+TASKDATA.state + mov esi,1 + + newct: + mov cl,[ebx] + cmp cl,byte 3 + jz terminate + cmp cl,byte 4 + jz terminate + + add ebx,0x20 + inc esi + dec eax + jnz newct + + ret + + + + +; redraw screen + +redrawscreen: + +; eax , if process window_data base is eax, do not set flag/limits + + pushad + push eax + +;;; mov eax,2 +;;; call delay_hs + + ;mov ecx,0 ; redraw flags for apps + xor ecx,ecx + newdw2: + + inc ecx + push ecx + + mov eax,ecx + shl eax,5 + add eax,window_data + + cmp eax,[esp+4] + je not_this_task + ; check if window in redraw area + mov edi,eax + + cmp ecx,1 ; limit for background + jz bgli + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + + mov ecx,[dlye] ; ecx = area y end ebx = window y start + cmp ecx,ebx + jb ricino + + mov ecx,[dlxe] ; ecx = area x end eax = window x start + cmp ecx,eax + jb ricino + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + + mov eax,[dly] ; eax = area y start edx = window y end + cmp edx,eax + jb ricino + + mov eax,[dlx] ; eax = area x start ecx = window x end + cmp ecx,eax + jb ricino + + bgli: + + cmp edi,esi + jz ricino + + mov eax,edi + add eax,draw_data-window_data + + mov ebx,[dlx] ; set limits + mov [eax + RECT.left], ebx + mov ebx,[dly] + mov [eax + RECT.top], ebx + mov ebx,[dlxe] + mov [eax + RECT.right], ebx + mov ebx,[dlye] + mov [eax + RECT.bottom], ebx + + sub eax,draw_data-window_data + + cmp ecx,1 + jne nobgrd + cmp esi,1 + je newdw8 + call drawbackground + + newdw8: + nobgrd: + + mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw + + ricino: + + not_this_task: + + pop ecx + + cmp ecx,[0x3004] + jle newdw2 + + pop eax + popad + + ret + +calculatebackground: ; background + + ; all black + + mov [display_data-8],dword 4 ; size x + mov [display_data-4],dword 2 ; size y + + mov edi, 0x300000 ; set background to black + xor eax, eax + mov ecx, 0x0fff00 / 4 + cld + rep stosd + + mov edi,display_data ; set os to use all pixels + mov eax,0x01010101 + mov ecx,0x1fff00 / 4 + rep stosd + + mov byte [0xFFF0], 0 ; do not draw background! + + ret + +uglobal + imax dd 0x0 +endg + + + +delay_ms: ; delay in 1/1000 sec + + + push eax + push ecx + + mov ecx,esi + ; + imul ecx, 33941 + shr ecx, 9 + ; + + in al,0x61 + and al,0x10 + mov ah,al + cld + + cnt1: in al,0x61 + and al,0x10 + cmp al,ah + jz cnt1 + + mov ah,al + loop cnt1 + + pop ecx + pop eax + + ret + + +set_app_param: + push edi + + mov edi,[0x3010] + mov [edi+TASKDATA.event_mask],eax + + pop edi + ret + + + +delay_hs: ; delay in 1/100 secs + push eax + push ecx + push edx + + mov edx,[timer_ticks] + add edx,eax + + newtic: + mov ecx,[timer_ticks] + cmp edx,ecx + jbe zerodelay + + call change_task + + jmp newtic + + zerodelay: + pop edx + pop ecx + pop eax + + ret + + +memmove: ; memory move in bytes + +; eax = from +; ebx = to +; ecx = no of bytes + test ecx, ecx + jle .ret + + + push esi edi ecx + + mov edi, ebx + mov esi, eax + + test ecx, not 11b + jz @f + + push ecx + shr ecx, 2 + rep movsd + pop ecx + and ecx, 11b + jz .finish + @@: + rep movsb + + .finish: + pop ecx edi esi + .ret: + ret + + +; Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead. +;align 4 +; +;read_floppy_file: +; +;; as input +;; +;; eax pointer to file +;; ebx file lenght +;; ecx start 512 byte block number +;; edx number of blocks to read +;; esi pointer to return/work area (atleast 20 000 bytes) +;; +;; +;; on return +;; +;; eax = 0 command succesful +;; 1 no fd base and/or partition defined +;; 2 yet unsupported FS +;; 3 unknown FS +;; 4 partition not defined at hd +;; 5 file not found +;; ebx = size of file +; +; mov edi,[0x3010] +; add edi,0x10 +; add esi,[edi] +; add eax,[edi] +; +; pushad +; mov edi,esi +; add edi,1024 +; mov esi,0x100000+19*512 +; sub ecx,1 +; shl ecx,9 +; add esi,ecx +; shl edx,9 +; mov ecx,edx +; cld +; rep movsb +; popad +; +; mov [esp+36],eax +; mov [esp+24],ebx +; ret + + + +align 4 + +sys_programirq: + + mov edi,[0x3010] + add eax,[edi+TASKDATA.mem_start] + + cmp ebx,16 + jae .not_owner + mov edi,[0x3010] + mov edi,[edi+TASKDATA.pid] + cmp edi,[irq_owner+ebx*4] + je spril1 +.not_owner: + mov [esp+36],dword 1 + ret + spril1: + + mov esi,eax + shl ebx,6 + add ebx,irq00read + mov edi,ebx + mov ecx,16 + cld + rep movsd + mov [esp+36],dword 0 + ret + + +align 4 + +get_irq_data: + cmp eax,16 + jae .not_owner + mov edx,eax ; check for correct owner + shl edx,2 + add edx,irq_owner + mov edx,[edx] + mov edi,[0x3010] + mov edi,[edi+TASKDATA.pid] + cmp edx,edi + je gidril1 +.not_owner: + mov [esp+32],dword 2 ; ecx=2 + ret + + gidril1: + + mov ebx,eax + shl ebx,12 + add ebx,0x2e0000 + mov eax,[ebx] + mov ecx,1 + test eax,eax + jz gid1 + + dec eax + mov esi,ebx + mov [ebx],eax + movzx ebx,byte [ebx+0x10] + add esi,0x10 + mov edi,esi + inc esi + mov ecx,4000 / 4 + cld + rep movsd +; xor ecx,ecx ; as result of 'rep' ecx=0 + gid1: + mov [esp+36],eax + mov [esp+32],ecx + mov [esp+24],ebx + ret + + +set_io_access_rights: + + pushad + + mov edi,[0x3000] + imul edi,tss_step + add edi,tss_data+128 +; add edi,128 + + mov ecx,eax + and ecx,7 ; offset in byte + + shr eax,3 ; number of byte + add edi,eax + + mov ebx,1 + shl ebx,cl + + cmp ebp,0 ; enable access - ebp = 0 + jne siar1 + + not ebx + and [edi],byte bl + + popad + + ret + + siar1: + + or [edi],byte bl ; disable access - ebp = 1 + + popad + + ret + + + + + +r_f_port_area: + + test eax, eax + jnz free_port_area +; je r_port_area +; jmp free_port_area + +; r_port_area: + + pushad + + cmp ebx,ecx ; beginning > end ? + ja rpal1 + cmp ecx,65536 + jae rpal1 + mov esi,[0x2d0000] + test esi,esi ; no reserved areas ? + je rpal2 + cmp esi,255 ; max reserved + jae rpal1 + rpal3: + mov edi,esi + shl edi,4 + add edi,0x2d0000 + cmp ebx,[edi+8] + ja rpal4 + cmp ecx,[edi+4] + jae rpal1 +; jb rpal4 +; jmp rpal1 + rpal4: + + dec esi + jnz rpal3 + jmp rpal2 + rpal1: + popad + mov eax,1 + ret + + rpal2: + popad + + + ; enable port access at port IO map + cli + pushad ; start enable io map + + cmp ecx,65536 ;16384 + jae no_unmask_io ; jge + + mov eax,ebx + + new_port_access: + + pushad + + xor ebp,ebp ; enable - eax = port + call set_io_access_rights + + popad + + inc eax + cmp eax,ecx + jbe new_port_access + + no_unmask_io: + + popad ; end enable io map + sti + + mov edi,[0x2d0000] + add edi,1 + mov [0x2d0000],edi + shl edi,4 + add edi,0x2d0000 + mov esi,[0x3010] + mov esi,[esi+TASKDATA.pid] + mov [edi],esi + mov [edi+4],ebx + mov [edi+8],ecx + + xor eax, eax + ret + + + + +free_port_area: + + pushad + + mov esi,[0x2d0000] ; no reserved areas ? + test esi,esi + je frpal2 + mov edx,[0x3010] + mov edx,[edx+TASKDATA.pid] + frpal3: + mov edi,esi + shl edi,4 + add edi,0x2d0000 + cmp edx,[edi] + jne frpal4 + cmp ebx,[edi+4] + jne frpal4 + cmp ecx,[edi+8] + jne frpal4 + jmp frpal1 + frpal4: + dec esi + jnz frpal3 + frpal2: + popad + mov eax,1 + ret + frpal1: + mov ecx,256 + sub ecx,esi + shl ecx,4 + mov esi,edi + add esi,16 + cld + rep movsb + + dec dword [0x2d0000] + + popad + + + ; disable port access at port IO map + + pushad ; start disable io map + + cmp ecx,65536 ;16384 + jge no_mask_io + + mov eax,ebx + + new_port_access_disable: + + pushad + + mov ebp,1 ; disable - eax = port + call set_io_access_rights + + popad + + inc eax + cmp eax,ecx + jbe new_port_access_disable + + no_mask_io: + + popad ; end disable io map + + xor eax, eax + ret + + +reserve_free_irq: + + mov ecx, 1 + cmp ebx, 16 + jae fril1 + test eax,eax + jz reserve_irq + + lea edi,[irq_owner+ebx*4] + mov edx,[edi] + mov eax,[0x3010] + cmp edx,[eax+TASKDATA.pid] + jne fril1 + dec ecx + mov [edi],ecx + fril1: + mov [esp+36],ecx ; return in eax + ret + + reserve_irq: + + lea edi,[irq_owner+ebx*4] + cmp dword [edi], 0 + jnz ril1 + + mov edx,[0x3010] + mov edx,[edx+TASKDATA.pid] + mov [edi],edx + dec ecx + ril1: + mov [esp+36],ecx ; return in eax + ret + + + +drawbackground: + inc [mouse_pause] + cmp [0xfe0c],word 0x12 + je dbrv20 + dbrv12: + cmp [0xfe0c],word 0100000000000000b + jge dbrv20 + cmp [0xfe0c],word 0x13 + je dbrv20 + call vesa12_drawbackground + dec [mouse_pause] + call [draw_pointer] + ret + dbrv20: + cmp [display_data-12],dword 1 + jne bgrstr + call vesa20_drawbackground_tiled + dec [mouse_pause] + call [draw_pointer] + ret + bgrstr: + call vesa20_drawbackground_stretch + dec [mouse_pause] + call [draw_pointer] + ret + +align 4 + +syscall_putimage: ; PutImage + + mov edx,ecx + mov ecx,ebx + lea ebx, [eax+std_application_base_address] + +sys_putimage: + test ecx,0x80008000 + jnz .exit + test ecx,0x0000FFFF + jz .exit + test ecx,0xFFFF0000 + jnz @f + .exit: + ret + @@: + mov edi,[0x3000] + shl edi,8 + add dx,word[edi+0x80000+APPDATA.wnd_clientbox.top] + rol edx,16 + add dx,word[edi+0x80000+APPDATA.wnd_clientbox.left] + rol edx,16 + .forced: +; mov eax, vga_putimage + cmp [0xfe0c], word 0x12 + jz @f ;.doit + mov eax, vesa12_putimage + cmp [0xfe0c], word 0100000000000000b + jae @f + cmp [0xfe0c], word 0x13 + jnz .doit +@@: + mov eax, vesa20_putimage +.doit: + inc [mouse_pause] + call eax + dec [mouse_pause] + jmp [draw_pointer] + +; eax x beginning +; ebx y beginning +; ecx x end +; edx y end +; edi color + +__sys_drawbar: + mov esi,[0x3000] + shl esi,8 + add eax,[esi+0x80000+APPDATA.wnd_clientbox.left] + add ecx,[esi+0x80000+APPDATA.wnd_clientbox.left] + add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top] + add edx,[esi+0x80000+APPDATA.wnd_clientbox.top] + .forced: + inc [mouse_pause] + cmp [0xfe0c],word 0x12 + je dbv20 + sdbv20: + cmp [0xfe0c],word 0100000000000000b + jge dbv20 + cmp [0xfe0c],word 0x13 + je dbv20 + call vesa12_drawbar + dec [mouse_pause] + call [draw_pointer] + ret + dbv20: + call vesa20_drawbar + dec [mouse_pause] + call [draw_pointer] + ret + + + +kb_read: + + push ecx edx + + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kr_loop: + in al,0x64 + test al,1 + jnz kr_ready + loop kr_loop + mov ah,1 + jmp kr_exit + kr_ready: + push ecx + mov ecx,32 + kr_delay: + loop kr_delay + pop ecx + in al,0x60 + xor ah,ah + kr_exit: + + pop edx ecx + + ret + + +kb_write: + + push ecx edx + + mov dl,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop1: + in al,0x64 + test al,0x20 + jz kw_ok1 + loop kw_loop1 + mov ah,1 + jmp kw_exit + kw_ok1: + in al,0x60 + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop: + in al,0x64 + test al,2 + jz kw_ok + loop kw_loop + mov ah,1 + jmp kw_exit + kw_ok: + mov al,dl + out 0x60,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop3: + in al,0x64 + test al,2 + jz kw_ok3 + loop kw_loop3 + mov ah,1 + jmp kw_exit + kw_ok3: + mov ah,8 + kw_loop4: + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + kw_loop5: + in al,0x64 + test al,1 + jnz kw_ok4 + loop kw_loop5 + dec ah + jnz kw_loop4 + kw_ok4: + xor ah,ah + kw_exit: + + pop edx ecx + + ret + + +kb_cmd: + + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + c_wait: + in al,0x64 + test al,2 + jz c_send + loop c_wait + jmp c_error + c_send: + mov al,bl + out 0x64,al + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + c_accept: + in al,0x64 + test al,2 + jz c_ok + loop c_accept + c_error: + mov ah,1 + jmp c_exit + c_ok: + xor ah,ah + c_exit: + ret + + +setmouse: ; set mousepicture -pointer + ; ps2 mouse enable + + mov [0xf200],dword mousepointer + + cli +; mov bl,0xa8 ; enable mouse cmd +; call kb_cmd +; call kb_read ; read status +; mov bl,0x20 ; get command byte +; call kb_cmd +; call kb_read +; or al,3 ; enable interrupt +; mov bl,0x60 ; write command +; push eax +; call kb_cmd +; pop eax +; call kb_write +; mov bl,0xd4 ; for mouse +; call kb_cmd +; mov al,0xf4 ; enable mouse device +; call kb_write +; call kb_read ; read status return + + ; com1 mouse enable + + mov bx,0x3f8 ; combase + + mov dx,bx + add dx,3 + mov al,0x80 + out dx,al + + mov dx,bx + add dx,1 + mov al,0 + out dx,al + + mov dx,bx + add dx,0 + mov al,0x30*2 ; 0x30 / 4 + out dx,al + + mov dx,bx + add dx,3 + mov al,2 ; 3 + out dx,al + + mov dx,bx + add dx,4 + mov al,0xb + out dx,al + + mov dx,bx + add dx,1 + mov al,1 + out dx,al + + + ; com2 mouse enable + + mov bx,0x2f8 ; combase + + mov dx,bx + add dx,3 + mov al,0x80 + out dx,al + + mov dx,bx + add dx,1 + mov al,0 + out dx,al + + mov dx,bx + add dx,0 + mov al,0x30*2 + out dx,al + + mov dx,bx + add dx,3 + mov al,2 + out dx,al + + mov dx,bx + add dx,4 + mov al,0xb + out dx,al + + mov dx,bx + add dx,1 + mov al,1 + out dx,al + + ret + + +_rdtsc: + + mov edx,[cpuid_1+3*4] + test edx,00010000b + jz ret_rdtsc + rdtsc + ret + ret_rdtsc: + mov edx,0xffffffff + mov eax,0xffffffff + ret + + + +rerouteirqs: + + cli + + mov al,0x11 ; icw4, edge triggered + out 0x20,al + call pic_delay + out 0xA0,al + call pic_delay + + mov al,0x20 ; generate 0x20 + + out 0x21,al + call pic_delay + mov al,0x28 ; generate 0x28 + + out 0xA1,al + call pic_delay + + mov al,0x04 ; slave at irq2 + out 0x21,al + call pic_delay + mov al,0x02 ; at irq9 + out 0xA1,al + call pic_delay + + mov al,0x01 ; 8086 mode + out 0x21,al + call pic_delay + out 0xA1,al + call pic_delay + + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay + + mov ecx,0x1000 + cld +picl1: call pic_delay + loop picl1 + + mov al,255 ; mask all irq's + out 0xA1,al + call pic_delay + out 0x21,al + call pic_delay + + cli + + ret + + +pic_delay: + + jmp pdl1 +pdl1: ret + + +sys_msg_board_str: + + pushad + @@: + cmp [esi],byte 0 + je @f + mov eax,1 + movzx ebx,byte [esi] + call sys_msg_board + inc esi + jmp @b + @@: + popad + ret + +uglobal + msg_board_data: times 512 db 0 + msg_board_count dd 0x0 +endg + +sys_msg_board: + +; eax=1 : write : bl byte to write +; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al + + mov ecx,[msg_board_count] + cmp eax, 1 + jne smbl1 + + + mov [msg_board_data+ecx],bl + inc ecx + and ecx, 511 + mov [msg_board_count], ecx + mov [check_idle_semaphore], 5 + ret + smbl1: + + cmp eax, 2 + jne smbl2 + test ecx, ecx + jz smbl21 +; mov edi, msg_board_data +; mov esi, msg_board_data+1 +; movzx eax, byte [edi] + mov eax, msg_board_data+1 + mov ebx, msg_board_data + movzx edx, byte [ebx] + call memmove +; push ecx +; shr ecx, 2 +; cld +; rep movsd +; pop ecx +; and ecx, 3 +; rep movsb + dec [msg_board_count] + mov [esp+36], edx ;eax + mov [esp+24], dword 1 + ret + smbl21: + mov [esp+36], ecx + mov [esp+24], ecx + + smbl2: + ret + + + +sys_trace: + + test eax, eax ; get event data + jnz no_get_sys_events + + mov esi,save_syscall_data ; data + mov edi,[0x3010] + mov edi,[edi+TASKDATA.mem_start] + add edi,ebx + cld + rep movsb + + mov [esp+24],dword 0 + mov eax,[save_syscall_count] ; count + mov [esp+36],eax + ret + + no_get_sys_events: + + ret + + +sys_process_def: + mov edi, [0x3000] + + dec eax ; 1 = set keyboard mode + jne no_set_keyboard_setup + + shl edi,8 + mov [edi+0x80000 + APPDATA.keyboard_mode],bl + + ret + + no_set_keyboard_setup: + + dec eax ; 2 = get keyboard mode + jne no_get_keyboard_setup + + shl edi,8 + movzx eax, byte [0x80000+edi + APPDATA.keyboard_mode] + + mov [esp+36],eax + + ret + + no_get_keyboard_setup: + + dec eax ; 3 = get keyboard ctrl, alt, shift + jne no_get_keyboard_cas + +; xor eax,eax +; movzx eax,byte [shift] +; movzx ebx,byte [ctrl] +; shl ebx,2 +; add eax,ebx +; movzx ebx,byte [alt] +; shl ebx,3 +; add eax,ebx + + ;// mike.dld [ + mov eax, [kb_state] + ;// mike.dld ] + + mov [esp+36],eax + + ret + + no_get_keyboard_cas: + + dec eax + jnz no_add_keyboard_hotkey + + mov eax, hotkey_list +@@: + cmp dword [eax+8], 0 + jz .found_free + add eax, 16 + cmp eax, hotkey_list+16*256 + jb @b + mov dword [esp+36], 1 + ret +.found_free: + mov [eax+8], edi + mov [eax+4], ecx + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov ecx, [ebx] + mov [eax], ecx + mov [ebx], eax + mov [eax+12], ebx + jecxz @f + mov [ecx+12], eax +@@: + and dword [esp+36], 0 + ret + +no_add_keyboard_hotkey: + + dec eax + jnz no_del_keyboard_hotkey + + movzx ebx, bl + lea ebx, [hotkey_scancodes+ebx*4] + mov eax, [ebx] +.scan: + test eax, eax + jz .notfound + cmp [eax+8], edi + jnz .next + cmp [eax+4], ecx + jz .found +.next: + mov eax, [eax] + jmp .scan +.notfound: + mov dword [esp+36], 1 + ret +.found: + mov ecx, [eax] + jecxz @f + mov edx, [eax+12] + mov [ecx+12], edx +@@: + mov ecx, [eax+12] + mov edx, [eax] + mov [ecx], edx + xor edx, edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax], edx + mov [esp+36], edx + ret + +no_del_keyboard_hotkey: + ret + + +sys_ipc: + cmp eax,1 ; DEFINE IPC MEMORY + jne no_ipc_def + mov edi,[0x3000] + shl edi,8 + add edi,0x80000 + mov [edi + APPDATA.ipc_start], ebx + mov [edi + APPDATA.ipc_size], ecx + mov [esp+36],dword 0 + ret + no_ipc_def: + + cmp eax,2 ; SEND IPC MESSAGE + jne no_ipc_send + mov esi,1 + mov edi,0x3020 + ipcs1: + cmp [edi+TASKDATA.pid], ebx + je ipcs2 + add edi,0x20 + inc esi + cmp esi,[0x3004] + jbe ipcs1 + mov [esp+36],dword 4 + ret + ipcs2: + + cli + + push esi + mov eax,esi + shl eax,8 + mov ebx,[eax+0x80000 + APPDATA.ipc_start] + test ebx,ebx ; ipc area not defined ? + je ipc_err1 + + add ebx,[eax+0x80000 + APPDATA.ipc_size] + mov eax,esi + shl eax,5 + add ebx,[eax+0x3000 + TASKDATA.mem_start] ; ebx <- max data position + + mov eax,esi ; to + shl esi,8 + add esi,0x80000 + mov edi,[esi+APPDATA.ipc_start] + shl eax,5 + add eax,0x3000 + add edi,[eax+TASKDATA.mem_start] + + cmp [edi],byte 0 ; overrun ? + jne ipc_err2 + + mov ebp,edi + add edi,[edi+4] + add edi,8 + + mov esi,ecx ; from + mov eax,[0x3010] + mov eax,[eax+TASKDATA.mem_start] + add esi,eax + + mov ecx,edx ; size + + mov eax,edi + add eax,ecx + cmp eax,ebx + jg ipc_err3 ; not enough room ? + + push ecx + + mov eax,[0x3010] + mov eax,[eax+TASKDATA.pid] + mov [edi-8],eax + mov [edi-4],ecx + cld + rep movsb + + pop ecx + add ecx,8 + + mov edi,ebp ; increase memory position + add dword [edi+4],ecx + + mov edi,[esp] + shl edi,8 + or dword [edi+0x80000+APPDATA.event_mask],dword 01000000b ; ipc message + + cmp [check_idle_semaphore],dword 20 + jge ipc_no_cis + mov [check_idle_semaphore],5 + ipc_no_cis: + + xor eax, eax + + ipc_err: + add esp,4 + mov [esp+36],eax + sti + ret + + ipc_err1: + add esp,4 + mov [esp+36],dword 1 + sti + ret + ipc_err2: + add esp,4 + mov [esp+36],dword 2 + sti + ret + ipc_err3: + add esp,4 + mov [esp+36],dword 3 + sti + ret + + no_ipc_send: + + mov [esp+36],dword -1 + ret + + +align 4 + +sys_gs: ; direct screen access + + cmp eax,1 ; resolution + jne no_gs1 + mov eax,[0xfe00] + shl eax,16 + mov ax,[0xfe04] + add eax,0x00010001 + mov [esp+36],eax + ret + no_gs1: + + cmp eax,2 ; bits per pixel + jne no_gs2 + movzx eax,byte [0xfbf1] + mov [esp+36],eax + ret + no_gs2: + + cmp eax,3 ; bytes per scanline + jne no_gs3 + mov eax,[0xfe08] + mov [esp+36],eax + ret + no_gs3: + + mov [esp+36],dword -1 + ret + + +align 4 ; PCI functions + +sys_pci: + + call pci_api + mov [esp+36],eax + ret + + +align 4 ; system functions + +syscall_setpixel: ; SetPixel + + + mov edx,[0x3010] + add eax,[edx-twdw+WDATA.box.left] + add ebx,[edx-twdw+WDATA.box.top] + mov edi,[0x3000] + shl edi,8 + add eax,[edi+0x80000+APPDATA.wnd_clientbox.left] + add ebx,[edi+0x80000+APPDATA.wnd_clientbox.top] + xor edi,edi ; no force +; mov edi,1 + call [disable_mouse] + jmp [putpixel] + +align 4 + +syscall_writetext: ; WriteText + + mov edi,[0x3010] + mov ebp,[edi-twdw+WDATA.box.left] + push esi + mov esi,[0x3000] + shl esi,8 + add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left] + shl ebp,16 + add ebp,[edi-twdw+WDATA.box.top] + add bp,word[esi+0x80000+APPDATA.wnd_clientbox.top] + pop esi + add ecx,[edi+TASKDATA.mem_start] + add eax,ebp + xor edi,edi + jmp dtext + +align 4 + +syscall_openramdiskfile: ; OpenRamdiskFile + + + mov edi,[0x3010] + add edi, TASKDATA.mem_start + add eax,[edi] + add edx,[edi] + mov esi,12 + call fileread + mov [esp+36],ebx + ret + +align 4 + +syscall_drawrect: ; DrawRect + + mov edi,ecx + and edi,0x80FFFFFF + test ax,ax + je drectr + test bx,bx + je drectr + movzx ecx,ax + shr eax,16 + movzx edx,bx + shr ebx,16 + mov esi,[0x3000] + shl esi,8 + add eax,[esi+0x80000+APPDATA.wnd_clientbox.left] + add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top] + add ecx,eax + add edx,ebx + jmp [drawbar] + drectr: + ret + +align 4 + +syscall_getscreensize: ; GetScreenSize + + movzx eax,word[0xfe00] + shl eax,16 + mov ax,[0xfe04] + mov [esp+36],eax + ret + +align 4 + +syscall_cdaudio: ; CD + + call sys_cd_audio + mov [esp+36],eax + ret + +align 4 + +syscall_delramdiskfile: ; DelRamdiskFile + + mov edi,[0x3010] + add edi, TASKDATA.mem_start + add eax,[edi] + call filedelete + mov [esp+36],eax + ret + +align 4 + +syscall_writeramdiskfile: ; WriteRamdiskFile + + mov edi,[0x3010] + add edi, TASKDATA.mem_start + add eax,[edi] + add ebx,[edi] + call filesave + mov [esp+36],eax + ret + +align 4 + +syscall_getpixel: ; GetPixel + mov ecx,[0xfe00] + inc ecx + xor edx,edx + div ecx + mov ebx,edx + xchg eax,ebx + call dword [0xe024] + mov [esp+36],ecx + ret + +align 4 + +syscall_readstring: ; ReadString + + mov edi,[0x3010] + add edi, TASKDATA.mem_start + add eax,[edi] + call read_string + mov [esp+36],eax + ret + +align 4 + +syscall_drawline: ; DrawLine + + mov edi,[0x3010] + movzx edx,word[edi-twdw+WDATA.box.left] + mov ebp,edx + mov esi,[0x3000] + shl esi,8 + add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left] + add dx,word[esi+0x80000+APPDATA.wnd_clientbox.left] + shl edx,16 + add ebp,edx + movzx edx,word[edi-twdw+WDATA.box.top] + add eax,ebp + mov ebp,edx + add ebp,[esi+0x80000+APPDATA.wnd_clientbox.top] + add dx,word[esi+0x80000+APPDATA.wnd_clientbox.top] + shl edx,16 + xor edi,edi + add edx,ebp + add ebx,edx + jmp [draw_line] + +align 4 + +syscall_getirqowner: ; GetIrqOwner + cmp eax,16 + jae .err + shl eax,2 + add eax,irq_owner + mov eax,[eax] + mov [esp+36],eax + ret +.err: + or dword [esp+36], -1 + ret + +align 4 + +syscall_reserveportarea: ; ReservePortArea and FreePortArea + + call r_f_port_area + mov [esp+36],eax + ret + +align 4 + +syscall_threads: ; CreateThreads + + call sys_threads + mov [esp+36],eax + ret + +align 4 + +stack_driver_stat: + + call app_stack_handler ; Stack status + +; mov [check_idle_semaphore],5 ; enable these for zero delay +; call change_task ; between sent packet + + mov [esp+36],eax + ret + +align 4 + +socket: ; Socket interface + call app_socket_handler + +; mov [check_idle_semaphore],5 ; enable these for zero delay +; call change_task ; between sent packet + + mov [esp+36],eax + mov [esp+24],ebx + ret + +align 4 + +user_events: ; User event times + + mov eax,0x12345678 + mov [esp+36],eax + + ret + +align 4 + +read_from_hd: ; Read from hd - fn not in use + + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add eax,[edi] + add ecx,[edi] + add edx,[edi] + call file_read + + mov [esp+36],eax + mov [esp+24],ebx + + ret + + +align 4 + +write_to_hd: ; Write a file to hd + + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add eax,[edi] + add ecx,[edi] + add edx,[edi] + call file_write + ret + +; Sysfunction 57, delete_from_hd, is obsolete. Use 58 or 70 functions instead. +;align 4 +; +;delete_from_hd: ; Delete a file from hd +; +; mov edi,[0x3010] +; add edi,0x10 +; add eax,[edi] +; add ecx,[edi] +; call file_delete +; ret +; + +; --------------- APM --------------------- +apm_entry dp 0 +apm_vf dd 0 +align 4 +sys_apm: + cmp word [apm_vf], 0 ; Check APM BIOS enable + jne @f + or [esp + 56], byte 1 ; error + mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported + ret + +@@: xchg eax, ecx + xchg ebx, ecx + + cmp al, 3 + ja @f + and [esp + 56], byte 0xfe ; emulate func 0..3 as func 0 + mov eax, [apm_vf] + mov [esp + 36], eax + shr eax, 16 + mov [esp + 32], eax + ret + +@@: call pword [apm_entry] ; call APM BIOS + mov [esp + 8 ], edi + mov [esp + 12], esi + mov [esp + 24], ebx + mov [esp + 28], edx + mov [esp + 32], ecx + mov [esp + 36], eax + setc al + and [esp + 56], byte 0xfe + or [esp + 56], al + ret +; ----------------------------------------- + +align 4 + +undefined_syscall: ; Undefined system call + + mov [esp+36],dword -1 + ret + + +;clear_busy_flag_at_caller: + +; push edi + +; mov edi,[0x3000] ; restore processes tss pointer in gdt, busyfl? +; imul edi,8 +; mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b + +; pop edi + +; ret + + + + +keymap: + + db '6',27 + db '1234567890-=',8,9 + db 'qwertyuiop[]',13 + db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'AB?',0,'45 ' + db '@234567890123',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + +keymap_alt: + + db ' ',27 + db ' @ $ {[]}\ ',8,9 + db ' ',13 + db ' ',0,' ',0,'4',0,' ' + db ' ',180,178,184,'6',176,'7' + db 179,'8',181,177,183,185,182 + db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + + +; device irq owners +uglobal +irq_owner: ; process id + + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 + dd 0x0 +endg + + +; on irq read ports +uglobal + irq00read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq01read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq02read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq03read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq04read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq05read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq06read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq07read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq08read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq09read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq10read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq11read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq12read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq13read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq14read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + irq15read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +endg + +; status +uglobal + hd1_status dd 0x0 ; 0 - free : other - pid + application_table_status dd 0x0 ; 0 - free : other - pid +endg + +; device addresses +uglobal + mididp dd 0x0 + midisp dd 0x0 + + cdbase dd 0x0 + cdid dd 0x0 + + hdbase dd 0x0 ; for boot 0x1f0 + hdid dd 0x0 + hdpos dd 0x0 ; for boot 0x1 + fat32part dd 0x0 ; for boot 0x1 + + ;part2_ld dd 0x0 + +;* start code - Mario79 +mouse_pause dd 0 +MouseTickCounter dd 0 +ps2_mouse_detected db 0 +com1_mouse_detected db 0 +com2_mouse_detected db 0 +;* end code - Mario79 + +wraw_bacground_select db 0 + lba_read_enabled dd 0x0 ; 0 = disabled , 1 = enabled + pci_access_enabled dd 0x0 ; 0 = disabled , 1 = enabled + + sb16 dd 0x0 + wss dd 0x0 + + buttontype dd 0x0 + windowtypechanged dd 0x0 +endg + +iglobal + keyboard dd 0x1 + sound_dma dd 0x1 + syslang dd 0x1 +endg + +IncludeIGlobals +endofcode: +IncludeUGlobals +uglobals_size = $ - endofcode +diff16 "end of kernel code",0,$ + diff --git a/kernel/tags/kolibri0.6.0.0/kernel16.inc b/kernel/tags/kolibri0.6.0.0/kernel16.inc new file mode 100644 index 0000000000..7b630dc66b --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/kernel16.inc @@ -0,0 +1,34 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; KERNEL16.INC ;; +;; ;; +;; Included 16 bit kernel files for MenuetOS ;; +;; ;; +;; This file is kept separate as it will be easier to ;; +;; maintain and compile with an automated SETUP program ;; +;; in the future. ;; +;; ;; +;; Copyright Ville Turjanmaa, see file COPYING for details. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;% +include + +;!!! +if lang eq en +include "boot/booteng.inc" ; english system boot messages +else if lang eq ru +include "boot/bootru.inc" ; russian system boot messages +else +include "boot/bootge.inc" ; german system boot messages +;!!! +end if +include "boot/ru.inc" ; Russian font +org $-0x10000 + +include "boot/bootcode.inc" ; 16 bit system boot code + +include "bus/pci/pci16.inc" + +;% -include \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/kernel32.inc b/kernel/tags/kolibri0.6.0.0/kernel32.inc new file mode 100644 index 0000000000..7eb691bf1a --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/kernel32.inc @@ -0,0 +1,256 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; KERNEL32.INC ;; +;; ;; +;; Included 32 bit kernel files for MenuetOS ;; +;; ;; +;; This file is kept separate as it will be easier to ;; +;; maintain and compile with an automated SETUP program ;; +;; in the future. ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; structure definition helper +macro struct name, [arg] + { + common + name@struct equ name + struc name arg { + } + +macro struct_helper name + { + match xname,name + \{ + virtual at 0 + xname xname + sizeof.#xname = $ - xname + name equ sizeof.#xname + end virtual + \} + } + +ends fix } struct_helper name@struct + +;// mike.dld, 2006-29-01 [ + +; macros definition +macro diff16 title,l1,l2 +{ + local s,d + s = l2-l1 + display title,': 0x' + repeat 8 + d = 48 + s shr ((8-%) shl 2) and $0F + if d > 57 + d = d + 65-57-1 + end if + display d + end repeat + display 13,10 +} + +struc db [a] { common . db a + if ~used . + display 'not used db: ',`.,13,10 + end if } +struc dw [a] { common . dw a + if ~used . + display 'not used dw: ',`.,13,10 + end if } +struc dd [a] { common . dd a + if ~used . + display 'not used dd: ',`.,13,10 + end if } +struc dp [a] { common . dp a + if ~used . + display 'not used dp: ',`.,13,10 + end if } +struc dq [a] { common . dq a + if ~used . + display 'not used dq: ',`.,13,10 + end if } +struc dt [a] { common . dt a + if ~used . + display 'not used dt: ',`.,13,10 + end if } + +struc RECT { + .left dd ? + .top dd ? + .right dd ? + .bottom dd ? +} +virtual at 0 + RECT RECT +end virtual + +struc BOX { + .left dd ? + .top dd ? + .width dd ? + .height dd ? +} +virtual at 0 + BOX BOX +end virtual + +; constants definition +WSTATE_NORMAL = 00000000b +WSTATE_MAXIMIZED = 00000001b +WSTATE_MINIMIZED = 00000010b +WSTATE_ROLLEDUP = 00000100b + +WSTATE_REDRAW = 00000001b +WSTATE_WNDDRAWN = 00000010b + +WSTYLE_HASCAPTION = 00010000b +WSTYLE_CLIENTRELATIVE = 00100000b + +struc TASKDATA +{ + .event_mask dd ? + .pid dd ? + dw ? + .state db ? + db ? + dw ? + .wnd_number db ? + db ? + .mem_start dd ? + .counter_sum dd ? + .counter_add dd ? + .cpu_usage dd ? +} +virtual at 0 + TASKDATA TASKDATA +end virtual + +; structures definition +struc WDATA { + .box BOX + .cl_workarea dd ? + .cl_titlebar dd ? + .cl_frames dd ? + .reserved db ? + .fl_wstate db ? + .fl_wdrawn db ? + .fl_redraw db ? +} +virtual at 0 + WDATA WDATA +end virtual +label WDATA.fl_wstyle byte at 0x13 + +struc APPDATA +{ + .app_name db 11 dup(?) + db 5 dup(?) + .fpu_save_area: db 108 dup(?) + db 3 dup(?) + .is_fpu_saved db ? + .wnd_shape dd ? + .wnd_shape_scale dd ? + dd ? + .mem_size dd ? + .saved_box BOX + .ipc_start dd ? + .ipc_size dd ? + .event_mask dd ? + .debugger_slot dd ? + dd ? + .keyboard_mode db ? + db 3 dup(?) + .dir_table dd ? + .dbg_event_mem dd ? + .dbg_regs: + .dbg_regs.dr0 dd ? + .dbg_regs.dr1 dd ? + .dbg_regs.dr2 dd ? + .dbg_regs.dr3 dd ? + .dbg_regs.dr7 dd ? + .wnd_caption dd ? + .wnd_clientbox BOX +} +virtual at 0 + APPDATA APPDATA +end virtual + +;// mike.dld, 2006-29-01 ] + + +; Core functions +include "core/sync.inc" ; macros for synhronization objects +include "core/sys32.inc" ; process management +include "core/sched.inc" ; process scheduling +include "core/syscall.inc" ; system call +include "core/mem.inc" ; high-level memory management +include "core/newproce.inc" ;new process management +include "core/physmem.inc" ; access to physical memory for applications + +; GUI stuff +include "gui/window.inc" +include "gui/event.inc" +include "gui/font.inc" +include "gui/button.inc" + +; shutdown + +include "boot/shutdown.inc" ; shutdown or restart + +; file system + +include "fs/fs.inc" ; syscall +include "fs/fat32.inc" ; read / write for fat32 filesystem +include "fs/fat12.inc" ; read / write for fat12 filesystem +include "blkdev/rd.inc" ; ramdisk read /write +include "fs/fs_lfn.inc" ; syscall, version 2 +include "fs/iso9660.inc" ; read for iso9660 filesystem CD + +; sound + +include "sound/sb16.inc" ; playback for Sound Blaster 16 +include "sound/playnote.inc" ; player Note for Speaker PC + +; display + +include "video/vesa12.inc" ; Vesa 1.2 functions +include "video/vesa20.inc" ; Vesa 2.0 functions +include "video/vga.inc" ; VGA 16 color functions + +; Network Interface & TCPIP Stack + +include "network/stack.inc" + +; Mouse pointer + +include "gui/mouse.inc" + +; Window skinning + +include "gui/skincode.inc" + +; Pci functions + +include "bus/pci/pci32.inc" + +; Floppy drive controller + +include "blkdev/fdc.inc" +include "blkdev/flp_drv.inc" + +; CD drive controller + +include "blkdev/cdrom.inc" +include "blkdev/cd_drv.inc" + +; Character devices + +include "hid/keyboard.inc" +include "hid/mousedrv.inc" + +; setting date,time,clock and alarm-clock + +include "hid/set_dtc.inc" + +;% -include diff --git a/kernel/tags/kolibri0.6.0.0/kglobals.inc b/kernel/tags/kolibri0.6.0.0/kglobals.inc new file mode 100644 index 0000000000..75688d765d --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/kglobals.inc @@ -0,0 +1,50 @@ +;------------------------------------------------------------------ +; use "iglobal" for inserting initialized global data definitions. +;------------------------------------------------------------------ +macro iglobal { + IGlobals equ IGlobals, + macro __IGlobalBlock { } + +;------------------------------------------------------------- +; use 'uglobal' for inserting uninitialized global definitions. +; even when you define some data values, these variables +; will be stored as uninitialized data. +;------------------------------------------------------------- +macro uglobal { + UGlobals equ UGlobals, + macro __UGlobalBlock { } + +endg fix } ; Use endg for ending iglobal and uglobal blocks. + +macro IncludeIGlobals{ + macro IGlobals dummy,[n] \{ __IGlobalBlock + purge __IGlobalBlock \} + match I, IGlobals \{ I \} } + + +macro IncludeUGlobals{ + macro UGlobals dummy,[n] \{ + \common + \local begin, size + begin = $ + virtual at $ + \forward + __UGlobalBlock + purge __UGlobalBlock + \common + size = $ - begin + end virtual + rb size + \} + match U, UGlobals \{ U \} } + +macro IncludeAllGlobals { + IncludeIGlobals + IncludeUGlobals +} + +iglobal +endg + +uglobal +endg diff --git a/kernel/tags/kolibri0.6.0.0/makefile b/kernel/tags/kolibri0.6.0.0/makefile new file mode 100644 index 0000000000..d07df1b9c9 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/makefile @@ -0,0 +1,16 @@ +FASM=fasm +KSRC=kernel.asm +KOUT=kernel.mnt + +en: kernel.asm + rm -f lang.inc + echo lang fix en > lang.inc + $(FASM) $(KSRC) $(KOUT) +ru: kernel.asm + rm -f lang.inc + echo lang fix ru > lang.inc + $(FASM) $(KSRC) $(KOUT) + +clean: + rm -f $(KOUT) + rm -f lang.inc diff --git a/kernel/tags/kolibri0.6.0.0/memmap.inc b/kernel/tags/kolibri0.6.0.0/memmap.inc new file mode 100644 index 0000000000..df7ddcd9ff --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/memmap.inc @@ -0,0 +1,233 @@ +; +; MEMORY MAP +; +; Boot: +; +; 0:9000 byte bits per pixel +; 0:9001 word scanline length +; 0:9008 word vesa video mode +; 0:900A word X res +; 0:900C word Y res +; 0:9010 byte mouse port - not used +; 0:9014 dword Vesa 1.2 pm bank switch +; 0:9018 dword Vesa 2.0 LFB address +; 0:901C byte 0 or 1 : enable MTRR graphics acceleration +; 0:901D byte not used anymore (0 or 1 : enable system log display) +; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled +; 0:9020 8bytes pci data +; 0:9030 byte VRR start enabled 1, 2-no +; 0:9031 word IDEContrRegsBaseAddr +; 0x9040 - dword - entry point of APM BIOS +; 0x9044 - word - version (BCD) +; 0x9046 - word - flags +; +; Runtime: +; +; 0000 -> 1FFF window_data - 256 entries +; +; 0000 dword x start +; 0004 dword y start +; 0008 dword x size +; 000C dword y size +; 0010 dword color of work area +; 0014 dword color of grab bar +; 0018 dword color of frames +; 001C dword window flags, +30 = window drawn, +31 redraw flag +; +; 2000 -> 2FFF free +; +; 3000 -> 4FFF task list - 256 entries +; +; 00 dword process count +; 04 dword no of processes +; 10 dword base of running process at 0x3000+ +; +; 20 dword application event mask +; 24 dword PID - process identification number +; 2a byte slot state: 0=running, 1,2=suspended +; 3=zombie, 4=terminate, +; 5=waiting for event, 9 = not used +; 2e byte window number on screen +; 30 dword exact position in memory +; 34 dword counter sum +; 38 dword time stamp counter add +; 3c dword cpu usage in cpu timer tics +; +; +; 5000 -> 5FFF save_syscall_data - syscall trace +; 6000 -> 68FF free +; 6900 -> 6EFF saved picture under mouse pointer +; +; 6F00 -> 6FFF free +; +; 7000 -> 7FFF used CD driver +; +; 8000 -> A3FF used FLOPPY driver +; +; A400 -> B0FF free + +; B100 -> B2FF IDT + +; B300 -> BFFF free + +; C000 -> C3FF window stack C000 no of windows - all in words +; C402 -> C7FF window position in stack +; D000 -> D1FF FDC controller +; D200 -> D3FF FDC controller for Fat12 +; D400 -> DFFF free +; E000 byte multitasking started +; E020 dword putpixel address +; E024 dword getpixel address +; E030 dword Vesa 1.2 pm bank switch address +; F200 dword mousepicture -pointer +; F204 dword mouse appearance counter +; F300 dword x & y temp for windowmove +; F400 byte no of keys in buffer +; F401 byte 'buffer' +; F402 -> F4FF reserved for keys +; F500 byte no of buttons in buffer +; F501 dword 'buffer' +; F502 -> F5FF reserved for buttons +; F600 dword tsc / second +; F604 byte mouse port: 1 ps2, 2 com1, 3 com2 +; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y +; FB10 -> FB17 mouse color mem +; FB21 x move +; FB22 y move +; FB28 high bits temp +; FB30 color temp +; FB40 byte buttons down +; FB44 byte 0 mouse down -> do not draw +; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under +; FBF1 byte bits per pixel +; FC00 -> FCFE com1/ps2 buffer +; FCFF com1/ps2 buffer count starting from FC00 +; FE00 dword screen x size +; FE04 dword screen y size +; FE08 dword screen y multiplier +; FE0C dword screen mode +; FE10 dword entries in hd cache +; FE80 dword address of LFB in physical +; FE84 dword address of applications memory start in physical +; FE88 dword address of button list +; FE8C dword memory to use +; FF00 byte 1 = system shutdown request +; FF01 dword free +; FFF0 byte 1 = redraw background request from app +; FFF1 byte 1 = diskette int occur +; FFF2 write and read bank in screen +; FFF4 byte 0 if first mouse draw & do not return picture under +; FFF5 byte 1 do not draw pointer +; FFFF byte do not change task for 1/100 sec. +; +; 10000 -> 3DBFF kernel, 32-bit run-time code (up to 183 Kb) +; 3DC00 -> 3EBFF stack at boot time (4Kb) +; 3EC00 -> 3F5FF basic text font II +; 3F600 -> 3FFFF basic text font I +; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79) + +; 50000 -> 5FFFF free (64 Kb) + +; 60000 -> 7FFFF reserved to physical memory manager +; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries +; +; 00 11db name of app running +; 10 108db floating point unit save area +; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore +; 80 dword address of random shaped window area +; 84 byte shape area scale +; 88 dword free +; 8C dword application memory size +; 90 dword window X position save +; 94 dword window Y position save +; 98 dword window X size save +; 9C dword window Y size save +; A0 dword IPC memory start +; A4 dword IPC memory size +; A8 dword event bits: mouse, stack,.. +; AC dword 0 or debugger slot +; B0 dword free +; B4 byte keyboard mode: 0 = keymap, 1 = scancodes +; B8 dword physical address of directory table +; BC dword address of debug event memory +; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 +; +; 90000 -> 9FFFF tmp +; A0000 -> AFFFF screen access area +; B0000 -> FFFFF bios rest in peace -area +; 100000 -> 27FFFF diskette image +; 280000 -> 281FFF ramdisk fat +; 282000 -> 283FFF floppy fat +; +; 284000 -> 29FFFF free (112 Kb) +; +; 2A0000 -> 2B00ff wav device data +; 2C0000 -> 2C3fff button info +; +; 0000 word number of buttons +; first button entry at 0x10 +; +0000 word process number +; +0002 word button id number : bits 00-15 +; +0004 word x start +; +0006 word x size +; +0008 word y start +; +000A word y size +; +000C word button id number : bits 16-31 +; +; 2C4000 -> 2CFFFF free (48Kb) +; +; 2D0000 -> 2DFFFF reserved port area +; +; 0000 dword no of port areas reserved +; 0010 dword process id +; dword start port +; dword end port +; dword 0 +; +; 2E0000 -> 2EFFFF irq data area +; 2F0000 -> 2FFFFF low memory save +; +; 300000 -> 45FFFF background image, max 1,375 M +; +; 460000 -> 5FFFFF display info +; +; 600000 -> 6FFFFF hd cache +; +; 700000 -> 71ffff tcp memory (128 kb) +; 720000 -> 75ffff free (256 kb) +; +; 760000 -> 76ffff !vrr driver +; 770000 -> 777fff tcp memory ( 32 kb) +; +; 778000 -> 77ffff window skinning ( 32 kb) +; 780000 -> 7fffff reserved to physical memory manager +; +; 800000 -> BFFFFF mapped to LFB +; +; +; C00000 -> C01FFF draw_data - 256 entries +; +; 00 dword draw limit - x start +; 04 dword draw limit - y start +; 08 dword draw limit - x end +; 0C dword draw limit - y end +; +; C02000 -> C02fff free (4 Kb) +; +; C03000 -> D02fff sysint_stack_data +; - ring0 stacks for ring3 processes +; - used for interrupt handling +; - 256 entries * 4096 step +; +; D03000 -> D1ffff free (116 Kb) +; +; D20000 -> F28000 TSS and IO map for (8192*8)=65536 ports +; (128+8192)*256 = 557956 = 0x88000 +; +; 1000000 -> 3FFFFFF for applications +; + + + + + diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/3c59x.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/3c59x.inc new file mode 100644 index 0000000000..4280823c59 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/3c59x.inc @@ -0,0 +1,2380 @@ +;; Copyright (c) 2004, Endre Kozma +;; All rights reserved. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following conditions are +;; met: +;; +;; 1. Redistributions of source code must retain the above copyright notice, +;; this list of conditions and the following disclaimer. +;; +;; 2. Redistributions in binary form must reproduce the above copyright +;; notice, this list of conditions and the following disclaimer in the +;; documentation and/or other materials provided with the distribution. +;; +;; 3. The name of the author may not be used to endorse or promote products +;; derived from this software without specific prior written permission. +;; +;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 3C59X.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Driver for 3Com fast etherlink 3c59x and ;; +;; etherlink XL 3c900 and 3c905 cards ;; +;; References: ;; +;; www.3Com.com - data sheets ;; +;; DP83840A.pdf - ethernet physical layer ;; +;; 3c59x.c - linux driver ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; Credits ;; +;; Mike Hibbett, ;; +;; who kindly supplied me with a 3Com905C-TX-M card ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; History +;; ======= +;; $Log: 3C59X.INC,v $ +;; Revision 1.3 2004/07/11 12:21:12 kozma +;; Support of vortex chips (3c59x) added. +;; Support of 3c920 and 3c982 added. +;; Corrections. +;; +;; Revision 1.2 2004/06/12 19:40:20 kozma +;; Function e3c59x_set_available_media added in order to set +;; the default media in case auto detection finds no valid link. +;; Incorrect mii check removed (3c900 Cyclone works now). +;; Cleanups. +;; +;; Revision 1.1 2004/06/12 18:27:15 kozma +;; Initial revision +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; comment the next line out if you don't want debug info printed +; on the debug board. This option adds a lot of bytes to the driver +; so it's worth to comment it out. +; E3C59X_DEBUG equ 1 + +; forcing full duplex mode makes sense at some cards and link types + E3C59X_FORCE_FD equ 1 + +macro virt_to_dma reg +{ +if defined E3C59X_LINUX + sub reg, [virt_addr] + add reg, [dma_addr] +end if +} + +macro dma_to_virt reg +{ +if defined E3C59X_LINUX + sub reg, [dma_addr] + add reg, [virt_addr] +end if +} + +macro zero_to_virt reg +{ +if defined E3C59X_LINUX + add reg, [virt_addr] +end if +} + +macro virt_to_zero reg +{ +if defined E3C59X_LINUX + sub reg, [virt_addr] +end if +} + +macro zero_to_dma reg +{ +if defined E3C59X_LINUX + add reg, [dma_addr] +end if +} + +macro dma_to_zero reg +{ +if defined E3C59X_LINUX + sub reg, [dma_addr] +end if +} + +macro strtbl name, [string] +{ +common + label name dword +forward + local label + dd label +forward + label db string, 0 +} + +; Ethernet frame symbols + ETH_ALEN equ 6 + ETH_HLEN equ (2*ETH_ALEN+2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length +; PCI programming + PCI_REG_COMMAND equ 0x4 ; command register + PCI_REG_STATUS equ 0x6 ; status register + PCI_REG_LATENCY equ 0xd ; latency timer register + PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer + PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block + PCI_REG_PM_STATUS equ 0x4 ; power management status register + PCI_REG_PM_CTRL equ 0x4 ; power management control register + PCI_BIT_PIO equ 0 ; bit0: io space control + PCI_BIT_MMIO equ 1 ; bit1: memory space control + PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master +; Registers + E3C59X_REG_POWER_MGMT_CTRL equ 0x7c + E3C59X_REG_UP_LIST_PTR equ 0x38 + E3C59X_REG_UP_PKT_STATUS equ 0x30 + E3C59X_REG_TX_FREE_THRESH equ 0x2f + E3C59X_REG_DN_LIST_PTR equ 0x24 + E3C59X_REG_DMA_CTRL equ 0x20 + E3C59X_REG_TX_STATUS equ 0x1b + E3C59X_REG_RX_STATUS equ 0x18 + E3C59X_REG_TX_DATA equ 0x10 +; Common window registers + E3C59X_REG_INT_STATUS equ 0xe + E3C59X_REG_COMMAND equ 0xe +; Register window 7 + E3C59X_REG_MASTER_STATUS equ 0xc + E3C59X_REG_POWER_MGMT_EVENT equ 0xc + E3C59X_REG_MASTER_LEN equ 0x6 + E3C59X_REG_VLAN_ETHER_TYPE equ 0x4 + E3C59X_REG_VLAN_MASK equ 0x0 + E3C59X_REG_MASTER_ADDRESS equ 0x0 +; Register window 6 + E3C59X_REG_BYTES_XMITTED_OK equ 0xc + E3C59X_REG_BYTES_RCVD_OK equ 0xa + E3C59X_REG_UPPER_FRAMES_OK equ 0x9 + E3C59X_REG_FRAMES_DEFERRED equ 0x8 + E3C59X_REG_FRAMES_RCVD_OK equ 0x7 + E3C59X_REG_FRAMES_XMITTED_OK equ 0x6 + E3C59X_REG_RX_OVERRUNS equ 0x5 + E3C59X_REG_LATE_COLLISIONS equ 0x4 + E3C59X_REG_SINGLE_COLLISIONS equ 0x3 + E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2 + E3C59X_REG_SQE_ERRORS equ 0x1 + E3C59X_REG_CARRIER_LOST equ 0x0 +; Register window 5 + E3C59X_REG_INDICATION_ENABLE equ 0xc + E3C59X_REG_INTERRUPT_ENABLE equ 0xa + E3C59X_REG_TX_RECLAIM_THRESH equ 0x9 + E3C59X_REG_RX_FILTER equ 0x8 + E3C59X_REG_RX_EARLY_THRESH equ 0x6 + E3C59X_REG_TX_START_THRESH equ 0x0 +; Register window 4 + E3C59X_REG_UPPER_BYTES_OK equ 0xe + E3C59X_REG_BAD_SSD equ 0xc + E3C59X_REG_MEDIA_STATUS equ 0xa + E3C59X_REG_PHYSICAL_MGMT equ 0x8 + E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6 + E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4 + E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported +; Bits in register window 4 + E3C59X_BIT_AUTOSELECT equ 24 +; Register window 3 + E3C59X_REG_TX_FREE equ 0xc + E3C59X_REG_RX_FREE equ 0xa + E3C59X_REG_MEDIA_OPTIONS equ 0x8 + E3C59X_REG_MAC_CONTROL equ 0x6 + E3C59X_REG_MAX_PKT_SIZE equ 0x4 + E3C59X_REG_INTERNAL_CONFIG equ 0x0 +; Register window 2 + E3C59X_REG_RESET_OPTIONS equ 0xc + E3C59X_REG_STATION_MASK_HI equ 0xa + E3C59X_REG_STATION_MASK_MID equ 0x8 + E3C59X_REG_STATION_MASK_LO equ 0x6 + E3C59X_REG_STATION_ADDRESS_HI equ 0x4 + E3C59X_REG_STATION_ADDRESS_MID equ 0x2 + E3C59X_REG_STATION_ADDRESS_LO equ 0x0 +; Register window 1 + E3C59X_REG_TRIGGER_BITS equ 0xc + E3C59X_REG_SOS_BITS equ 0xa + E3C59X_REG_WAKE_ON_TIMER equ 0x8 + E3C59X_REG_SMB_RXBYTES equ 0x7 + E3C59X_REG_SMB_DIAG equ 0x5 + E3C59X_REG_SMB_ARB equ 0x4 + E3C59X_REG_SMB_STATUS equ 0x2 + E3C59X_REG_SMB_ADDRESS equ 0x1 + E3C59X_REG_SMB_FIFO_DATA equ 0x0 +; Register window 0 + E3C59X_REG_EEPROM_DATA equ 0xc + E3C59X_REG_EEPROM_COMMAND equ 0xa + E3C59X_REG_BIOS_ROM_DATA equ 0x8 + E3C59X_REG_BIOS_ROM_ADDR equ 0x4 +; Physical management bits + E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData + E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit + E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock +; MII commands + E3C59X_MII_CMD_MASK equ (1111b shl 10) + E3C59X_MII_CMD_READ equ (0110b shl 10) + E3C59X_MII_CMD_WRITE equ (0101b shl 10) +; MII registers + E3C59X_REG_MII_BMCR equ 0 ; basic mode control register + E3C59X_REG_MII_BMSR equ 1 ; basic mode status register + E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register + E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register + E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register +; MII bits + E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete + E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6 +; eeprom bits and commands + E3C59X_EEPROM_CMD_READ equ 0x80 + E3C59X_EEPROM_BIT_BUSY equ 15 +; eeprom registers + E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa + E3C59X_EEPROM_REG_CAPABILITIES equ 0x10 +; Commands for command register + E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11) + + IS_VORTEX equ 0x1 + IS_BOOMERANG equ 0x2 + IS_CYCLONE equ 0x4 + IS_TORNADO equ 0x8 + EEPROM_8BIT equ 0x10 + HAS_PWR_CTRL equ 0x20 + HAS_MII equ 0x40 + HAS_NWAY equ 0x80 + HAS_CB_FNS equ 0x100 + INVERT_MII_PWR equ 0x200 + INVERT_LED_PWR equ 0x400 + MAX_COLLISION_RESET equ 0x800 + EEPROM_OFFSET equ 0x1000 + HAS_HWCKSM equ 0x2000 + EXTRA_PREAMBLE equ 0x4000 + +iglobal + align 4 +e3c59x_hw_versions: + dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps + dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex + dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex + dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx + dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4 + dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII + dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT + dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo + dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO + dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo + dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC + dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL + dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx + dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4 + dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx + dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC + dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx + dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado + dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone + dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone + dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane + dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane + dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \ + or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado + dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \ + or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane + dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus + dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus + dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus + dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus + dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus + dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus + dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \ + or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus + dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado + dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado + dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A + dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B + dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4 + dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado +E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions +endg + +; RX/TX buffers sizes + E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size + E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number + E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number + E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC) + E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC) +; Download Packet Descriptor + E3C59X_DPD_DN_NEXT_PTR equ 0 + E3C59X_DPD_FRAME_START_HDR equ 4 + E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data + E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data + E3C59X_DPD_SIZE equ 16 ; a power of 2 number +; Upload Packet Descriptor + E3C59X_UPD_UP_NEXT_PTR equ 0 + E3C59X_UPD_PKT_STATUS equ 4 + E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data + E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data + E3C59X_UPD_SIZE equ 16 + +; RX/TX buffers +if defined E3C59X_LINUX + E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment + e3c59x_rx_buff = 0 +else + E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment + e3c59x_rx_buff = eth_data_start +end if + + e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE + e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE + e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC) + +uglobal +e3c59x_curr_upd: dd 0 +e3c59x_prev_dpd: dd 0 +e3c59x_prev_tx_frame: dd 0 +e3c59x_transmit_function: dd 0 +e3c59x_receive_function: dd 0 +endg + +iglobal +e3c59x_ver_id: db 17 +endg +uglobal +e3c59x_full_bus_master: db 0 +e3c59x_has_hwcksm: db 0 +e3c59x_preamble: db 0 +e3c59x_dn_list_ptr_cleared: db 0 +e3c59x_self_directed_packet: rb 6 +endg + +if defined E3C59X_DEBUG +e3c59x_hw_type_str: db "Detected hardware type : ", 0 +e3c59x_device_str: db "Device ID : 0x" +e3c59x_device_id_str: db "ffff", 13, 10, 0 +e3c59x_vendor_str: db "Vendor ID : 0x" +e3c59x_vendor_id_str: db "ffff", 13, 10, 0 +e3c59x_io_info_str: db "IO address : 0x" +e3c59x_io_addr_str: db "ffff", 13, 10, 0 +e3c59x_mac_info_str: db "MAC address : " +e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0 +e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0 +e3c59x_vortex_str: db " (vortex)", 13, 10, 0 +e3c59x_link_type_str: db "Established link type : ", 0 +e3c59x_new_line_str: db 13, 10, 0 +e3c59x_link_type: dd 0 + +e3c59x_charset: db '0123456789abcdef' + +strtbl e3c59x_link_str, \ + "No valid link type detected", \ + "10BASE-T half duplex", \ + "10BASE-T full-duplex", \ + "100BASE-TX half duplex", \ + "100BASE-TX full duplex", \ + "100BASE-T4", \ + "100BASE-FX", \ + "10Mbps AUI", \ + "10Mbps COAX (BNC)", \ + "miiDevice - not supported" + +strtbl e3c59x_hw_str, \ + "3c590 Vortex 10Mbps", \ + "3c592 EISA 10Mbps Demon/Vortex", \ + "3c597 EISA Fast Demon/Vortex", \ + "3c595 Vortex 100baseTx", \ + "3c595 Vortex 100baseT4", \ + "3c595 Vortex 100base-MII", \ + "3c900 Boomerang 10baseT", \ + "3c900 Boomerang 10Mbps Combo", \ + "3c900 Cyclone 10Mbps TPO", \ + "3c900 Cyclone 10Mbps Combo", \ + "3c900 Cyclone 10Mbps TPC", \ + "3c900B-FL Cyclone 10base-FL", \ + "3c905 Boomerang 100baseTx", \ + "3c905 Boomerang 100baseT4", \ + "3c905B Cyclone 100baseTx", \ + "3c905B Cyclone 10/100/BNC", \ + "3c905B-FX Cyclone 100baseFx", \ + "3c905C Tornado", \ + "3c980 Cyclone", \ + "3c982 Dual Port Server Cyclone", \ + "3cSOHO100-TX Hurricane", \ + "3c555 Laptop Hurricane", \ + "3c556 Laptop Tornado", \ + "3c556B Laptop Hurricane", \ + "3c575 [Megahertz] 10/100 LAN CardBus", \ + "3c575 Boomerang CardBus", \ + "3CCFE575BT Cyclone CardBus", \ + "3CCFE575CT Tornado CardBus", \ + "3CCFE656 Cyclone CardBus", \ + "3CCFEM656B Cyclone+Winmodem CardBus", \ + "3CXFEM656C Tornado+Winmodem CardBus", \ + "3c450 HomePNA Tornado", \ + "3c920 Tornado", \ + "3c982 Hydra Dual Port A", \ + "3c982 Hydra Dual Port B", \ + "3c905B-T4", \ + "3c920B-EMB-WNM Tornado" + +end if ; defined E3C59X_DEBUG + +;*************************************************************************** +; Function +; e3c59x_debug +; Description +; prints debug info to the debug board +; Parameters +; ebp - io_addr +; Return value +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** +if defined E3C59X_DEBUG + align 4 +e3c59x_debug: + pushad +; print device type + mov esi, e3c59x_hw_type_str + call sys_msg_board_str + movzx ecx, byte [e3c59x_ver_id] + mov esi, [e3c59x_hw_str+ecx*4] + call sys_msg_board_str + mov esi, e3c59x_boomerang_str + cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit + jz .boomerang + mov esi, e3c59x_vortex_str +.boomerang: + call sys_msg_board_str +; print device/vendor + mov ax, [pci_data+2] + mov cl, 2 + mov ebx, e3c59x_device_id_str + call e3c59x_print_hex + mov esi, e3c59x_device_str + call sys_msg_board_str + mov ax, [pci_data] + mov cl, 2 + mov ebx, e3c59x_vendor_id_str + call e3c59x_print_hex + mov esi, e3c59x_vendor_str + call sys_msg_board_str +; print io address + mov ax, [io_addr] + mov ebx, e3c59x_io_addr_str + mov cl, 2 + call e3c59x_print_hex + mov esi, e3c59x_io_info_str + call sys_msg_board_str +; print MAC address + mov ebx, e3c59x_mac_addr_str + xor ecx, ecx +.mac_loop: + push ecx + mov al, [node_addr+ecx] + mov cl, 1 + call e3c59x_print_hex + inc ebx + pop ecx + inc cl + cmp cl, 6 + jne .mac_loop + mov esi, e3c59x_mac_info_str + call sys_msg_board_str +; print link type + mov esi, e3c59x_link_type_str + call sys_msg_board_str + xor eax, eax + bsr ax, word [e3c59x_link_type] + jz @f + sub ax, 4 +@@: + mov esi, [e3c59x_link_str+eax*4] + call sys_msg_board_str + mov esi, e3c59x_new_line_str + call sys_msg_board_str + popad + ret + +;*************************************************************************** +; Function +; e3c59x_print_hex +; Description +; prints a hexadecimal value +; Parameters +; eax - value to be printed out +; ebx - where to print +; cl - value size (1, 2, 4) +; Return value +; ebx - end address after the print +; Destroyed registers +; eax, ebx +; +;*************************************************************************** + align 4 +e3c59x_print_hex: + cmp cl, 1 + je .print_byte + cmp cl, 2 + jz .print_word +.print_dword: + push eax + bswap eax + xchg ah, al + call .print_word + pop eax +.print_word: + push eax + xchg ah, al + call .print_byte + pop eax +.print_byte: + movzx eax, al + push eax + and al, 0xf0 + shr al, 4 + mov al, byte [eax+e3c59x_charset] + mov [ebx], al + inc ebx + pop eax + and al, 0x0f + mov al, byte [eax+e3c59x_charset] + mov [ebx], al + inc ebx + ret +end if ; defined E3C59X_DEBUG + +;*************************************************************************** +; Function +; e3c59x_try_link_detect +; Description +; e3c59x_try_link_detect checks if link exists +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no link detected +; al - 1 ; link detected +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_try_link_detect: +; download self-directed packet + mov edi, node_addr + mov bx, 0x0608 ; packet type + mov esi, e3c59x_self_directed_packet + mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes + call dword [e3c59x_transmit_function] +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; program RxFilter for promiscuous operation + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1111b + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; switch to register window 4 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; check loop + xor ebx, ebx + mov ecx, 0xffff ; 65535 tries +.loop: + push ecx ebx + call dword [e3c59x_receive_function] + pop ebx ecx + test al, al + jnz .finish +.no_packet_received: +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; read linkbeatdetect + lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] + in ax, dx + test ah, 1000b ; test linkBeatDetect + jnz .link_detected + xor al, al + jmp .finish +.link_detected: +; test carrierSense + test al, 100000b + jz .no_carrier_sense + inc ebx +.no_carrier_sense: + dec ecx + jns .loop +; assume the link is good if 0 < ebx < 25 % + test ebx, ebx + setnz al + jz .finish + cmp ebx, 16384 ; 25% + setb al +.finish: +if defined E3C59X_DEBUG + test al, al + jz @f + or byte [e3c59x_link_type+1], 100b +@@: +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_try_phy +; Description +; e3c59x_try_phy checks the auto-negotiation function +; in the PHY at PHY index. It can also be extended to +; include link detection for non-IEEE 802.3u +; auto-negotiation devices, for instance the BCM5000. +; Parameters +; ah - PHY index +; ebp - io_addr +; Return value +; al - 0 link is auto-negotiated +; al - 1 no link is auto-negotiated +; Destroyed registers +; eax, ebx, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_try_phy: + mov al, E3C59X_REG_MII_BMCR + push eax + call e3c59x_mdio_read ; returns with window #4 + or ah, 0x80 ; software reset + mov ebx, eax + pop eax + push eax + call e3c59x_mdio_write ; returns with window #4 +; wait for reset to complete + mov esi, 2000 ; 2000ms = 2s + call delay_ms + pop eax + push eax + call e3c59x_mdio_read ; returns with window #4 + test ah, 0x80 + jnz .fail_finish + pop eax + push eax +; wait for a while after reset + mov esi, 20 ; 20ms + call delay_ms + pop eax + push eax + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read ; returns with window #4 + test al, 1 ; extended capability supported? + jz .no_ext_cap +; auto-neg capable? + test al, 1000b + jz .fail_finish ; not auto-negotiation capable +; auto-neg complete? + test al, 100000b + jnz .auto_neg_ok +; restart auto-negotiation + pop eax + push eax + mov al, E3C59X_REG_MII_ANAR + push eax + call e3c59x_mdio_read ; returns with window #4 + or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX + mov ebx, eax + pop eax + call e3c59x_mdio_write ; returns with window #4 + pop eax + push eax + call e3c59x_mdio_read ; returns with window #4 + mov ebx, eax + or bh, 10010b ; restart auto-negotiation + pop eax + push eax + call e3c59x_mdio_write ; returns with window #4 + mov esi, 4000 ; 4000ms = 4 seconds + call delay_ms + pop eax + push eax + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read ; returns with window #4 + test al, 100000b ; auto-neg complete? + jnz .auto_neg_ok + jmp .fail_finish +.auto_neg_ok: +; compare advertisement and link partner ability registers + pop eax + push eax + mov al, E3C59X_REG_MII_ANAR + call e3c59x_mdio_read ; returns with window #4 + xchg eax, [esp] + mov al, E3C59X_REG_MII_ANLPAR + call e3c59x_mdio_read ; returns with window #4 + pop ebx + and eax, ebx + and eax, 1111100000b + push eax +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], ax +end if ; defined E3C59X_DEBUG +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; set full-duplex mode + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + and ax, not 0x120 ; clear full duplex and flow control + pop ebx + test ebx, (1010b shl 5) ; check for full-duplex + jz .half_duplex + or ax, 0x120 ; set full duplex and flow control +.half_duplex: + out dx, ax + mov al, 1 + ret +.no_ext_cap: +; not yet implemented BCM5000 +.fail_finish: + pop eax + xor al, al + ret + +;*************************************************************************** +; Function +; e3c59x_try_mii +; Description +; e3c59x_try_MII checks the on-chip auto-negotiation logic +; or an off-chip MII PHY, depending upon what is set in +; xcvrSelect by the caller. +; It exits when it finds the first device with a good link. +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_try_mii: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, (1111b shl 20) + cmp eax, (1000b shl 20) ; is auto-negotiation set? + jne .mii_device +; auto-negotiation is set +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; PHY==24 is the on-chip auto-negotiation logic +; it supports only 10base-T and 100base-TX + mov ah, 24 + call e3c59x_try_phy + test al, al + jz .fail_finish + mov cl, 24 + jmp .check_preamble +.mii_device: + cmp eax, (0110b shl 20) + jne .fail_finish + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + in ax, dx + and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA) + cmp al, (1 shl E3C59X_BIT_MGMT_DATA) + je .serch_for_phy + xor al, al + ret +.serch_for_phy: +; search for PHY + mov cl, 31 +.search_phy_loop: + cmp cl, 24 + je .next_phy + mov ah, cl ; ah = phy + mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register + push ecx + call e3c59x_mdio_read + pop ecx + test ax, ax + jz .next_phy + cmp ax, 0xffff + je .next_phy + mov ah, cl ; ah = phy + push ecx + call e3c59x_try_phy + pop ecx + test al, al + jnz .check_preamble +.next_phy: + dec cl + jns .search_phy_loop +.fail_finish: + xor al, al + ret +; epilog +.check_preamble: + push eax ; eax contains the return value of e3c59x_try_phy +; check hard coded preamble forcing + movzx eax, byte [e3c59x_ver_id] + test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE + setnz [e3c59x_preamble] ; force preamble + jnz .finish +; check mii for preamble suppression + mov ah, cl + mov al, E3C59X_REG_MII_BMSR + call e3c59x_mdio_read + test al, 1000000b ; preamble suppression? + setz [e3c59x_preamble] ; no +.finish: + pop eax + ret + +;*************************************************************************** +; Function +; e3c59x_test_packet +; Description +; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_test_packet: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; set fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + or ax, 0x120 + out dx, ax +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; set RxFilter to enable individual address matches + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1 + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; issue RxEnable and TxEnable + call e3c59x_rx_reset + call e3c59x_tx_reset +; download a self-directed test packet + mov edi, node_addr + mov bx, 0x0608 ; packet type + mov esi, e3c59x_self_directed_packet + mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes + call dword [e3c59x_transmit_function] +; wait for 2s + mov esi, 2000 ; 2000ms = 2s + call delay_ms +; check if self-directed packet is received + call dword [e3c59x_receive_function] + test al, al + jnz .finish +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; clear fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + and ax, not 0x120 + out dx, ax + xor al, al +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_try_loopback +; Description +; tries a loopback packet for 10BASE2 or AUI port +; Parameters +; al - 0: 10Mbps AUI connector +; 1: 10BASE-2 +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_try_loopback: + push eax +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + pop eax + push eax +if defined E3C59X_DEBUG + mov bl, al + inc bl + shl bl, 3 + or byte [e3c59x_link_type+1], bl +end if ; defined E3C59X_DEBUG + test al, al ; aui or coax? + jz .complete_loopback +; enable 100BASE-2 DC-DC converter + mov ax, (10b shl 11) ; EnableDcConverter + out dx, ax +.complete_loopback: + mov cl, 2 ; give a port 3 chances to complete a loopback +.next_try: + push ecx + call e3c59x_test_packet + pop ecx + test al, al + jnz .finish + dec cl + jns .next_try +.finish: + xchg eax, [esp] + test al, al + jz .aui_finish +; issue DisableDcConverter command + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10111b shl 11) + out dx, ax +.aui_finish: + pop eax ; al contains the result of operation +if defined E3C59X_DEBUG + test al, al + jnz @f + and byte [e3c59x_link_type+1], not 11000b +@@: +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_set_available_media +; Description +; sets the first available media +; Parameters +; ebp - io_addr +; Return value +; al - 0 +; al - 1 +; Destroyed registers +; eax, edx +; +;*************************************************************************** + align 4 +e3c59x_set_available_media: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + push eax + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 10b + jz @f +; baseTXAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (100b shl 20) +if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD + mov word [e3c59x_link_type], (1 shl 8) +else if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 7) +end if + jmp .set_media +@@: + test al, 100b + jz @f +; baseFXAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (101b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 10) +end if + jmp .set_media +@@: + test al, 1000000b + jz @f +; miiDevice + pop eax + and eax, not (1111b shl 20) + or eax, (0110b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 13) +end if + jmp .set_media +@@: + test al, 1000b + jz @f +.set_default: +; 10bTAvailable + pop eax + and eax, not (1111b shl 20) +if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD + mov word [e3c59x_link_type], (1 shl 6) +else if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 5) +end if ; E3C59X_FORCE_FD + jmp .set_media +@@: + test al, 10000b + jz @f +; coaxAvailable + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10b shl 11) ; EnableDcConverter + out dx, ax + pop eax + and eax, not (1111b shl 20) + or eax, (11b shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 12) +end if ; defined E3C59X_DEBUG + jmp .set_media +@@: + test al, 10000b + jz .set_default +; auiAvailable + pop eax + and eax, not (1111b shl 20) + or eax, (1 shl 20) +if defined E3C59X_DEBUG + mov word [e3c59x_link_type], (1 shl 11) +end if ; defined E3C59X_DEBUG +.set_media: + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + out dx, eax +if defined E3C59X_FORCE_FD +; set fullDuplexEnable in MacControl register + lea edx, [ebp+E3C59X_REG_MAC_CONTROL] + in ax, dx + or ax, 0x120 + out dx, ax +end if ; E3C59X_FORCE_FD + mov al, 1 + ret + +;*************************************************************************** +; Function +; e3c59x_set_active_port +; Description +; It selects the media port (transceiver) to be used +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_set_active_port: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + test eax, (1 shl 24) ; check if autoselect enable + jz .set_first_available_media +; check 100BASE-TX and 10BASE-T + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 1010b ; check whether 100BASE-TX or 10BASE-T available + jz .mii_device ; they are not available +; set auto-negotiation + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (1000b shl 20) + out dx, eax + call e3c59x_try_mii + test al, al + jz .mii_device + ret +.mii_device: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for off-chip mii device + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx + test al, 1000000b ; check miiDevice + jz .base_fx + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0110b shl 20) ; set MIIDevice + out dx, eax + call e3c59x_try_mii + test al, al + jz .base_fx + ret +.base_fx: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for 100BASE-FX + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 100b ; check 100BASE-FX + jz .aui_enable + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0101b shl 20) ; set 100base-FX + out dx, eax + call e3c59x_try_link_detect + test al, al + jz .aui_enable + ret +.aui_enable: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for 10Mbps AUI connector + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 100000b ; check 10Mbps AUI connector + jz .coax_available + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0001b shl 20) ; set 10Mbps AUI connector + out dx, eax + xor al, al ; try 10Mbps AUI connector + call e3c59x_try_loopback + test al, al + jz .coax_available + ret +.coax_available: +; switch to register window 3 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+3 + out dx, ax +; check for coaxial 10BASE-2 port + lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS] + in ax, dx ; read media option register + test al, 10000b ; check 10BASE-2 + jz .set_first_available_media + lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG] + in eax, dx + and eax, not (1111b shl 20) + or eax, (0011b shl 20) ; set 10BASE-2 + out dx, eax + mov al, 1 + call e3c59x_try_loopback + test al, al + jz .set_first_available_media + ret +.set_first_available_media: + jmp e3c59x_set_available_media + +;*************************************************************************** +; Function +; e3c59x_wake_up +; Description +; set the power state to D0 +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_wake_up: +; wake up - we directly do it by programming PCI +; check if the device is power management capable + mov al, 2 + mov ah, [pci_bus] + mov bl, PCI_REG_STATUS + mov bh, [pci_dev] + push eax ebx + call pci_read_reg + test al, 10000b ; is there "new capabilities" linked list? + pop ebx eax + jz .device_awake +; search for power management register + mov al, 1 + mov bl, PCI_REG_CAP_PTR + push eax ebx + call pci_read_reg + mov cl, al + cmp cl, 0x3f + pop ebx eax + jbe .device_awake +; traverse the list + mov al, 2 +.pm_loop: + mov bl, cl + push eax ebx + call pci_read_reg + cmp al, 1 + je .set_pm_state + test ah, ah + mov cl, ah + pop ebx eax + jnz .pm_loop + jmp .device_awake +; waku up the device if necessary +.set_pm_state: + pop ebx eax + add bl, PCI_REG_PM_CTRL + push eax ebx + call pci_read_reg + mov cx, ax + test cl, 3 + pop ebx eax + jz .device_awake + and cl, not 11b ; set state to D0 + call pci_write_reg +.device_awake: + ret + +;*************************************************************************** +; Function +; e3c59x_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_probe: + movzx ebp, word [io_addr] + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + push ebp eax ebx + call pci_read_reg + mov cx, ax + or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) + and cl, not (1 shl PCI_BIT_MMIO) + pop ebx eax + call pci_write_reg +; wake up the card + call e3c59x_wake_up + pop ebp +; get chip version + mov ax, [pci_data+2] + mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1 +.chip_ver_loop: + cmp ax, [e3c59x_hw_versions+ecx*4] + jz .chip_ver_found + dec ecx + jns .chip_ver_loop + xor ecx, ecx +.chip_ver_found: + mov [e3c59x_ver_id], cl + test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM + setnz [e3c59x_has_hwcksm] +; set pci latency for vortex cards + test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX + jz .not_vortex + mov cx, 11111000b ; 248 = max latency + mov al, 1 + mov ah, [pci_bus] + mov bl, PCI_REG_LATENCY + mov bh, [pci_dev] + call pci_write_reg +.not_vortex: +; set RX/TX functions + mov ax, E3C59X_EEPROM_REG_CAPABILITIES + call e3c59x_read_eeprom + test al, 100000b ; full bus master? + setnz [e3c59x_full_bus_master] + jnz .boomerang_func + mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit + mov dword [e3c59x_receive_function], e3c59x_vortex_poll + jmp @f +.boomerang_func: ; full bus master, so use boomerang functions + mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit + mov dword [e3c59x_receive_function], e3c59x_boomerang_poll +@@: +; read MAC from eeprom + mov ecx, 2 +.mac_loop: + lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx] + call e3c59x_read_eeprom + xchg ah, al ; htons + mov [node_addr+ecx*2], ax + dec ecx + jns .mac_loop + test byte [e3c59x_full_bus_master], 0xff + jz .set_preamble +; switch to register window 2 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 + out dx, ax +; activate xcvr by setting some magic bits + lea edx, [ebp+E3C59X_REG_RESET_OPTIONS] + in ax, dx + and ax, not 0x4010 + movzx ebx, byte [e3c59x_ver_id] + test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR + jz @f + or al, 0x10 +@@: + test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR + jz @f + or ah, 0x40 +@@: + out dx, ax +.set_preamble: +; use preamble as default + mov byte [e3c59x_preamble], 1 ; enable preamble + +;*************************************************************************** +; Function +; e3c59x_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** +e3c59x_reset: +; issue global reset + call e3c59x_global_reset +; disable interrupts + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (1110b shl 11) + out dx, ax +; enable Statistics + mov ax, (10101b shl 11) + out dx, ax +; set indication + mov ax, (1111b shl 11) or 0x6c6 + out dx, ax +; acknowledge (clear) every interrupt indicator + mov ax, (1101b shl 11) or 0x661 + out dx, ax +; switch to register window 2 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+2 + out dx, ax +; write MAC addres back into the station address registers + lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO] + mov esi, node_addr + cld + outsw + add edx, 2 + outsw + add edx, 2 + outsw + add edx, 2 +; clear station mask + xor eax, eax + out dx, ax + add edx, 2 + out dx, ax + add edx, 2 + out dx, ax +; switch to register window 6 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+6 + out dx, ax +; clear all statistics by reading + lea edx, [ebp+E3C59X_REG_CARRIER_LOST] + mov cl, 9 +.stat_clearing_loop: + in al, dx + inc edx + dec cl + jns .stat_clearing_loop + in ax, dx + add dx, 2 + in ax, dx +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; clear BadSSD + lea edx, [ebp+E3C59X_REG_BAD_SSD] + in al, dx +; clear extra statistics bit in NetworkDiagnostic + lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC] + in ax, dx + or ax, 0x0040 + out dx, ax +; SetRxEarlyThreshold + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2) + out dx, ax + test byte [e3c59x_full_bus_master], 0xff + jz .skip_boomerang_setting +; set upRxEarlyEnable + lea edx, [ebp+E3C59X_REG_DMA_CTRL] + in eax, dx + or eax, 0x20 + out dx, eax +; TxFreeThreshold + lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH] + mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256) + out dx, al +; program DnListPtr + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + xor eax, eax + out dx, eax +.skip_boomerang_setting: +; initialization + call e3c59x_rx_reset + call e3c59x_tx_reset + call e3c59x_set_active_port + call e3c59x_rx_reset + call e3c59x_tx_reset +; switch to register window 5 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+5 + out dx, ax +; program RxFilter for promiscuous operation + mov ax, (10000b shl 11) + lea edx, [ebp+E3C59X_REG_RX_FILTER] + in al, dx + or al, 1111b + lea edx, [ebp+E3C59X_REG_COMMAND] + out dx, ax +; switch to register window 4 + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax +; wait for linkDetect + lea edx, [ebp+E3C59X_REG_MEDIA_STATUS] + mov cl, 20 ; wait for max 2s + mov esi, 100 ; 100ms +.link_detect_loop: + call delay_ms + in ax, dx + test ah, 1000b ; linkDetect + jnz @f + dec cl + jnz .link_detect_loop +@@: +; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax +if defined E3C59X_DEBUG + call e3c59x_debug +end if ; defined E3C59X_DEBUG + ret + +;*************************************************************************** +; Function +; e3c59x_global_reset +; Description +; resets the device +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; ax, ecx, edx, esi +; +;*************************************************************************** + align 4 +e3c59x_global_reset: +; GlobalReset + lea edx, [ebp+E3C59X_REG_COMMAND] + xor eax, eax +; or al, 0x14 + out dx, ax +; wait for GlobalReset to complete + mov ecx, 64000 +.global_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .finish + dec ecx + jnz .global_reset_loop +.finish: +; wait for 2 seconds for NIC to boot + mov esi, 2000 ; 2000ms = 2s + push ebp + call delay_ms + pop ebp + ret + +;*************************************************************************** +; Function +; e3c59x_tx_reset +; Description +; resets and enables transmitter engine +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; ax, ecx, edx +; +;*************************************************************************** + align 4 +e3c59x_tx_reset: +; TxReset + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01011b shl 11) + out dx, ax +; wait for TxReset to complete + mov ecx, 2000 +.tx_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .tx_enable + dec ecx + jns .tx_reset_loop + test byte [e3c59x_full_bus_master], 0xff + jz .tx_enable +; init last_dpd + mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE + mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE +.tx_enable: + mov ax, (01001b shl 11) ; TxEnable + out dx, ax + ret + +;*************************************************************************** +; Function +; e3c59x_rx_reset +; Description +; resets and enables receiver engine +; Parameters: +; ebp - io_addr +; Return value: +; Destroyed registers +; eax, ebx, ecx, edx, edi, esi +; +;*************************************************************************** + align 4 +e3c59x_rx_reset: + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (0101b shl 11) or 0x4 ; RxReset + out dx, ax +; wait for RxReset to complete + mov ecx, 200000 +.rx_reset_loop: + in ax, dx + test ah, 10000b ; check CmdInProgress + jz .setup_upd + dec ecx + jns .rx_reset_loop +.setup_upd: +; check if full bus mastering + test byte [e3c59x_full_bus_master], 0xff + jz .rx_enable +; create upd ring + mov eax, e3c59x_upd_buff + zero_to_virt eax + mov [e3c59x_curr_upd], eax + mov esi, eax + virt_to_dma esi + mov edi, e3c59x_rx_buff + zero_to_dma edi + mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE + zero_to_virt ebx + mov cl, E3C59X_NUM_RX_DESC-1 +.upd_loop: + mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi + mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31) + add edi, E3C59X_MAX_ETH_FRAME_SIZE + add esi, E3C59X_UPD_SIZE + mov ebx, eax + add eax, E3C59X_UPD_SIZE + dec cl + jns .upd_loop + mov eax, e3c59x_upd_buff + zero_to_dma eax + lea edx, [ebp+E3C59X_REG_UP_LIST_PTR] + out dx, eax ; write E3C59X_REG_UP_LIST_PTR + lea edx, [ebp+E3C59X_REG_COMMAND] +.rx_enable: + mov ax, (00100b shl 11) ; RxEnable + out dx, ax + ret + +;*************************************************************************** +; Function +; e3c59x_write_eeprom +; Description +; reads eeprom +; Note : the caller must switch to the register window 0 +; before calling this function +; Parameters: +; ax - register to be read (only the first 63 words can be read) +; cx - value to be read into the register +; Return value: +; ax - word read +; Destroyed registers +; ax, ebx, edx +; +;*************************************************************************** +; align 4 +;e3c59x_write_eeprom: +; mov edx, [io_addr] +; add edx, E3C59X_REG_EEPROM_COMMAND +; cmp ah, 11b +; ja .finish ; address may have a value of maximal 1023 +; shl ax, 2 +; shr al, 2 +; push eax +;; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .write_enable +; dec ebx +; jns @r +;; write enable +;.write_enable: +; xor eax, eax +; mov eax, (11b shl 4) +; out dx, ax +;; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .erase_loop +; dec ebx +; jns @r +;.erase_loop: +; pop eax +; push eax +; or ax, (11b shl 6) ; erase register +; out dx, ax +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .write_reg +; dec ebx +; jns @r +;.write_reg: +; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND +; mov eax, ecx +; out dx, ax +;; write enable +; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA +; xor eax, eax +; mov eax, (11b shl 4) +; out dx, ax +; wait for busy +; mov ebx, 0xffff +;@@: +; in ax, dx +; test ah, 0x80 +; jz .issue_write_reg +; dec ebx +; jns @r +;.issue_write_reg: +; pop eax +; or ax, 01b shl 6 +; out dx, ax +;.finish: +; ret +;*************************************************************************** +; Function +; e3c59x_read_eeprom +; Description +; reads eeprom +; Parameters: +; ax - register to be read (only the first 63 words can be read) +; ebp - io_addr +; Return value: +; ax - word read +; Destroyed registers +; ax, ebx, edx, ebp +; +;*************************************************************************** + align 4 +e3c59x_read_eeprom: + push eax +; switch to register window 0 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+0 + out dx, ax + pop eax + and ax, 111111b ; take only the first 6 bits into account + movzx ebx, byte [e3c59x_ver_id] + test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT + jz @f + add ax, 0x230 ; hardware constant + jmp .read +@@: + add ax, E3C59X_EEPROM_CMD_READ + test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET + jz .read + add ax, 0x30 +.read: + lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND] + out dx, ax + mov ebx, 0xffff ; duration of about 162 us ;-) +.wait_for_reading: + in ax, dx + test ah, 0x80 ; check bit eepromBusy + jz .read_data + dec ebx + jns .wait_for_reading +.read_data: + lea edx, [ebp+E3C59X_REG_EEPROM_DATA] + in ax, dx + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_sync +; Description +; initial synchronization +; Parameters +; ebp - io_addr +; Return value +; Destroyed registers +; ax, edx, cl +; +;*************************************************************************** + align 4 +e3c59x_mdio_sync: +; switch to register window 4 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+4 + out dx, ax + cmp byte [e3c59x_preamble], 0 + je .no_preamble +; send 32 logic ones + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + mov cl, 31 +.loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR) + out dx, ax + in ax, dx ; delay + mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \ + or (1 shl E3C59X_BIT_MGMT_DIR) \ + or (1 shl E3C59X_BIT_MGMT_CLK) + out dx, ax + in ax, dx ; delay + dec cl + jns .loop +.no_preamble: + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_read +; Description +; read MII register +; see page 16 in D83840A.pdf +; Parameters +; ah - PHY addr +; al - register addr +; ebp - io_addr +; Return value +; ax - register read +; Destroyed registers +; eax, ebx, cx, edx +; +;*************************************************************************** + align 4 +e3c59x_mdio_read: + push eax + call e3c59x_mdio_sync ; returns with window #4 + pop eax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + shl al, 3 + shr ax, 3 + and ax, not E3C59X_MII_CMD_MASK + or ax, E3C59X_MII_CMD_READ + mov ebx, eax + xor ecx, ecx + mov cl, 13 +.cmd_loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii + bt ebx, ecx + jnc .zero_bit + or al, (1 shl E3C59X_BIT_MGMT_DATA) +.zero_bit: + out dx, ax + push eax + in ax, dx ; delay + pop eax + or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write + out dx, ax + in ax, dx ; delay + dec cl + jns .cmd_loop +; read data (18 bits with the two transition bits) + mov cl, 17 + xor ebx, ebx +.read_loop: + shl ebx, 1 + xor eax, eax ; read comand + out dx, ax + in ax, dx ; delay + in ax, dx + test al, (1 shl E3C59X_BIT_MGMT_DATA) + jz .dont_set + inc ebx +.dont_set: + mov ax, (1 shl E3C59X_BIT_MGMT_CLK) + out dx, ax + in ax, dx ; delay + dec cl + jns .read_loop + mov eax, ebx + ret + +;*************************************************************************** +; Function +; e3c59x_mdio_write +; Description +; write MII register +; see page 16 in D83840A.pdf +; Parameters +; ah - PHY addr +; al - register addr +; bx - word to be written +; ebp - io_addr +; Return value +; ax - register read +; Destroyed registers +; eax, ebx, cx, edx +; +;*************************************************************************** + align 4 +e3c59x_mdio_write: + push eax + call e3c59x_mdio_sync + pop eax + lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT] + shl al, 3 + shr ax, 3 + and ax, not E3C59X_MII_CMD_MASK + or ax, E3C59X_MII_CMD_WRITE + shl eax, 2 + or eax, 10b ; transition bits + shl eax, 16 + mov ax, bx + mov ebx, eax + mov ecx, 31 +.cmd_loop: + mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii + bt ebx, ecx + jnc .zero_bit + or al, (1 shl E3C59X_BIT_MGMT_DATA) +.zero_bit: + out dx, ax + push eax + in ax, dx ; delay + pop eax + or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write + out dx, ax + in ax, dx ; delay + dec ecx + jns .cmd_loop + ret + +;*************************************************************************** +; Function +; e3c59x_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, ecx, edx, ebp +; +;*************************************************************************** + align 4 +e3c59x_transmit: + jmp dword [e3c59x_transmit_function] + +;*************************************************************************** +; Function +; e3c59x_check_tx_status +; Description +; Checks TxStatus queue. +; Return value +; al - 0 no error was found +; al - 1 error was found TxReset is needed +; Destroyed registers +; eax, ecx, edx, ebp +; +;*************************************************************************** +e3c59x_check_tx_status: + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +; clear TxStatus queue + lea edx, [ebp+E3C59X_REG_TX_STATUS] + mov cl, 31 ; max number of queue entries +.tx_status_loop: + in al, dx + test al, al + jz .finish ; no error + test al, 0x3f + jnz .finish ; error +.no_error_found: +; clear current TxStatus entry which advances the next one + xor al, al + out dx, al + dec cl + jns .tx_status_loop +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_vortex_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_vortex_transmit: + push ecx + call e3c59x_check_tx_status + pop ecx + test al, al + jz .no_error_found + jmp e3c59x_tx_reset +.no_error_found: +; switch to register window 7 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 + out dx, ax +; check for master operation in progress + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jnz .finish ; no DMA for sending +; dword boundary correction + cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE + ja .finish ; packet is too long +; write Frame Start Header + mov eax, ecx +; add header length and extend the complete length to dword boundary + add eax, ETH_HLEN+3 + and eax, not 3 + lea edx, [ebp+E3C59X_REG_TX_DATA] + out dx, eax +; prepare the complete frame + push esi + mov esi, edi + mov edi, e3c59x_tx_buff + zero_to_virt edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy packet data + pop esi + push ecx + shr ecx, 2 + rep movsd + pop ecx + and ecx, 3 + rep movsb + mov ecx, eax +; program frame address to be sent + lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] + mov eax, e3c59x_tx_buff + zero_to_dma eax + out dx, eax +; program frame length + lea edx, [ebp+E3C59X_REG_MASTER_LEN] + mov eax, ecx + out dx, ax +; start DMA Down + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10100b shl 11) + 1 ; StartDMADown + out dx, ax +.finish: + ret + +;*************************************************************************** +; Function +; e3c59x_boomerang_transmit +; Description +; Transmits a packet of data via the ethernet card +; edi - Pointer to 48 bit destination address +; bx - Type of packet +; ecx - size of packet +; esi - pointer to packet data +; ebp - io_addr +; Destroyed registers +; eax, ebx, ecx, edx, esi, edi, ebp +; +;*************************************************************************** + align 4 +e3c59x_boomerang_transmit: + push ecx + call e3c59x_check_tx_status + pop ecx + test al, al + jz .no_error_found + jmp e3c59x_tx_reset +.no_error_found: + cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE + ja .finish ; packet is too long +; calculate descriptor address + mov eax, [e3c59x_prev_dpd] + cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE + jb @f +; wrap around + mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE +@@: + add eax, E3C59X_DPD_SIZE + zero_to_virt eax + push eax +; check DnListPtr + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + in eax, dx +; mark if Dn_List_Ptr is cleared + test eax, eax + setz [e3c59x_dn_list_ptr_cleared] +; finish if no more free descriptor is available - FIXME! + cmp eax, [esp] + pop eax + jz .finish + push eax esi + mov esi, edi +; calculate tx_buffer address + mov edi, [e3c59x_prev_tx_frame] + cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE + jb @f +; wrap around + mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE +@@: + add edi, E3C59X_MAX_ETH_FRAME_SIZE + zero_to_virt edi + mov eax, edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy packet data + pop esi + push ecx + shr ecx, 2 + rep movsd + pop ecx + push ecx + and ecx, 3 + rep movsb +; padding, do we really need it? + pop ecx + add ecx, ETH_HLEN + cmp ecx, ETH_ZLEN + jae @f + mov ecx, ETH_ZLEN +@@: +; calculate + mov ebx, ecx + test byte [e3c59x_has_hwcksm], 0xff + jz @f + or ebx, (1 shl 26) ; set AddTcpChecksum +@@: + or ebx, 0x8000 ; transmission complete notification + or ecx, 0x80000000 ; last fragment +; program DPD + mov edi, eax + pop eax + and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0 + mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx + virt_to_dma edi + mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi + mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx +; calculate physical address + virt_to_dma eax + push eax + cmp byte [e3c59x_dn_list_ptr_cleared], 0 + jz .add_to_list +; write Dn_List_Ptr + out dx, eax + jmp .finish +.add_to_list: +; DnStall + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+2) + out dx, ax +; wait for DnStall to complete + mov ecx, 6000 +.wait_for_stall: + in ax, dx ; read E3C59X_REG_INT_STATUS + test ah, 10000b + jz .dnstall_ok + dec ecx + jnz .wait_for_stall +.dnstall_ok: + pop eax + push eax + mov ebx, [e3c59x_prev_dpd] + zero_to_virt ebx + mov [ebx], eax + lea edx, [ebp+E3C59X_REG_DN_LIST_PTR] + in eax, dx + test eax, eax + jnz .dnunstall +; if Dn_List_Ptr has been cleared fill it up + pop eax + push eax + out dx, eax +.dnunstall: +; DnUnStall + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+3) + out dx, ax +.finish: + pop eax + dma_to_zero eax + mov [e3c59x_prev_dpd], eax + dma_to_zero edi + mov [e3c59x_prev_tx_frame], edi + ret + +;*************************************************************************** +; Function +; e3c59x_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed registers +; eax, ebx, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_poll: + jmp dword [e3c59x_receive_function] + +;*************************************************************************** +; Function +; e3c59x_vortex_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no packet received +; al - 1 ; packet received +; Destroyed registers +; eax, ebx, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_vortex_poll: + and word [eth_rx_data_len], 0 ; assume no packet received + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +.rx_status_loop: +; examine RxStatus + lea edx, [ebp+E3C59X_REG_RX_STATUS] + in ax, dx + test ax, ax + jz .finish + test ah, 0x80 ; rxIncomplete + jz .check_error + jmp .finish +.check_error: + test ah, 0x40 + jz .check_length +; discard the top frame received advancing the next one + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01000b shl 11) + out dx, ax + jmp .rx_status_loop +.check_length: + and eax, 0x1fff + cmp eax, E3C59X_MAX_ETH_PKT_SIZE + ja .discard_frame ; frame is too long discard it +.check_dma: + push eax +; switch to register window 7 + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, E3C59X_SELECT_REGISTER_WINDOW+7 + out dx, ax +; check for master operation in progress + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jz .read_frame ; no DMA for receiving + pop eax + jmp .finish +.read_frame: +; program buffer address to read in + lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS] +if defined E3C59X_LINUX + mov eax, e3c59x_rx_buff + zero_to_dma eax +else + mov eax, Ether_buffer +end if + out dx, eax +; program frame length + lea edx, [ebp+E3C59X_REG_MASTER_LEN] + mov ax, 1560 + out dx, ax +; start DMA Up + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (10100b shl 11) ; StartDMAUp + out dx, ax +; check for master operation in progress +.dma_loop: + lea edx, [ebp+E3C59X_REG_MASTER_STATUS] + in ax, dx + test ah, 0x80 + jnz .dma_loop +; registrate the received packet length + pop eax + mov word [eth_rx_data_len], ax +; discard the top frame received +.discard_frame: + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, (01000b shl 11) + out dx, ax +.finish: +; set return value + cmp word [eth_rx_data_len], 0 + setne al + ret + +;*************************************************************************** +; Function +; e3c59x_boomerang_poll +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Parameters +; ebp - io_addr +; Return value +; al - 0 ; no packet received +; al - 1 ; packet received +; Destroyed registers +; eax, edx, ecx, edi, esi, ebp +; +;*************************************************************************** + align 4 +e3c59x_boomerang_poll: + and word [eth_rx_data_len], 0 ; assume no packet received + movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC +; check if packet is uploaded + mov eax, [e3c59x_curr_upd] + test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete + jnz .check_error + jmp .finish +; packet is uploaded check for any error +.check_error: + test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError + jz .copy_packet_length + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + jmp .finish +.copy_packet_length: + mov ecx, [eax+E3C59X_UPD_PKT_STATUS] + and ecx, 0x1fff + cmp ecx, E3C59X_MAX_ETH_PKT_SIZE + jbe .copy_packet + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + jmp .finish +.copy_packet: + push ecx + mov word [eth_rx_data_len], cx + mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR] + dma_to_virt esi + mov edi, Ether_buffer + shr ecx, 2 ; first copy dword-wise + cld + rep movsd ; copy the dwords + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes + mov eax, [e3c59x_curr_upd] + and dword [eax+E3C59X_UPD_PKT_STATUS], 0 + virt_to_zero eax + cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE + jb .no_wrap +; wrap around + mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE +.no_wrap: + add eax, E3C59X_UPD_SIZE + zero_to_virt eax + mov [e3c59x_curr_upd], eax +.finish: +; check if the NIC is in the upStall state + lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS] + in eax, dx + test ah, 0x20 ; UpStalled + jz .noUpUnStall +; issue upUnStall command + lea edx, [ebp+E3C59X_REG_COMMAND] + mov ax, ((110b shl 11)+1) ; upUnStall + out dx, ax +.noUpUnStall: +; set return value + cmp word [eth_rx_data_len], 0 + setnz al + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/ethernet.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/ethernet.inc new file mode 100644 index 0000000000..b72be5b685 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/ethernet.inc @@ -0,0 +1,1701 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; ETHERNET.INC ;; +;; ;; +;; Ethernet network layer for Menuet OS ;; +;; ;; +;; Version 0.4 22 September 2003 ;; +;; ;; +;; This file contains the following: ;; +;; PCI bus scanning for valid devices ;; +;; Table of supported ethernet drivers ;; +;; Code to identify and activate a supported driver ;; +;; ARP handler ;; +;; Driver interface to the IP layer ;; +;; Gateway support ;; +;; ;; +;; Individual driver files are included here ;; +;; ;; +;; The PCI bus scanning code was ported from the etherboot ;; +;; 5.0.6 project. The copyright statement for that code is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;******************************************************************** +; Interface +; ethernet_driver called by stack_handler in stack.inc +; eth_probe called by app_stack_handler in stack.inc +; +;******************************************************************** + +; Some useful information on data structures + +; Ethernet Packet - ARP Request example +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Dest H/W Address | +; | ( 14 byte header ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Source H/W Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Protocol - ARP 08 06 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | H/W Type 00 01 | Protocol Type 08 00 | +; | ( ARP Request packet ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | HLen 0x06 | PLen 0x04 | OpCode 00 01 | +; | ( 0001 for request, 0002 for reply ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Source Hardware Address ( MAC Address ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Source IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | Destination Hardware Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Destination IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +; Include individual drivers source files at this point. +; If you create a new driver, include it below. + +include "rtl8029.inc" +include "i8255x.inc" +include "rtl8139.inc" +include "3c59x.inc" +include "sis900.inc" +include "pcnet32.inc" + +; DEBUGGING_STATE enables or disables output of received and transmitted +; data over the serial port +DEBUGGING_ENABLED equ 1 +DEBUGGING_DISABLED equ 0 +DEBUGGING_STATE equ DEBUGGING_DISABLED + +; PCICards +; ======== +; PCI vendor and hardware types for hardware supported by the above drivers +; If you add a driver, ensure you update this datastructure, otherwise the +; card will not be probed. +; Each driver is defined by 4 double words. These are +; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction +; The last entry must be kept at all zeros, to indicate the end of the list +; As a PCI driver may support more than one hardware implementation, there may +; be several lines which refer to the same functions. +; The first driver found on the PCI bus will be the one used. + +PCICARDS_ENTRY_SIZE equ 20 ; Size of each PCICARDS entry + +iglobal +PCICards: +dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit +dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit +dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit +dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit +dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit +dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit +dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit +dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +; /+/ Новые вендоры сетевых карт на базе rtl8139 +dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit +; /-/ +dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit +dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit +dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit +dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit +dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit +; following card is untested +dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit +dd 0,0,0,0,0 ; end of list marker, do not remove +endg + +; PCI Bus defines +PCI_HEADER_TYPE equ 0x0e ;8 bit +PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit +PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_VENDOR_ID equ 0x00 ;16 bit +PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC + +ETHER_IP equ 0x0008 ; Reversed from 0800 for intel +ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel +ETHER_RARP equ 0x3580 +ARP_REQ_OPCODE equ 0x0100 +ARP_REP_OPCODE equ 0x0200 + +uglobal + arp_rx_count: dd 0 + ip_rx_count: dd 0 + dumped_rx_count: dd 0 + ip_tx_count: dd 0 + node_addr: db 0,0,0,0,0,0 + eth_rx_data_len: dw 0 + eth_status: dd 0 + io_addr: dd 0 + hdrtype: db 0 + vendor_device: dd 0 + pci_data: dd 0 + pci_dev: dd 0 + pci_bus: dd 0 + + ; These will hold pointers to the selected driver functions + drvr_probe: dd 0 + drvr_reset: dd 0 + drvr_poll: dd 0 + drvr_transmit: dd 0 + + ; These hold the destination Host identity for ARP responses + remote_ip_add: dd 0 + remote_hw_add: db 0, 0, 0, 0, 0, 0 +endg + +iglobal + broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff + subnet_mask: dd 0x00ffffff +endg + +uglobal + ; This is used by getMACfromIP + MACAddress: db 0,0,0,0,0,0 + gateway_ip: db 0, 0, 0, 0 + dns_ip: dd 0 +endg + +; The follow is the ARP Table. +; This table must be manually updated and the kernel recompilied if +; changes are made to it. +; ARP_TABLE_SIZE defines the size of the table +; ARP_TABLE_ENTRIES defines the number of entries in the table +; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address, +; 2 bytes status, 2 bytes TTL ( in seconds ) +; Empty entries are filled with zeros +; The TTL field is decremented every second, and is deleted when it +; reaches 0. It is refreshed every time a packet is received +; If the TTL field is 0xFFFF it is a permanent entry and is never deleted +; The status field can be the following values +; 0x0000 entry not used +; 0x0001 entry holds a valid mapping +; 0x0002 entry contains an IP address, awaiting ARP response +; 0x0003 No response received to ARP request. +; The last status value is provided to allow the network layer to delete +; a packet that is queued awaiting an ARP response + +ARP_NO_ENTRY equ 0 +ARP_VALID_MAPPING equ 1 +ARP_AWAITING_RESPONSE equ 2 +ARP_RESPONSE_TIMEOUT equ 3 + +ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry +ARP_TABLE_SIZE equ 20 ; Size of table +ARP_TABLE_ENTRIES equ 0 ; Inital, hardcoded entries + +uglobal + ARPTable: + times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 +endg + +iglobal + NumARP: db ARP_TABLE_ENTRIES +endg + +;*************************************************************************** +; Function +; eth_probe +; Description +; Searches for an ethernet card. If found, the card is enabled and +; the ethernet -> IP link established +; +; This function scans the PCI bus looking for a supported device. +; ISA bus is currently not supported. +; +; eax is 0 if no hardware found +;*************************************************************************** +eth_probe: + ; Find a card on the PCI bus, and get it's address + call scan_bus ; Find the ethernet cards PIC address + xor eax, eax + cmp [io_addr], eax + je ep_00x ; Return 0 in eax if no cards found + + call dword [drvr_probe] ; Call the drivers probe function + + mov eax, [io_addr] ; return a non zero value + +ep_00x: + ret + +;*************************************************************************** +; Function +; ethernet_driver +; +; Description +; The ethernet RX and TX handler +; This is a kernel function, called by stack_handler +; +;*************************************************************************** +ethernet_driver: + ; Do nothing if the driver is inactive + cmp [ethernet_active], byte 0 + je eth_exit + + call eth_rx + call eth_tx + +eth_exit: + ret + +;*************************************************************************** +; Function +; eth_rx +; +; Description +; Polls the ethernet card for received data. Extracts if present +; Depending on the Protocol within the packet: +; ARP : Pass to ARP_handler. This may result in an ARP reply +; being tx'ed +; IP : Store in an IP buffer +; +;*************************************************************************** +eth_rx: + xor ax, ax + mov [eth_rx_data_len], ax + call dword [drvr_poll] ; Call the drivers poll function + + mov ax, [eth_rx_data_len] + cmp ax, 0 + je erx_exit + +if DEBUGGING_STATE = DEBUGGING_ENABLED + pusha + mov eax, 0 ;Indicate that this is a received packet + mov cx, [eth_rx_data_len] + mov esi, Ether_buffer + cmp word [esi + 12], ETHER_IP + jnz erxd_done +; cmp byte [esi + 14 + 9], 0x06 ; TCP +; jnz erxd_done + call eth_dump +erxd_done: + popa +end if + + ; Check the protocol. Call appropriate handler + mov eax, Ether_buffer + add eax, 12 ; The address of the protocol word + + mov ax, [eax] + + cmp ax, ETHER_ARP + je erx_001 ; It is ARP + + cmp ax, ETHER_IP + je erx_002 ; It's IP + +; inc dword [dumped_rx_count] + + jmp erx_exit ; If not IP or ARP, ignore + +erx_001: + mov eax, [arp_rx_count] + inc eax + mov [arp_rx_count], eax + + ; At this point, the packet is still in the Ether_buffer + call arp_handler + + jmp erx_exit + +erx_002: + mov eax, [ip_rx_count] + inc eax + mov [ip_rx_count], eax + + ; Check to see if the MAC address is in our arp table + ; refresh the arp ttl if so + + mov esi, Ether_buffer + add esi, 6 + + call refreshARP + + call ether_IP_handler + + jmp erx_exit + +erx_exit: + ret + +;*************************************************************************** +; Function +; eth_tx +; +; Description +; Looks at the NET1OUT_QUEUE for data to send. +; Stores that destination IP in a location used by the tx routine +; Looks up the MAC address in the ARP table; stores that where +; the tx routine can get it +; Get the length of the data. Store that where the tx routine wants it +; Call tx +; Places buffer on empty queue when the tx routine finished +; +;*************************************************************************** +eth_tx: + ; Look for a buffer to tx + mov eax, NET1OUT_QUEUE + call dequeue + cmp ax, NO_BUFFER + je eth_exit ; Exit if no buffer available + + push eax + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + ; Extract the destination IP + ; find the destination IP in the ARP table, get MAC + ; store this MAC in 'MACAddress' + mov ebx, eax ; Save buffer address + mov edx, [ebx + 16] ; get destination address + + ; If the destination address is 255.255.255.255, + ; set the MACAddress to all ones ( broadcast ) + mov [MACAddress], dword 0xffffffff + mov [MACAddress + 4], word 0xffff + cmp edx, 0xffffffff + je etx_send ; If it is broadcast, just send + + call getMACfromIP ; Get the MAC address. + + cmp eax, ARP_VALID_MAPPING + jz etx_send + + ; No valid entry. Are we waiting for a response? + cmp eax, ARP_AWAITING_RESPONSE + jne etx_001 + + ; Re-queue the packet, and exit + pop ebx + mov eax, NET1OUT_QUEUE + call queue + jmp etx_exit + +etx_001: + ; HAs the request been sent, but timed out? + cmp eax, ARP_RESPONSE_TIMEOUT + jne etx_002 + + pop eax + call freeBuff + jmp etx_exit + +etx_002: + ; There is no entry. Re queue the request, and ask ARP to send a request + + ; IP address is in edx + push edx + call arp_request + pop ebx + + ; Add an entry in the ARP table, awaiting response + + cmp byte [NumARP], ARP_TABLE_SIZE + je etx_003 ; We cannot add a new entry in the table + + inc byte [NumARP] + + movzx eax, byte [NumARP] + mov ecx, ARP_ENTRY_SIZE + mul ecx + sub eax, ARP_ENTRY_SIZE + + mov [eax + ARPTable], ebx + xor ebx, ebx + mov [eax + ARPTable + 4], ebx + mov [eax + ARPTable + 8], bx + + ; set the status field up - awaiting response + mov cl, 0x00 + mov [eax + ARPTable + 10], cl + mov cl, 0x02 + mov [eax + ARPTable + 11], cl + + ; Initialise the time to live field - 10s + mov cx, 0x000A + mov [eax + ARPTable + 12], cx + +etx_003: + pop ebx ; Get the buffer back + mov eax, NET1OUT_QUEUE + call queue + jmp etx_exit + +etx_send: + xor ecx, ecx + mov ch, [ebx+2] + mov cl, [ebx+3] ; ; Size of IP packet to send + + mov esi, ebx + + mov edi, MACAddress + +if DEBUGGING_STATE = DEBUGGING_ENABLED + pusha + mov cx, 42 + mov eax, 1 ; Indicate that this is a tx packet + call eth_dump + popa +end if + + mov bx, ETHER_IP + call dword [drvr_transmit] ; Call the drivers transmit function + + ; OK, we have sent a packet, so increment the count + inc dword [ip_tx_count] + + ; And finally, return the buffer to the free queue + pop eax + call freeBuff + +etx_exit: + ret + +;*************************************************************************** +; Function +; ether_IP_handler +; +; Description +; Called when an IP ethernet packet is received on the ethernet +; Header + Data is in Ether_buffer[] +; We just need to get a buffer from the 'free' queue, and +; store the packet in it, then insert the packet number into the +; IPRX queue. +; If no queue entry is available, the packet is silently discarded +; All registers may be destroyed +; +;*************************************************************************** +ether_IP_handler: + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je eiph00x + + ; convert buffer pointer eax to the absolute address + push eax + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edi, eax + + ; get a pointer to the start of the DATA + mov esi, Ether_buffer + 14 + + ; Now store it all away + mov ecx, IPBUFFSIZE / 4 ; Copy all of the available + ; data across - worse case + cld + rep movsd + + ; And finally, place the buffer in the IPRX queue + pop ebx + mov eax, IPIN_QUEUE + call queue + +eiph00x: + ret + +;*************************************************************************** +; +; ARP CODE FOLLOWS +; +; The ARP code is used by ethernet drivers to translate an destination +; IP address into an ethernet hardware address. Functions to broadcast +; requests and handle response are (or will be) here. +; The IP layer has no knowledge of ARP, as this is a network interface +; issue +; +;*************************************************************************** + +;*************************************************************************** +; Function +; arp_timer +; +; Description +; Called every 1s +; It is responsible for removing expired routes +; All registers may be destroyed +; +;*************************************************************************** +arp_timer: + ; loop through all the ARP entries, decrementing each one + ; that doesn't have a TTL of 0xFFFF + movzx eax, byte [NumARP] + +arp_001: + cmp eax, 0 + je arp_003 + + push eax + dec eax + mov ecx, ARP_ENTRY_SIZE + mul ecx + cmp word [ eax + ARPTable + 12], 0xFFFF + je arp_002 + + cmp word [ eax + ARPTable + 12], 0 + je arp_002 + + dec word [eax + ARPTable + 12] + +arp_002: + pop eax + dec eax + jmp arp_001 + + ; Now, look for entries with a TTL of 0 + ; Valid entries and response timeout entries get removed + ; awaiting response gets converted into a response timeout, with a + ; short life time - this allows queued packets to be flushed +arp_003: + movzx edx, byte [NumARP] + cmp edx, 0 + je arp_exit + + ; EDX holds the # of entries to search through + mov eax, 0 + +arp_005: + cmp word [ eax + ARPTable + 12], 0 + jne arp_004 + + ; If it's status code is 0001 or 0003, delete the entry + cmp word [eax + ARPTable + 10], 0x0100 + je arp_007 + cmp word [eax + ARPTable + 10], 0x0300 + je arp_007 + + ; The only other valid code is 0002 - indicating a + ; timeout while waiting for a response. Change the + ; entry to response timed out + + mov [eax + ARPTable + 10], word 0x0300 + mov [eax + ARPTable + 12], word 0x000A + jmp arp_004 + +arp_007: + ; Delete this entry + mov edi, ARPTable + add edi, eax + mov esi, edi + add esi, ARP_ENTRY_SIZE + + mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE + sub ecx, eax + + rep movsb + + dec byte [NumARP] + jmp arp_006 + +arp_004: + add eax, ARP_ENTRY_SIZE +arp_006: + dec edx + cmp edx, 0 + jne arp_005 + +arp_exit: + ret + +;*************************************************************************** +; Function +; arp_request +; +; Description +; Sends an ARP request on the ethernet +; The requested IP address is in edx +; All registers may be destroyed +; +;*************************************************************************** +arp_request: + mov ebx, Ether_buffer + mov ax, 0x0100 + mov [ebx], ax + add ebx, 2 + + mov ax, 0x0008 + mov [ebx], ax + add ebx, 2 + + mov ax, 0x0406 + mov [ebx], ax + add ebx, 2 + + mov ax, 0x0100 + mov [ebx], ax + add ebx, 2 + + mov ecx, node_addr + mov eax, [ecx] + mov [ebx], eax + add ecx, 4 + add ebx, 4 + mov ax, [ecx] + mov [ebx], ax + add ebx, 2 + mov eax, [stack_ip] + mov [ebx], eax + add ebx, 4 + + xor eax, eax + mov [ebx], eax + add ebx, 4 + mov [ebx], ax + + add ebx, 2 + mov [ebx], edx + + ; Now, send it! + + ; Pointer to 48 bit destination address in edi + ; Type of packet in bx + ; size of packet in ecx + ; pointer to packet data in esi + mov edi, broadcast_add + +;if DEBUGGING_STATE = DEBUGGING_ENABLED +; pusha +; mov eax, 1 ; Indicate that this is a tx packet +; mov ecx, 28 +; mov esi, Ether_buffer +; call eth_dump +; popa +;end if + + mov bx, ETHER_ARP + mov ecx, 28 + mov esi, Ether_buffer + call dword [drvr_transmit] ; Call the drivers transmit function + ret + +;*************************************************************************** +; Function +; arp_handler +; +; Description +; Called when an ARP packet is received on the ethernet +; Header + Data is in Ether_buffer[] +; It looks to see if the packet is a request to resolve this Hosts +; IP address. If it is, send the ARP reply packet. +; This Hosts IP address is in dword [stack_ip] ( in network format ) +; This Hosts MAC address is in node_addr[6] +; All registers may be destroyed +; +;*************************************************************************** +arp_handler: + ; Is this a REQUEST? + ; Is this a request for My Host IP + ; Yes - So construct a response message. + ; Send this message to the ethernet card for transmission + + mov ebx, Ether_buffer + + mov edx, ebx + add edx, 20 + mov ax, [edx] + cmp ax, ARP_REQ_OPCODE ; Is this a request packet? + jne arph_resp ; No - so test for response + + mov edx, ebx + add edx, 38 + mov eax, [edx] + + cmp eax, [stack_ip] ; Is it looking for my IP address? + jne arph_exit ; No - so quit now + + ; OK, it is a request for my MAC address. Build the frame and send it + + ; Save the important data from the original packet + ; remote MAC address first + mov ecx, remote_hw_add + mov edx, ebx + add edx, 22 ; edx points to Source h/w address + mov eax, [edx] + mov [ecx], eax + add edx, 4 + add ecx, 4 + mov ax, [edx] + mov [ecx],ax + + ; and also the remote IP address + add edx, 2 + mov eax,[edx] + mov [remote_ip_add], eax + + ; So now we can reuse the packet. ebx still holds the address of + ; the header + packet + ; We dont need the header ( first 14 bytes ) + + mov edx, ebx + add edx, 20 + mov ax, ARP_REP_OPCODE + mov [edx], ax + add edx, 2 + + mov ecx, node_addr + mov eax, [ecx] + mov [edx], eax + add ecx, 4 + add edx, 4 + mov ax, [ecx] + mov [edx], ax + add edx, 2 + mov eax, [stack_ip] + mov [edx], eax + add edx, 4 + mov ecx, remote_hw_add + mov eax, [ecx] + mov [edx], eax + add ecx, 4 + add edx, 4 + mov ax, [ecx] + mov [edx], ax + + add edx, 2 + mov eax, [remote_ip_add] + mov [edx], eax + + ; Now, send it! + + ; Pointer to 48 bit destination address in edi + ; Type of packet in bx + ; size of packet in ecx + ; pointer to packet data in esi + mov edi, remote_hw_add + +;if DEBUGGING_STATE = DEBUGGING_ENABLED +; pusha +; mov eax, 1 ; Indicate that this is a tx packet +; mov ecx, 28 +; mov esi, Ether_buffer + 14 + ; call eth_dump +; popa +;end if + + mov bx, ETHER_ARP + mov ecx, 28 + mov esi, Ether_buffer + 14 + call dword [drvr_transmit] ; Call the drivers transmit function + jmp arph_exit + +arph_resp: + cmp ax, ARP_REP_OPCODE ; Is this a replypacket? + jne arph_resp ; No - so quit + + ; This was a reply, probably directed at me. + ; save the remotes MAC & IP + mov ecx, remote_hw_add + mov edx, ebx + add edx, 22 ; edx points to Source h/w address + mov eax, [edx] + mov [ecx], eax + add edx, 4 + add ecx, 4 + mov ax, [edx] + mov [ecx],ax + + ; and also the remote IP address + add edx, 2 + mov eax,[edx] + mov [remote_ip_add], eax + + ; Now, add an entry in the table for this IP address if it doesn't exist + + push eax + movzx eax, byte [NumARP] + mov ecx, ARP_ENTRY_SIZE + mul ecx + pop edx + movzx ecx, byte [NumARP] + cmp ecx, 0 + je arph_002 + +arph_001: + sub eax, ARP_ENTRY_SIZE + cmp [eax + ARPTable], edx + loopnz arph_001 ; Return back if non match + + jnz arph_002 ; None found, add to end + + mov ecx, [remote_hw_add] + mov [eax + ARPTable + 4], ecx + mov cx, [remote_hw_add+4] + mov [eax + ARPTable + 8], cx + + ; specify the type - a valid entry + mov cl, 0x00 + mov [eax + ARPTable + 10], cl + mov cl, 0x01 + mov [eax + ARPTable + 11], cl + + ; Initialise the time to live field - 1 hour + mov cx, 0x0E10 + mov [eax + ARPTable + 12], cx + jmp arph_exit + +arph_002: + + cmp byte [NumARP], ARP_TABLE_SIZE + je arph_exit + + inc byte [NumARP] + + movzx eax, byte [NumARP] + mov ecx, ARP_ENTRY_SIZE + mul ecx + sub eax, ARP_ENTRY_SIZE + + mov ecx, [remote_ip_add] + mov [eax + ARPTable], ecx + mov ecx, [remote_hw_add] + mov [eax + ARPTable + 4], ecx + mov cx, [remote_hw_add+4] + mov [eax + ARPTable + 8], cx + + mov cl, 0x00 + mov [eax + ARPTable + 10], cl + mov cl, 0x01 + mov [eax + ARPTable + 11], cl + + ; Initialise the time to live field - 1 hour + mov cx, 0x0E10 + mov [eax + ARPTable + 12], cx + +arph_exit: + ret + +; pointer to MAC in esi +refreshARP: + mov ebx, [esi] + mov dx, [esi+4] + push edx + movzx eax, byte [NumARP] + mov ecx, ARP_ENTRY_SIZE + mul ecx + pop edx + movzx ecx, byte [NumARP] + cmp ecx, 0 + je rf_exit + +rf_001: + sub eax, ARP_ENTRY_SIZE + cmp [eax + ARPTable+4], ebx + + je rf_002 + loop rf_001 + jmp rf_exit + +rf_002: + cmp [eax + ARPTable+8], dx + je rf_gotone + loop rf_001 + jmp rf_exit + +rf_gotone: + ; Initialise the time to live field - 1 hour + mov cx, 0x0E10 + mov [eax + ARPTable + 12], cx + +rf_exit: + ret + +;*************************************************************************** +; Function +; getMACfromIP +; +; Description +; Takes an IP address in edx and scans the ARP table for +; a matching entry +; If a match is found, it's MAC address is stored in MACAddress. +; Otherwise the value 0 is writen to MACAddress +; eax holds ARP table entry status code ( ARP_ ) +; ebx unchanged +; +;*************************************************************************** +getMACfromIP: + ; first, check destination IP to see if it is on 'this' network. + ; The test is: + ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) + ; desitnation is local + ; else + ; destination is remote, so pass to gateway + + mov eax, edx + and eax, [subnet_mask] + mov ecx, [stack_ip] + and ecx, [subnet_mask] + cmp eax, ecx + je gm0 + + mov edx, [gateway_ip] +gm0: + push edx + xor eax, eax + mov [MACAddress], eax + mov [MACAddress + 4], ax + + movzx eax, byte [NumARP] + mov ecx, ARP_ENTRY_SIZE + mul ecx + + pop edx + + movzx ecx, byte [NumARP] + cmp ecx, 0 + je gm_none +gm1: + sub eax, ARP_ENTRY_SIZE + cmp [eax + ARPTable], edx + loopnz gm1 ; Return back if non match + jnz gm_none ; Quit if none found + + ; eax holds index + mov ecx, [eax + ARPTable + 4] + mov [MACAddress], ecx + mov cx, [eax + ARPTable + 8] + mov [MACAddress+4], cx + + ; Return the entry status in eax + mov ch, [eax + ARPTable + 10] + mov cl, [eax + ARPTable + 11] + movzx eax, cx + jmp gm_exit + +gm_none: + mov eax, ARP_NO_ENTRY + +gm_exit: + ret + +;*************************************************************************** +; +; PCI CODE FOLLOWS +; +; the following functions provide access to the PCI interface. +; These functions are used by scan_bus, and also some ethernet drivers +; +;*************************************************************************** + +;*************************************************************************** +; Function +; config_cmd +; +; Description +; creates a command dword for use with the PCI bus +; bus # in ebx +; devfn in ecx +; where in edx +; +; command dword returned in eax +; Only eax destroyed +;*************************************************************************** +config_cmd: + push ecx + mov eax, ebx + shl eax, 16 + or eax, 0x80000000 + shl ecx, 8 + or eax, ecx + pop ecx + or eax, edx + and eax, 0xFFFFFFFC + ret + +;*************************************************************************** +; Function +; pcibios_read_config_byte +; +; Description +; reads a byte from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; byte returned in al ( rest of eax zero ) +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_byte: + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + + xor eax, eax + and dx, 0x03 + add dx, 0xCFC +; and dx, 0xFFC + in al, dx + ret + +;*************************************************************************** +; Function +; pcibios_read_config_word +; +; Description +; reads a word from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; word returned in ax ( rest of eax zero ) +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_word: + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + + xor eax, eax + and dx, 0x02 + add dx, 0xCFC +; and dx, 0xFFC + in ax, dx + ret + +;*************************************************************************** +; Function +; pcibios_read_config_dword +; +; Description +; reads a dword from the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; dword returned in eax +; Only eax/edx destroyed +;*************************************************************************** +pcibios_read_config_dword: + push edx + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + xor eax, eax + mov dx, 0xCFC + in eax, dx + pop edx + ret + +;*************************************************************************** +; Function +; pcibios_write_config_byte +; +; Description +; write a byte in al to the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; Only eax/edx destroyed +;*************************************************************************** +pcibios_write_config_byte: + push ax + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + pop ax + + and dx, 0x03 + add dx, 0xCFC + out dx, al + ret + +;*************************************************************************** +; Function +; pcibios_write_config_word +; +; Description +; write a word in ax to the PCI config space +; bus # in ebx +; devfn in ecx +; where in edx ( ls 16 bits significant ) +; +; Only eax/edx destroyed +;*************************************************************************** +pcibios_write_config_word: + push ax + call config_cmd + push dx + mov dx, 0xCF8 + out dx, eax + pop dx + pop ax + + and dx, 0x02 + add dx, 0xCFC + out dx, ax + ret + +;*************************************************************************** +; Function +; delay_us +; +; Description +; delays for 30 to 60 us +; +; I would prefer this routine to be able to delay for +; a selectable number of microseconds, but this works for now. +; +; If you know a better way to do 2us delay, pleae tell me! +;*************************************************************************** +delay_us: + push eax + push ecx + + mov ecx,2 + + in al,0x61 + and al,0x10 + mov ah,al + cld + +dcnt1: + in al,0x61 + and al,0x10 + cmp al,ah + jz dcnt1 + + mov ah,al + loop dcnt1 + + pop ecx + pop eax + + ret + +;*************************************************************************** +; Function +; scan_bus +; +; Description +; Scans the PCI bus for a supported device +; If a supported device is found, the drvr_ variables are initialised +; to that drivers functions ( as defined in the PCICards table) +; +; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid +; pci_data holds the PCI vendor + device code +; pci_dev holds PCI bus dev # +; pci_bus holds PCI bus # +; +; io_addr will be zero if no card found +; +;*************************************************************************** +scan_bus: + xor eax, eax + mov [hdrtype], al + mov [pci_data], eax + + xor ebx, ebx ; ebx = bus# 0 .. 255 + +sb_bus_loop: + xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) + +sb_devf_loop: + mov eax, ecx + and eax, 0x07 + + cmp eax, 0 + jne sb_001 + + mov edx, PCI_HEADER_TYPE + call pcibios_read_config_byte + mov [hdrtype], al + jmp sb_002 + +sb_001: + mov al, [hdrtype] + and al, 0x80 + cmp al, 0x80 + jne sb_inc_devf + +sb_002: + mov edx, PCI_VENDOR_ID + call pcibios_read_config_dword + mov [vendor_device], eax + cmp eax, 0xffffffff + je sb_empty + cmp eax, 0 + jne sb_check_vendor + +sb_empty: + mov [hdrtype], byte 0 + jmp sb_inc_devf + +sb_check_vendor: + ; iterate though PCICards until end or match found + mov esi, PCICards + +sb_check: + cmp [esi], dword 0 + je sb_inc_devf ; Quit if at last entry + cmp eax, [esi] + je sb_got_card + add esi, PCICARDS_ENTRY_SIZE + jmp sb_check + +sb_got_card: + ; indicate that we have found the card + mov [pci_data], eax + mov [pci_dev], ecx + mov [pci_bus], ebx + + ; Define the driver functions + push eax + mov eax, [esi+4] + mov [drvr_probe], eax + mov eax, [esi+8] + mov [drvr_reset], eax + mov eax, [esi+12] + mov [drvr_poll], eax + mov eax, [esi+16] + mov [drvr_transmit], eax + pop eax + + mov edx, PCI_BASE_ADDRESS_0 + +sb_reg_check: + call pcibios_read_config_dword + mov [io_addr], eax + and eax, PCI_BASE_ADDRESS_IO_MASK + cmp eax, 0 + je sb_inc_reg + mov eax, [io_addr] + and eax, PCI_BASE_ADDRESS_SPACE_IO + cmp eax, 0 + je sb_inc_reg + + mov eax, [io_addr] + and eax, PCI_BASE_ADDRESS_IO_MASK + mov [io_addr], eax + +sb_exit1: + ret + +sb_inc_reg: + add edx, 4 + cmp edx, PCI_BASE_ADDRESS_5 + jbe sb_reg_check + +sb_inc_devf: + inc ecx + cmp ecx, 255 + jb sb_devf_loop + inc ebx + cmp ebx, 256 + jb sb_bus_loop + + ; We get here if we didn't find our card + ; set io_addr to 0 as an indication + xor eax, eax + mov [io_addr], eax + +sb_exit2: + ret + +;*************************************************************************** +; +; DEBUGGING CODE FOLLOWS +; +; If debugging data output is not required, ALL code & data below may +; be removed. +; +;*************************************************************************** + +if DEBUGGING_STATE = DEBUGGING_ENABLED + +;*************************************************************************** +; Function +; eth_dump +; +; Description +; Dumps a tx or rx ethernet packet over the rs232 link +; This is a debugging routine that seriously slows down the stack. +; Use with caution. +; +; Baud rate is 57600, 8n1 com1 +; eax : type (0 == rx, 1 == tx ) +; cx : # of bytes in buffer +; esi : address of buffer start +; edi : pointer to MACAddress ( tx only ) +; +;*************************************************************************** +eth_dump: + pusha + + ; Set the port to the desired speed + mov ebx, 0x3f8 ; combase + + mov edx, ebx + add edx, 3 ; data format register + mov al, 0x80 ; enable access to divisor latch + out dx, al + + mov edx, ebx + add edx, 1 ; interrupt enable register + mov al, 0x00 ; No interruts enabled + out dx, al + + mov edx, ebx + mov al, 0x20 / 16 ; set baud rate to 57600 0x10 =115200 + out dx, al + + mov edx, ebx + add edx, 3 ; data format register + mov al, 0x03 ; 8 data bits + out dx, al + + mov edx, ebx + add edx, 4 ; Modem control register + mov al, 0x08 ; out2 enabled. No handshaking. + out dx, al + + mov edx, ebx + add edx, 1 ; interrupt enable register + mov al, 0x01 ; Receive data interrupt enabled, + out dx, al + + popa + + ; First, display the type of the buffer. + ; If it is a tx buffer, display the macaddress + + pusha + + cmp eax, 0 + jne dd001 + + mov bl, 0x0a + call tx_byted + mov bl, 0x0d + call tx_byted + + ; Output "RX:" + mov bl, 'R' + call tx_byted + mov bl, 'X' + call tx_byted + mov bl, ':' + call tx_byted + jmp dump_data + +dd001: + mov bl, 0x0a + call tx_byted + mov bl, 0x0d + call tx_byted + + ; Output TX: xxxxxxxxxxxx + mov bl, 'T' + call tx_byted + mov bl, 'X' + call tx_byted + mov bl, ':' + call tx_byted + mov bl, ' ' + call tx_byted + + ; Display MAC address + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + inc edi + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + inc edi + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + inc edi + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + inc edi + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + inc edi + xor eax, eax + mov al, [edi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [edi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + +dump_data: + popa + + ; OK, we come in here with + ; cx == number of byte to send + ; esi == buffer start + ; +dd_000: + mov bl, 0x0a + call tx_byted + mov bl, 0x0d + call tx_byted + + mov eax, 16 ; Number of characters on the line + mov edi, esi ; Save first byte position for later + + push ecx + +dd_001: + push eax + + ; Print a byte, and a space + xor eax, eax + mov al, [esi] + shr al, 4 + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + xor eax, eax + mov al, [esi] + and al, 0x0f + mov bl, [eax + hexchars] + call tx_byted ; byte in bl eax ebx edx destroyed + + mov bl, ' ' + call tx_byted + + pop eax + + inc esi + dec ecx + cmp ecx, 0 + je dd_0011 ; Print the ASCII format + + dec eax + + cmp eax, 0 + je dd_002 ; Print the ASCII format + jmp dd_001 ; Print rest of line + +dd_0011: + ; First, complete the 16 bytes of data, by printing spaces + dec eax + cmp eax, 0 + je dd_002 + + push eax + mov bl, ' ' + call tx_byted + mov bl, ' ' + call tx_byted + mov bl, ' ' + call tx_byted + pop eax + jmp dd_0011 + +dd_002: + pop ecx + mov esi, edi ; Go back to the start of the line data + + mov eax, 16 + +outLineAscii: + push eax + + xor eax, eax + mov al, [esi] + mov bl, '.' + + cmp al, 0x1F + jle outAscii + cmp al, 0x7e + jge outAscii + + mov bl, al + +outAscii: + call tx_byted ; byte in bl eax ebx edx destroyed + + pop eax + dec ecx + inc esi + cmp ecx, 0 + je dd_003 + + dec eax + cmp eax, 0 + je dd_003 + jmp outLineAscii + +dd_003: + cmp ecx, 0 + je dd_004 + jmp dd_000 + +dd_004: + ret + +;*************************************************************************** +; Function +; tx_byte +; +; Description +; Send a byte in bl out of the com port 1 +; destroys eax, edx +; +;*************************************************************************** +tx_byted: + push ebx ; Save the byte + + mov ebx, 0x3f8 ; get the com port address + + ; Wait for transmit buffer to empty. This could take 1ms @ 9600baud + + mov edx, ebx + add edx, 5 + +wait_txd: + in al, dx ; read uart serialisation status + and al, 0x40 + cmp al, 0 + jz wait_txd ; loop until free + + mov edx, ebx + pop eax ; restore the byte to send + out dx, al + ret + +iglobal + ; This is used for translating hex to ASCII for display or output + hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' +endg +end if + diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/i8255x.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/i8255x.inc new file mode 100644 index 0000000000..2aeb86414b --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/i8255x.inc @@ -0,0 +1,739 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; I8255X.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.3 11 August 2003 ;; +;; ;; +;; This driver is based on the eepro100 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett, ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************** +; Interface +; I8255x_reset +; I8255x_probe +; I8255x_poll +; I8255x_transmit +; +; These functions are referenced in ethernet.inc +; +;******************************************************************** + + +rxfd_status equ eth_data_start +rxfd_command equ eth_data_start + 2 +rxfd_link equ eth_data_start + 4 +rxfd_rx_buf_addr equ eth_data_start + 8 +rxfd_count equ eth_data_start + 12 +rxfd_size equ eth_data_start + 14 +rxfd_packet equ eth_data_start + 16 + + + +uglobal +eeprom_data: times 16 dd 0 + +align 4 + +lstats: +tx_good_frames: dd 0 +tx_coll16_errs: dd 0 +tx_late_colls: dd 0 +tx_underruns: dd 0 +tx_lost_carrier: dd 0 +tx_deferred: dd 0 +tx_one_colls: dd 0 +tx_multi_colls: dd 0 +tx_total_colls: dd 0 +rx_good_frames: dd 0 +rx_crc_errs: dd 0 +rx_align_errs: dd 0 +rx_resource_errs: dd 0 +rx_overrun_errs: dd 0 +rx_colls_errs: dd 0 +rx_runt_errs: dd 0 +done_marker: dd 0 + +align 4 + +confcmd: +confcmd_status: dw 0 +confcmd_command: dw 0 +confcmd_link: dd 0 +endg + +iglobal +confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 + db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 + db 0x80, 0x3f, 0x05 +endg + +uglobal +align 4 + +txfd: +txfd_status: dw 0 +txfd_command: dw 0 +txfd_link: dd 0 +txfd_tx_desc_addr: dd 0 +txfd_count: dd 0 +txfd_tx_buf_addr0: dd 0 +txfd_tx_buf_size0: dd 0 +txfd_tx_buf_addr1: dd 0 +txfd_tx_buf_size1: dd 0 + +align 4 + +hdr: +hdr_dst_addr: times 6 db 0 +hdr_src_addr: times 6 db 0 +hdr_type: dw 0 +endg + + +;*************************************************************************** +; Function +; wait_for_cmd_done +; +; Description +; waits for the hardware to complete a command +; port address in edx +; +; al destroyed +;*************************************************************************** +wait_for_cmd_done: + in al, dx + cmp al, 0 + jne wait_for_cmd_done + ret + + + +;*************************************************************************** +; Function +; mdio_read +; +; Description +; This probably reads a register in the "physical media interface chip" +; Phy_id in ebx +; location in ecx +; +; Data returned in eax +; +;*************************************************************************** +mdio_read: + mov edx, [io_addr] + add edx, 16 ; SCBCtrlMDI + + mov eax, 0x08000000 + shl ecx, 16 + or eax, ecx + shl ebx, 21 + or eax, ebx + + out dx, eax + +mrlp: + call delay_us + in eax, dx + mov ecx, eax + and ecx, 0x10000000 + jz mrlp + + and eax, 0xffff + ret + + + +;*************************************************************************** +; Function +; mdio_write +; +; Description +; This probably writes a register in the "physical media interface chip" +; Phy_id in ebx +; location in ecx +; data in edx +; Data returned in eax +; +;*************************************************************************** +mdio_write: + mov eax, 0x04000000 + shl ecx, 16 + or eax, ecx + shl ebx, 21 + or eax, ebx + or eax, edx + + mov edx, [io_addr] + add edx, 16 ; SCBCtrlMDI + out dx, eax + +mwlp: + call delay_us + in eax, dx + mov ecx, eax + and ecx, 0x10000000 + jz mwlp + + and eax, 0xffff + ret + + + +;/***********************************************************************/ +;/* I82557 related defines */ +;/***********************************************************************/ + +; Serial EEPROM section. +; A "bit" grungy, but we work our way through bit-by-bit :->. +; EEPROM_Ctrl bits. +EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock. +EE_CS equ 0x02 ; EEPROM chip select. +EE_DATA_WRITE equ 0x04 ; EEPROM chip data in. +EE_DATA_READ equ 0x08 ; EEPROM chip data out. +EE_WRITE_0 equ 0x4802 +EE_WRITE_1 equ 0x4806 +EE_ENB equ 0x4802 + + +; The EEPROM commands include the alway-set leading bit. +EE_READ_CMD equ 6 + +; The SCB accepts the following controls for the Tx and Rx units: +CU_START equ 0x0010 +CU_RESUME equ 0x0020 +CU_STATSADDR equ 0x0040 +CU_SHOWSTATS equ 0x0050 ; Dump statistics counters. +CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands. +CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters. + +RX_START equ 0x0001 +RX_RESUME equ 0x0002 +RX_ABORT equ 0x0004 +RX_ADDR_LOAD equ 0x0006 +RX_RESUMENR equ 0x0007 +INT_MASK equ 0x0100 +DRVR_INT equ 0x0200 ; Driver generated interrupt. + + +;*************************************************************************** +; Function +; do_eeprom_cmd +; +; Description +; writes a cmd to the ethernet cards eeprom, by bit bashing +; cmd in ebx +; cmd length in ecx +; return in eax +;*************************************************************************** +do_eeprom_cmd: + mov edx, [io_addr] ; We only require the value in dx + add dx, 14 ; the value SCBeeprom + + mov ax, EE_ENB + out dx, ax + call delay_us + + mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK + out dx, ax + call delay_us + + ; dx holds ee_addr + ; ecx holds count + ; eax holds cmd + xor edi, edi ; this will be the receive data + +dec_001: + mov esi, 1 + + dec ecx + shl esi, cl + inc ecx + and esi, ebx + mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags.. + cmp esi,0 + jz dec_002 + mov eax, EE_WRITE_1 + +dec_002: + out dx, ax + call delay_us + + or ax, EE_SHIFT_CLK + out dx, ax + call delay_us + + shl edi,1 + + in ax, dx + and ax, EE_DATA_READ + cmp ax,0 + jz dec_003 + inc edi + +dec_003: + loop dec_001 + + mov ax, EE_ENB + out dx, ax + call delay_us + + mov ax, 0x4800 + out dx, ax + call delay_us + + mov eax, edi + + ret + + + +;*************************************************************************** +; Function +; I8255x_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +I8255x_reset: + ret + + + +;*************************************************************************** +; Function +; I8255x_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; +;*************************************************************************** +I8255x_probe: + mov eax, [io_addr] + + mov ebx, [pci_bus] + mov ecx, [pci_dev] + mov edx, 0x04 ; PCI_COMMAND + call pcibios_read_config_word + + or ax, 0x05 + mov ebx, [pci_bus] + mov ecx, [pci_dev] + mov edx, 0x04 ; PCI_COMMAND + call pcibios_write_config_word + + mov ebx, 0x6000000 + mov ecx, 27 + call do_eeprom_cmd + and eax, 0xffe0000 + cmp eax, 0xffe0000 + je bige + + mov ebx, 0x1800000 + mov ecx, 0x40 + jmp doread + +bige: + mov ebx, 0x6000000 + mov ecx, 0x100 + +doread: + ; do-eeprom-cmd will destroy all registers + ; we have eesize in ecx + ; read_cmd in ebx + + ; Ignore full eeprom - just load the mac address + mov ecx, 0 + +drlp: + push ecx ; save count + push ebx + mov eax, ecx + shl eax, 16 + or ebx, eax + mov ecx, 27 + call do_eeprom_cmd + + pop ebx + pop ecx + + mov edx, ecx + shl edx, 2 + mov esi, eeprom_data + add esi, edx + mov [esi], eax + + inc ecx + cmp ecx, 16 + jne drlp + + ; OK, we have the MAC address. + ; Now reset the card + + mov edx, [io_addr] + add dx, 8 ; SCBPort + xor eax, eax ; The reset cmd == 0 + out dx, eax + + mov esi, 10 + call delay_ms ; Give the card time to warm up. + + mov eax, lstats + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0140 ; INT_MASK | CU_STATSADDR + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + mov eax, 0 + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + ; build rxrd structure + mov ax, 0x0001 + mov [rxfd_status], ax + mov ax, 0x0000 + mov [rxfd_command], ax + + mov eax, rxfd_status + mov [rxfd_link], eax + + mov eax, Ether_buffer + mov [rxfd_rx_buf_addr], eax + + mov ax, 0 + mov [rxfd_count], ax + + mov ax, 1528 + mov [rxfd_size], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + call wait_for_cmd_done + + ; start the reciver + + mov ax, 0 + mov [rxfd_status], ax + + mov ax, 0xc000 + mov [rxfd_command], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + ; Init TX Stuff + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, 0 + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE + out dx, ax + + call wait_for_cmd_done + + ; Set TX Base address + + ; First, set up confcmd values + + mov ax, 2 + mov [confcmd_command], ax + mov eax, txfd + mov [confcmd_link], eax + + mov ax, 1 + mov [txfd_command], ax ; CmdIASetup + + mov ax, 0 + mov [txfd_status], ax + + mov eax, confcmd + mov [txfd_link], eax + + ; ETH_ALEN is 6 bytes + + mov esi, eeprom_data + mov edi, node_addr + mov ecx, 3 +drp000: + mov eax, [esi] + mov [edi], al + shr eax, 8 + inc edi + mov [edi], al + inc edi + add esi, 4 + loop drp000 + + ; Hard code your MAC address into node_addr at this point, + ; If you cannot read the MAC address from the eeprom in the previous step. + ; You also have to write the mac address into txfd_tx_desc_addr, rather + ; than taking data from eeprom_data + + mov esi, eeprom_data + mov edi, txfd_tx_desc_addr + mov ecx, 3 +drp001: + mov eax, [esi] + mov [edi], al + shr eax, 8 + inc edi + mov [edi], al + inc edi + add esi, 4 + loop drp001 + + mov esi, eeprom_data + (6 * 4) + mov eax, [esi] + shr eax, 8 + and eax, 0x3f + cmp eax, 4 ; DP83840 + je drp002 + cmp eax, 10 ; DP83840A + je drp002 + jmp drp003 + +drp002: + mov ebx, [esi] + and ebx, 0x1f + push ebx + mov ecx, 23 + call mdio_read + pop ebx + or eax, 0x0422 + mov ecx, 23 + mov edx, eax + call mdio_write + +drp003: + mov ax, 0x4002 ; Cmdsuspend | CmdConfigure + mov [confcmd_command], ax + mov ax, 0 + mov [confcmd_status], ax + mov eax, txfd + mov [confcmd_link], eax + mov ebx, confcmd_data + mov al, 0x88 ; fifo of 8 each + mov [ebx + 1], al + mov al, 0 + mov [ebx + 4], al + mov al, 0x80 + mov [ebx + 5], al + mov al, 0x48 + mov [ebx + 15], al + mov al, 0x80 + mov [ebx + 19], al + mov al, 0x05 + mov [ebx + 21], al + + mov eax, txfd + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov eax, 0x0110 ; INT_MASK | CU_START + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done +jmp skip + + ; wait for thing to start +drp004: + mov ax, [txfd_status] + cmp ax, 0 + je drp004 + +skip: + ; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + +I8255x_exit: + ret + + + +;*************************************************************************** +; Function +; I8255x_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; +;*************************************************************************** +I8255x_poll: + mov ax, 0 ; assume no data + mov [eth_rx_data_len], ax + + mov ax, [rxfd_status] + cmp ax, 0 + je i8p_exit + + mov ax, 0 + mov [rxfd_status], ax + + mov ax, 0xc000 + mov [rxfd_command], ax + + mov edx, [io_addr] + add edx, 4 ; SCBPointer + + mov eax, rxfd_status + out dx, eax + + mov edx, [io_addr] + add edx, 2 ; SCBCmd + + mov ax, 0x0101 ; INT_MASK | RX_START + out dx, ax + + call wait_for_cmd_done + + mov esi, rxfd_packet + mov edi, Ether_buffer + mov ecx, 1518 + cld + rep movsb + + mov ax, [rxfd_count] + and ax, 0x3fff + mov [eth_rx_data_len], ax + +i8p_exit: + ret + + + +;*************************************************************************** +; Function +; I8255x_transmit +; +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +I8255x_transmit: + + mov [hdr_type], bx + + mov eax, [edi] + mov [hdr_dst_addr], eax + mov ax, [edi+4] + mov [hdr_dst_addr+4], ax + + mov eax, [node_addr] + mov [hdr_src_addr], eax + mov ax, [node_addr+4] + mov [hdr_src_addr+4], ax + + mov edx, [io_addr] + in ax, dx + and ax, 0xfc00 + out dx, ax + + xor ax, ax + mov [txfd_status], ax + mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex + mov [txfd_command], ax + mov eax, txfd + mov [txfd_link], eax + mov eax, 0x02208000 + mov [txfd_count], eax + mov eax, txfd_tx_buf_addr0 + mov [txfd_tx_desc_addr], eax + mov eax, hdr + mov [txfd_tx_buf_addr0], eax + mov eax, 14 ; sizeof hdr + mov [txfd_tx_buf_size0], eax + + ; Copy the buffer address and size in + mov eax, esi + mov [txfd_tx_buf_addr1], eax + mov eax, ecx + mov [txfd_tx_buf_size1], eax + + mov eax, txfd + mov edx, [io_addr] + add edx, 4 ; SCBPointer + out dx, eax + + mov ax, 0x0110 ; INT_MASK | CU_START + mov edx, [io_addr] + add edx, 2 ; SCBCmd + out dx, ax + + call wait_for_cmd_done + + mov edx, [io_addr] + in ax, dx + +I8t_001: + mov ax, [txfd_status] + cmp ax, 0 + je I8t_001 + + mov edx, [io_addr] + in ax, dx + + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/pcnet32.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/pcnet32.inc new file mode 100644 index 0000000000..4f6e3db1ad --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/pcnet32.inc @@ -0,0 +1,814 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; PCNET32.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 1.0 31 July 2004 ;; +;; ;; +;; This driver is based on the PCNet32 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2004 Jarek Pelczar, ;; +;; jpelczar@interia.pl ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;macro PutStr X +;{ +; local .__xyz1 +; local .__xyz2 +; push esi +; mov esi,.__xyz1 +; call sys_msg_board_str +; push eax +; mov eax,1 +; call delay_hs +; pop eax +; jmp .__xyz2 +;.__xyz1: +; db X +; db 13,10,0 +;.__xyz2: +; pop esi +;} +PCNET32_PORT_AUI equ 0x00 +PCNET32_PORT_10BT equ 0x01 +PCNET32_PORT_GPSI equ 0x02 +PCNET32_PORT_MII equ 0x03 +PCNET32_PORT_PORTSEL equ 0x03 +PCNET32_PORT_ASEL equ 0x04 +PCNET32_PORT_100 equ 0x40 +PCNET32_PORT_FD equ 0x80 +PCNET32_DMA_MASK equ 0xffffffff +PCNET32_LOG_TX_BUFFERS equ 1 +PCNET32_LOG_RX_BUFFERS equ 2 +PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS) +PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1) +PCNET32_TX_RING_LEN_BITS equ 0 +PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS) +PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1) +PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4) +PCNET32_PKT_BUF_SZ equ 1544 +PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8 +pcnet32_txb equ (eth_data_start) +pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0) +virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0) +pcnet32_private: +.mode dw ? +.tlen_rlen dw ? +.phys_addr db ?,?,?,?,?,? +.reserved dw ? +.filter dd ?,? +.rx_ring dd ? +.tx_ring dd ? +.cur_rx dd ? +.cur_tx dd ? +.dirty_rx dd ? +.dirty_tx dd ? +.tx_full db ? +.options dd ? +.full_duplex db ? +.chip_version dd ? +.mii db ? +.ltint db ? +.dxsuflo db ? +.fset db ? +.fdx db ? +end virtual +virtual at 0 +pcnet32_rx_head: +.base dd ? +.buf_length dw ? +.status dw ? +.msg_length dd ? +.reserved dd ? +end virtual +virtual at 0 +pcnet32_tx_head: +.base dd ? +.length dw ? +.status dw ? +.misc dd ? +.reserved dd ? +end virtual + +uglobal +pcnet32_access: +.read_csr dd ? +.write_csr dd ? +.read_bcr dd ? +.write_bcr dd ? +.read_rap dd ? +.write_rap dd ? +.reset dd ? +endg + +iglobal +pcnet32_options_mapping: +dd PCNET32_PORT_ASEL ; 0 Auto-select +dd PCNET32_PORT_AUI ; 1 BNC/AUI +dd PCNET32_PORT_AUI ; 2 AUI/BNC +dd PCNET32_PORT_ASEL ; 3 not supported +dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD +dd PCNET32_PORT_ASEL ; 5 not supported +dd PCNET32_PORT_ASEL ; 6 not supported +dd PCNET32_PORT_ASEL ; 7 not supported +dd PCNET32_PORT_ASEL ; 8 not supported +dd PCNET32_PORT_MII ; 9 MII 10baseT +dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD +dd PCNET32_PORT_MII ; 11 MII (autosel) +dd PCNET32_PORT_10BT ; 12 10BaseT +dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx +dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD +dd PCNET32_PORT_ASEL ; 15 not supported +endg + +PCNET32_WIO_RDP equ 0x10 +PCNET32_WIO_RAP equ 0x12 +PCNET32_WIO_RESET equ 0x14 +PCNET32_WIO_BDP equ 0x16 +PCNET32_DWIO_RDP equ 0x10 +PCNET32_DWIO_RAP equ 0x14 +PCNET32_DWIO_RESET equ 0x18 +PCNET32_DWIO_BDP equ 0x1C +PCNET32_TOTAL_SIZE equ 0x20 +; ebx - index +; return: +; eax - data +pcnet32_wio_read_csr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + mov ax,bx + out dx,ax + lea edx,[ebp+PCNET32_WIO_RDP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - data +; ebx - index +pcnet32_wio_write_csr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + xchg eax,ebx + out dx,ax + xchg eax,ebx + lea edx,[ebp+PCNET32_WIO_RDP] + out dx,ax + pop edx + ret +; ebx - index +; return: +; eax - data +pcnet32_wio_read_bcr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + mov ax,bx + out dx,ax + lea edx,[ebp+PCNET32_WIO_BDP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - data +; ebx - index +pcnet32_wio_write_bcr: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + xchg eax,ebx + out dx,ax + xchg eax,ebx + lea edx,[ebp+PCNET32_WIO_BDP] + out dx,ax + pop edx + ret +pcnet32_wio_read_rap: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + in ax,dx + and eax,0xffff + pop edx + ret +; eax - val +pcnet32_wio_write_rap: + push edx + lea edx,[ebp+PCNET32_WIO_RAP] + out dx,ax + pop edx + ret +pcnet32_wio_reset: + push edx + push eax + lea edx,[ebp+PCNET32_WIO_RESET] + in ax,dx + pop eax + pop edx + ret +pcnet32_wio_check: + push edx + mov ax,88 + lea edx,[ebp+PCNET32_WIO_RAP] + out dx,ax + nop + nop + in ax,dx + cmp ax,88 + sete al + pop edx + ret + +iglobal +pcnet32_wio: + dd pcnet32_wio_read_csr + dd pcnet32_wio_write_csr + dd pcnet32_wio_read_bcr + dd pcnet32_wio_write_bcr + dd pcnet32_wio_read_rap + dd pcnet32_wio_write_rap + dd pcnet32_wio_reset +endg + +; ebx - index +; return: +; eax - data +pcnet32_dwio_read_csr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + mov ebx,eax + out dx,eax + lea edx,[ebp+PCNET32_DWIO_RDP] + in eax,dx + and eax,0xffff + pop edx + ret +; ebx - index +; eax - data +pcnet32_dwio_write_csr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + xchg eax,ebx + out dx,eax + lea edx,[ebp+PCNET32_DWIO_RDP] + xchg eax,ebx + out dx,eax + pop edx + ret +; ebx - index +; return: +; eax - data +pcnet32_dwio_read_bcr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + mov ebx,eax + out dx,eax + lea edx,[ebp+PCNET32_DWIO_BDP] + in eax,dx + and eax,0xffff + pop edx + ret +; ebx - index +; eax - data +pcnet32_dwio_write_bcr: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + xchg eax,ebx + out dx,eax + lea edx,[ebp+PCNET32_DWIO_BDP] + xchg eax,ebx + out dx,eax + pop edx + ret +pcnet32_dwio_read_rap: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + in eax,dx + and eax,0xffff + pop edx + ret +; eax - val +pcnet32_dwio_write_rap: + push edx + lea edx,[ebp+PCNET32_DWIO_RAP] + out dx,eax + pop edx + ret +pcnet32_dwio_reset: + push edx + push eax + lea edx,[ebp+PCNET32_DWIO_RESET] + in eax,dx + pop eax + pop edx + ret +pcnet32_dwio_check: + push edx + lea edx,[PCNET32_DWIO_RAP] + mov eax,88 + out dx,eax + nop + nop + in eax,dx + and eax,0xffff + cmp eax,88 + sete al + pop edx + ret + +iglobal +pcnet32_dwio: + dd pcnet32_dwio_read_csr + dd pcnet32_dwio_write_csr + dd pcnet32_dwio_read_bcr + dd pcnet32_dwio_write_bcr + dd pcnet32_dwio_read_rap + dd pcnet32_dwio_write_rap + dd pcnet32_dwio_reset +endg + +pcnet32_init_ring: + mov [pcnet32_private.tx_full],0 + mov [pcnet32_private.cur_rx],0 + mov [pcnet32_private.cur_tx],0 + mov [pcnet32_private.dirty_rx],0 + mov [pcnet32_private.dirty_tx],0 + mov edi,pcnet32_rx_ring + mov ecx,PCNET32_RX_RING_SIZE + mov ebx,pcnet32_rxb +.rx_init: + mov [edi+pcnet32_rx_head.base],ebx + mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG + mov [edi+pcnet32_rx_head.status],word 0x8000 + add ebx,PCNET32_PKT_BUF_SZ +; inc ebx + add edi,16 + loop .rx_init + mov edi,pcnet32_tx_ring + mov ecx,PCNET32_TX_RING_SIZE +.tx_init: + mov [edi+pcnet32_tx_head.base],dword 0 + mov [edi+pcnet32_tx_head.status],word 0 + add edi,16 + loop .tx_init + mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) + mov esi,node_addr + mov edi,pcnet32_private.phys_addr + cld + movsd + movsw + mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring + mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring + ret +pcnet32_reset: + ; Reset PCNET32 + mov ebp,[io_addr] + call dword [pcnet32_access.reset] + ; set 32bit mode + mov ebx,20 + mov eax,2 + call dword [pcnet32_access.write_bcr] + ; set/reset autoselect bit + mov ebx,2 + call dword [pcnet32_access.read_bcr] + and eax,not 2 + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L1 + or eax,2 +.L1: + call dword [pcnet32_access.write_bcr] + ; Handle full duplex setting + cmp byte [pcnet32_private.full_duplex],0 + je .L2 + mov ebx,9 + call dword [pcnet32_access.read_bcr] + and eax,not 3 + test [pcnet32_private.options],PCNET32_PORT_FD + jz .L3 + or eax,1 + cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI + jne .L4 + or eax,2 + jmp .L4 +.L3: + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L4 + cmp [pcnet32_private.chip_version],0x2627 + jne .L4 + or eax,3 +.L4: + mov ebx,9 + call dword [pcnet32_access.write_bcr] +.L2: + ; set/reset GPSI bit + mov ebx,124 + call dword [pcnet32_access.read_csr] + mov ecx,[pcnet32_private.options] + and ecx,PCNET32_PORT_PORTSEL + cmp ecx,PCNET32_PORT_GPSI + jne .L5 + or eax,0x10 +.L5: + call dword [pcnet32_access.write_csr] + cmp [pcnet32_private.mii],0 + je .L6 + test [pcnet32_private.options],PCNET32_PORT_ASEL + jnz .L6 + mov ebx,32 + call dword [pcnet32_access.read_bcr] + and eax,not 0x38 + test [pcnet32_private.options],PCNET32_PORT_FD + jz .L7 + or eax,0x10 +.L7: + test [pcnet32_private.options],PCNET32_PORT_100 + jz .L8 + or eax,0x08 +.L8: + call dword [pcnet32_access.write_bcr] + jmp .L9 +.L6: + test [pcnet32_private.options],PCNET32_PORT_ASEL + jz .L9 + mov ebx,32 +; PutStr "ASEL, enable auto-negotiation" + call dword [pcnet32_access.read_bcr] + and eax,not 0x98 + or eax,0x20 + call dword [pcnet32_access.write_bcr] +.L9: + cmp [pcnet32_private.ltint],0 + je .L10 + mov ebx,5 + call dword [pcnet32_access.read_csr] + or eax,(1 shl 14) + call dword [pcnet32_access.write_csr] +.L10: + mov eax,[pcnet32_private.options] + and eax,PCNET32_PORT_PORTSEL + shl eax,7 + mov [pcnet32_private.mode],ax + mov [pcnet32_private.filter],dword 0xffffffff + mov [pcnet32_private.filter+4],dword 0xffffffff + call pcnet32_init_ring + mov ebx,1 + mov eax,pcnet32_private + and eax,0xffff + call dword [pcnet32_access.write_csr] + mov eax,pcnet32_private + mov ebx,2 + shr eax,16 + call dword [pcnet32_access.write_csr] + mov ebx,4 + mov eax,0x0915 + call dword [pcnet32_access.write_csr] + mov ebx,0 + mov eax,1 + call dword [pcnet32_access.write_csr] + mov ecx,100 +.L11: + xor ebx,ebx + call dword [pcnet32_access.read_csr] + test ax,0x100 + jnz .L12 + loop .L11 +.L12: +; PutStr "hardware reset" + xor ebx,ebx + mov eax,0x0002 + call dword [pcnet32_access.write_csr] + xor ebx,ebx + call dword [pcnet32_access.read_csr] +; PutStr "PCNET reset complete" + ret +pcnet32_adjust_pci_device: + ;*******Get current setting************************ + mov al, 2 ;read a word + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x04 ;from command Register + call pci_read_reg + ;******see if its already set as bus master******** + mov bx, ax + and bx,5 + cmp bx,5 + je pcnet32_adjust_pci_device_Latency + ;******Make card a bus master******* + mov cx, ax ;value to write + mov bh, [pci_dev] + mov al, 2 ;write a word + or cx,5 + mov ah, [pci_bus] + mov bl, 0x04 ;to command register + call pci_write_reg + ;******Check latency setting*********** +pcnet32_adjust_pci_device_Latency: + ;*******Get current latency setting************************ +; mov al, 1 ;read a byte +; mov bh, [pci_dev] +; mov ah, [pci_bus] +; mov bl, 0x0D ;from Lantency Timer Register +; call pci_read_reg + ;******see if its aat least 64 clocks******** +; cmp ax,64 +; jge pcnet32_adjust_pci_device_Done + ;******Set latency to 32 clocks******* +; mov cx, 64 ;value to write +; mov bh, [pci_dev] +; mov al, 1 ;write a byte +; mov ah, [pci_bus] +; mov bl, 0x0D ;to Lantency Timer Register +; call pci_write_reg + ;******Check latency setting*********** +pcnet32_adjust_pci_device_Done: + ret +pcnet32_probe: + mov ebp,[io_addr] + call pcnet32_wio_reset + xor ebx,ebx + call pcnet32_wio_read_csr + cmp eax,4 + jne .try_dwio + call pcnet32_wio_check + and al,al + jz .try_dwio +; PutStr "Using WIO" + mov esi,pcnet32_wio + jmp .L1 +.try_dwio: + call pcnet32_dwio_reset + xor ebx,ebx + call pcnet32_dwio_read_csr + cmp eax,4 + jne .no_dev + call pcnet32_dwio_check + and al,al + jz .no_dev +; PutStr "Using DWIO" + mov esi,pcnet32_dwio + jmp .L1 +.no_dev: +; PutStr "PCNET32 not found" + ret +.L1: + mov edi,pcnet32_access + mov ecx,7 + cld + rep movsd + mov ebx,88 + call dword [pcnet32_access.read_csr] + mov ecx,eax + mov ebx,89 + call dword [pcnet32_access.read_csr] + shl eax,16 + or eax,ecx + mov ecx,eax + and ecx,0xfff + cmp ecx,3 + jne .no_dev + shr eax,12 + and eax,0xffff + mov [pcnet32_private.chip_version],eax +; PutStr "PCNET32 chip version OK" + mov [pcnet32_private.fdx],0 + mov [pcnet32_private.mii],0 + mov [pcnet32_private.fset],0 + mov [pcnet32_private.dxsuflo],0 + mov [pcnet32_private.ltint],0 + mov eax,[pcnet32_private.chip_version] + cmp eax,0x2420 + je .L2 + cmp eax,0x2430 + je .L3 + cmp eax,0x2621 + je .L4 + cmp eax,0x2623 + je .L5 + cmp eax,0x2624 + je .L6 + cmp eax,0x2625 + je .L7 + cmp eax,0x2626 + je .L8 + cmp eax,0x2627 + je .L9 +; PutStr "Invalid chip rev" + jmp .no_dev +.L2: +; PutStr "PCnet/PCI 79C970" + jmp .L10 +.L3: +; PutStr "PCnet/PCI 79C970" + jmp .L10 +.L4: +; PutStr "PCnet/PCI II 79C970A" + mov [pcnet32_private.fdx],1 + jmp .L10 +.L5: +; PutStr "PCnet/FAST 79C971" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + mov [pcnet32_private.ltint],1 + jmp .L10 +.L6: +; PutStr "PCnet/FAST+ 79C972" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + mov [pcnet32_private.fset],1 + jmp .L10 +.L7: +; PutStr "PCnet/FAST III 79C973" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 + jmp .L10 +.L8: +; PutStr "PCnet/Home 79C978" + mov [pcnet32_private.fdx],1 + mov ebx,49 + call dword [pcnet32_access.read_bcr] + call dword [pcnet32_access.write_bcr] + jmp .L10 +.L9: +; PutStr "PCnet/FAST III 79C975" + mov [pcnet32_private.fdx],1 + mov [pcnet32_private.mii],1 +.L10: + cmp [pcnet32_private.fset],1 + jne .L11 + mov ebx,18 + call dword [pcnet32_access.read_bcr] + or eax,0x800 + call dword [pcnet32_access.write_bcr] + mov ebx,80 + call dword [pcnet32_access.read_csr] + and eax,0xc00 + or eax,0xc00 + call dword [pcnet32_access.write_csr] + mov [pcnet32_private.dxsuflo],1 + mov [pcnet32_private.ltint],1 +.L11: + ; read MAC + mov edi,node_addr + mov edx,ebp + mov ecx,6 +.Lmac: + in al,dx + stosb + inc edx + loop .Lmac +; PutStr "MAC read" + call pcnet32_adjust_pci_device +; PutStr "PCI done" + mov eax,PCNET32_PORT_ASEL + mov [pcnet32_private.options],eax + mov [pcnet32_private.mode],word 0x0003 + mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS) + mov esi,node_addr + mov edi,pcnet32_private.phys_addr + cld + movsd + movsw + mov [pcnet32_private.filter],dword 0 + mov [pcnet32_private.filter+4],dword 0 + mov dword [pcnet32_private.rx_ring],pcnet32_rx_ring + mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring +; PutStr "Switching to 32" + mov ebx,20 + mov eax,2 + call dword [pcnet32_access.write_bcr] + mov ebx,1 + mov eax,(pcnet32_private and 0xffff) + call dword [pcnet32_access.write_csr] + mov ebx,2 + mov eax,(pcnet32_private shr 16) and 0xffff + call dword [pcnet32_access.write_csr] + mov ebx,0 + mov eax,1 + call dword [pcnet32_access.write_csr] + mov esi,1 + call delay_ms + call pcnet32_reset + mov eax, [pci_data] + mov [eth_status], eax + ret +pcnet32_poll: + xor eax,eax + mov [eth_rx_data_len],ax + mov eax,[pcnet32_private.cur_rx] + and eax,PCNET32_RX_RING_MOD_MASK + mov ebx,eax + imul esi,eax,PCNET32_PKT_BUF_SZ + add esi,pcnet32_rxb + shl ebx,4 + add ebx,pcnet32_rx_ring + mov cx,[ebx+pcnet32_rx_head.status] + test cx,0x8000 + jnz .L1 + cmp ch,3 + jne .L1 +; PutStr "PCNETRX" + mov ecx,[ebx+pcnet32_rx_head.msg_length] + and ecx,0xfff + sub ecx,4 + mov [eth_rx_data_len],cx + push ecx + shr ecx,2 + mov edi,Ether_buffer + cld + rep movsd + pop ecx + and ecx,3 + rep movsb + mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG + or [ebx+pcnet32_rx_head.status],word 0x8000 + inc [pcnet32_private.cur_rx] +.L1: + ret +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +pcnet32_xmit: + push edi + push esi + push ebx + push ecx +; PutStr "PCNETTX" + mov esi,edi + mov edi,[pcnet32_private.cur_tx] + imul edi,PCNET32_PKT_BUF_SZ + add edi,pcnet32_txb ; edi=ptxb + mov eax,edi + cld ; copy MAC + movsd + movsw + mov esi,node_addr + cld + movsd + movsw + mov [edi],bx + add edi,2 + mov esi,[esp+8] + mov ecx,[esp] + push ecx + shr ecx,2 + cld + rep movsd + pop ecx + and ecx,3 + rep movsb +; mov ecx,[esp] +; add ecx,14 ; ETH_HLEN +; xor eax,eax +; pad to min length (60=ETH_ZLEN) +; cmp ecx,60 +; jae .L1 +; sub ecx,60 +; cld +; rep stosb +;.L1: + mov edi,pcnet32_tx_ring+0 ; entry=0 + mov ecx,[esp] + add ecx,14 + cmp cx,60 + jae .L1 + mov cx,60 +.L1: + neg cx + mov [edi+pcnet32_tx_head.length],cx + mov [edi+pcnet32_tx_head.misc],dword 0 + mov [edi+pcnet32_tx_head.base],eax + mov [edi+pcnet32_tx_head.status],word 0x8300 + ; trigger an immediate send poll + mov ebx,0 + mov eax,0x0008 ; 0x0048 + mov ebp,[io_addr] + call dword [pcnet32_access.write_csr] + mov dword [pcnet32_private.cur_tx],0 + ; wait for TX to complete + mov ecx,[timer_ticks];[0xfdf0] + add ecx,100 +.L2: + mov ax,[edi+pcnet32_tx_head.status] + test ax,0x8000 + jz .L3 + cmp ecx,[timer_ticks];[0xfdf0] + jb .L4 + mov esi,10 + call delay_ms + jnz .L2 +.L4: +; PutStr "PCNET: Send timeout" +.L3: + mov dword [edi+pcnet32_tx_head.base],0 + pop ecx + pop ebx + pop esi + pop edi + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8029.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8029.inc new file mode 100644 index 0000000000..40683316b1 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8029.inc @@ -0,0 +1,955 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; RTL8029.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.2 31 July 2002 ;; +;; ;; +;; This driver is based on the ns8390 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2002 Mike Hibbett, ;; +;; mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; While this implementation handles only PCI bus RTL8029 ;; +;; hardware, it can be easily adapted to other NE2000 clone ;; +;; products. I just dont have any to try! ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +;******************************************************************** +; Interface +; rtl8029_reset +; rtl8029_probe +; rtl8029_poll +; rtl8029_transmit +; +;******************************************************************** + + + + +;************************************************************************** +; 8390 Register Definitions +;************************************************************************** +D8390_P0_COMMAND equ 0x00 +D8390_P0_PSTART equ 0x01 +D8390_P0_PSTOP equ 0x02 +D8390_P0_BOUND equ 0x03 +D8390_P0_TSR equ 0x04 +D8390_P0_TPSR equ 0x04 +D8390_P0_TBCR0 equ 0x05 +D8390_P0_TBCR1 equ 0x06 +D8390_P0_ISR equ 0x07 +D8390_P0_RSAR0 equ 0x08 +D8390_P0_RSAR1 equ 0x09 +D8390_P0_RBCR0 equ 0x0A +D8390_P0_RBCR1 equ 0x0B +D8390_P0_RSR equ 0x0C +D8390_P0_RCR equ 0x0C +D8390_P0_TCR equ 0x0D +D8390_P0_DCR equ 0x0E +D8390_P0_IMR equ 0x0F +D8390_P1_COMMAND equ 0x00 +D8390_P1_PAR0 equ 0x01 +D8390_P1_PAR1 equ 0x02 +D8390_P1_PAR2 equ 0x03 +D8390_P1_PAR3 equ 0x04 +D8390_P1_PAR4 equ 0x05 +D8390_P1_PAR5 equ 0x06 +D8390_P1_CURR equ 0x07 +D8390_P1_MAR0 equ 0x08 + +D8390_COMMAND_PS0 equ 0x0 ; Page 0 select +D8390_COMMAND_PS1 equ 0x40 ; Page 1 select +D8390_COMMAND_PS2 equ 0x80 ; Page 2 select +D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control +D8390_COMMAND_RD1 equ 0x10 +D8390_COMMAND_RD0 equ 0x08 +D8390_COMMAND_TXP equ 0x04 ; transmit packet +D8390_COMMAND_STA equ 0x02 ; start +D8390_COMMAND_STP equ 0x01 ; stop + +D8390_COMMAND_RD2_STA equ 0x22 +D8390_COMMAND_RD2_STP equ 0x21 +D8390_COMMAND_RD1_STA equ 0x12 +D8390_COMMAND_RD0_STA equ 0x0A +D8390_COMMAND_PS0_RD2_STP equ 0x21 +D8390_COMMAND_PS1_RD2_STP equ 0x61 +D8390_COMMAND_PS0_RD2_STA equ 0x22 +D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 + +D8390_RCR_MON equ 0x20 ; monitor mode + +D8390_DCR_FT1 equ 0x40 +D8390_DCR_LS equ 0x08 ; Loopback select +D8390_DCR_WTS equ 0x01 ; Word transfer select + +D8390_DCR_FT1_LS equ 0x48 +D8390_DCR_WTS_FT1_LS equ 0x49 + +D8390_ISR_PRX equ 0x01 ; successful recv +D8390_ISR_PTX equ 0x02 ; successful xmit +D8390_ISR_RXE equ 0x04 ; receive error +D8390_ISR_TXE equ 0x08 ; transmit error +D8390_ISR_OVW equ 0x10 ; Overflow +D8390_ISR_CNT equ 0x20 ; Counter overflow +D8390_ISR_RDC equ 0x40 ; Remote DMA complete +D8390_ISR_RST equ 0x80 ; reset + +D8390_RSTAT_PRX equ 0x01 ; successful recv +D8390_RSTAT_CRC equ 0x02 ; CRC error +D8390_RSTAT_FAE equ 0x04 ; Frame alignment error +D8390_RSTAT_OVER equ 0x08 ; FIFO overrun + +D8390_TXBUF_SIZE equ 6 +D8390_RXBUF_END equ 32 +D8390_PAGE_SIZE equ 256 + +ETH_ALEN equ 6 +ETH_HLEN equ 14 +ETH_ZLEN equ 60 +ETH_FRAME_LEN equ 1514 + +FLAG_PIO equ 0x01 +FLAG_16BIT equ 0x02 +ASIC_PIO equ 0 + +VENDOR_NONE equ 0 +VENDOR_WD equ 1 +VENDOR_NOVELL equ 2 +VENDOR_3COM equ 3 + +NE_ASIC_OFFSET equ 0x10 +NE_RESET equ 0x0F ; Used to reset card +NE_DATA equ 0x00 ; Used to read/write NIC mem + +MEM_8192 equ 32 +MEM_16384 equ 64 +MEM_32768 equ 128 + +ISA_MAX_ADDR equ 0x400 + +uglobal +eth_flags: db 0 +eth_vendor: db 0 +eth_nic_base: dw 0 +eth_asic_base: dw 0 +eth_memsize: db 0 +eth_rx_start: db 0 +eth_tx_start: db 0 +eth_bmem: dd 0 +eth_rmem: dd 0 +romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +endg + +iglobal +test_data: db 'NE*000 memory',0 +test_buffer: db ' ',0 +endg + +uglobal +eth_type: dw 0 +pkthdr: db 0,0,0,0 ; status, next, (short) len +pktoff: dw 0 +eth_rx_data_ptr: dd 0 +eth_tmp_len: dw 0 +endg + + + +;*************************************************************************** +; Function +; eth_pio_read +; +; Description +; Read a frame from the ethernet card via Programmed I/O +; src in ebx +; cnt in ecx +; dst in edi +;*************************************************************************** +eth_pio_read: + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epr_001 + + inc ecx + and ecx, 0xFFFFFFFE + +epr_001: + mov al, D8390_COMMAND_RD2_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov al, cl + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR0 + out dx, al + + mov al, ch + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR1 + out dx, al + + mov al, bl + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR0 + out dx, al + + mov al, bh + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR1 + out dx, al + + mov al, D8390_COMMAND_RD0_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov dx, [eth_asic_base] + add dx, ASIC_PIO + + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epr_003 + + shr ecx, 1 + +epr_002: + ; 2 bytes at a time + in ax, dx + mov [edi], ax + add edi, 2 + loop epr_002 + ret + +epr_003: + ; 1 byte at a time + in al, dx + mov [edi], al + inc edi + loop epr_003 + ret + + + + +;*************************************************************************** +; Function +; eth_pio_write +; +; Description +; writes a frame to the ethernet card via Programmed I/O +; dst in ebx +; cnt in ecx +; src in esi +;*************************************************************************** +eth_pio_write: + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epw_001 + + inc ecx + and ecx, 0xFFFFFFFE + +epw_001: + mov al, D8390_COMMAND_RD2_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov al, D8390_ISR_RDC + mov dx, [eth_nic_base] + add dx, D8390_P0_ISR + out dx, al + + + mov al, cl + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR0 + out dx, al + + mov al, ch + mov dx, [eth_nic_base] + add dx, D8390_P0_RBCR1 + out dx, al + + mov al, bl + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR0 + out dx, al + + mov al, bh + mov dx, [eth_nic_base] + add dx, D8390_P0_RSAR1 + out dx, al + + mov al, D8390_COMMAND_RD1_STA + mov dx, [eth_nic_base] + add dx, D8390_P0_COMMAND + out dx, al + + mov dx, [eth_asic_base] + add dx, ASIC_PIO + + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, 0 + je epw_003 + + shr ecx, 1 + +epw_002: + ; 2 bytes at a time + mov ax, [esi] + add esi, 2 + out dx, ax + + loop epw_002 + jmp epw_004 + +epw_003: + ; 1 byte at a time + mov al, [esi] + inc esi + out dx, al + loop epw_003 + +epw_004: + mov dx, [eth_nic_base] + add dx, D8390_P0_ISR + +epw_005: + in al, dx + and al, D8390_ISR_RDC + cmp al, D8390_ISR_RDC + jne epw_005 + + ret + + + +;*************************************************************************** +; Function +; rtl8029_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; No inputs +; All registers destroyed +; +;*************************************************************************** +rtl8029_reset: + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P0_DCR + mov al, [eth_flags] + and al, FLAG_16BIT + cmp al, FLAG_16BIT + jne nsr_001 + + mov al, 0x49 + jmp nsr_002 + +nsr_001: + mov al, 0x48 + +nsr_002: + out dx, al + + xor al, al + + mov dx, bx + add dx, D8390_P0_RBCR0 + out dx, al + + mov dx, bx + add dx, D8390_P0_RBCR1 + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, 0x20 + out dx, al + + mov dx, bx + add dx, D8390_P0_TCR + mov al, 2 + out dx, al + + mov dx, bx + add dx, D8390_P0_TPSR + mov al, [eth_tx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, [eth_rx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, [eth_memsize] + out dx, al + + mov dx, bx + add dx, D8390_P0_BOUND + mov al, [eth_memsize] + dec al + out dx, al + + mov dx, bx + add dx, D8390_P0_ISR + mov al, 0xff + out dx, al + + mov dx, bx + add dx, D8390_P0_IMR + xor al, al + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS1_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P1_PAR0 + mov esi, node_addr + mov ecx, ETH_ALEN + +nsr_003: + mov al, [esi] + out dx, al + + inc esi + inc dx + loop nsr_003 + + mov dx, bx + add dx, D8390_P1_MAR0 + mov ecx, ETH_ALEN + + mov al, 0xff + +nsr_004: + out dx, al + inc dx + loop nsr_004 + + mov dx, bx + add dx, D8390_P1_CURR + mov al, [eth_rx_start] + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STA + out dx, al + + mov dx, bx + add dx, D8390_P0_ISR + mov al, 0xff + out dx, al + + mov dx, bx + add dx, D8390_P0_TCR + mov al, 0 + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, 4 + out dx, al + + ret + + + +;*************************************************************************** +; Function +; rtl8029_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; +;*************************************************************************** +rtl8029_probe: + mov eax, [io_addr] + mov [eth_nic_base], ax ; The IO address space is 16 bit only + + mov al, VENDOR_NONE + mov [eth_vendor], al + + mov al, [eth_vendor] + cmp al, VENDOR_NONE + + jne ep_check_have_vendor + xor eax, eax + mov [eth_bmem], eax + + mov al, FLAG_PIO + mov [eth_flags], al + + mov ax, [eth_nic_base] + add ax, NE_ASIC_OFFSET + mov [eth_asic_base], ax + + mov al, MEM_16384 + mov [eth_memsize], al + + mov al, 32 + mov [eth_tx_start], al + + add al, D8390_TXBUF_SIZE + mov [eth_rx_start], al + + mov dx, [eth_asic_base] + add dx, NE_RESET + + in al, dx + out dx, al + + in al, 0x84 + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_RD2_STP + out dx, al + + mov dx, bx + add dx, D8390_P0_RCR + mov al, D8390_RCR_MON + out dx, al + + mov dx, bx + add dx, D8390_P0_DCR + mov al, D8390_DCR_FT1_LS + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, MEM_8192 + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, MEM_16384 + out dx, al + + mov esi, test_data + mov ebx, 8192 + mov ecx, 14 + call eth_pio_write + + mov ebx, 8192 + mov ecx, 14 + mov edi, test_buffer + call eth_pio_read + + mov esi, test_buffer + mov edi, test_data + mov ecx, 13 + cld + rep cmpsb + + je ep_set_vendor + + mov al, [eth_flags] + or al, FLAG_16BIT + mov [eth_flags], al + + mov al, MEM_32768 + mov [eth_memsize], al + + mov al, 64 + mov [eth_tx_start], al + + add al, D8390_TXBUF_SIZE + mov [eth_rx_start], al + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_DCR + mov al, D8390_DCR_WTS_FT1_LS + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTART + mov al, MEM_16384 + out dx, al + + mov dx, bx + add dx, D8390_P0_PSTOP + mov al, MEM_32768 + out dx, al + + mov esi, test_data + mov ebx, 16384 + mov ecx, 14 + call eth_pio_write + + mov ebx, 16384 + mov ecx, 14 + mov edi, test_buffer + call eth_pio_read + + mov esi, test_buffer + mov edi, test_data + mov ecx, 13 + cld + rep cmpsb + +ep_set_vendor: + ; this bit is odd - probably left over from my hacking + mov ax, [eth_nic_base] + cmp ax, 0 + je rtl8029_exit + cmp ax, ISA_MAX_ADDR + jbe ep_001 + mov al, [eth_flags] + or al, FLAG_16BIT + mov [eth_flags], al + +ep_001: + mov al, VENDOR_NOVELL + mov [eth_vendor], al + + mov ebx, 0 + mov ecx, 16 + mov edi, romdata + call eth_pio_read + + + mov ecx, ETH_ALEN + mov esi, romdata + mov edi, node_addr + + mov bl, [eth_flags] + and bl, FLAG_16BIT + +ep_002: + mov al, [esi] + mov [edi], al + + inc edi + inc esi + cmp bl, FLAG_16BIT + jne ep_003 + + inc esi + +ep_003: + loop ep_002 + +ep_check_have_vendor: + mov al, [eth_vendor] + cmp al, VENDOR_NONE + je rtl8029_exit + + cmp al, VENDOR_3COM + je ep_reset_card + + mov eax, [eth_bmem] + mov [eth_rmem], eax + +ep_reset_card: + ; Reset the card + call rtl8029_reset + + ; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + +rtl8029_exit: + ret + + + +;*************************************************************************** +; Function +; rtl8029_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; +;*************************************************************************** +rtl8029_poll: + mov eax, Ether_buffer + mov [eth_rx_data_ptr], eax + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_RSR + in al, dx + + and al, D8390_RSTAT_PRX + cmp al, D8390_RSTAT_PRX + jne nsp_exit + + mov dx, bx + add dx, D8390_P0_BOUND + in al, dx + inc al + + cmp al, [eth_memsize] + jb nsp_001 + + mov al, [eth_rx_start] + +nsp_001: + mov ch, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS1 + out dx, al + + mov dx, bx + add dx, D8390_P1_CURR + in al, dx ; get current page + mov cl, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0 + out dx, al + + cmp cl, [eth_memsize] + jb nsp_002 + + mov cl, [eth_rx_start] + +nsp_002: + cmp cl, ch + je nsp_exit + + xor ax, ax + mov ah, ch + + mov [pktoff], ax + + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_003 + + movzx ebx, word [pktoff] + mov edi, pkthdr + mov ecx, 4 + call eth_pio_read + jmp nsp_004 + +nsp_003: + mov edi, [eth_rmem] + movzx eax, word [pktoff] + add edi, eax + mov eax, [edi] + mov [pkthdr], eax + +nsp_004: + mov ax, [pktoff] + add ax, 4 + mov [pktoff], ax + + mov ax, [pkthdr + 2] + sub ax, 4 + + mov [eth_tmp_len], ax + + cmp ax, ETH_ZLEN + jb nsp_exit + + cmp ax, ETH_FRAME_LEN + ja nsp_exit + + mov al, [pkthdr] + and al, D8390_RSTAT_PRX + cmp al, D8390_RSTAT_PRX + jne nsp_exit + + ; Right, we can now get the data + + mov ax, [eth_tmp_len] + mov [eth_rx_data_len], ax + + xor ebx, ebx + mov bh, [eth_memsize] + sub bx, [pktoff] + + cmp [eth_tmp_len], bx + jbe nsp_005 + + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_006 + + push ebx + mov ecx, ebx + xor ebx, ebx + mov bx, [pktoff] + mov edi, [eth_rx_data_ptr] + call eth_pio_read + pop ebx + jmp nsp_007 + +nsp_006: + ; Not implemented, as we are using PIO mode on this card + +nsp_007: + xor ax, ax + mov ah, [eth_rx_start] + mov [pktoff], ax + + mov eax, [eth_rx_data_ptr] + add eax, ebx + mov [eth_rx_data_ptr], eax + + mov ax, [eth_tmp_len] + sub ax, bx + mov [eth_tmp_len], ax + +nsp_005: + mov al, [eth_flags] + and al, FLAG_PIO + cmp al, FLAG_PIO + jne nsp_008 + + xor ebx, ebx + mov bx, [pktoff] + xor ecx, ecx + mov cx, [eth_tmp_len] + mov edi, [eth_rx_data_ptr] + call eth_pio_read + jmp nsp_009 + +nsp_008: + ; Not implemented, as we are using PIO mode on this card + +nsp_009: + mov al, [pkthdr+1] + cmp al, [eth_rx_start] + jne nsp_010 + + mov al, [eth_memsize] + +nsp_010: + mov dx, [eth_nic_base] + add dx, D8390_P0_BOUND + dec al + out dx, al + +nsp_exit: + ret + + + +;*************************************************************************** +; Function +; rtl8029_transmit +; +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +;*************************************************************************** +rtl8029_transmit: + mov [eth_type], bx + + pusha + + mov esi, edi + xor bx, bx + mov bh, [eth_tx_start] + mov ecx, ETH_ALEN + call eth_pio_write + + mov esi, node_addr + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_ALEN + mov ecx, ETH_ALEN + call eth_pio_write + + mov esi, eth_type + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_ALEN + add bx, ETH_ALEN + mov ecx, 2 + call eth_pio_write + + popa + + xor bx, bx + mov bh, [eth_tx_start] + add bx, ETH_HLEN + push ecx + call eth_pio_write + pop ecx + + add ecx, ETH_HLEN + cmp ecx, ETH_ZLEN + jae nst_001 + + mov ecx, ETH_ZLEN + +nst_001: + push ecx + + mov bx, [eth_nic_base] + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_RD2_STA + out dx, al + + mov dx, bx + add dx, D8390_P0_TPSR + mov al, [eth_tx_start] + out dx, al + + pop ecx + + mov dx, bx + add dx, D8390_P0_TBCR0 + mov al, cl + out dx, al + + mov dx, bx + add dx, D8390_P0_TBCR1 + mov al, ch + out dx, al + + mov dx, bx + add dx, D8390_P0_COMMAND + mov al, D8390_COMMAND_PS0_TXP_RD2_STA + out dx, al + + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8139.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8139.inc new file mode 100644 index 0000000000..d4e50b4225 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/rtl8139.inc @@ -0,0 +1,595 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; RTL8139.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.2 11 August 2003 ;; +;; ;; +;; Driver for chips of RealTek 8139 family ;; +;; References: ;; +;; www.realtek.com.hw - data sheets ;; +;; rtl8139.c - linux driver ;; +;; 8139too.c - linux driver ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2003 Endre Kozma, ;; +;; endre.kozma@axelero.hu ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ETH_ALEN equ 6 + ETH_HLEN equ (2 * ETH_ALEN + 2) + ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for + ; mininmum 64bytes frame length + + PCI_REG_COMMAND equ 0x04 ; command register + PCI_BIT_PIO equ 0 ; bit0: io space control + PCI_BIT_MMIO equ 1 ; bit1: memory space control + PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master + + RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 + RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 + RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor + RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor + RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address + RTL8139_REG_COMMAND equ 0x37 ; command register + RTL8139_REG_CAPR equ 0x38 ; current address of packet read + RTL8139_REG_IMR equ 0x3c ; interrupt mask register + RTL8139_REG_ISR equ 0x3e ; interrupt status register + RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register + RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 + RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 + RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 + RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 + RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 + RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 + RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 + RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 + RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 + RTL8139_REG_MPC equ 0x4c ; missed packet counter + RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register + RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 + RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 + RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register + RTL8139_REG_BMCR equ 0x62 ; basic mode control register + RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register + +; 5.1 packet header + RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes + RTL8139_BIT_LONG equ 3 ; total packet length > 4k + RTL8139_BIT_CRC equ 2 ; crc error occured + RTL8139_BIT_FAE equ 1 ; frame alignment error occured + RTL8139_BIT_ROK equ 0 ; received packet is ok +; 5.4 command register + RTL8139_BIT_RST equ 4 ; reset bit + RTL8139_BIT_RE equ 3 ; receiver enabled + RTL8139_BIT_TE equ 2 ; transmitter enabled + RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored +; 5.6 interrupt status register + RTL8139_BIT_ISR_TOK equ 2 ; transmit ok + RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt + RTL8139_BIT_ISR_ROK equ 0 ; receive ok +; 5.7 transmit configyration register + RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst + RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) +; 5.8 receive configuration register + RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold + RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator + RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst + RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping + RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 + RTL8139_BIT_AER equ 5 ; accept error packets + RTL8139_BIT_AR equ 4 ; accept runt packets + RTL8139_BIT_AB equ 3 ; accept broadcast packets + RTL8139_BIT_AM equ 2 ; accept multicast packets + RTL8139_BIT_APM equ 1 ; accept physical match packets + RTL8139_BIT_AAP equ 0 ; accept all packets +; 5.9 93C46/93C56 command register + RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 + RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 + RTL8139_BIT_93C46_EECS equ 3 ; chip select + RTL8139_BIT_93C46_EESK equ 2 ; serial data clock + RTL8139_BIT_93C46_EEDI equ 1 ; serial data input + RTL8139_BIT_93C46_EEDO equ 0 ; serial data output +; 5.11 configuration register 1 + RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 + RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips + RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips + RTL8139_BIT_PMEn equ 0 ; power management enabled +; 5.14 configuration register 4 + RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 +; 6.2 transmit status register + RTL8139_BIT_ERTXTH equ 16 ; early TX threshold + RTL8139_BIT_TOK equ 15 ; transmit ok + RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed +; 6.18 basic mode control register + RTL8139_BIT_ANE equ 12 ; auto negotiation enable +; 6.20 auto negotiation advertisement register + RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex + RTL8139_BIT_TX equ 7 ; 100base-T + RTL8139_BIT_10FD equ 6 ; 10base-T full duplex + RTL8139_BIT_10 equ 5 ; 10base-T + RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 +; RX/TX buffer size + RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k + RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) + MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC + RTL8139_NUM_TX_DESC equ 4 + RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) + RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) + RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==2048 + RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 + RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==unlimited + RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 + ; 4==256 5==512 6==1024 7==no threshold + RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ + or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ + or (1 shl RTL8139_BIT_NOWRAP) \ + or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ + or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ + or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ + or (1 shl RTL8139_BIT_AM)) + RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout + + EE_93C46_REG_ETH_ID equ 7 ; MAC offset + EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address + EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address + EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address + EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress + + VER_RTL8139 equ 1100000b + VER_RTL8139A equ 1110000b +; VER_RTL8139AG equ 1110100b + VER_RTL8139B equ 1111000b + VER_RTL8130 equ VER_RTL8139B + VER_RTL8139C equ 1110100b + VER_RTL8100 equ 1111010b + VER_RTL8100B equ 1110101b + VER_RTL8139D equ VER_RTL8100B + VER_RTL8139CP equ 1110110b + VER_RTL8101 equ 1110111b + + IDX_RTL8139 equ 0 + IDX_RTL8139A equ 1 + IDX_RTL8139B equ 2 + IDX_RTL8139C equ 3 + IDX_RTL8100 equ 4 + IDX_RTL8139D equ 5 + IDX_RTL8139D equ 6 + IDX_RTL8101 equ 7 + + +; These two must be 4 byte aligned ( which they are ) +rtl8139_rx_buff equ eth_data_start +rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) + +uglobal + align 4 +rtl8139_rx_buff_offset: dd 0 +curr_tx_desc: dd 0 +endg + +iglobal +hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C + db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 +HW_VER_ARRAY_SIZE = $-hw_ver_array +endg + +uglobal +hw_ver_id: db 0 +endg + +;*************************************************************************** +; Function +; rtl8139_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +rtl8139_probe: +; enable the device + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + call pci_read_reg + mov cx, ax + or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) + and cl, not (1 shl PCI_BIT_MMIO) + mov al, 2 + mov ah, [pci_bus] + mov bh, [pci_dev] + mov bl, PCI_REG_COMMAND + call pci_write_reg +; get chip version + mov edx, [io_addr] + add edx, RTL8139_REG_TXCONFIG_2 + in ax, dx + shr ah, 2 + shr ax, 6 + and al, 01111111b + mov ecx, HW_VER_ARRAY_SIZE-1 +.chip_ver_loop: + cmp al, [hw_ver_array+ecx] + je .chip_ver_found + dec ecx + jns .chip_ver_loop + xor cl, cl ; default RTL8139 +.chip_ver_found: + mov [hw_ver_id], cl +; wake up the chip + mov edx, [io_addr] + add edx, RTL8139_REG_HLTCLK + mov al, 'R' ; run the clock + out dx, al +; unlock config and BMCR registers + add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) + out dx, al +; enable power management + add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR + in al, dx + cmp byte [hw_ver_id], IDX_RTL8139B + jl .old_chip +; set LWAKE pin to active high (default value). +; it is for Wake-On-LAN functionality of some motherboards. +; this signal is used to inform the motherboard to execute a wake-up process. +; only at newer chips. + or al, (1 shl RTL8139_BIT_PMEn) + and al, not (1 shl RTL8139_BIT_LWACT) + out dx, al + add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 + in al, dx + and al, not (1 shl RTL8139_BIT_LWPTN) + out dx, al + jmp .finish_wake_up +.old_chip: +; wake up older chips + and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) + out dx, al +.finish_wake_up: +; lock config and BMCR registers + xor al, al + mov edx, [io_addr] + add edx, RTL8139_REG_9346CR + out dx, al +;*************************************************************************** +; Function +; rt8139_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +rtl8139_reset: + mov edx, [io_addr] + add edx, RTL8139_REG_COMMAND + mov al, 1 shl RTL8139_BIT_RST + out dx, al + mov cx, 1000 ; wait no longer for the reset +.wait_for_reset: + in al, dx + test al, 1 shl RTL8139_BIT_RST + jz .reset_completed ; RST remains 1 during reset + dec cx + jns .wait_for_reset +.reset_completed: +; get MAC (hardware address) + mov ecx, 2 +.mac_read_loop: + lea eax, [EE_93C46_REG_ETH_ID+ecx] + push ecx + call rtl8139_read_eeprom + pop ecx + mov [node_addr+ecx*2], ax + dec ecx + jns .mac_read_loop +; unlock config and BMCR registers + mov edx, [io_addr] + add edx, RTL8139_REG_9346CR + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) + out dx, al +; initialize multicast registers (no filtering) + mov eax, 0xffffffff + add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR + out dx, eax + add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 + out dx, eax +; enable Rx/Tx + mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) + add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 + out dx, al +; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold +; accept broadcast packets, accept physical match packets + mov ax, RTL8139_RX_CONFIG + add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND + out dx, ax +; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 + mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ + or (RTL8139_TXRR shl RTL8139_BIT_TXRR) + add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG + out dx, ax +; enable auto negotiation + add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG + in ax, dx + or ax, (1 shl RTL8139_BIT_ANE) + out dx, ax +; set auto negotiation advertisement + add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR + in ax, dx + or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ + or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ + or (1 shl RTL8139_BIT_TXFD) + out dx, ax +; lock config and BMCR registers + xor eax, eax + add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR + out dx, al +; init RX/TX pointers + mov [rtl8139_rx_buff_offset], eax + mov [curr_tx_desc], eax +; clear missing packet counter + add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR + out dx, eax +; disable all interrupts + add edx, RTL8139_REG_IMR - RTL8139_REG_MPC + out dx, ax +; set RxBuffer address, init RX buffer offset, init TX ring + mov eax, rtl8139_rx_buff + add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR + out dx, eax +; Indicate that we have successfully reset the card + mov eax, [pci_data] + mov [eth_status], eax + ret + +;*************************************************************************** +; Function +; rtl8139_read_eeprom +; Description +; reads eeprom type 93c46 and 93c56 +; Parameters +; al - word to be read (6bit in case of 93c46 and 8bit otherwise) +; Return value +; ax - word read in +; Destroyed register(s) +; eax, cx, ebx, edx +; +;*************************************************************************** +rtl8139_read_eeprom: + movzx ebx, al + mov edx, [io_addr] + add edx, RTL8139_REG_RXCONFIG + in al, dx + test al, (1 shl RTL8139_BIT_9356SEL) + jz .type_93c46 +; and bl, 01111111b ; don't care first bit + or bx, EE_93C56_READ_CMD ; it contains start bit + mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter + jmp .read_eeprom +.type_93c46: + and bl, 00111111b + or bx, EE_93C46_READ_CMD ; it contains start bit + mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter +.read_eeprom: + add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 +; mov al, (1 shl RTL8139_BIT_93C46_EEM1) +; out dx, al + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom + out dx, al +.cmd_loop: + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) + bt bx, cx + jnc .zero_bit + or al, (1 shl RTL8139_BIT_93C46_EEDI) +.zero_bit: + out dx, al +; push eax +; in eax, dx ; eeprom delay +; pop eax + or al, (1 shl RTL8139_BIT_93C46_EESK) + out dx, al +; in eax, dx ; eeprom delay + dec cx + jns .cmd_loop +; in eax, dx ; eeprom delay + mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) + out dx, al + mov cl, 0xf +.read_loop: + shl ebx, 1 + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) \ + or (1 shl RTL8139_BIT_93C46_EESK) + out dx, al +; in eax, dx ; eeprom delay + in al, dx + and al, (1 shl RTL8139_BIT_93C46_EEDO) + jz .dont_set + inc ebx +.dont_set: + mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ + or (1 shl RTL8139_BIT_93C46_EECS) + out dx, al +; in eax, dx ; eeprom delay + dec cl + jns .read_loop + xor al, al + out dx, al + mov ax, bx + ret + +;*************************************************************************** +; Function +; rtl8139_transmit +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; Destroyed registers +; eax, edx, esi, edi +; ToDo +; for waiting of timeout the rtl8139 internal timer +; should be used +; +;*************************************************************************** +rtl8139_transmit: + cmp ecx, MAX_ETH_FRAME_SIZE + jg .finish ; packet is too long + push ecx +; check descriptor + mov ecx, [curr_tx_desc] + mov edx, [io_addr] + lea edx, [edx+ecx*4+RTL8139_REG_TSD0] + push edx ebx + in ax, dx + and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + jz .send_packet + test ax, 0x1fff ; or no size given + jz .send_packet +; wait for timeout + mov ebx, RTL8139_TX_TIMEOUT + mov eax, 0x5 ; delay x/100 secs + int 0x40 + in ax, dx + and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) + jz .send_packet +; chip hung, reset it + call rtl8139_reset +; reset the card +.send_packet: +; calculate tx_buffer address + pop ebx + push esi + mov eax, MAX_ETH_FRAME_SIZE + mul dword [curr_tx_desc] + mov esi, edi + lea edi, [rtl8139_tx_buff+eax] + mov eax, edi + cld +; copy destination address + movsd + movsw +; copy source address + mov esi, node_addr + movsd + movsw +; copy packet type + mov [edi], bx + add edi, 2 +; copy the packet data + pop esi edx ecx + push ecx + shr ecx, 2 + rep movsd + pop ecx + push ecx + and ecx, 3 + rep movsb +; set address + add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 + out dx, eax +; set size and early threshold + pop eax ; pick up the size + add eax, ETH_HLEN + cmp eax, ETH_ZLEN + jnc .no_pad + mov eax, ETH_ZLEN +.no_pad: + or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) + add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 + out dx, eax +; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... + inc dword [curr_tx_desc] + and dword [curr_tx_desc], 3 +.finish: + ret + +;*************************************************************************** +; Function +; rtl8139_poll +; +; Description +; Polls the ethernet card for a received packet +; Received data, if any, ends up in Ether_buffer +; Destroyed register(s) +; eax, edx, ecx +; +;*************************************************************************** +rtl8139_poll: + mov word [eth_rx_data_len], 0 + mov edx, [io_addr] + add edx, RTL8139_REG_COMMAND + in al, dx + test al, (1 shl RTL8139_BIT_BUFE) + jnz .finish +; new packet received copy it from rx_buffer into Ether_buffer + mov eax, rtl8139_rx_buff + add eax, [rtl8139_rx_buff_offset] +; check if packet is ok + test byte [eax], (1 shl RTL8139_BIT_ROK) + jz .reset_rx +; packet is ok copy it into the Ether_buffer + movzx ecx, word [eax+2] ; packet length + sub ecx, 4 ; don't copy CRC + mov word [eth_rx_data_len], cx + push ecx + shr ecx, 2 ; first copy dword-wise + lea esi, [eax+4] ; don't copy the packet header + mov edi, Ether_buffer + cld + rep movsd ; copy the dwords + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes +; update rtl8139_rx_buff_offset + movzx eax, word [eax+2] ; packet length + add eax, [rtl8139_rx_buff_offset] + add eax, 4+3 ; packet header is 4 bytes long + dword alignment + and eax, not 3 ; dword alignment + cmp eax, RTL8139_RX_BUFFER_SIZE + jl .no_wrap + sub eax, RTL8139_RX_BUFFER_SIZE +.no_wrap: + mov [rtl8139_rx_buff_offset], eax +; update CAPR register + sub eax, 0x10 ; value 0x10 is a constant for CAPR + add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND + out dx, ax +.finish: +; clear active interrupt sources + mov edx, [io_addr] + add edx, RTL8139_REG_ISR + in ax, dx + out dx, ax + ret +.reset_rx: + in al, dx ; read command register + push eax + and al, not (1 shl RTL8139_BIT_RE) + out dx, al + pop eax + out dx, al + add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND + mov ax, RTL8139_RX_CONFIG + out dx, ax + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/eth_drv/sis900.inc b/kernel/tags/kolibri0.6.0.0/network/eth_drv/sis900.inc new file mode 100644 index 0000000000..af54313b9e --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/eth_drv/sis900.inc @@ -0,0 +1,1148 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SIS900.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.4 26 April 2004 ;; +;; ;; +;; This driver is based on the SIS900 driver from ;; +;; the etherboot 5.0.6 project. The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; remaining parts Copyright 2004 Jason Delozier, ;; +;; cordata51@hotmail.com ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; Updates: ;; +;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;******************************************************************** +; Interface +; SIS900_reset +; SIS900_probe +; SIS900_poll +; SIS900_transmit +; +;******************************************************************** +;******************************************************************** +; Comments: +; Known to work with the following SIS900 ethernet cards: +; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 +; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 +; +; If your card is not listed, try it and let me know if it +; functions properly and it will be aded to the list. If not +; we may be able to add support for it. +; +; How To Use: +; Add the following lines to Ethernet.inc in their appropriate locations +; +; include "Sis900.INC" +; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, +; SIS900_transmit +; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, +; SIS900_transmit ;untested +; +; ToDo: +; - Enable MII interface for reading speed +; and duplex settings. +; +; - Update Poll routine to support packet fragmentation. +; +; - Add additional support for other sis900 based cards +; +;******************************************************************** + +; comment the next line out if you don't want debug info printed +; on the debug board. This option adds a lot of bytes to the driver +; so it's worth to comment it out. +; SIS900_DEBUG equ 1 + + +;* buffers and descriptors +cur_rx db 0 +NUM_RX_DESC equ 4 ;* Number of RX descriptors * +NUM_TX_DESC equ 1 ;* Number of TX descriptors * +RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer * +TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer * + +uglobal +align 4 +txd: times (3 * NUM_TX_DESC) dd 0 +rxd: times (3 * NUM_RX_DESC) dd 0 +endg + +txb equ eth_data_start +rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ) +SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address * +SIS900_ETH_HLEN equ 14 ;* Size of ethernet header * +SIS900_ETH_ZLEN equ 60 ;* Minimum packet length * +SIS900_DSIZE equ 0x00000fff +SIS900_CRC_SIZE equ 4 +SIS900_RFADDR_shift equ 16 +;SIS900 Symbolic offsets to registers. + SIS900_cr equ 0x0 ; Command Register + SIS900_cfg equ 0x4 ; Configuration Register + SIS900_mear equ 0x8 ; EEPROM Access Register + SIS900_ptscr equ 0xc ; PCI Test Control Register + SIS900_isr equ 0x10 ; Interrupt Status Register + SIS900_imr equ 0x14 ; Interrupt Mask Register + SIS900_ier equ 0x18 ; Interrupt Enable Register + SIS900_epar equ 0x18 ; Enhanced PHY Access Register + SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register + SIS900_txcfg equ 0x24 ; Transmit Configuration Register + SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register + SIS900_rxcfg equ 0x34 ; Receive Configuration Register + SIS900_flctrl equ 0x38 ; Flow Control Register + SIS900_rxlen equ 0x3c ; Receive Packet Length Register + SIS900_rfcr equ 0x48 ; Receive Filter Control Register + SIS900_rfdr equ 0x4C ; Receive Filter Data Register + SIS900_pmctrl equ 0xB0 ; Power Management Control Register + SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register +;SIS900 Command Register Bits + SIS900_RELOAD equ 0x00000400 + SIS900_ACCESSMODE equ 0x00000200 + SIS900_RESET equ 0x00000100 + SIS900_SWI equ 0x00000080 + SIS900_RxRESET equ 0x00000020 + SIS900_TxRESET equ 0x00000010 + SIS900_RxDIS equ 0x00000008 + SIS900_RxENA equ 0x00000004 + SIS900_TxDIS equ 0x00000002 + SIS900_TxENA equ 0x00000001 +;SIS900 Configuration Register Bits + SIS900_DESCRFMT equ 0x00000100 ; 7016 specific + SIS900_REQALG equ 0x00000080 + SIS900_SB equ 0x00000040 + SIS900_POW equ 0x00000020 + SIS900_EXD equ 0x00000010 + SIS900_PESEL equ 0x00000008 + SIS900_LPM equ 0x00000004 + SIS900_BEM equ 0x00000001 + SIS900_RND_CNT equ 0x00000400 + SIS900_FAIR_BACKOFF equ 0x00000200 + SIS900_EDB_MASTER_EN equ 0x00002000 +;SIS900 Eeprom Access Reigster Bits + SIS900_MDC equ 0x00000040 + SIS900_MDDIR equ 0x00000020 + SIS900_MDIO equ 0x00000010 ; 7016 specific + SIS900_EECS equ 0x00000008 + SIS900_EECLK equ 0x00000004 + SIS900_EEDO equ 0x00000002 + SIS900_EEDI equ 0x00000001 +;SIS900 TX Configuration Register Bits + SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding + SIS900_MLB equ 0x20000000 ;Mac Loopback Enable + SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup) + SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du +;SIS900 RX Configuration Register Bits + SIS900_AJAB equ 0x08000000 ; + SIS900_ATX equ 0x10000000 ;Accept Transmit Packets + SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes) + SIS900_AEP equ 0x80000000 ;accept error packets +;SIS900 Interrupt Reigster Bits + SIS900_WKEVT equ 0x10000000 + SIS900_TxPAUSEEND equ 0x08000000 + SIS900_TxPAUSE equ 0x04000000 + SIS900_TxRCMP equ 0x02000000 + SIS900_RxRCMP equ 0x01000000 + SIS900_DPERR equ 0x00800000 + SIS900_SSERR equ 0x00400000 + SIS900_RMABT equ 0x00200000 + SIS900_RTABT equ 0x00100000 + SIS900_RxSOVR equ 0x00010000 + SIS900_HIBERR equ 0x00008000 + SIS900_SWINT equ 0x00001000 + SIS900_MIBINT equ 0x00000800 + SIS900_TxURN equ 0x00000400 + SIS900_TxIDLE equ 0x00000200 + SIS900_TxERR equ 0x00000100 + SIS900_TxDESC equ 0x00000080 + SIS900_TxOK equ 0x00000040 + SIS900_RxORN equ 0x00000020 + SIS900_RxIDLE equ 0x00000010 + SIS900_RxEARLY equ 0x00000008 + SIS900_RxERR equ 0x00000004 + SIS900_RxDESC equ 0x00000002 + SIS900_RxOK equ 0x00000001 +;SIS900 Interrupt Enable Reigster Bits + SIS900_IE equ 0x00000001 +;SIS900 Revision ID + SIS900B_900_REV equ 0x03 + SIS630A_900_REV equ 0x80 + SIS630E_900_REV equ 0x81 + SIS630S_900_REV equ 0x82 + SIS630EA1_900_REV equ 0x83 + SIS630ET_900_REV equ 0x84 + SIS635A_900_REV equ 0x90 + SIS900_960_REV equ 0x91 +;SIS900 Receive Filter Control Register Bits + SIS900_RFEN equ 0x80000000 + SIS900_RFAAB equ 0x40000000 + SIS900_RFAAM equ 0x20000000 + SIS900_RFAAP equ 0x10000000 + SIS900_RFPromiscuous equ 0x70000000 +;SIS900 Reveive Filter Data Mask + SIS900_RFDAT equ 0x0000FFFF +;SIS900 Eeprom Address + SIS900_EEPROMSignature equ 0x00 + SIS900_EEPROMVendorID equ 0x02 + SIS900_EEPROMDeviceID equ 0x03 + SIS900_EEPROMMACAddr equ 0x08 + SIS900_EEPROMChecksum equ 0x0b +;The EEPROM commands include the alway-set leading bit. +;SIS900 Eeprom Command + SIS900_EEread equ 0x0180 + SIS900_EEwrite equ 0x0140 + SIS900_EEerase equ 0x01C0 + SIS900_EEwriteEnable equ 0x0130 + SIS900_EEwriteDisable equ 0x0100 + SIS900_EEeraseAll equ 0x0120 + SIS900_EEwriteAll equ 0x0110 + SIS900_EEaddrMask equ 0x013F + SIS900_EEcmdShift equ 16 +;For SiS962 or SiS963, request the eeprom software access + SIS900_EEREQ equ 0x00000400 + SIS900_EEDONE equ 0x00000200 + SIS900_EEGNT equ 0x00000100 +;General Varibles + SIS900_pci_revision: db 0 + SIS900_Status dd 0x03000000 +sis900_specific_table: +; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0 +; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0 + dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN + dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0 + dd SIS900_960_REV,SIS960_get_mac_addr,0 + dd SIS900B_900_REV,SIS900_get_mac_addr,0 + dd 0,0,0,0 ; end of list +sis900_get_mac_func: dd 0 +sis900_special_func: dd 0 +sis900_table_entries: db 8 + +;*************************************************************************** +; Function +; SIS900_probe +; Description +; Searches for an ethernet card, enables it and clears the rx buffer +; If a card was found, it enables the ethernet -> TCPIP link +;not done - still need to probe mii transcievers +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0 +end if +SIS900_probe: +;******Wake Up Chip******* + mov al, 4 + mov bh, [pci_dev] + mov ecx, 0 + mov ah, [pci_bus] + mov bl, 0x40 + call pci_write_reg +;*******Set some PCI Settings********* + call SIS900_adjust_pci_device +;*****Get Card Revision****** + mov al, 1 ;one byte to read + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x08 ;Revision Register + call pci_read_reg + mov [SIS900_pci_revision], al ;save the revision for later use +;****** Look up through the sis900_specific_table + mov esi,sis900_specific_table +.probe_loop: + cmp dword [esi],0 ; Check if we reached end of the list + je .probe_loop_failed + cmp al,[esi] ; Check if revision is OK + je .probe_loop_ok + add esi,12 ; Advance to next entry + jmp .probe_loop +.probe_loop_failed: + jmp SIS900_Probe_Unsupported +;*********Find Get Mac Function********* +.probe_loop_ok: + mov eax,[esi+4] ; Get pointer to "get MAC" function + mov [sis900_get_mac_func],eax + mov eax,[esi+8] ; Get pointer to special initialization fn + mov [sis900_special_func],eax +;******** Get MAC ******** + call dword [sis900_get_mac_func] +;******** Call special initialization fn if requested ******** + cmp dword [sis900_special_func],0 + je .no_special_init + call dword [sis900_special_func] +.no_special_init: +;******** Set table entries ******** + mov al,[SIS900_pci_revision] + cmp al,SIS635A_900_REV + jae .ent16 + cmp al,SIS900B_900_REV + je .ent16 + jmp .ent8 +.ent16: + mov byte [sis900_table_entries],16 +.ent8: +;*******Probe for mii transceiver******* +;TODO!!********************* +;*******Initialize Device******* + call sis900_init + ret + +SIS900_Probe_Unsupported: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Str_Unsupported + call sys_msg_board_str +end if + ret +;*************************************************************************** +; Function: sis900_init +; +; Description: resets the ethernet controller chip and various +; data structures required for sending and receiving packets. +; +; Arguments: +; +; returns: none +;not done +;*************************************************************************** +sis900_init: + call SIS900_reset ;Done + call SIS900_init_rxfilter ;Done + call SIS900_init_txd ;Done + call SIS900_init_rxd ;Done + call SIS900_set_rx_mode ;done + call SIS900_set_tx_mode + ;call SIS900_check_mode + ret + +;*************************************************************************** +; Function +; SIS900_reset +; Description +; disables interrupts and soft resets the controller chip +; +;done+ +;*************************************************************************** +if defined SIS900_DEBUG + SIS900_Debug_Reset_Failed db 'Reset Failed ',0 +end if +SIS900_reset: + ;******Disable Interrupts and reset Receive Filter******* + mov ebp, [io_addr] ; base address + xor eax, eax ; 0 to initialize + lea edx,[ebp+SIS900_ier] + out dx, eax ; Write 0 to location + lea edx,[ebp+SIS900_imr] + out dx, eax ; Write 0 to location + lea edx,[ebp+SIS900_rfcr] + out dx, eax ; Write 0 to location + ;*******Reset Card*********************************************** + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_RESET ; set flags + or eax, SIS900_RxRESET ; + or eax, SIS900_TxRESET ; + out dx, eax ; Write new Command Register + ;*******Wait Loop************************************************ + lea edx,[ebp+SIS900_isr] + mov ecx, [SIS900_Status] ; Status we would like to see from card + mov ebx, 2001 ; only loop 1000 times +SIS900_Wait: + dec ebx ; 1 less loop + jz SIS900_DoneWait_e ; 1000 times yet? + in eax, dx ; move interrup status to eax + and eax, ecx + xor ecx, eax + jz SIS900_DoneWait + jmp SIS900_Wait +SIS900_DoneWait_e: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Reset_Failed + call sys_msg_board_str +end if +SIS900_DoneWait: + ;*******Set Configuration Register depending on Card Revision******** + lea edx,[ebp+SIS900_cfg] + mov eax, SIS900_PESEL ; Configuration Register Bit + mov bl, [SIS900_pci_revision] ; card revision + mov cl, SIS635A_900_REV ; Check card revision + cmp bl, cl + je SIS900_RevMatch + mov cl, SIS900B_900_REV ; Check card revision + cmp bl, cl + je SIS900_RevMatch + out dx, eax ; no revision match + jmp SIS900_Reset_Complete +SIS900_RevMatch: ; Revision match + or eax, SIS900_RND_CNT ; Configuration Register Bit + out dx, eax +SIS900_Reset_Complete: + mov eax, [pci_data] + mov [eth_status], eax + ret + +;*************************************************************************** +; Function: sis_init_rxfilter +; +; Description: sets receive filter address to our MAC address +; +; Arguments: +; +; returns: +;done+ +;*************************************************************************** +SIS900_init_rxfilter: + ;****Get Receive Filter Control Register ******** + mov ebp, [io_addr] ; base address + lea edx,[ebp+SIS900_rfcr] + in eax, dx ; get register + push eax + ;****disable packet filtering before setting filter******* + mov eax, SIS900_RFEN ;move receive filter enable flag + not eax ;1s complement + pop ebx ;and with our saved register + and eax, ebx ;disable receiver + push ebx ;save filter for another use + out dx, eax ;set receive disabled + ;********load MAC addr to filter data register********* + xor ecx, ecx +SIS900_RXINT_Mac_Write: + ;high word of eax tells card which mac byte to write + mov eax, ecx + lea edx,[ebp+SIS900_rfcr] + shl eax, 16 ; + out dx, eax ; + lea edx,[ebp+SIS900_rfdr] + mov ax, word [node_addr+ecx*2] ; Get Mac ID word + out dx, ax ; Send Mac ID + inc cl ; send next word + cmp cl, 3 ; more to send? + jne SIS900_RXINT_Mac_Write + ;********enable packet filitering ***** + pop eax ;old register value + lea edx,[ebp+SIS900_rfcr] + or eax, SIS900_RFEN ;enable filtering + out dx, eax ;set register + ret + +;*************************************************************************** +;* +;* Function: sis_init_txd +;* +;* Description: initializes the Tx descriptor +;* +;* Arguments: +;* +;* returns: +;*done +;*************************************************************************** +SIS900_init_txd: + ;********** initialize TX descriptor ************** + mov [txd], dword 0 ;put link to next descriptor in link field + mov [txd+4],dword 0 ;clear status field + mov [txd+8], dword txb ;save address to buffer ptr field + ;*************** load Transmit Descriptor Register *************** + mov dx, [io_addr] ; base address + add dx, SIS900_txdp ; TX Descriptor Pointer + mov eax, txd ; First Descriptor + out dx, eax ; move the pointer + ret + +;*************************************************************************** +;* Function: sis_init_rxd +;* +;* Description: initializes the Rx descriptor ring +;* +;* Arguments: +;* +;* Returns: +;*done +;*************************************************************************** +SIS900_init_rxd: + xor ecx,ecx + mov [cur_rx], cl ;Set cuurent rx discriptor to 0 + ;******** init RX descriptors ******** +SIS900_init_rxd_Loop: + mov eax, ecx ;current descriptor + imul eax, 12 ; + mov ebx, ecx ;determine next link descriptor + inc ebx ; + cmp ebx, NUM_RX_DESC ; + jne SIS900_init_rxd_Loop_0 ; + xor ebx, ebx ; +SIS900_init_rxd_Loop_0: ; + imul ebx, 12 ; + add ebx, rxd ; + mov [rxd+eax], ebx ;save link to next descriptor + mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size + mov ebx, ecx ;find where the buf is located + imul ebx,RX_BUFF_SZ ; + add ebx, rxb ; + mov [rxd+eax+8], ebx ;save buffer pointer + inc ecx ;next descriptor + cmp ecx, NUM_RX_DESC ; + jne SIS900_init_rxd_Loop ; + ;********* load Receive Descriptor Register with address of first + ; descriptor********* + mov dx, [io_addr] + add dx, SIS900_rxdp + mov eax, rxd + out dx, eax + ret + +;*************************************************************************** +;* Function: sis900_set_tx_mode +;* +;* Description: +;* sets the transmit mode to allow for full duplex +;* +;* +;* Arguments: +;* +;* Returns: +;* +;* Comments: +;* If you are having problems transmitting packet try changing the +;* Max DMA Burst, Possible settings are as follows: +;* 0x00000000 = 512 bytes +;* 0x00100000 = 4 bytes +;* 0x00200000 = 8 bytes +;* 0x00300000 = 16 bytes +;* 0x00400000 = 32 bytes +;* 0x00500000 = 64 bytes +;* 0x00600000 = 128 bytes +;* 0x00700000 = 256 bytes +;*************************************************************************** +SIS900_set_tx_mode: + mov ebp,[io_addr] + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_TxENA ;Enable Receive + out dx, eax + lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset + mov eax, SIS900_ATP ;allow automatic padding + or eax, SIS900_HBI ;allow heartbeat ignore + or eax, SIS900_CSI ;allow carrier sense ignore + or eax, 0x00600000 ;Max DMA Burst + or eax, 0x00000100 ;TX Fill Threshold + or eax, 0x00000020 ;TX Drain Threshold + out dx, eax + ret + +;*************************************************************************** +;* Function: sis900_set_rx_mode +;* +;* Description: +;* sets the receive mode to accept all broadcast packets and packets +;* with our MAC address, and reject all multicast packets. Also allows +;* full-duplex +;* +;* Arguments: +;* +;* Returns: +;* +;* Comments: +;* If you are having problems receiving packet try changing the +;* Max DMA Burst, Possible settings are as follows: +;* 0x00000000 = 512 bytes +;* 0x00100000 = 4 bytes +;* 0x00200000 = 8 bytes +;* 0x00300000 = 16 bytes +;* 0x00400000 = 32 bytes +;* 0x00500000 = 64 bytes +;* 0x00600000 = 128 bytes +;* 0x00700000 = 256 bytes +;*************************************************************************** +SIS900_mc_filter: times 16 dw 0 +SIS900_set_rx_mode: + mov ebp,[io_addr] + ;**************update Multicast Hash Table in Receive Filter + mov ebx, 0xffff + xor cl, cl +SIS900_set_rx_mode_Loop: + mov eax, ecx + shl eax, 1 + mov [SIS900_mc_filter+eax], ebx + lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset + mov eax, 4 ;determine table entry + add al, cl + shl eax, 16 + out dx, eax ;tell card which entry to modify + lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset + mov eax, ebx ;entry value + out dx, ax ;write value to table in card + inc cl ;next entry + cmp cl,[sis900_table_entries] ; + jl SIS900_set_rx_mode_Loop + ;*******Set Receive Filter Control Register************* + lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset + mov eax, SIS900_RFAAB ;accecpt all broadcast packets + or eax, SIS900_RFAAM ;accept all multicast packets + or eax, SIS900_RFAAP ;Accept all packets + or eax, SIS900_RFEN ;enable receiver filter + out dx, eax + ;******Enable Receiver************ + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_RxENA ;Enable Receive + out dx, eax + ;*********Set + lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset + mov eax, SIS900_ATX ;Accept Transmit Packets + ; (Req for full-duplex and PMD Loopback) + or eax, 0x00600000 ;Max DMA Burst + or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes + out dx, eax ; + ret + +;*************************************************************************** +; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model +; * @pci_dev: the sis900 pci device +; * @net_dev: the net device to get address for +; * +; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM +; * is shared by +; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first +; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access +; * by LAN, otherwise is not. After MAC address is read from EEPROM, send +; * EEDONE signal to refuse EEPROM access by LAN. +; * The EEPROM map of SiS962 or SiS963 is different to SiS900. +; * The signature field in SiS962 or SiS963 spec is meaningless. +; * MAC address is read into @net_dev->dev_addr. +; *done +;* +;* Return 0 is EAX = failure +;*Done+ +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0 +SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0 +SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0 +SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0 +end if +SIS960_get_mac_addr: + mov ebp,[io_addr] + ;**********Send Request for eeprom access********************* + lea edx,[ebp+SIS900_mear] ; Eeprom access register + mov eax, SIS900_EEREQ ; Request access to eeprom + out dx, eax ; Send request + xor ebx,ebx ; + ;******Loop 4000 times and if access not granted error out***** +SIS96X_Get_Mac_Wait: + in eax, dx ;get eeprom status + and eax, SIS900_EEGNT ;see if eeprom access granted flag is set + jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom + inc ebx ;else keep waiting + cmp ebx, 4000 ;have we tried 4000 times yet? + jl SIS96X_Get_Mac_Wait ;if not ask again + xor eax, eax ;return zero in eax indicating failure + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Failed + call sys_msg_board_str +end if + jmp SIS960_get_mac_addr_done + ;**********EEprom access granted, read MAC from card************* +SIS900_Got_EEP_Access: + ; zero based so 3-16 bit reads will take place + mov ecx, 2 +SIS96x_mac_read_loop: + mov eax, SIS900_EEPROMMACAddr ;Base Mac Address + add eax, ecx ;Current Mac Byte Offset + push ecx + call sis900_read_eeprom ;try to read 16 bits + pop ecx + mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible + dec ecx ;one less word to read + jns SIS96x_mac_read_loop ;if more read more + mov eax, 1 ;return non-zero indicating success + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address2 + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ;**********Tell EEPROM We are Done Accessing It********************* +SIS960_get_mac_addr_done: + lea edx,[ebp+SIS900_mear] ; Eeprom access register + mov eax, SIS900_EEDONE ;tell eeprom we are done + out dx,eax + ret +;*************************************************************************** +;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model +;* @pci_dev: the sis900 pci device +;* @net_dev: the net device to get address for +;* +;* Older SiS900 and friends, use EEPROM to store MAC address. +;* MAC address is read from read_eeprom() into @net_dev->dev_addr. +;* done/untested +;*************************************************************************** +SIS900_get_mac_addr: + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Start + call sys_msg_board_str +end if + ;******** check to see if we have sane EEPROM ******* + mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature + call sis900_read_eeprom ;try to read 16 bits + cmp ax, 0xffff + je SIS900_Bad_Eeprom + cmp ax, 0 + je SIS900_Bad_Eeprom + ;**************Read MacID************** + ; zero based so 3-16 bit reads will take place + mov ecx, 2 +SIS900_mac_read_loop: + mov eax, SIS900_EEPROMMACAddr ;Base Mac Address + add eax, ecx ;Current Mac Byte Offset + push ecx + call sis900_read_eeprom ;try to read 16 bits + pop ecx + mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage + dec ecx ;one less word to read + jns SIS900_mac_read_loop ;if more read more + mov eax, 1 ;return non-zero indicating success + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ret + +SIS900_Bad_Eeprom: + xor eax, eax + ;*******Debug ********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Failed + call sys_msg_board_str +end if + ret +;*************************************************************************** +;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635 +;* +;* +;*************************************************************************** +Get_Mac_SIS635_900_REV: +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Start + call sys_msg_board_str +end if + mov ebp,[io_addr] + lea edx,[ebp+SIS900_rfcr] + in eax,dx + mov edi,eax ; EDI=rfcrSave + lea edx,[ebp+SIS900_cr] + or eax,SIS900_RELOAD + out dx,eax + xor eax,eax + out dx,eax + ; Disable packet filtering before setting filter + lea edx,[ebp+SIS900_rfcr] + mov eax,edi + and edi,not SIS900_RFEN + out dx,eax + ; Load MAC to filter data register + xor ecx,ecx + mov esi,node_addr +.get_mac_loop: + lea edx,[ebp+SIS900_rfcr] + mov eax,ecx + shl eax,SIS900_RFADDR_shift + out dx,eax + lea edx,[ebp+SIS900_rfdr] + in eax,dx + mov [esi],ax + add esi,2 + inc ecx + cmp ecx,3 + jne .get_mac_loop + ; Enable packet filtering + ;lea edx,[ebp+SIS900_rfcr] + ;mov eax,edi + ;or eax,SIS900_RFEN + ;out dx, eax + ;*******Debug Print MAC ID to debug window********************** +if defined SIS900_DEBUG + mov esi,SIS900_Debug_Str_GetMac_Address + call sys_msg_board_str + mov edx, node_addr + call Create_Mac_String +end if + ret +;*************************************************************************** +;* Function: sis900_read_eeprom +;* +;* Description: reads and returns a given location from EEPROM +;* +;* Arguments: eax - location: requested EEPROM location +;* +;* Returns: eax : contents of requested EEPROM location +;* +; Read Serial EEPROM through EEPROM Access Register, Note that location is +; in word (16 bits) unit */ +;done+ +;*************************************************************************** +sis900_read_eeprom: + push esi + push edx + push ecx + push ebx + mov ebp,[io_addr] + mov ebx, eax ;location of Mac byte to read + or ebx, SIS900_EEread ; + lea edx,[ebp+SIS900_mear] ; Eeprom access register + xor eax, eax ; start send + out dx,eax + call SIS900_Eeprom_Delay_1 + mov eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + ;************ Shift the read command (9) bits out. ********* + mov cl, 8 ; +sis900_read_eeprom_Send: + mov eax, 1 + shl eax, cl + and eax, ebx + jz SIS900_Read_Eeprom_8 + mov eax, 9 + jmp SIS900_Read_Eeprom_9 +SIS900_Read_Eeprom_8: + mov eax, 8 +SIS900_Read_Eeprom_9: + out dx, eax + call SIS900_Eeprom_Delay_1 + or eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + cmp cl, 0 + je sis900_read_eeprom_Send_Done + dec cl + jmp sis900_read_eeprom_Send + ;********************* +sis900_read_eeprom_Send_Done: + mov eax, SIS900_EECS ; + out dx, eax + call SIS900_Eeprom_Delay_1 + ;********** Read 16-bits of data in *************** + mov cx, 16 ;16 bits to read +sis900_read_eeprom_Send2: + mov eax, SIS900_EECS + out dx, eax + call SIS900_Eeprom_Delay_1 + or eax, SIS900_EECLK + out dx, eax + call SIS900_Eeprom_Delay_1 + in eax, dx + shl ebx, 1 + and eax, SIS900_EEDO + jz SIS900_Read_Eeprom_0 + or ebx, 1 +SIS900_Read_Eeprom_0: + dec cx + jnz sis900_read_eeprom_Send2 + ;************** Terminate the EEPROM access. ************** + xor eax, eax + out dx, eax + call SIS900_Eeprom_Delay_1 + mov eax, SIS900_EECLK + out dx, eax + mov eax, ebx + and eax, 0x0000ffff ;return only 16 bits + pop ebx + pop ecx + pop edx + pop esi + ret +;*************************************************************************** +; Function +; SIS900_Eeprom_Delay_1 +; Description +; +; +; +; +;*************************************************************************** +SIS900_Eeprom_Delay_1: + push eax + in eax, dx + pop eax + ret + +;*************************************************************************** +; Function +; SIS900_poll +; Description +; polls card to see if there is a packet waiting +; +; Currently only supports one descriptor per packet, if packet is fragmented +; between multiple descriptors you will lose part of the packet +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0 +SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0 +SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0 +end if +SIS900_poll: + ;**************Get Status ************** + xor eax, eax ;get RX_Status + mov [eth_rx_data_len], ax + mov al, [cur_rx] ;find current discriptor + imul eax, 12 ; + mov ecx, [rxd+eax+4] ; get receive status + ;**************Check Status ************** + mov ebx, ecx ;move status + ;Check RX_Status to see if packet is waiting + and ebx, 0x80000000 + jnz SIS900_poll_IS_packet + ret + ;**********There is a packet waiting check it for errors************** +SIS900_poll_IS_packet: + mov ebx, ecx ;move status + and ebx, 0x67C0000 ;see if there are any errors + jnz SIS900_Poll_Error_Status + ;**************Check size of packet************* + and ecx, SIS900_DSIZE ;get packet size minus CRC + cmp cx, SIS900_CRC_SIZE + ;make sure packet contains data + jle SIS900_Poll_Error_Size + ;*******Copy Good Packet to receive buffer****** + sub cx, SIS900_CRC_SIZE ;dont want crc + mov word [eth_rx_data_len], cx ;save size of packet + ;**********Continue copying packet**************** + push ecx + ; first copy dword-wise, divide size by 4 + shr ecx, 2 + mov esi, [rxd+eax+8] ; set source + mov edi, Ether_buffer ; set destination + cld ; clear direction + rep movsd ; copy the dwords + pop ecx + and ecx, 3 ; + rep movsb + ;********Debug, tell user we have a good packet************* +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Packet_good + call sys_msg_board_str +end if + jmp SIS900_Poll_Cnt ; + ;*************Error occured let user know through debug window*********** +SIS900_Poll_Error_Status: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Bad_Packet_Status + call sys_msg_board_str +end if + jmp SIS900_Poll_Cnt +SIS900_Poll_Error_Size: +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Pull_Bad_Packet_Size + call sys_msg_board_str +end if + ;*************Increment to next available descriptor************** +SIS900_Poll_Cnt: + ;Reset status, allow ethernet card access to descriptor + mov ecx, RX_BUFF_SZ + mov [rxd+eax+4], ecx ; + inc [cur_rx] ;get next descriptor + and [cur_rx],3 ;only 4 descriptors 0-3 + ;******Enable Receiver************ + mov ebp, [io_addr] ; Base Address + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_RxENA ;Enable Receive + out dx, eax + ret +;*************************************************************************** +; Function +; SIS900_transmit +; Description +; Transmits a packet of data via the ethernet card +; Pointer to 48 bit destination address in edi +; Type of packet in bx +; size of packet in ecx +; pointer to packet data in esi +; +; only one transmit descriptor is used +; +;*************************************************************************** +if defined SIS900_DEBUG +SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0 +SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0 +end if +SIS900_transmit: + mov ebp, [io_addr] ; Base Address + ;******** Stop the transmitter ******** + lea edx,[ebp+SIS900_cr] ; Command Register offset + in eax, dx ; Get current Command Register + or eax, SIS900_TxDIS ; Disable Transmitter + out dx, eax + ;*******load Transmit Descriptor Register ******* + lea edx,[ebp+SIS900_txdp] + mov eax, txd + out dx, eax + ;******* copy packet to descriptor******* + push esi + mov esi, edi ;copy destination addess + mov edi, txb + cld + movsd + movsw + mov esi, node_addr ;copy my mac address + movsd + movsw + mov [edi], bx ;copy packet type + add edi, 2 + pop esi ;restore pointer to source of packet + push ecx ;save packet size + shr ecx, 2 ;divide by 4, size in bytes send in dwords + rep movsd ;copy data to decriptor + pop ecx ;restore packet size + push ecx ;save packet size + and ecx, 3 ;last three bytes if not a multiple of 4 + rep movsb + ;**************set length tag************** + pop ecx ;restore packet size + add ecx, SIS900_ETH_HLEN ;add header to length + and ecx, SIS900_DSIZE ; + ;**************pad to minimum packet size **************not needed + ;cmp ecx, SIS900_ETH_ZLEN + ;jge SIS900_transmit_Size_Ok + ;push ecx + ;mov ebx, SIS900_ETH_ZLEN + ;sub ebx, ecx + ;mov ecx, ebx + ;rep movsb + ;pop ecx +SIS900_transmit_Size_Ok: + mov [txd+4], dword 0x80000000 ;card owns descriptor + or [txd+4], ecx ;set size of packet +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Transmit_Packet + call sys_msg_board_str +end if + ;***************restart the transmitter ******** + lea edx,[ebp+SIS900_cr] + in eax, dx ; Get current Command Register + or eax, SIS900_TxENA ; Enable Transmitter + out dx, eax + ;****make sure packet transmitted successfully**** +; mov esi,10 +; call delay_ms + mov eax, [txd+4] + and eax, 0x6200000 + jz SIS900_transmit_OK + ;**************Tell user there was an error through debug window +if defined SIS900_DEBUG + mov esi, SIS900_Debug_Transmit_Packet_Err + call sys_msg_board_str +end if +SIS900_transmit_OK: + ;******** Disable interrupts by clearing the interrupt mask. ******** + lea edx,[ebp+SIS900_imr] ; Interupt Mask Register + xor eax, eax + out dx,eax + ret + +;*************************************************************************** +;* Function: Create_Mac_String +;* +;* Description: Converts the 48 bit value to a string for display +;* +;* String Format: XX:XX:XX:XX:XX:XX +;* +;* Arguments: node_addr is location of 48 bit MAC ID +;* +;* Returns: Prints string to general debug window +;* +;* +;done +;*************************************************************************** +if defined SIS900_DEBUG + +SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9' + db 'A','B','C','D','E','F' +Mac_str_build: times 20 db 0 +Create_Mac_String: + pusha + xor ecx, ecx +Create_Mac_String_loop: + mov al,byte [edx+ecx];[node_addr+ecx] + push eax + shr eax, 4 + and eax, 0x0f + mov bl, byte [SIS900_Char_String+eax] + mov [Mac_str_build+ecx*3], bl + pop eax + and eax, 0x0f + mov bl, byte [SIS900_Char_String+eax] + mov [Mac_str_build+1+ecx*3], bl + cmp ecx, 5 + je Create_Mac_String_done + mov bl, ':' + mov [Mac_str_build+2+ecx*3], bl + inc ecx + jmp Create_Mac_String_loop +Create_Mac_String_done: ;Insert CR and Zero Terminate + mov [Mac_str_build+2+ecx*3],byte 13 + mov [Mac_str_build+3+ecx*3],byte 10 + mov [Mac_str_build+4+ecx*3],byte 0 + mov esi, Mac_str_build + call sys_msg_board_str ;Print String to message board + popa + ret +end if +;*************************************************************************** +;* Set device to be a busmaster in case BIOS neglected to do so. +;* Also adjust PCI latency timer to a reasonable value, 64. +;*************************************************************************** +SIS900_adjust_pci_device: + ;*******Get current setting************************ + mov al, 2 ;read a word + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x04 ;from command Register + call pci_read_reg + ;******see if its already set as bus master******** + mov bx, ax + and bx,5 + cmp bx,5 + je SIS900_adjust_pci_device_Latency + ;******Make card a bus master******* + mov cx, ax ;value to write + mov bh, [pci_dev] + mov al, 2 ;write a word + or cx,5 + mov ah, [pci_bus] + mov bl, 0x04 ;to command register + call pci_write_reg + ;******Check latency setting*********** +SIS900_adjust_pci_device_Latency: + ;*******Get current latency setting************************ + mov al, 1 ;read a byte + mov bh, [pci_dev] + mov ah, [pci_bus] + mov bl, 0x0D ;from Lantency Timer Register + call pci_read_reg + ;******see if its aat least 64 clocks******** + cmp ax,64 + jge SIS900_adjust_pci_device_Done + ;******Set latency to 32 clocks******* + mov cx, 64 ;value to write + mov bh, [pci_dev] + mov al, 1 ;write a byte + mov ah, [pci_bus] + mov bl, 0x0D ;to Lantency Timer Register + call pci_write_reg + ;******Check latency setting*********** +SIS900_adjust_pci_device_Done: + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/ip.inc b/kernel/tags/kolibri0.6.0.0/network/ip.inc new file mode 100644 index 0000000000..36d46cff75 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/ip.inc @@ -0,0 +1,202 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; IP.INC ;; +;; ;; +;; IP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Version 0.3 29 August 2002 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; Interface +; +; ip_rx processes all packets received by the network layer +; It calls the appropriate protocol handler +; +; +; +;******************************************************************* + + +;*************************************************************************** +; Function +; ip_rx +; +; Description +; Handles received IP packets +; This is a kernel function, called by stack_handler +; +;*************************************************************************** +ip_rx: + ; Look for a buffer to tx + mov eax, IPIN_QUEUE + call dequeue + cmp ax, NO_BUFFER + je ipr_exit ; Exit if no buffer available + + push eax + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax ; Save the address in edx for use by future processes + + ; Validate the IP checksum + mov ebx, edx + mov ah, [ebx + 10] + mov al, [ebx + 11] ; Get the checksum in intel format + mov [ebx + 10], word 0 ; clear checksum field - need to when + ; recalculating checksum + + ; this needs two data pointers and two size #. + ; 2nd pointer can be of length 0 + mov ebx, edx + mov [checkAdd1], ebx + mov [checkSize1], word 20 + mov [checkAdd2], dword 0 + mov [checkSize2], word 0 + + call checksum ; Recalculate IP checksum + cmp ax, [checkResult] + jnz ipr_dump + + ; If the IP address is 255.255.255.255, accept it + ; - it is a broadcast packet, which we need for dhcp + mov eax, [edx + 16] + cmp eax, 0xffffffff + je ipr_p0 + + ; Validate the IP address, if it isn't broadcast + cmp eax, [stack_ip] + jnz ipr_dump + +ipr_p0: + mov al, [edx] + and al, 0x0f + cmp al, 0x05 + jnz ipr_dump + + cmp [edx+8], byte 0 + jz ipr_dump + + mov ax, [edx + 6] + and ax, 0xFFBF + cmp ax, 0 + jnz ipr_dump + + ; Check the protocol, and call the appropriate handler + ; Each handler will re-use or free the queue buffer as appropriate + mov al, [edx + 9] + cmp al , PROTOCOL_ICMP + jnz ipr_p1 + pop eax + call icmp_rx + jmp ipr_exit + +ipr_p1: + cmp al , PROTOCOL_TCP + jnz ipr_p2 + pop eax + call tcp_rx + jmp ipr_exit + +ipr_p2: + cmp al , PROTOCOL_UDP + jnz ipr_dump + pop eax + call udp_rx + jmp ipr_exit + +ipr_dump: + ; No protocol handler available, so + ; silently dump the packet, freeing up the queue buffer + +; inc dword [dumped_rx_count] + + pop eax + call freeBuff + +ipr_exit: + ret + + + +;*************************************************************************** +; Function +; icmp_rx +; +; Description +; ICMP protocol handler +; This is a kernel function, called by ip_rx +; edx contains the address of the buffer in use. +; This buffer must be reused or marked as empty afterwards +; +;*************************************************************************** +icmp_rx: + cmp [edx + 20], byte 8 ; Is this an echo request? discard if not + jz icmp_echo + + call freeBuff + jmp icmp_exit + +icmp_echo: + push eax + mov [edx + 10], word 0 ; I think this was already done by IP rx + + ; swap the source and destination addresses + mov ecx, [edx + 16] + mov eax, [edx + 12] + mov [edx + 16], eax + mov [edx + 12], ecx + + ; recaluculate the IP header checksum + + mov ebx, edx + mov [checkAdd1], ebx + mov [checkSize1], word 20 + mov [checkAdd2], dword 0 + mov [checkSize2], word 0 + + call checksum + mov ax, [checkResult] + mov [edx + 10], ah + mov [edx + 11], al ; ?? correct byte order? + + mov [edx + 20], byte 0 ; change the request to a response + mov [edx + 22], word 0 ; clear ICMP checksum prior to re-calc + + ; Calculate the length of the ICMP data ( IP payload) + mov ah, [edx + 2] + mov al, [edx + 3] + sub ax, 20 + + mov [checkSize1], ax + mov ebx, edx + add ebx, 20 + + mov [checkAdd1], ebx + mov [checkAdd2], dword 0 + mov [checkSize2], word 0 + + call checksum + + mov ax, [checkResult] + mov [edx + 22], ah + mov [edx + 23], al + + ; Queue packet for transmission + + pop ebx + mov eax, NET1OUT_QUEUE + call queue + +icmp_exit: + ret \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/network/queue.inc b/kernel/tags/kolibri0.6.0.0/network/queue.inc new file mode 100644 index 0000000000..6dc6a00033 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/queue.inc @@ -0,0 +1,214 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; QUEUE.INC ;; +;; ;; +;; Buffer queue management for Menuet OS TCP/IP Stack ;; +;; ;; +;; Version 0.3 29 August 2002 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; Interface +; +; queueInit Configures the queues to empty +; dequeue Removes a buffer pointer from a queue +; queue Inserts a buffer pointer into a queue +; freeBuff Adds the buffer pointer to the list of free buffers +; queueSize Returns the number of entries in a queue +; +; The various defines for queue names can be found in stack.inc +; +;******************************************************************* + + +;*************************************************************************** +; Function +; freeBuff +; +; Description +; Adds a buffer number to the beginning of the free list. +; buffer number in eax ( ms word zeroed ) +; all other registers preserved +; This always works, so no error returned +;*************************************************************************** +freeBuff: + push ebx + push ecx + mov ebx, EMPTY_QUEUE + shl ebx, 1 + add ebx, queues + cli ; Ensure that another process does not interfer + movzx ecx, word [ebx] + mov [ebx], ax + shl eax, 1 + add eax, queueList + mov [eax], cx + sti + pop ecx + pop ebx + + ret + + +;*************************************************************************** +; Function +; queueSize +; +; Description +; Counts the number of entries in a queue +; queue number in ebx ( ms word zeroed ) +; Queue size returned in eax +; This always works, so no error returned +;*************************************************************************** +queueSize: + xor eax, eax + shl ebx, 1 + add ebx, queues + movzx ecx, word [ebx] + cmp cx, NO_BUFFER + je qs_exit + +qs_001: + inc eax + shl ecx, 1 + add ecx, queueList + movzx ecx, word [ecx] + cmp cx, NO_BUFFER + je qs_exit + jmp qs_001 + +qs_exit: + ret + + +;*************************************************************************** +; Function +; queue +; +; Description +; Adds a buffer number to the *end* of a queue +; This is quite quick because these queues will be short +; queue number in eax ( ms word zeroed ) +; buffer number in ebx ( ms word zeroed ) +; all other registers preserved +; This always works, so no error returned +;*************************************************************************** +queue: + push ebx + shl ebx, 1 + add ebx, queueList ; eax now holds address of queue entry + mov [ebx], word NO_BUFFER ; This buffer will be the last + + cli + shl eax, 1 + add eax, queues ; eax now holds address of queue + movzx ebx, word [eax] + + cmp bx, NO_BUFFER + jne qu_001 + + pop ebx + ; The list is empty, so add this to the head + mov [eax], bx + jmp qu_exit + +qu_001: + ; Find the last entry + shl ebx, 1 + add ebx, queueList + mov eax, ebx + movzx ebx, word [ebx] + cmp bx, NO_BUFFER + jne qu_001 + + mov ebx, eax + pop eax + mov [ebx], ax + +qu_exit: + sti + ret + + + +;*************************************************************************** +; Function +; dequeue +; +; Description +; removes a buffer number from the head of a queue +; This is fast, as it unlinks the first entry in the list +; queue number in eax ( ms word zeroed ) +; buffer number returned in eax ( ms word zeroed ) +; all other registers preserved +; +;*************************************************************************** +dequeue: + push ebx + shl eax, 1 + add eax, queues ; eax now holds address of queue + mov ebx, eax + cli + movzx eax, word [eax] + cmp ax, NO_BUFFER + je dq_exit + push eax + shl eax, 1 + add eax, queueList ; eax now holds address of queue entry + mov ax, [eax] + mov [ebx], ax + pop eax + +dq_exit: + sti + pop ebx + ret + + +;*************************************************************************** +; Function +; queueInit +; +; Description +; Initialises the queues to empty, and creates the free queue +; list. +; +;*************************************************************************** +queueInit: + mov esi, queues + mov ecx, NUMQUEUES + mov ax, NO_BUFFER + +qi001: + mov [esi], ax + inc esi + inc esi + loop qi001 + + mov esi, queues + ( 2 * EMPTY_QUEUE ) + + ; Initialise empty queue list + + xor ax, ax + mov [esi], ax + + mov ecx, NUMQUEUEENTRIES - 1 + mov esi, queueList + +qi002: + inc ax + mov [esi], ax + inc esi + inc esi + loop qi002 + + mov ax, NO_BUFFER + mov [esi], ax + + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/stack.inc b/kernel/tags/kolibri0.6.0.0/network/stack.inc new file mode 100644 index 0000000000..2d0427d1f3 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/stack.inc @@ -0,0 +1,1784 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; STACK.INC ;; +;; ;; +;; TCP/IP stack for Menuet OS ;; +;; ;; +;; Version 0.7 4th July 2004 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; Version 0.7 ;; +;; Added a timer per socket to allow delays when rx window ;; +;; gets below 1KB ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; Interface +; The interfaces defined in ETHERNET.INC plus: +; stack_init +; stack_handler +; app_stack_handler +; app_socket_handler +; checksum +; +;******************************************************************* + + + +; +; IP Packet after reception - Normal IP packet format +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;0 |Version| IHL |Type of Service| Total Length | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;4 | Identification |Flags| Fragment Offset | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;8 | Time to Live | Protocol | Header Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;12 | Source Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;16 | Destination Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Data | +; +-+-+-.......... -+ + + +; TCP Payload ( Data field in IP datagram ) +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;20 | Source Port | Destination Port | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;24 | Sequence Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;28 | Acknowledgment Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;32 | Data | |U|A|P|R|S|F| | +; | Offset| Reserved |R|C|S|S|Y|I| Window | +; | | |G|K|H|T|N|N| | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;36 | Checksum | Urgent Pointer | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;40 | Options | Padding | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | data + + +; +; UDP Payload ( Data field in IP datagram ) +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Source Port | Destination Port | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Length ( UDP Header + Data ) | Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | UDP Data | +; +-+-+-.......... -+ +; + + +; +; Socket Descriptor + Buffer +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Status ( of this buffer ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Application Process ID | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Local IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Local IP Port | Unused ( set to 0 ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Remote IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Remote IP Port | Unused ( set to 0 ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 24| Rx Data Count INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 28| TCB STATE INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 32| TCB Timer (seconds) INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 36| ISS (Inital Sequence # used by this connection ) INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 40| IRS ( Inital Receive Sequence # ) INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 44| SND.UNA Seq # of unack'ed sent packets INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 48| SND.NXT Next send seq # to use INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 52| SND.WND Send window INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 56| RCV.NXT Next expected receive sequence # INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 60| RCV.WND Receive window INET format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 64| SEG.LEN Segment length INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 68| SEG.WND Segment window INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format| +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 76| RX Data | +; +-+-+-.......... -+ + + + +; IP protocol numbers +PROTOCOL_ICMP equ 1 +PROTOCOL_TCP equ 6 +PROTOCOL_UDP equ 17 + + +; TIPBUFF status values +BUFF_EMPTY equ 0 +BUFF_RX_FULL equ 1 +BUFF_ALLOCATED equ 2 +BUFF_TX_FULL equ 3 + +NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX + +SOCK_EMPTY equ 0 ; socket not in use +SOCK_OPEN equ 1 ; open issued, but no data sent + +; TCP opening modes +SOCKET_PASSIVE equ 0 +SOCKET_ACTIVE equ 1 + +; TCP TCB states +TCB_LISTEN equ 1 +TCB_SYN_SENT equ 2 +TCB_SYN_RECEIVED equ 3 +TCB_ESTABLISHED equ 4 +TCB_FIN_WAIT_1 equ 5 +TCB_FIN_WAIT_2 equ 6 +TCB_CLOSE_WAIT equ 7 +TCB_CLOSING equ 8 +TCB_LAST_ACK equ 9 +TCB_TIME_WAIT equ 10 +TCB_CLOSED equ 11 + +TWOMSL equ 10 ; # of secs to wait before closing socket + +; socket buffers +SOCKETBUFFSIZE equ 4096 ; state + config + buffer. +SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data + +NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 + + +NUMQUEUES equ 4 +EMPTY_QUEUE equ 0 +IPIN_QUEUE equ 1 +IPOUT_QUEUE equ 2 +NET1OUT_QUEUE equ 3 + +NO_BUFFER equ 0xFFFF +IPBUFFSIZE equ 1500 ; MTU of an ethernet packet +NUMQUEUEENTRIES equ NUM_IPBUFFERS +NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets +TCP_RETRIES equ 5 ; Number of times to resend a packet +TCP_TIMEOUT equ 10 ; resend if not replied to in x hs + +; These are the 0x40 function codes for application access to the stack +STACK_DRIVER_STATUS equ 52 +SOCKET_INTERFACE equ 53 + + +; 128KB allocated for the stack and network driver buffers and other +; data requirements +stack_data_start equ 0x700000 +eth_data_start equ 0x700000 +stack_data equ 0x704000 +stack_data_end equ 0x71ffff + +; 32 bit word +stack_config equ stack_data +; 32 bit word - IP Address in network format +stack_ip equ stack_data + 4 +; 1 byte. 0 == inactive, 1 = active +slip_active equ stack_data + 8 ; no longer used +; 1 byte. 0 == inactive, 1 = active +ethernet_active equ stack_data + 9 +unused equ stack_data + 10 +; word. Buffer number, -1 if none +rx_buff_ptr equ stack_data + 12 +; dword. Buffer number, -1 if none +tx_buff_ptr equ stack_data + 16 +; byte. +slip_rx_state equ stack_data + 20 ; no longer used +; byte +slip_tx_state equ stack_data + 21 ; no longer used +; dword. Index into data +rx_data_ptr equ stack_data + 22 +; dword. Index into data +tx_data_ptr equ stack_data + 26 +; word. Count of bytes to send +tx_msg_len equ stack_data + 30 +; Address of selected socket +sktAddr equ stack_data + 32 +; Parameter to checksum routine - data ptr +checkAdd1 equ stack_data + 36 +; Parameter to checksum routine - 2nd data ptr +checkAdd2 equ stack_data + 40 +; Parameter to checksum routine - data size +checkSize1 equ stack_data + 44 +; Parameter to checksum routine - 2nd data size +checkSize2 equ stack_data + 46 +; result of checksum routine +checkResult equ stack_data + 48 + +; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| +pseudoHeader equ stack_data + 50 + +; receive and transmit IP buffer allocation +sockets equ stack_data + 62 +Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) +; 1560 byte buffer for rx / tx ethernet packets +Ether_buffer equ Next_free2 +Next_free3 equ Ether_buffer + 1560 +last_1sTick equ Next_free3 +IPbuffs equ Next_free3 + 1 +queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) +queueList equ queues + (2 * NUMQUEUES) +last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) + +;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) +;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP +; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) + + + +resendQ equ 0x770000 +resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP + + +;*************************************************************************** +; Function +; stack_init +; +; Description +; Clear all allocated memory to zero. This ensures that +; on startup, the stack is inactive, and consumes no resources +; This is a kernel function, called prior to the OS main loop +; in set_variables +; +;*************************************************************************** +stack_init: + xor eax,eax + mov edi,stack_data_start + mov ecx,0x20000 / 4 ; Assume that we have 128KB of data + cld + rep stosd + + ; Initialise TCP resend queue data structures + mov eax, 0xFFFFFFFF + mov edi, resendQ + mov ecx, NUMRESENDENTRIES ; 1 dword per entry + cld + rep stosd + + + mov eax, 0xFFFFFFFF + mov [rx_buff_ptr], eax + mov [tx_buff_ptr], eax + + ; Put in some defaults : slip, 0x3f8, 4, ip=192.168.1.22 + ; Saves me entering them each boot up when debugging + mov eax, 0x03f80401 + mov [stack_config], eax + mov eax, 0xc801a8c0 + mov [stack_ip], eax + + call queueInit + + ; The following block sets up the 1s timer + mov al,0x0 + out 0x70,al + in al,0x71 + mov [last_1sTick], al + + ret + + + +;*************************************************************************** +; Function +; stack_handler +; +; Description +; The kernel loop routine for the stack +; This is a kernel function, called in the main loop +; +;*************************************************************************** +stack_handler: + + call ethernet_driver + call ip_rx + + + ; Test for 10ms tick, call tcp timer + mov eax, [timer_ticks] ;[0xfdf0] + cmp eax, [last_1hsTick] + je sh_001 + + mov [last_1hsTick], eax + call tcp_tx_handler + +sh_001: + + ; Test for 1 second event, call 1s timer functions + mov al,0x0 ;second + out 0x70,al + in al,0x71 + cmp al, [last_1sTick] + je sh_exit + + mov [last_1sTick], al + + call arp_timer + call tcp_tcb_handler + +sh_exit: + ret + + + + +;*************************************************************************** +; Function +; is_localport_unused +; +; Description +; scans through all the active sockets , looking to see if the +; port number specified in bx is in use as a localport number. +; This is useful when you want a to generate a unique local port +; number. +; On return, eax = 1 for free, 0 for in use +; +;*************************************************************************** +is_localport_unused: + mov al, bh + mov ah, bl + mov bx, ax + + mov edx, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + mov eax, 0 ; Assume the return value is 'in use' + +ilu1: + sub edx, SOCKETBUFFSIZE + cmp [edx + sockets + 12], bx + loopnz ilu1 ; Return back if the socket is occupied + + jz ilu_exit + inc eax ; return port not in use + +ilu_exit: + ret + + + +;*************************************************************************** +; Function +; get_free_socket +; +; Description +; +;*************************************************************************** +get_free_socket: + push ecx + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +gfs1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets], dword SOCK_EMPTY + loopnz gfs1 ; Return back if the socket is occupied + mov eax, ecx + pop ecx + jz gfs_exit + mov eax, 0xFFFFFFFF + +gfs_exit: + ret + + + +;*************************************************************************** +; Function +; checksum +; +; Description +; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult +; Dont break anything; Most registers are used by the caller +; This code is derived from the 'C' source, cksum.c, in the book +; Internetworking with TCP/IP Volume II by D.E. Comer +; +;*************************************************************************** +checksum: + pusha + + xor edx, edx ; edx is the accumulative checksum + xor ebx, ebx + mov cx, [checkSize1] + shr cx, 1 + jz cs1_1 + + mov eax, [checkAdd1] + +cs1: + mov bh, [eax] + mov bl, [eax + 1] + + add eax, 2 + add edx, ebx + + loopw cs1 + +cs1_1: + and word [checkSize1], 0x01 + jz cs_test2 + + mov bh, [eax] + xor bl, bl + + add edx, ebx + +cs_test2: + mov cx, [checkSize2] + cmp cx, 0 + jz cs_exit ; Finished if no 2nd buffer + + shr cx, 1 + jz cs2_1 + + mov eax, [checkAdd2] + +cs2: + mov bh, [eax] + mov bl, [eax + 1] + + add eax, 2 + add edx, ebx + + loopw cs2 + +cs2_1: + and word [checkSize2], 0x01 + jz cs_exit + + mov bh, [eax] + xor bl, bl + + add edx, ebx + +cs_exit: + mov ebx, edx + + shr ebx, 16 + and edx, 0xffff + add edx, ebx + mov eax, edx + shr eax, 16 + add edx, eax + not dx + + mov [checkResult], dx + popa + ret + + + + +;*************************************************************************** +; Function +; app_stack_handler +; +; Description +; This is an application service, called by int 0x40 fn 52 +; It provides application access to the network interface layer +; +;*************************************************************************** +app_stack_handler: + cmp eax, 0 + jnz not0 + ; Read the configuartion word + mov eax, [stack_config] + ret + +not0: + cmp eax, 1 + jnz not1 + ; read the IP address + + mov eax, [stack_ip] + ret + +not1: + cmp eax, 2 + jnz not2 + + ; write the configuration word + mov [stack_config], ebx + + ; + ; If ethernet now enabled, probe for the card, reset it and empty + ; the packet buffer + ; If all successfull, enable the card. + ; If ethernet now disabled, set it as disabled. Should really + ; empty the tcpip data area too. + + ; ethernet interface is '3' in ls 7 bits + and bl, 0x7f + cmp bl, 3 + + je ash_eth_enable + ; Ethernet isn't enabled, so make sure that the card is disabled + mov [ethernet_active], byte 0 + + ret + +ash_eth_enable: + ; Probe for the card. This will reset it and enable the interface + ; if found + call eth_probe + cmp eax, 0 + je ash_eth_done ; Abort if no hardware found + + mov [ethernet_active], byte 1 + +ash_eth_done: + ret + +not2: + cmp eax, 3 + jnz not3 + ; write the IP Address + mov [stack_ip], ebx + ret + +not3: + cmp eax, 4 + jnz not4 + ; Enabled the slip driver on the comm port + ; slip removed + ret + +not4: + cmp eax, 5 + jnz not5 + ; Disable the slip driver on the comm port + ; slip removed + +not5: + cmp eax, 6 + jnz not6 + + ; Insert an IP packet into the stacks received packet queue + call stack_insert_packet + ret + +not6: + cmp eax, 7 + jnz not7 + + ; Test for any packets queued for transmission over the network + +not7: + cmp eax, 8 + jnz not8 + + call stack_get_packet + ; Extract a packet queued for transmission by the network + ret + +not8: + cmp eax, 9 + jnz not9 + + ; read the gateway IP address + + mov eax, [gateway_ip] + ret + +not9: + cmp eax, 10 + jnz not10 + + ; read the subnet mask + + mov eax, [subnet_mask] + ret + +not10: + cmp eax, 11 + jnz not11 + + ; write the gateway IP Address + mov [gateway_ip], ebx + + ret + +not11: + cmp eax, 12 + jnz not12 + + ; write the subnet mask + mov [subnet_mask], ebx + + +not12: + cmp eax, 13 + jnz not13 + + ; read the dns + + mov eax, [dns_ip] + ret + +not13: + cmp eax, 14 + jnz stack_driver_end + + ; write the dns IP Address + mov [dns_ip], ebx + + ret + +stack_driver_end: + ret + + + +;*************************************************************************** +; Function +; app_socket_handler +; +; Description +; This is an application service, called by int 0x40 +; It provides application access to stack socket services +; such as opening sockets +; +;*************************************************************************** +app_socket_handler: + cmp eax, 0 + jnz nots0 + + call socket_open + ret + +nots0: + cmp eax, 1 + jnz nots1 + + call socket_close + ret + +nots1: + cmp eax, 2 + jnz nots2 + + call socket_poll + ret + +nots2: + cmp eax, 3 + jnz nots3 + + call socket_read + ret + +nots3: + cmp eax, 4 + jnz nots4 + + call socket_write + ret + +nots4: + cmp eax, 5 + jnz nots5 + + call socket_open_tcp + ret + +nots5: + cmp eax, 6 + jnz nots6 + + call socket_status + ret + +nots6: + cmp eax, 7 + jnz nots7 + + call socket_write_tcp + ret + +nots7: + cmp eax, 8 + jnz nots8 + + call socket_close_tcp + ret + +nots8: + cmp eax, 9 + jnz nots9 + + call is_localport_unused + ret + +nots9: + cmp eax, 254 + jnz notdump + + ret + +notdump: + cmp eax, 255 + jnz notsdebug + + ; This sub function allows access to debugging information on the stack + ; ebx holds the request: + ; 100 : return length of empty queue + ; 101 : return length of IPOUT QUEUE + ; 102 : return length of IPIN QUEUE + ; 103 : return length of NET1OUT QUEUE + ; 200 : return # of ARP entries + ; 201 : return size of ARP table ( max # entries ) + ; 202 : select ARP table entry # + ; 203 : return IP of selected table entry + ; 204 : return High 4 bytes of MAC address of selected table entry + ; 205 : return low 2 bytes of MAC address of selected table entry + ; 206 : return status word of selected table entry + ; 207 : return Time to live of selected table entry + + + ; 2 : return number of IP packets received + ; 3 : return number of packets transmitted + ; 4 : return number of received packets dumped + ; 5 : return number of arp packets received + ; 6 : return status of packet driver + ; ( 0 == not active, FFFFFFFF = successful ) + + call stack_internal_status + ret + +notsdebug: + ; Invalid Option + ret + + +uglobal + ARPTmp: + times 14 db 0 +endg + +;*************************************************************************** +; Function +; stack_internal_status +; +; Description +; Returns information about the internal status of the stack +; This is only useful for debugging +; It works with the ethernet driver +; sub function in ebx +; return requested data in eax +; +;*************************************************************************** +stack_internal_status: + cmp ebx, 100 + jnz notsis100 + + ; 100 : return length of EMPTY QUEUE + mov ebx, EMPTY_QUEUE + call queueSize + ret + +notsis100: + cmp ebx, 101 + jnz notsis101 + + ; 101 : return length of IPOUT QUEUE + mov ebx, IPOUT_QUEUE + call queueSize + ret + +notsis101: + cmp ebx, 102 + jnz notsis102 + + ; 102 : return length of IPIN QUEUE + mov ebx, IPIN_QUEUE + call queueSize + ret + +notsis102: + cmp ebx, 103 + jnz notsis103 + + ; 103 : return length of NET1OUT QUEUE + mov ebx, NET1OUT_QUEUE + call queueSize + ret + +notsis103: + cmp ebx, 200 + jnz notsis200 + + ; 200 : return num entries in arp table + movzx eax, byte [NumARP] + ret + +notsis200: + cmp ebx, 201 + jnz notsis201 + + ; 201 : return arp table size + mov eax, 20 ; ARP_TABLE_SIZE + ret + +notsis201: + cmp ebx, 202 + jnz notsis202 + + ; 202 - read the requested table entry + ; into a temporary buffer + ; ecx holds the entry number + + mov eax, ecx + mov ecx, 14 ; ARP_ENTRY_SIZE + mul ecx + + mov ecx, [eax + ARPTable] + mov [ARPTmp], ecx + mov ecx, [eax + ARPTable+4] + mov [ARPTmp+4], ecx + mov ecx, [eax + ARPTable+8] + mov [ARPTmp+8], ecx + mov cx, [eax + ARPTable+12] + mov [ARPTmp+12], cx + ret + +notsis202: + cmp ebx, 203 + jnz notsis203 + + ; 203 - return IP address + mov eax, [ARPTmp] + ret + +notsis203: + cmp ebx, 204 + jnz notsis204 + + ; 204 - return MAC high dword + mov eax, [ARPTmp+4] + ret + +notsis204: + cmp ebx, 205 + jnz notsis205 + + ; 205 - return MAC ls word + movzx eax, word [ARPTmp+8] + ret + +notsis205: + cmp ebx, 206 + jnz notsis206 + + ; 206 - return status word + movzx eax, word [ARPTmp+10] + ret + +notsis206: + cmp ebx, 207 + jnz notsis207 + + ; 207 - return ttl word + movzx eax, word [ARPTmp+12] + ret + +notsis207: + cmp ebx, 2 + jnz notsis2 + + ; 2 : return number of IP packets received + mov eax, [ip_rx_count] + ret + +notsis2: + cmp ebx, 3 + jnz notsis3 + + ; 3 : return number of packets transmitted + mov eax, [ip_tx_count] + ret + +notsis3: + cmp ebx, 4 + jnz notsis4 + + ; 4 : return number of received packets dumped + mov eax, [dumped_rx_count] + ret + +notsis4: + cmp ebx, 5 + jnz notsis5 + + ; 5 : return number of arp packets received + mov eax, [arp_rx_count] + ret + +notsis5: + cmp ebx, 6 + jnz notsis6 + + ; 6 : return status of packet driver + ; ( 0 == not active, FFFFFFFF = successful ) + mov eax, [eth_status] + ret + +notsis6: + xor eax, eax + ret + + + +;*************************************************************************** +; Function +; stack_get_packet +; +; Description +; extracts an IP packet from the NET1 output queue +; and sends the data to the calling process +; pointer to data in edx +; returns number of bytes read in eax +; +;*************************************************************************** +stack_get_packet: + ; Look for a buffer to tx + mov eax, NET1OUT_QUEUE + call dequeue + cmp ax, NO_BUFFER + je sgp_non_exit ; Exit if no buffer available + + push eax ; Save buffer number for freeing at end + + push edx + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + pop edx + + push eax ; save address of IP data + + ; Get the address of the callers data + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add edx,[edi] + mov edi, edx + + pop eax + + mov ecx, 1500 ; should get the actual number of bytes to write + mov esi, eax + cld + rep movsb ; copy the data across + + ; And finally, return the buffer to the free queue + pop eax + call freeBuff + + mov eax, 1500 + ret + +sgp_non_exit: + xor eax, eax + ret + + + +;*************************************************************************** +; Function +; stack_insert_packet +; +; Description +; writes an IP packet into the stacks receive queue +; # of bytes to write in ecx +; pointer to data in edx +; returns 0 in eax ok, -1 == failed +; +;*************************************************************************** +stack_insert_packet: + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je sip_err_exit + + push eax + + ; save the pointers to the data buffer & size + push edx + push ecx + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax + + ; So, edx holds the IPbuffer ptr + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + pop eax ; get callers ptr to data to send + + ; Get the address of the callers data + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add eax,[edi] + mov esi, eax + + mov edi, edx + cld + rep movsb ; copy the data across + + pop ebx + + mov eax, IPIN_QUEUE + call queue + + inc dword [ip_rx_count] + + mov eax, 0 + ret + +sip_err_exit: + mov eax, 0xFFFFFFFF + ret + + + +;*************************************************************************** +; Function +; socket_open +; +; Description +; find a free socket +; local port in ebx +; remote port in ecx +; remote ip in edx +; return socket # in eax, -1 if none available +; +;*************************************************************************** +socket_open: + call get_free_socket + + cmp eax, 0xFFFFFFFF + jz so_exit + + ; ax holds the socket number that is free. Get real address + push eax + shl eax, 12 + add eax, sockets + + mov [eax], dword SOCK_OPEN + + mov [eax + 12], byte bh ; Local port ( LS 16 bits ) + mov [eax + 13], byte bl ; Local port ( LS 16 bits ) + mov ebx, [stack_ip] + mov [eax + 8], ebx ; Local IP + mov [eax + 20], ch ; Remote Port ( LS 16 bits ) + mov [eax + 21], cl ; Remote Port ( LS 16 bits ) + mov [eax + 16], edx ; Remote IP ( in Internet order ) + mov [eax + 24], dword 0 ; recieved data count + + mov esi, [0x3010] + mov ebx, [esi+TASKDATA.pid] + mov [eax + 4], ebx ; save the process ID + pop eax ; Get the socket number back, so we can return it + +so_exit: + ret + + + +;*************************************************************************** +; Function +; socket_open_tcp +; +; Description +; Opens a TCP socket in PASSIVE or ACTIVE mode +; find a free socket +; local port in ebx ( intel format ) +; remote port in ecx ( intel format ) +; remote ip in edx ( in Internet byte order ) +; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE ) +; return socket # in eax, -1 if none available +; +;*************************************************************************** +socket_open_tcp: + call get_free_socket + + cmp eax, 0xFFFFFFFF + jz so_exit + + ; ax holds the socket number that is free. Get real address + push eax + shl eax, 12 + add eax, sockets + + mov [sktAddr], eax + mov [eax], dword SOCK_OPEN + + ; TODO - check this works! + mov [eax + 72], dword 0 ; Reset the window timer. + + mov [eax + 12], byte bh ; Local port ( LS 16 bits ) + mov [eax + 13], byte bl ; Local port ( LS 16 bits ) + mov ebx, [stack_ip] + mov [eax + 8], ebx ; Local IP + mov [eax + 20], ch ; Remote Port ( LS 16 bits ) + mov [eax + 21], cl ; Remote Port ( LS 16 bits ) + mov [eax + 16], edx ; Remote IP ( in Internet order ) + mov [eax + 24], dword 0 ; recieved data count + + ; Now fill in TCB state + mov ebx, TCB_LISTEN + cmp esi, SOCKET_PASSIVE + jz sot_001 + mov ebx, TCB_SYN_SENT + +sot_001: + mov [eax + 28], ebx ; Indicate the state of the TCB + + mov esi, [0x3010] + mov ecx, [esi+TASKDATA.pid] + mov [eax + 4], ecx ; save the process ID + + cmp ebx, TCB_LISTEN + je sot_done + + ; Now, if we are in active mode, then we have to send a SYN to the specified remote port + + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je sot_done + + push eax + + mov bl, 0x02 ; SYN + mov ecx, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne sot_notlocal + mov eax, IPIN_QUEUE + +sot_notlocal: + ; Send it. + pop ebx + call queue + + mov esi, [sktAddr] + + ; increment SND.NXT in socket + add esi, 48 + call inc_inet_esi + +sot_done: + pop eax ; Get the socket number back, so we can return it + +sot_exit: + ret + + + +;*************************************************************************** +; Function +; socket_close +; +; Description +; socket # in ebx +; returns 0 for ok, -1 for socket not open (fail) +; +;*************************************************************************** +socket_close: + shl ebx, 12 + add ebx, sockets + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp [ebx], dword SOCK_EMPTY + jz sc_exit + + ; Clear the socket varaibles + xor eax, eax + mov edi,ebx + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +sc_exit: + ret + + + +;*************************************************************************** +; Function +; socket_close_tcp +; +; Description +; socket # in ebx +; returns 0 for ok, -1 for socket not open (fail) +; +;*************************************************************************** +socket_close_tcp: + ; first, remove any resend entries + pusha + + mov esi, resendQ + mov ecx, 0 + +sct001: + cmp ecx, NUMRESENDENTRIES + je sct003 ; None left + cmp [esi], bl + je sct002 ; found one + inc ecx + add esi, 4 + jmp sct001 + +sct002: + dec dword [arp_rx_count] ; ************ TEST ONLY! + + mov [esi], byte 0xFF + jmp sct001 + +sct003: + popa + + shl ebx, 12 + add ebx, sockets + mov [sktAddr], ebx + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp [ebx], dword SOCK_EMPTY + jz sct_exit + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stl_exit + + push eax + + mov bl, 0x11 ; FIN + ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov ebx, [sktAddr] + + ; increament SND.NXT in socket + mov esi, 48 + add esi, ebx + call inc_inet_esi + + + ; Get the socket state + mov eax, [ebx + 28] + cmp eax, TCB_LISTEN + je destroyTCB + cmp eax, TCB_SYN_SENT + je destroyTCB + cmp eax, TCB_SYN_RECEIVED + je sct_finwait1 + cmp eax, TCB_ESTABLISHED + je sct_finwait1 + + ; assume CLOSE WAIT + ; Send a fin, then enter last-ack state + mov eax, TCB_LAST_ACK + mov [ebx + 28], eax + xor eax, eax + jmp sct_send + +sct_finwait1: + ; Send a fin, then enter finwait2 state + mov eax, TCB_FIN_WAIT_1 + mov [ebx + 28], eax + xor eax, eax + +sct_send: + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne sct_notlocal + mov eax, IPIN_QUEUE + +sct_notlocal: + ; Send it. + pop ebx + call queue + jmp sct_exit + +destroyTCB: + pop eax + ; Clear the socket varaibles + xor eax, eax + mov edi,ebx + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +sct_exit: + ret + + + +;*************************************************************************** +; Function +; socket_poll +; +; Description +; socket # in ebx +; returns count in eax. +; +;*************************************************************************** +socket_poll: + shl ebx, 12 + add ebx, sockets + mov eax, [ebx + 24] + + ret + + + +;*************************************************************************** +; Function +; socket_status +; +; Description +; socket # in ebx +; returns TCB state in eax. +; +;*************************************************************************** +socket_status: + shl ebx, 12 + add ebx, sockets + mov eax, [ebx + 28] + + ret + + + +;*************************************************************************** +; Function +; socket_read +; +; Description +; socket # in ebx +; returns # of bytes remaining in eax, data in bl +; +;*************************************************************************** +socket_read: + shl ebx, 12 + add ebx, sockets + mov eax, [ebx + 24] ; get count of bytes + mov ecx,1 + test eax, eax + jz sr2 + + dec eax + mov esi, ebx ; esi is address of socket + mov [ebx + 24], eax ; store new count + movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte + add esi, SOCKETHEADERSIZE + mov edi, esi + inc esi + + mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4 + cld + rep movsd + xor ecx, ecx + +sr1: + jmp sor_exit + +sr2: + xor bl, bl + +sor_exit: + ret + + + +;*************************************************************************** +; Function +; socket_write +; +; Description +; socket in ebx +; # of bytes to write in ecx +; pointer to data in edx +; returns 0 in eax ok, -1 == failed ( invalid socket, or +; could not queue IP packet ) +; +;*************************************************************************** +socket_write: + ; First, find the address of the socket descriptor + shl ebx, 12 + add ebx, sockets ; ebx = address of actual socket + + mov eax, 0xFFFFFFFF + ; If the socket is invalid, return with an error code + cmp [ebx], dword SOCK_EMPTY + je sw_exit + + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je sw_exit + + ; Save the queue entry number + push eax + + ; save the pointers to the data buffer & size + push edx + push ecx + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax + + ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr + + ; Fill in the IP header ( some data is in the socket descriptor) + mov eax, [ebx + 8] + mov [edx + 12], eax ; source IP + mov eax, [ebx + 16] + mov [edx + 16], eax ; Destination IP + + mov al, 0x45 + mov [edx], al ; Version, IHL + xor al, al + mov [edx + 1], al ; Type of service + + pop eax ; Get the UDP data length + push eax + + add eax, 20 + 8 ; add IP header and UDP header lengths + mov [edx + 2], ah + mov [edx + 3], al + xor al, al + mov [edx + 4], al + mov [edx + 5], al + mov al, 0x40 + mov [edx + 6], al + xor al, al + mov [edx + 7], al + mov al, 0x20 + mov [edx + 8], al + mov al, 17 + mov [edx + 9], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 10], ax + + ; Fill in the UDP header ( some data is in the socket descriptor) + mov ax, [ebx + 12] + mov [edx + 20], ax + + mov ax, [ebx + 20] + mov [edx + 20 + 2], ax + + pop eax + push eax + + add eax, 8 + mov [edx + 20 + 4], ah + mov [edx + 20 + 5], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 20 + 6], ax + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + pop eax ; get callers ptr to data to send + + ; Get the address of the callers data + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add eax,[edi] + mov esi, eax + + mov edi, edx + add edi, 28 + cld + rep movsb ; copy the data across + + ; we have edx as IPbuffer ptr. + ; Fill in the UDP checksum + ; First, fill in pseudoheader + mov eax, [edx + 12] + mov [pseudoHeader], eax + mov eax, [edx + 16] + mov [pseudoHeader+4], eax + mov ax, 0x1100 ; 0 + protocol + mov [pseudoHeader+8], ax + add ebx, 8 + mov eax, ebx + mov [pseudoHeader+10], ah + mov [pseudoHeader+11], al + + mov eax, pseudoHeader + mov [checkAdd1], eax + mov [checkSize1], word 12 + mov eax, edx + add eax, 20 + mov [checkAdd2], eax + mov eax, ebx + mov [checkSize2], ax ; was eax!! mjh 8/7/02 + + call checksum + + ; store it in the UDP checksum ( in the correct order! ) + mov ax, [checkResult] + + ; If the UDP checksum computes to 0, we must make it 0xffff + ; (0 is reserved for 'not used') + cmp ax, 0 + jne sw_001 + mov ax, 0xffff + +sw_001: + mov [edx + 20 + 6], ah + mov [edx + 20 + 7], al + + ; Fill in the IP header checksum + mov eax, edx + mov [checkAdd1], eax + mov [checkSize1], word 20 + mov [checkAdd2], dword 0 + mov [checkSize2], word 0 + + call checksum + + mov ax, [checkResult] + mov [edx + 10], ah + mov [edx + 11], al + + ; Check destination IP address. + ; If it is the local host IP, route it back to IP_RX + + pop ebx + mov eax, NET1OUT_QUEUE + + mov ecx, [ edx + 16] + mov edx, [stack_ip] + cmp edx, ecx + jne sw_notlocal + mov eax, IPIN_QUEUE + +sw_notlocal: + ; Send it. + call queue + + xor eax, eax + +sw_exit: + ret + + + +;*************************************************************************** +; Function +; socket_write_tcp +; +; Description +; socket in ebx +; # of bytes to write in ecx +; pointer to data in edx +; returns 0 in eax ok, -1 == failed ( invalid socket, or +; could not queue IP packet ) +; +;*************************************************************************** +socket_write_tcp: + ; First, find the address of the socket descriptor + shl ebx, 12 + add ebx, sockets ; ebx = address of actual socket + + mov [sktAddr], ebx + + mov eax, 0xFFFFFFFF + ; If the socket is invalid, return with an error code + cmp [ebx], dword SOCK_EMPTY + je swt_exit + + ; If the sockets window timer is nonzero, do not queue packet + ; TODO - done + cmp [ebx + 72], dword 0 + jne swt_exit + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je swt_exit + + push eax + + mov bl, 0x10 ; ACK + + ; Get the address of the callers data + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add edx,[edi] + mov esi, edx + + pop eax + push eax + + push ecx + call buildTCPPacket + pop ecx + + ; Check destination IP address. + ; If it is the local host IP, route it back to IP_RX + + pop ebx + push ecx + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne swt_notlocal + mov eax, IPIN_QUEUE + +swt_notlocal: + pop ecx + + push ebx ; save ipbuffer number + + call queue + + mov esi, [sktAddr] + + ; increament SND.NXT in socket + ; Amount to increment by is in ecx + add esi, 48 + call add_inet_esi + + pop ebx + + ; Copy the IP buffer to a resend queue + ; If there isn't one, dont worry about it for now + mov esi, resendQ + mov ecx, 0 + +swt003: + cmp ecx, NUMRESENDENTRIES + je swt001 ; None found + cmp [esi], byte 0xFF + je swt002 ; found one + inc ecx + add esi, 4 + jmp swt003 + +swt002: + push ebx + + ; OK, we have a buffer descriptor ptr in esi. + ; resend entry # in ecx + ; Populate it + ; socket # + ; retries count + ; retry time + ; fill IP buffer associated with this descriptor + + mov eax, [sktAddr] + sub eax, sockets + shr eax, 12 ; get skt # + mov [esi], al + mov [esi + 1], byte TCP_RETRIES + mov [esi + 2], word TCP_TIMEOUT + + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov edi, resendBuffer - IPBUFFSIZE +swt002a: + add edi, IPBUFFSIZE + loop swt002a + + ; we have dest buffer location in edi + pop eax + ; convert source buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + mov esi, eax + + ; do copy + mov ecx, IPBUFFSIZE + cld + rep movsb + + inc dword [arp_rx_count] ; ************ TEST ONLY! + +swt001: + xor eax, eax + +swt_exit: + ret + + + +; Below, the main network layer source code is included +; + +include "queue.inc" +include "ip.inc" +include "tcp.inc" +include "udp.inc" +include "eth_drv/ethernet.inc" diff --git a/kernel/tags/kolibri0.6.0.0/network/tcp.inc b/kernel/tags/kolibri0.6.0.0/network/tcp.inc new file mode 100644 index 0000000000..179f42535e --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/tcp.inc @@ -0,0 +1,1243 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; TCP.INC ;; +;; ;; +;; TCP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Version 0.6 4th July 2004 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; v0.6 : Added reset handling in the established state ;; +;; Added a timer per socket to allow delays when rx window ;; +;; gets below 1KB ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; Interface +; +; tcp_tx_handler Handles the TCP transmit queue +; tcp_rx The protocol handler for received data +; buildTCPPacket fills in the packet headers and data +; tcpStateMachine Main state machine for received TCP packets +; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state +; +;******************************************************************* + + + +;*************************************************************************** +; Function +; tcp_tcb_handler +; +; Description +; Handles sockets in the timewait state, closing them +; when the TCB timer expires +; +;*************************************************************************** +tcp_tcb_handler: + ; scan through all the sockets, decrementing active timers + + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +tth1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets + 32], dword 0 + jne tth2 + +tth1a: + cmp [eax + sockets + 72], dword 0 + jne tth4 + + loop tth1 + ret + +tth2: + ; decrement it, delete socket if TCB timer = 0 & socket in timewait state + pusha + dec dword [eax + sockets + 32] + cmp [eax + sockets + 32], dword 0 + jne tth3 + + cmp [eax + sockets + 28], dword TCB_TIME_WAIT + jne tth3 + + ; OK, delete socket + mov edi, eax + add edi, sockets + + xor eax, eax + mov ecx, SOCKETHEADERSIZE + cld + rep stosb + +tth3: + popa + + jmp tth1a + + loop tth1 + ret + + ; TODO - prove it works! +tth4: + dec dword [eax + sockets + 72] + loop tth1 + ret + + + + +tth_exit: + ret + + +;*************************************************************************** +; Function +; tcp_tx_handler +; +; Description +; Handles queued TCP data +; This is a kernel function, called by stack_handler +; +;*************************************************************************** +tcp_tx_handler: + ; decrement all resend buffers timers. If they + ; expire, queue them for sending, and restart the timer. + ; If the retries counter reach 0, delete the entry + + mov esi, resendQ + mov ecx, 0 + +tth001: + cmp ecx, NUMRESENDENTRIES + je tth003 ; None left + cmp [esi], byte 0xFF + jne tth002 ; found one + inc ecx + add esi, 4 + jmp tth001 + +tth002: + ; we have one. decrement it's timer by 1 + dec word [esi+2] + mov ax, [esi+2] + cmp ax, 0 + je tth002a + inc ecx + add esi, 4 + jmp tth001 ; Timer not zero, so move on + +tth002a: + mov bl, 0xff + ; restart timer, and decrement retries + ; After the first resend, back of on next, by a factor of 5 + mov [esi+2], word TCP_TIMEOUT * 5 + dec byte [esi+1] + mov al, [esi+1] + cmp al, 0 + jne tth004 + + ; retries now 0, so delete from queue + xchg [esi], bl +tth004: + + ; resend packet + pusha + + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + jne tth004z + + ; TODO - try again in 10ms. + cmp bl, 0xff + jne tth004za + mov [esi], bl + +tth004za: + ; Mark it to expire in 10ms - 1 tick + mov [esi+1], byte 1 + mov [esi+2], word 1 + jmp tth005 + +tth004z: + ; we have a buffer # in ax + + push eax + push ecx + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + ; we have the buffer address in eax + mov edi, eax + pop ecx + ; get resend data address + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov esi, resendBuffer - IPBUFFSIZE +tth004a: + add esi, IPBUFFSIZE + loop tth004a + + ; we have resend buffer location in esi + mov ecx, IPBUFFSIZE + + ; copy data across + cld + rep movsb + + ; queue packet + + + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ edi + 16 ] + cmp edx, ecx + jne tth004b + mov eax, IPIN_QUEUE + +tth004b: + pop ebx + + call queue + + +tth005: + popa + + inc ecx + add esi, 4 + jmp tth001 + +tth003: + ret + + + + +;*************************************************************************** +; Function +; tcp_rx +; +; Description +; TCP protocol handler +; This is a kernel function, called by ip_rx +; IP buffer address given in edx +; IP buffer number in eax +; Free up (or re-use) IP buffer when finished +; +;*************************************************************************** +tcp_rx: + ; The process is as follows. + ; Look for a socket with matching remote IP, remote port, local port + ; if not found, then + ; look for remote IP + local port match ( where sockets remote port = 0) + ; if not found, then + ; look for a socket where local socket port == IP packets remote port + ; where sockets remote port, remote IP = 0 + ; discard if not found + ; Call sockets tcbStateMachine, with pointer to packet. + ; the state machine will not delete the packet, so do that here. + + push eax + + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; IP Packet SA = Remote IP + ; IP Packet TCP Source Port = remote Port + + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS +ss1: + sub eax, SOCKETBUFFSIZE + movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst1 ; different - try next socket + + movzx ebx, word [edx + 20] ; get the source port from the TCP hdr + cmp [eax + sockets + 20], bx ; compare with socket's remote port + jnz nxttst1 ; different - try next socket + + + mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr + cmp [eax + sockets + 16], ebx ; compare with socket's remote IP + jnz nxttst1 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst1: + loop ss1 ; Return back if no match + + ; If we got here, there was no match + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; IP Packet SA = Remote IP + ; socket remote Port = 0 + + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +ss2: + sub eax, SOCKETBUFFSIZE + + movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst2 ; different - try next socket + + mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr + cmp [eax + sockets + 16], ebx ; compare with socket's remote IP + jnz nxttst2 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 20], bx ; only match a remote socket of 0 + jnz nxttst2 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst2: + loop ss2 ; Return back if no match + + ; If we got here, there was no match + ; Look for a socket where + ; IP Packet TCP Destination Port = local Port + ; socket Remote IP = 0 + ; socket remote Port = 0 + + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +ss3: + sub eax, SOCKETBUFFSIZE + + movzx ebx, word [edx + 22] ; get destination port from the TCP hdr + cmp [eax + sockets + 12], bx ; compare with socket's local port + jnz nxttst3 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 20], bx ; only match a remote socket of 0 + jnz nxttst3 ; different - try next socket + + mov ebx, 0 + cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0 + jnz nxttst3 ; different - try next socket + + ; We have a complete match - use this socket + jmp tcprx_001 + +nxttst3: + loop ss3 ; Return back if no match + + ; If we got here, we need to reject the packet + inc dword [dumped_rx_count] + jmp tcprx_exit + +tcprx_001: + ; We have a valid socket/TCB, so call the TCB State Machine for that skt. + ; socket is pointed to by [eax + sockets] + ; IP packet is pointed to by [edx] + ; IP buffer number is on stack ( it will be popped at the end) + call tcpStateMachine + +tcprx_exit: + pop eax + call freeBuff + + ret + + + +;*************************************************************************** +; Function +; buildTCPPacket +; +; Description +; builds an IP Packet with TCP data fully populated for transmission +; You may destroy any and all registers +; TCP control flags specified in bl +; This TCB is in [sktAddr] +; User data pointed to by esi +; Data length in ecx +; Transmit buffer number in eax +; +;*************************************************************************** +buildTCPPacket: + push ecx ; Save data length + + ; convert buffer pointer eax to the absolute address + mov ecx, IPBUFFSIZE + mul ecx + add eax, IPbuffs + + mov edx, eax + + mov [edx + 33], bl ; TCP flags + + mov ebx, [sktAddr] + + ; So, ebx holds the socket ptr, edx holds the IPbuffer ptr + + ; Fill in the IP header ( some data is in the socket descriptor) + mov eax, [ebx + 8] + mov [edx + 12], eax ; source IP + mov eax, [ebx + 16] + mov [edx + 16], eax ; Destination IP + + mov al, 0x45 + mov [edx], al ; Version, IHL + xor al, al + mov [edx + 1], al ; Type of service + + pop eax ; Get the TCP data length + push eax + + add eax, 20 + 20 ; add IP header and TCP header lengths + mov [edx + 2], ah + mov [edx + 3], al + xor al, al + mov [edx + 4], al + mov [edx + 5], al + mov al, 0x40 + mov [edx + 6], al + xor al, al + mov [edx + 7], al + mov al, 0x20 + mov [edx + 8], al + mov al, 6 ; TCP protocol + mov [edx + 9], al + + ; Checksum left unfilled + xor ax, ax + mov [edx + 10], ax + + ; Fill in the TCP header ( some data is in the socket descriptor) + mov ax, [ebx + 12] + mov [edx + 20], ax ; Local Port + + mov ax, [ebx + 20] + mov [edx + 20 + 2], ax ; desitination Port + + ; Checksum left unfilled + xor ax, ax + mov [edx + 20 + 16], ax + + ; sequence number + mov eax, [ebx + 48] + mov [edx + 20 + 4], eax + + ; ack number + mov eax, [ebx + 56] + mov [edx + 20 + 8], eax + + ; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size) + ; 768 bytes seems better + mov ax, 0x0003 + mov [edx + 20 + 14], ax + + ; Urgent pointer (0) + mov ax, 0 + mov [edx + 20 + 18], ax + + ; data offset ( 0x50 ) + mov al, 0x50 + mov [edx + 20 + 12], al + + pop ecx ; count of bytes to send + mov ebx, ecx ; need the length later + + cmp ebx, 0 + jz btp_001 + + mov edi, edx + add edi, 40 + cld + rep movsb ; copy the data across + +btp_001: + ; we have edx as IPbuffer ptr. + ; Fill in the TCP checksum + ; First, fill in pseudoheader + mov eax, [edx + 12] + mov [pseudoHeader], eax + mov eax, [edx + 16] + mov [pseudoHeader+4], eax + mov ax, 0x0600 ; 0 + protocol + mov [pseudoHeader+8], ax + add ebx, 20 + mov eax, ebx + mov [pseudoHeader+10], ah + mov [pseudoHeader+11], al + + mov eax, pseudoHeader + mov [checkAdd1], eax + mov [checkSize1], word 12 + mov eax, edx + add eax, 20 + mov [checkAdd2], eax + mov eax, ebx + mov [checkSize2], ax + + call checksum + + ; store it in the TCP checksum ( in the correct order! ) + mov ax, [checkResult] + + mov [edx + 20 + 16], ah + mov [edx + 20 + 17], al + + ; Fill in the IP header checksum + mov eax, edx + mov [checkAdd1], eax + mov [checkSize1], word 20 + mov [checkAdd2], dword 0 + mov [checkSize2], word 0 + + call checksum + + mov ax, [checkResult] + mov [edx + 10], ah + mov [edx + 11], al + + ret + + +; Increments the 32 bit value pointed to by esi in internet order +inc_inet_esi: + push eax + add esi, 3 + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + cmp al, 0 + jnz iie_exit + dec esi + mov al, byte[esi] + inc al + mov byte[esi], al + +iie_exit: + pop eax + ret + + +; Increments the 32 bit value pointed to by esi in internet order +; by the value in ecx +add_inet_esi: + push eax + + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + shl eax, 8 + inc esi + mov al, [esi] + add eax, ecx + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + dec esi + shr eax, 8 + mov [esi], al + pop eax + ret + + +iglobal + TCBStateHandler: + dd stateTCB_LISTEN + dd stateTCB_SYN_SENT + dd stateTCB_SYN_RECEIVED + dd stateTCB_ESTABLISHED + dd stateTCB_FIN_WAIT_1 + dd stateTCB_FIN_WAIT_2 + dd stateTCB_CLOSE_WAIT + dd stateTCB_CLOSING + dd stateTCB_LAST_ACK + dd stateTCB_TIME_WAIT + dd stateTCB_CLOSED +endg + +;*************************************************************************** +; Function +; tcpStateMachine +; +; Description +; TCP state machine +; This is a kernel function, called by tcp_rx +; +; IP buffer address given in edx +; Socket/TCB address in [eax + sockets] +; +; The IP buffer will be released by the caller +;*************************************************************************** +tcpStateMachine: + mov ebx, sockets + add ebx, eax + mov [sktAddr], ebx + + ; as a packet has been received, update the TCB timer + mov ecx, TWOMSL + mov [ebx + 32], ecx + + ; If the received packet has an ACK bit set, + ; remove any packets in the resend queue that this + ; received packet acknowledges + pusha + mov cl, [edx + 33] + and cl, 0x10 + cmp cl, 0x10 + jne tsm001 ; No ACK, so no data yet + + + ; get skt number in al + shr eax, 12 + + ; The ack number is in [edx + 28], inet format + ; skt in al + + mov esi, resendQ + mov ecx, 0 + +t001: + cmp ecx, NUMRESENDENTRIES + je t003 ; None left + cmp [esi], al + je t002 ; found one + inc ecx + add esi, 4 + jmp t001 + +t002: ; Can we delete this buffer? + + ; If yes, goto t004. No, goto t001 + ; Get packet data address + + push ecx + inc ecx + ; Now get buffer location, and copy buffer across. argh! more copying,, + mov edi, resendBuffer - IPBUFFSIZE +t002a: + add edi, IPBUFFSIZE + loop t002a + + ; we have dest buffer location in edi. incoming packet in edx. + ; Get this packets sequence number + ; preserve al, ecx, esi, edx + + mov cl, [edi + 24] + shl ecx, 8 + mov cl, [edi + 25] + shl ecx, 8 + mov cl, [edi + 26] + shl ecx, 8 + mov cl, [edi + 27] + movzx ebx, byte [edi + 3] + mov bh, [edi + 2] + sub ebx, 40 + add ecx, ebx ; ecx is now seq# of last byte +1, intel format + + ; get recievd ack #, in intel format + mov bl, [edx + 28] + shl ebx, 8 + mov bl, [edx + 29] + shl ebx, 8 + mov bl, [edx + 30] + shl ebx, 8 + mov bl, [edx + 31] + + cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que + ; DANGER! need to handle case that we have just + ; passed the 2**32, and wrapped round! + pop ecx + + jae t004 ; if rx > old, delete old + inc ecx + add esi, 4 + jmp t001 + + +t004: + dec dword [arp_rx_count] ; ************ TEST ONLY! + + mov [esi], byte 0xFF + inc ecx + add esi, 4 + jmp t001 + +t003: + +tsm001: + popa + + ; Call handler for given TCB state + mov ebx, [eax + sockets+28] + cmp ebx, TCB_LISTEN + jb tsm_exit + cmp ebx, TCB_CLOSED + ja tsm_exit + + dec ebx + call dword [TCBStateHandler+ebx*4] + +tsm_exit: + ret + + + +stateTCB_LISTEN: + ; In this case, we are expecting a SYN packet + ; For now, if the packet is a SYN, process it, and send a response + ; If not, ignore it + + ; Look at control flags + mov bl, [edx + 33] + and bl, 0x02 + cmp bl, 0x02 + jnz stl_exit + + ; We have a SYN. update the socket with this IP packets details, + ; And send a response + + mov ebx, [edx + 12] ; IP source address + mov [eax + sockets + 16], ebx + mov bx, [edx + 20] ; IP source port + mov [eax + sockets + 20], bx + mov ebx, [edx + 24] ; IRS + mov [eax + sockets + 40], ebx + mov [eax + sockets + 56], ebx + mov esi, sockets + add esi, eax + add esi, 56 + call inc_inet_esi ; RCV.NXT + mov ebx, [eax + sockets + 36] ; ISS + mov [eax + sockets + 48], ebx ; SND.NXT + + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stl_exit + + push eax + mov bl, 0x12 ; SYN + ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stl_notlocal + mov eax, IPIN_QUEUE + +stl_notlocal: + ; Send it. + pop ebx + call queue + + + mov ebx, TCB_SYN_RECEIVED + mov esi, [sktAddr] + mov [esi + 28], ebx + + ; increament SND.NXT in socket + add esi, 48 + call inc_inet_esi + +stl_exit: + ret + + + +stateTCB_SYN_SENT: + ; We are awaiting an ACK to our SYN, with a SYM + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x12 + cmp bl, 0x12 + jnz stss_exit + + mov ebx, TCB_ESTABLISHED + mov esi, [sktAddr] + mov [esi + 28], ebx + + ; Store the recv.nxt field + mov eax, [edx + 24] + + ; Update our recv.nxt field + mov esi, [sktAddr] + add esi, 56 + mov [esi], eax + call inc_inet_esi + + ; Send an ACK + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stss_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stss_notlocal + mov eax, IPIN_QUEUE + +stss_notlocal: + ; Send it. + pop ebx + call queue + +stss_exit: + ret + + + +stateTCB_SYN_RECEIVED: + ; In this case, we are expecting an ACK packet + ; For now, if the packet is an ACK, process it, + ; If not, ignore it + + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stsr_exit + + mov ebx, TCB_ESTABLISHED + mov esi, [sktAddr] + mov [esi + 28], ebx + +stsr_exit: + ret + + + +stateTCB_ESTABLISHED: + ; Here we are expecting data, or a request to close + ; OR both... + + ; Did we receive a FIN or RST? + mov bl, [edx + 33] + and bl, 0x05 + cmp bl, 0 + je ste_chkack + + ; It was a fin or reset. + + ; Remove resend entries from the queue - I dont want to send any more data + pusha + + mov ebx, [sktAddr] + sub ebx, sockets + shr ebx, 12 ; get skt # + + mov esi, resendQ + mov ecx, 0 + +ste001: + cmp ecx, NUMRESENDENTRIES + je ste003 ; None left + cmp [esi], bl + je ste002 ; found one + inc ecx + add esi, 4 + jmp ste001 + +ste002: + dec dword [arp_rx_count] ; ************ TEST ONLY! + + mov [esi], byte 0xFF + jmp ste001 + +ste003: + popa + + ; was it a reset? + mov bl, [edx + 33] + and bl, 0x04 + cmp bl, 0x04 + jne ste003a + + mov esi, [sktAddr] + mov ebx, TCB_CLOSED + mov [esi + 28], ebx + jmp ste_exit + +ste003a: + ; Send an ACK to that fin, and enter closewait state + + mov esi, [sktAddr] + mov ebx, TCB_CLOSE_WAIT + mov [esi + 28], ebx + add esi, 56 + mov eax, [esi] ; save original + call inc_inet_esi + ;; jmp ste_ack - NO, there may be data + +ste_chkack: + ; Check that we received an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz ste_exit + + + ; TODO - done, I think! + ; First, look at the incoming window. If this is less than or equal to 1024, + ; Set the socket window timer to 1. This will stop an additional packets being + ; queued. + ; ** I may need to tweak this value, since I do not know how many packets are already queued + mov ch, [edx + 34] + mov cl, [edx + 35] + cmp cx, 1024 + ja ste004 + + mov ecx, [sktAddr] + mov [ecx+72], dword 1 + +ste004: + + ; OK, here is the deal + ; My recv.nct field holds the seq of the expected next rec byte + ; if the recevied sequence number is not equal to this, do not + ; increment the recv.nxt field, do not copy data - just send a + ; repeat ack. + + ; recv.nxt is in dword [edx+24], in inext format + ; recv seq is in [sktAddr]+56, in inet format + ; just do a comparision + mov ecx, [sktAddr] + add ecx, 56 + + cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT + mov ecx, [ecx] + jne stenofin + mov ecx, eax + +stenofin: + cmp ecx, [edx+24] + jne ste_ack + + + ; Read the data bytes, store in socket buffer + xor ecx, ecx + mov ch, [edx + 2] + mov cl, [edx + 3] + sub ecx, 40 ; Discard 40 bytes of header + + cmp ecx, 0 + jnz ste_data ; Read data, if any + + ; If we had received a fin, we need to ACK it. + mov esi, [sktAddr] + mov ebx, [esi + 28] + cmp ebx, TCB_CLOSE_WAIT + jz ste_ack + jnz ste_exit + +ste_data: + push ecx + mov esi, [sktAddr] + + add [esi + 24], ecx ; increment the count of bytes in buffer + + mov eax, [esi + 4] ; get socket owner PID + push eax + + mov eax, [esi + 24] ; get # of bytes already in buffer + + ; point to the location to store the data + add esi, eax + sub esi, ecx + add esi, SOCKETHEADERSIZE + + add edx, 40 ; edx now points to the data + mov edi, esi + mov esi, edx + + cld + rep movsb ; copy the data across + + ; flag an event to the application + pop eax + mov ecx,1 + mov esi,0x3020+TASKDATA.pid + +news: + cmp [esi],eax + je foundPID1 + inc ecx + add esi,0x20 + cmp ecx,[0x3004] + jbe news + +foundPID1: + shl ecx,8 + or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event + + pop ecx + + ; Update our recv.nxt field + mov esi, [sktAddr] + add esi, 56 + call add_inet_esi + +ste_ack: + ; Send an ACK + ; Now construct the response, and queue for sending by IP + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je ste_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne ste_notlocal + mov eax, IPIN_QUEUE +ste_notlocal: + + ; Send it. + pop ebx + call queue + +ste_exit: + ret + + + +stateTCB_FIN_WAIT_1: + ; We can either receive an ACK of a fin, or a fin + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stfw1_001 + + ; It was an ACK + mov esi, [sktAddr] + mov ebx, TCB_FIN_WAIT_2 + mov [esi + 28], ebx + jmp stfw1_exit + +stfw1_001: + ; It must be a fin then + mov esi, [sktAddr] + mov ebx, TCB_CLOSING + mov [esi + 28], ebx + add esi, 56 + call inc_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stfw1_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stfw1_notlocal + mov eax, IPIN_QUEUE + +stfw1_notlocal: + ; Send it. + pop ebx + call queue + +stfw1_exit: + ret + + + +stateTCB_FIN_WAIT_2: + mov esi, [sktAddr] + + ; Get data length + xor ecx, ecx + mov ch, [edx+2] + mov cl, [edx+3] + sub ecx, 40 + + mov bl, [edx + 33] + and bl, 0x01 + cmp bl, 0x01 + jne stfw2001 + + ; Change state, as we have a fin + mov ebx, TCB_TIME_WAIT + mov [esi + 28], ebx + + inc ecx ; FIN is part of the sequence space + +stfw2001: + add esi, 56 + call add_inet_esi + + ; Send an ACK + mov eax, EMPTY_QUEUE + call dequeue + cmp ax, NO_BUFFER + je stfw2_exit + + push eax + + mov bl, 0x10 ; ACK + mov ecx, 0 + mov esi, 0 + + call buildTCPPacket + + mov eax, NET1OUT_QUEUE + + mov edx, [stack_ip] + mov ecx, [ sktAddr ] + mov ecx, [ ecx + 16 ] + cmp edx, ecx + jne stfw2_notlocal + mov eax, IPIN_QUEUE + +stfw2_notlocal: + ; Send it. + pop ebx + call queue + + ; Only delete the socket if we received the FIN + + mov bl, [edx + 33] + and bl, 0x01 + cmp bl, 0x01 + jne stfw2_exit + +; mov edi, [sktAddr] + + ; delete the socket. Should really wait for 2MSL +; xor eax, eax +; mov ecx,SOCKETHEADERSIZE +; cld +; rep stosb + +stfw2_exit: + ret + + + +stateTCB_CLOSE_WAIT: + ; Intentionally left empty + ; socket_close_tcp handles this + ret + + + +stateTCB_CLOSING: + ; We can either receive an ACK of a fin, or a fin + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stc_exit + + ; It was an ACK + + mov edi, [sktAddr] + + ; delete the socket + xor eax, eax + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +stc_exit: + ret + + + +stateTCB_LAST_ACK: + ; Look at control flags - expecting an ACK + mov bl, [edx + 33] + and bl, 0x10 + cmp bl, 0x10 + jnz stla_exit + + mov edi, [sktAddr] + + ; delete the socket + xor eax, eax + mov ecx,SOCKETHEADERSIZE + cld + rep stosb + +stla_exit: + ret + + + +stateTCB_TIME_WAIT: + ret + + + +stateTCB_CLOSED: + ret diff --git a/kernel/tags/kolibri0.6.0.0/network/udp.inc b/kernel/tags/kolibri0.6.0.0/network/udp.inc new file mode 100644 index 0000000000..ff36d37ab2 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/network/udp.inc @@ -0,0 +1,137 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; UDP.INC ;; +;; ;; +;; UDP Processes for Menuet OS TCP/IP stack ;; +;; ;; +;; Version 0.3 29 August 2002 ;; +;; ;; +;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;******************************************************************* +; Interface +; +; udp_rx Handles received IP packets with the UDP protocol +; +;******************************************************************* + + + + +;*************************************************************************** +; Function +; udp_rx +; +; Description +; UDP protocol handler +; This is a kernel function, called by ip_rx +; IP buffer address given in edx +; Free up (or re-use) IP buffer when finished +; +;*************************************************************************** +udp_rx: + push eax + + ; First validate the header & checksum. Discard buffer if error + + ; Look for a socket where + ; IP Packet UDP Destination Port = local Port + ; IP Packet SA = Remote IP + + movzx ebx, word [edx + 22] ; get the local port from + ; the IP packet's UDP header + mov eax, SOCKETBUFFSIZE * NUM_SOCKETS + mov ecx, NUM_SOCKETS + +fs1: + sub eax, SOCKETBUFFSIZE + cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value, + ; but the comparision is correct + loopnz fs1 ; Return back if no match + jz fs_done + + ; No match, so exit + jmp udprx_001 + +fs_done: + ; For dhcp, we must allow any remote server to respond. + ; I will accept the first incoming response to be the one + ; I bind to, if the socket is opened with a destination IP address of + ; 255.255.255.255 + mov ebx, [eax + sockets + 16] + cmp ebx, 0xffffffff + je udprx_002 + + mov ebx, [edx + 12] ; get the Source address from the IP packet + cmp [eax + sockets + 16], ebx + jne udprx_001 ; Quit if the source IP is not valid + +udprx_002: + ; OK - we have a valid UDP packet for this socket. + ; First, update the sockets remote port number with the incoming msg + ; - it will have changed + ; from the original ( 69 normally ) to allow further connects + movzx ebx, word [edx + 20] ; get the UDP source port + ; ( was 69, now new ) + mov [eax + sockets + 20], bx + + ; Now, copy data to socket. We have socket address as [eax + sockets]. + ; We have IP packet in edx + + ; get # of bytes in ecx + movzx ecx, byte [edx + 3] ; total length of IP packet. Subtract + mov ch, byte [edx + 2] ; 20 + 8 gives data length + sub ecx, 28 + + mov ebx, eax + add ebx, sockets ; ebx = address of actual socket + + mov eax, [ebx+ 4] ; get socket owner PID + push eax + + mov eax, [ebx + 24] ; get # of bytes already in buffer + add [ebx + 24], ecx ; increment the count of bytes in buffer + + ; point to the location to store the data + add ebx, eax + add ebx, SOCKETHEADERSIZE + + ; ebx = location for first byte, ecx has count, + ; edx points to data + + add edx, 28 ; edx now points to the data + mov edi, ebx + mov esi, edx + + cld + rep movsb ; copy the data across + + ; flag an event to the application + pop eax + mov ecx,1 + mov esi,0x3020+TASKDATA.pid + +newsearch: + cmp [esi],eax + je foundPID + inc ecx + add esi,0x20 + cmp ecx,[0x3004] + jbe newsearch + +foundPID: + shl ecx,8 + or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event + + mov [check_idle_semaphore],200 + +udprx_001: + pop eax + call freeBuff ; Discard the packet + ret + \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/skin/base.bmp b/kernel/tags/kolibri0.6.0.0/skin/base.bmp new file mode 100644 index 0000000000..185b1f8289 Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/base.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/base_1.bmp b/kernel/tags/kolibri0.6.0.0/skin/base_1.bmp new file mode 100644 index 0000000000..f53bbeb6f4 Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/base_1.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/default.asm b/kernel/tags/kolibri0.6.0.0/skin/default.asm new file mode 100644 index 0000000000..5d0ea59deb --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/skin/default.asm @@ -0,0 +1,31 @@ +include 'me_skin.inc' + +SKIN_PARAMS \ + height = bmp_base.height,\ ; skin height + margins = [5:1:43:1],\ ; margins [left:top:right:bottom] + colors active = [binner=0x00081d:\ ; border inner color + bouter=0x00081d:\ ; border outer color + bframe=0x0054e7],\ ; border frame color + colors inactive = [binner=0x00081d:\ ; border inner color + bouter=0x00081d:\ ; border outer color + bframe=0x1a8acc],\ ; border frame color + dtp = 'myblue.dtp' ; dtp colors + +SKIN_BUTTONS \ + close = [-21:3][16:16],\ ; buttons coordinates + minimize = [-39:3][16:16] ; [left:top][width:height] + +SKIN_BITMAPS \ + left active = bmp_left,\ ; skin bitmaps pointers + left inactive = bmp_left1,\ + oper active = bmp_oper,\ + oper inactive = bmp_oper1,\ + base active = bmp_base,\ + base inactive = bmp_base1 + +BITMAP bmp_left ,'left.bmp' ; skin bitmaps +BITMAP bmp_oper ,'oper.bmp' +BITMAP bmp_base ,'base.bmp' +BITMAP bmp_left1,'left_1.bmp' +BITMAP bmp_oper1,'oper_1.bmp' +BITMAP bmp_base1,'base_1.bmp' diff --git a/kernel/tags/kolibri0.6.0.0/skin/left.bmp b/kernel/tags/kolibri0.6.0.0/skin/left.bmp new file mode 100644 index 0000000000..bfd97344eb Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/left.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/left_1.bmp b/kernel/tags/kolibri0.6.0.0/skin/left_1.bmp new file mode 100644 index 0000000000..51b9d15f7f Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/left_1.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/me_skin.inc b/kernel/tags/kolibri0.6.0.0/skin/me_skin.inc new file mode 100644 index 0000000000..ccbb3c191c --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/skin/me_skin.inc @@ -0,0 +1,235 @@ +;============================================================================ +; This file should be used to generate skins of new standard +;============================================================================ +; skin file structure: +;---------------------------------------------------------------------------- +; header: +; dd 'SKIN' +; dd = version (1 for now) +; dd @ params +; dd @ buttons +; dd @ bitmaps +; ... +;---------------------------------------------------------------------------- +; NOTE: order of sections listed below is insignificant +; since they're identified by pointer in above header +;---------------------------------------------------------------------------- +; ... +; params: +; dd = skin height +; dw = right margin +; dw = left margin +; dw = bottom margin +; dw = top margin +; dd = inner line color +; dd = outer line color +; dd = frame color +; dd = dtp file size +; ?? = dtp file itself +; ... +;---------------------------------------------------------------------------- +; ... +; buttons: +; dd = button type (1 = close, 2 = minimize) +; dw = left button coord (could be negative) +; dw = top button coord (could be negative) +; dw = button width +; dw = button height +; ... etc for all buttons +; dd = 0 (end of buttons list) +; ... +;---------------------------------------------------------------------------- +; ... +; bitmaps: +; dw = bitmap kind (1 = left, 2 = oper, 3 = base) +; dw = bitmap type (1 = active, 0 = inactive) +; dd @ bitmap +; ... etc for all bitmaps +; dd 0 (end of bitmaps list) +; ... +;---------------------------------------------------------------------------- +; ... +; bitmap: +; dd = bitmap width +; dd = bitmap height +; ?? = raw bitmap data +; ... etc for all bitmaps +; ... +;============================================================================ + +dd 'SKIN',1,__params__,__buttons__,__bitmaps__ + +struc BITMAPFILEHEADER { + .bfType dw ? ; WORD + .bfSize dd ? ; DWORD + .bfReserved1 dw ? ; WORD + .bfReserved2 dw ? ; WORD + .bfOffBits dd ? ; DWORD +} + +struc BITMAPINFOHEADER { + .biSize dd ? ; DWORD + .biWidth dd ? ; LONG + .biHeight dd ? ; LONG + .biPlanes dw ? ; WORD + .biBitCount dw ? ; WORD + .biCompression dd ? ; DWORD + .biSizeImage dd ? ; DWORD + .biXPelsPerMeter dd ? ; LONG + .biYPelsPerMeter dd ? ; LONG + .biClrUsed dd ? ; DWORD + .biClrImportant dd ? ; DWORD +} + +struc _bmp { + .h BITMAPFILEHEADER + .i BITMAPINFOHEADER +} +virtual at 0 + _bmp _bmp +end virtual + +macro BITMAP _name*,_fname* +{ + local w,h,a,r,g,b + virtual at 0 + file _fname + load w dword from _bmp.i.biWidth + load h dword from _bmp.i.biHeight + end virtual + align 4 + label _name + .width = w + .height = h + dd w,h + a=54+(w*3+(w mod 4))*(h-1) + size = $ + repeat h + repeat w + virtual at 0 + file _fname + load r from a+0 + load g from a+1 + load b from a+2 + end virtual + db r,g,b + a=a+3 + end repeat + a=a-w*3*2-(w mod 4) + end repeat +} + +macro define_colors name,[col,val] +{ + common + local a,b,c + forward + match =binner,col \{ a = val \} + match =bouter,col \{ b = val \} + match =bframe,col \{ c = val \} + common + name equ a,b,c +} + +macro SKIN_PARAMS [a] +{ + common + local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz + __params__: + forward + match qq == ww,a + \{ + match =height,qq \\{ _height = ww \\} + match =margins,qq \\{ + match [q1:q2:q3:q4],ww + \\\{ + _margins equ q3,q1,q4,q2 + \\\} + \\} + match =colors =active,qq + \\{ + match [q10==q11:q20==q21:q30==q31],ww + \\\{ + define_colors _colors,q10,q11,q20,q21,q30,q31 + \\\} + \\} + match =colors =inactive,qq + \\{ + match [q10==q11:q20==q21:q30==q31],ww + \\\{ + define_colors _colors_1,q10,q11,q20,q21,q30,q31 + \\\} + \\} + match =dtp,qq \\{ _dtp equ ww \\} + \} + common + dd _height + dw _margins + dd _colors,_colors_1 + virtual at 0 + file _dtp + _dtp_sz = $ + end virtual + dd _dtp_sz + file _dtp +} + +macro SKIN_BUTTONS [a] +{ + common + local btn + __buttons__: + forward + match qq == ww,a + \{ + btn = 0 + match =close,qq \\{ btn = 1 \\} + match =minimize,qq \\{ btn = 2 \\} + match [q1:q2][q3:q4],ww + \\{ + if btn <> 0 + dd btn + dw q1,q2,q3,q4 + end if + \\} + \} + common + dd 0 +} + +macro SKIN_BITMAPS [a] +{ + common + local bmp + __bitmaps__: + forward + match qq == ww,a + \{ + bmp=-1 + match qqq =active,qq \\{ bmp = 1 \\} + match qqq =inactive,qq \\{ bmp = 0 \\} + match =left qqq,qq + \\{ + if bmp >= 0 + dw 1,bmp + dd ww + end if + \\} + match =oper qqq,qq + \\{ + if bmp >= 0 + dw 2,bmp + dd ww + end if + \\} + match =base qqq,qq + \\{ + if bmp >= 0 + dw 3,bmp + dd ww + end if + \\} + \} + common + dd 0 +} \ No newline at end of file diff --git a/kernel/tags/kolibri0.6.0.0/skin/myblue.dtp b/kernel/tags/kolibri0.6.0.0/skin/myblue.dtp new file mode 100644 index 0000000000..9e268cc7a7 Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/myblue.dtp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/oper.bmp b/kernel/tags/kolibri0.6.0.0/skin/oper.bmp new file mode 100644 index 0000000000..6011b6d1bd Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/oper.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/skin/oper_1.bmp b/kernel/tags/kolibri0.6.0.0/skin/oper_1.bmp new file mode 100644 index 0000000000..d57bd2d161 Binary files /dev/null and b/kernel/tags/kolibri0.6.0.0/skin/oper_1.bmp differ diff --git a/kernel/tags/kolibri0.6.0.0/sound/playnote.inc b/kernel/tags/kolibri0.6.0.0/sound/playnote.inc new file mode 100644 index 0000000000..79548434a2 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/sound/playnote.inc @@ -0,0 +1,135 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; PLAYNOTE.INC version 1.1 22 November 2003 ;; +;; ;; +;; Player Notes for Speaker PC ;; +;; subfunction #55 from function #55 Menuet OS ;; +;; ;; +;; Copyright 2003 VaStaNi ;; +;; vastani@ukr.net ;; +;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;; +;; ;; +;; Note: playnote.txt ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562 + dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF +memAdrNote dd 0 +pidProcessNote dd 0 +slotProcessNote dd 0 +count_timer_Note dd 1 +mem8253r42 dw 0 +countDelayNote db 0 + +playNote: +; jmp NotPlayNotes + mov esi, [memAdrNote] + or esi, esi ; ESI = 0 ? - OFF Notes Play ? + jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure + cmp eax, [count_timer_Note] + jb NotPlayNotes + push eax + inc eax + mov [count_timer_Note], eax + mov al, [countDelayNote] + dec al ; decrement counter Delay for Playing Note + jz NewLoadNote@Delay + cmp al, 0xFF ; this is first Note Play ? + jne NextDelayNote + ;This is FIRST Note, save counter channel 2 chip 8253 + mov al, 0xB6 ; control byte to timer chip 8253 + out 0x43, al ; Send it to the control port chip 8253 + in al, 0x42 ; Read Lower byte counter channel 2 chip 8253 + mov ah, al ; AH = Lower byte counter channel 2 + in al, 0x42 ; Read Upper byte counter channel 2 chip 8253 + mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253 + NewLoadNote@Delay: + cld +; lodsb ; load AL - counter Delay + call ReadNoteByte + or al, al ; THE END ? + jz EndPlayNote + cmp al, 0x81 + jnc NoteforOctave + mov [countDelayNote], al +; lodsw ; load AX - counter for Note! + call ReadNoteByte + mov ah,al + call ReadNoteByte + xchg al,ah + jmp pokeNote + + EndPlayNote: ; THE END Play Notes! + in al, 0x61 ; Get contents of system port B chip 8255 + and al, 0xFC ; Turn OFF timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253 + xchg al, ah ; reverse byte in word + out 0x42, al ; restore Lower byte counter channel 2 + mov al, ah ; AL = Upper byte counter channel 2 + out 0x42, al ; restore Upper byte channel 2 + xor eax, eax ; EAX = 0 + mov [memAdrNote], eax ; clear header control Delay-Note string + NextDelayNote: + mov [countDelayNote], al ; save new counter delay Note + pop eax + NotPlayNotes: + RET + + NoteforOctave: + sub al, 0x81 ; correction value for delay Note + mov [countDelayNote], al ; save counter delay this new Note +; lodsb ; load pack control code + call ReadNoteByte + cmp al, 0xFF ; this is PAUSE ? + jne packCode ; no, this is PACK CODE + in al, 0x61 ; Get contents of system port B chip 8255 + and al, 0xFC ; Turn OFF timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + jmp saveESI + + packCode: + mov cl, al ; save code + and al, 0xF ; clear upper bits + dec al ; correction + add al, al ; transform number to offset constant + movsx eax, al ; EAX - offset + add eax, dword kontrOctave ; EAX - address from constant + mov ax, [eax] ; read constant + shr cl, 4 ; transform for number Octave + shr ax, cl ; calculate from Note this Octave! + pokeNote: + out 0x42, al ; Lower byte Out to channel 2 timer chip 8253 + mov al, ah + out 0x42, al ; Upper byte Out to channel 2 timer chip 8253 + in al, 0x61 ; Get contents of system port B chip 8255 + or al, 3 ; Turn ON timer and speaker + out 0x61, al ; Send out new values to port B chip 8255 + saveESI: +; mov [memAdrNote], esi ; save new header control Delay-Note string + pop eax + RET +ReadNoteByte: +;result: +; al - note + push eax + push ebx + push ecx + push edx + mov eax,[pidProcessNote] + call pid_to_slot + test eax,eax + jz .failed + lea ebx,[esp+12] + mov ecx,1 + mov edx,[memAdrNote] + inc [memAdrNote] + call read_process_memory +.failed: + pop edx + pop ecx + pop ebx + pop eax + ret +;------------------- END CODE ------------------- diff --git a/kernel/tags/kolibri0.6.0.0/sound/sb16.inc b/kernel/tags/kolibri0.6.0.0/sound/sb16.inc new file mode 100644 index 0000000000..6d7ec5e979 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/sound/sb16.inc @@ -0,0 +1,350 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SB16.INC ;; +;; ;; +;; Sound Blaster 16 functions for MenuetOS ;; +;; ;; +;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;; - 11.07.2002 8 bit stereo mode - Ville Turjanmaa ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +SB16_load_music equ 0xc0000000 +SB16_play_music equ 0xc0000001 +DMAPage equ 0x2A +Rate equ 44100 +SB16Buffer equ 0x2A0000 +SB16_Status equ SB16Buffer+65536 + +iglobal + sound_data_format dd 0x1 + sound_data_length dd 65536 + sound_data_freq dd 44100 +endg + +sound_interface: + + cmp eax,0 ; Load data + jne no_SB16_load_music + mov edi,[0x3010] + add edi,TASKDATA.mem_start + add ebx,[edi] + call code_SB16_load_music + ret + no_SB16_load_music: + + cmp eax,1 ; Play data + jne no_SB16_play_music + call code_SB16_play_music + ret + no_SB16_play_music: + + cmp eax,2 ; Set data formats + jne no_SB16_data_format + cmp ebx,0 ; ebx=0 play format + jne no_sound_format + mov [sound_data_format],ecx ; 1=8b mono, 2=8b stereo + ret + no_sound_format: + cmp ebx,1 ; ebx=1 data length + jne no_sound_length + mov [sound_data_length],ecx ; + ret + no_sound_length: + cmp ebx,2 ; ebx=2 sound data frequency + jne no_sound_freq + mov [sound_data_freq],ecx + ret + no_sound_freq: + ret + + no_SB16_data_format: + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + cmp eax, edi ; this is subfunction #55 ? + jne retFunc55 ; if no then return. + cmp byte [sound_flag],0 + jne retFunc55 + movzx eax, byte [countDelayNote] + or al, al ; player is busy ? + jnz retFunc55 ; return counter delay Note +; mov eax, [0x3010] +; mov eax, [eax+0x10] ; address application im memory +; add eax, edx ; add offset Delay-Note string +; mov [memAdrNote], eax + mov [memAdrNote],edx + mov eax,[0x3010] + mov eax,[eax+TASKDATA.pid] + mov [pidProcessNote],eax + xor eax, eax ; Ok! EAX = 0 + retFunc55: + mov [esp+36], eax ; return value EAX for application +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + ret + + + + +code_SB16_play_music: + + cmp [sound_data_format],1 + jne no_sound_8bm + call sb_play_8b_mono + ret + no_sound_8bm: + + cmp [sound_data_format],2 + jne no_sound_8bs + call sb_play_8b_stereo + ret + no_sound_8bs: + + ret + + + + + +Blaster_command: + + push eax + push ecx + push edx + + mov dx,word [sb16] + add dx,0xc + mov cx,1000 + bcl1: + in al,dx + and al,128 + jz bcl2 + loop bcl1 + bcl2: + mov al,[esp+8] + mov dx,[esp+0] + add dx,word [sb16] + out dx,al + + pop edx + pop ecx + pop eax + + ret + + +sb_play_8b_stereo: + + pusha + + call sb_set_dma + + call sb_set_stereo + + mov dx,0xc + mov al,0xa8 + call Blaster_command + + mov al,0x40 + call Blaster_command + + mov al,245 + call Blaster_command + + mov al,0x48 + call Blaster_command + + mov al,0xff + call Blaster_command + call Blaster_command + + mov al,0x91 + call Blaster_command + + popa + ret + + + +sb_set_stereo: + + push eax + push edx + + call sb_wait + + mov dx,word [sb16] + add dx,0x4 + mov al,0xe + out dx,al + inc dx + in al,dx + and al,253 + or al,2 ; stereo + out dx,al + + pop edx + pop eax + ret + + + +code_SB16_load_music: + + cmp byte [SB16_Status],1 + je nol + mov edi,SB16Buffer + mov esi,ebx + mov ecx,65536/4 + cld + rep movsd +nol: ret + + +iglobal + dma_table db 0x87,0x83,0x81,0x82 +endg + + + +;-------------------------------- +; program dma +;-------------------------------- + +sb_set_dma: + + pusha + + mov eax,[sound_dma] + add eax,4 + out 0xa,al + + mov al,0 + out 0xc,al + + mov eax,[sound_dma] + add eax,0x48 + out 0xb,al + + mov edx,[sound_dma] + shl edx,1 + mov al,0 + out dx,al + + mov al,0 + out dx,al + + mov edx,[sound_dma] + add edx,dma_table + movzx edx,byte [edx] + mov al,DMAPage + out dx,al + + mov edx,[sound_dma] + shl edx,1 + inc edx + mov eax,[sound_data_length] + dec eax + and eax,0xff + ; mov al,(DataLength-1) and 0xff + out dx,al + + mov eax,[sound_data_length] + dec eax + shr eax,8 + ; mov al,(DataLength-1) shr 8 + out dx,al + + mov eax,[sound_dma] ; DMA + out 0xa,al + + popa + ret + + + +sb_play_8b_mono: + + + call sb_set_dma + + cmp byte [SB16_Status],1 + jne contsb16 + jmp retserve + contsb16: + + mov dx,word [sb16] + add dx,4 + mov ecx,[sound_dma] + mov ax,0x01 + shl ax,cl + shl ax,8 + add ax,0x81 + out dx,ax + + mov ax,0f280h ;enable irq5 + out dx,ax + + +adr1_SB: mov dx,word [sb16] + add dx,0ch + in al,dx + and al,080h + jnz adr1_SB + + call sb_set_stereo + + mov al,0d1h + out dx,al + + + mov dx,word [sb16] + add dx,0ch + + call sb_wait + + mov al,40h ; Rate + out dx,al + call sb_wait + mov al,256-1000000/Rate + out dx,al + + call sb_wait + + mov al,14h ; Datalength + out dx,al + call sb_wait + + mov eax,[sound_data_length] + dec eax + and eax,0xff + ;mov al,(DataLength-1) and 0xff + out dx,al + call sb_wait + mov eax,[sound_data_length] + dec eax + shr eax,8 + ;mov al,(DataLength-1) shr 8 + out dx,al + + retserve: + + ret + + +sb_wait: in al,dx ;wait + and al,080h + jnz sb_wait + + ret + + + + +;**************************************** +; END CODE SB16 by Minazzi Paolo +;*************************************** diff --git a/kernel/tags/kolibri0.6.0.0/video/vesa12.inc b/kernel/tags/kolibri0.6.0.0/video/vesa12.inc new file mode 100644 index 0000000000..fd8aeef34a --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/video/vesa12.inc @@ -0,0 +1,987 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; VESA12.INC ;; +;; ;; +;; Vesa 1.2 functions for MenuetOS ;; +;; ;; +;; Copyright 2002 Ville Turjanmaa ;; +;; ;; +;; quickcode@mail.ru - bankswitch for S3 cards ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +; A complete video driver should include the following types of function +; +; Putpixel +; Getpixel +; +; Drawimage +; Drawbar +; +; Drawbackground +; +; +; Modifying the set_bank -function is mostly enough +; for different Vesa 1.2 setups. + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +; set_bank for Trident videocards, work on Trident 9440 +; modified by Mario79 +;set_bank: +;cli +;cmp al,[0xfff2] +;je retsb +;mov [0xfff2],al +;push dx +;mov dx,3D8h +;out dx,al +;pop dx +;retsb: +;sti +;ret + + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +; set_bank for S3 videocards, work on S3 ViRGE PCI (325) +; modified by kmeaw +set_bank: +pushfd +cli +cmp al,[0xfff2] +je retsb +mov [0xfff2],al +push ax +push dx +push cx +mov cl, al +mov dx, 0x3D4 +mov al, 0x38 +out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to + ;unlock and 00h to lock +inc dx +mov al, 0x48 +out dx, al ;3d5 -? +dec dx +mov al, 0x31 +out dx, al ;CR31 Memory Configuration Register +;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear. +;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h, +;for the 864/964 see index 69h. + +inc dx +in al, dx +dec dx +mov ah, al +mov al, 0x31 +out dx, ax +mov al, ah +or al, 9 +inc dx +out dx, al +dec dx +mov al, 0x35 +out dx, al ;CR35 CRT Register Lock +inc dx +in al, dx +dec dx +and al, 0xF0 +mov ch, cl +and ch, 0x0F +or ch, al +mov al, 0x35 +out dx, al +inc dx +mov al, ch +out dx, ax +dec dx +mov al, 0x51 ;Extended System Control 2 Register +out dx, al +inc dx +in al, dx +dec dx +and al, 0xF3 +shr cl, 2 +and cl, 0x0C +or cl, al +mov al, 0x51 +out dx, al +inc dx +mov al, cl +out dx, al +dec dx +mov al, 0x38 +out dx, al +inc dx +xor al, al +out dx, al +dec dx +pop cx +pop dx +pop ax +retsb: +popfd +ret + +;Set bank function for Intel 810/815 chipsets +; *****Modified by Protopopius, Russia.***** +; ********* http://menuetos.hut.ru ************** +; ************************************************ +; +;set_bank: +;cli +;cmp al,[0xfff2] +;je retsb +;mov [0xfff2],al +;push ax +;push dx +;mov dx,3CEh +;mov ah,al ; Save value for later use +;mov al,10h ; Index GR10 (Address Mapping) +;out dx,al ; Select GR10 +;inc dl +;mov al,3 ; Set bits 0 and 1 (Enable linear page mapping) +;out dx,al ; Write value +;dec dl +;mov al,11h ; Index GR11 (Page Selector) +;out dx,al ; Select GR11 +;inc dl +;mov al,ah ; Write address +;out dx,al ; Write the value +;pop dx +;pop ax +;retsb: +;sti +;ret + +;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} + +;set_bank: +; cli +; cmp al,[0xfff2] +; je retsb +; mov [0xfff2],al +; push ax +; push dx +; mov ah,al +; mov dx,0x03D4 +; mov al,0x39 +; out dx,al +; inc dl +; mov al,0xA5 +; out dx,al +; dec dl +; mov al,6Ah +; out dx,al +; inc dl +; mov al,ah +; out dx,al +; dec dl +; mov al,0x39 +; out dx,al +; inc dl +; mov al,0x5A +; out dx,al +; dec dl +; pop dx +; pop ax +; +; retsb: +; ret + + +vesa12_drawbackground: + + call [disable_mouse] + + push eax + push ebx + push ecx + push edx + + xor edx,edx + mov eax,dword[WinMapAddress-8] + mov ebx,dword[WinMapAddress-4] + mul ebx + mov ebx,3 + mul ebx + mov [imax],eax + mov eax,[draw_data+32+RECT.left] + mov ebx,[draw_data+32+RECT.top] + mov edi,0 ;no force + + v12dp3: + + push eax + push ebx + mov esi,0x300000 + + cmp [WinMapAddress-12],dword 1 ; tiled background + jne no_vesa12_tiled_bgr + + push edx + + xor edx,edx + mov ecx,[WinMapAddress-8] + div ecx + mov eax,edx + + push eax + mov eax,ebx + xor edx,edx + mov ecx,[WinMapAddress-4] + div ecx + mov ebx,edx + pop eax + + pop edx + + no_vesa12_tiled_bgr: + + cmp [WinMapAddress-12],dword 2 ; stretched background + jne no_vesa12_stretched_bgr + + push edx + + imul eax,dword [WinMapAddress-8] + xor edx,edx + mov ecx,[0xfe00] + inc ecx + div ecx + + push eax + mov eax,ebx + imul eax,dword [WinMapAddress-4] + xor edx,edx + mov ecx,[0xfe04] + inc ecx + div ecx + mov ebx,eax + pop eax + + pop edx + + no_vesa12_stretched_bgr: + + + push eax + mov eax,ebx + xor edx,edx + mov ebx,[WinMapAddress-8] + add ebx,[WinMapAddress-8] + add ebx,[WinMapAddress-8] + mul ebx + mov esi,eax + pop eax + add esi,eax + add esi,eax + add esi,eax + add esi,0x300000 + pop ebx + pop eax + + v12di4: + + mov ecx,[esi] + pusha + mov esi,eax + mov edi,ebx + mov eax,[0xfe00] + add eax,1 + mul ebx + add eax,esi + add eax,WinMapAddress + cmp [eax],byte 1 + jnz v12nbgp + mov eax,[0xfe08] + mov ebx,edi + mul ebx + add eax,esi + add eax,esi + add eax,esi + cmp [0xFBF1],byte 24 + jz v12bgl3 + add eax,esi + + v12bgl3: + + push ebx + push eax + + sub eax,[0xfe80] + + shr eax,16 + call set_bank + pop eax + and eax,65535 + add eax,0xa0000 + pop ebx + + mov [eax],cx + add eax,2 + shr ecx,16 + mov [eax],cl + sti + + v12nbgp: + + popa + add esi,3 + inc eax + cmp eax,[draw_data+32+RECT.right] + jg v12nodp31 + jmp v12dp3 + + v12nodp31: + + mov eax,[draw_data+32+RECT.left] + inc ebx + cmp ebx,[draw_data+32+RECT.bottom] + jg v12dp4 + jmp v12dp3 + + v12dp4: + + pop edx + pop ecx + pop ebx + pop eax + ret + + +vesa12_drawbar: + + call [disable_mouse] + +;; mov [novesachecksum],dword 0 + sub edx,ebx + sub ecx,eax + push esi + push edi + push eax + push ebx + push ecx + push edx + mov ecx,[0x3010] + add eax,[ecx-twdw+WDATA.box.left] + add ebx,[ecx-twdw+WDATA.box.top] + push eax + mov eax,ebx ; y + mov ebx,[0xfe08] + mul ebx + pop ecx + add eax,ecx ; x + add eax,ecx + add eax,ecx + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start + jz dbpi2412 + add eax,ecx + + dbpi2412: + + add eax,[0xfe80] + mov edi,eax + + ; x size + + mov eax,[esp+4] ; [esp+6] + mov ecx,eax + add ecx,eax + add ecx,eax + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size + jz dbpi24312 + add ecx,eax + + dbpi24312: + + mov ebx,[esp+0] + + ; check limits ? + + push eax + push ecx + mov eax,[0x3010] + mov ecx,[eax+draw_data-0x3000+RECT.left] + cmp ecx,0 + jnz dbcblimitlset12 + mov ecx,[eax+draw_data-0x3000+RECT.top] + cmp ecx,0 + jnz dbcblimitlset12 + mov ecx,[eax+draw_data-0x3000+RECT.right] + cmp ecx,[0xfe00] + jnz dbcblimitlset12 + mov ecx,[eax+draw_data-0x3000+RECT.bottom] + cmp ecx,[0xfe04] + jnz dbcblimitlset12 + pop ecx + pop eax + push dword 0 + jmp dbcblimitlno12 + + dbcblimitlset12: + + pop ecx + pop eax + push dword 1 + + dbcblimitlno12: + + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? + jz dbpi24bit12 + jmp dbpi32bit12 + + +; DRAWBAR 24 BBP + + +dbpi24bit12: + + push eax + push ebx + push edx + mov eax,ecx + mov ebx,3 + div ebx + mov ecx,eax + pop edx + pop ebx + pop eax + cld + + dbnewpi12: + + push ebx + push edi + push ecx + + xor edx,edx + mov eax,edi + sub eax,[0xfe80] + mov ebx,3 + div ebx + add eax,WinMapAddress + mov ebx,[0x3000] + cld + + dbnp2412: + + mov dl,[eax] + push eax + push ecx + cmp dl,bl + jnz dbimp24no12 + cmp [esp+5*4],dword 0 + jz dbimp24yes12 +; call dbcplimit +; jnz dbimp24no12 + + dbimp24yes12: + + push edi + mov eax,edi + sub eax,[0xfe80] + shr eax,16 + call set_bank + and edi,0xffff + add edi,0xa0000 + mov eax,[esp+8+3*4+16+4+4] + stosw + shr eax,16 + stosb + sti + pop edi + add edi,3 + pop ecx + pop eax + inc eax + loop dbnp2412 + jmp dbnp24d12 + + dbimp24no12: + + pop ecx + pop eax + cld + add edi,3 + inc eax + loop dbnp2412 + + dbnp24d12: + + mov eax,[esp+3*4+16+4] + test eax,0x80000000 + jz nodbgl2412 + cmp al,0 + jz nodbgl2412 + dec eax + mov [esp+3*4+16+4],eax + + nodbgl2412: + + pop ecx + pop edi + pop ebx + add edi,[0xfe08] + dec ebx + jz dbnonewpi12 + jmp dbnewpi12 + + dbnonewpi12: + + add esp,7*4 + + ret + + +; DRAWBAR 32 BBP + + + dbpi32bit12: + + cld + shr ecx,2 + + dbnewpi3212: + + push ebx + push edi + push ecx + + mov eax,edi + sub eax,[0xfe80] + shr eax,2 + add eax,WinMapAddress + mov ebx,[0x3000] + cld + + dbnp3212: + + mov dl,[eax] + push eax + push ecx + cmp dl,bl + jnz dbimp32no12 + cmp [esp+5*4],dword 0 + jz dbimp32yes12 +; call dbcplimit +; jnz dbimp32no12 + + dbimp32yes12: + + push edi + mov eax,edi + sub eax,[0xfe80] + shr eax,16 + call set_bank + and edi,0xffff + add edi,0xa0000 + mov eax,[esp+8+3*4+16+4+4] + stosw + shr eax,16 + stosb + sti + pop edi + add edi,4 + inc ebp + pop ecx + pop eax + inc eax + loop dbnp3212 + jmp dbnp32d12 + + dbimp32no12: + + pop ecx + pop eax + inc eax + add edi,4 + inc ebp + loop dbnp3212 + + dbnp32d12: + + mov eax,[esp+12+16+4] + test eax,0x80000000 + jz nodbgl3212 + cmp al,0 + jz nodbgl3212 + dec eax + mov [esp+12+16+4],eax + + nodbgl3212: + + pop ecx + pop edi + pop ebx + add edi,[0xfe08] + dec ebx + jz nodbnewpi3212 + jmp dbnewpi3212 + + nodbnewpi3212: + + add esp,7*4 + ret + + +Vesa12_putpixel24: + + mov edi,eax ; x + mov eax,ebx ; y + lea edi,[edi+edi*2] + mov ebx,[0xfe08] + mul ebx + add edi,eax + mov eax,edi + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov eax,[esp+28] + stosw + shr eax,16 + mov [edi],al + sti + ret + + + +Vesa12_putpixel32: + + mov edi,eax ; x + mov eax,ebx ; y + shl edi,2 + mov ebx,[0xfe08] + mul ebx + add edi,eax + mov eax,edi + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov ecx,[esp+28] + mov [edi],ecx + sti + ret + + +Vesa12_getpixel24: + + mov edi,eax ; x + mov eax,ebx ; y + lea edi,[edi+edi*2] + mov ebx,[0xfe08] + mul ebx + add edi,eax + mov eax,edi + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov ecx,[edi] + and ecx,255*256*256+255*256+255 + sti + ret + + +Vesa12_getpixel32: + + mov edi,eax ; x + mov eax,ebx ; y + shl edi,2 + mov ebx,[0xfe08] + xor edx,edx + mul ebx + add edi,eax + mov eax,edi + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov ecx,[edi] + and ecx,255*256*256+255*256+255 + sti + + ret + + + +vesa12_putimage: + +; mov ebx,image +; mov ecx,320*65536+240 +; mov edx,20*65536+20 + + call [disable_mouse] + + mov [novesachecksum],dword 0 + push esi + push edi + push eax + push ebx + push ecx + push edx + movzx eax,word [esp+2] + movzx ebx,word [esp+0] + mov ecx,[0x3010] + add eax,[ecx-twdw+WDATA.box.left] + add ebx,[ecx-twdw+WDATA.box.top] + push eax + mov eax,ebx ; y + mov ebx,[0xfe08] + mul ebx + pop ecx + add eax,ecx ; x + add eax,ecx + add eax,ecx + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start + jz pi2412 + add eax,ecx + + pi2412: + + add eax,[0xfe80] + mov edi,eax + + ; x size + + movzx eax,word [esp+6] + mov ecx,eax + add ecx,eax + add ecx,eax + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size + jz pi24312 + add ecx,eax + + pi24312: + + mov esi,[esp+8] + movzx ebx,word [esp+4] + + ; check limits while draw ? + + push eax + push ecx + mov eax,[0x3010] + mov ecx,[eax+draw_data-0x3000+RECT.left] + cmp ecx,0 + jnz dbcblimitlset212 + mov ecx,[eax+draw_data-0x3000+RECT.top] + cmp ecx,0 + jnz dbcblimitlset212 + mov ecx,[eax+draw_data-0x3000+RECT.right] + cmp ecx,[0xfe00] + jnz dbcblimitlset212 + mov ecx,[eax+draw_data-0x3000+RECT.bottom] + cmp ecx,[0xfe04] + jnz dbcblimitlset212 + pop ecx + pop eax + push dword 0 + jmp dbcblimitlno212 + + dbcblimitlset212: + + pop ecx + pop eax + push dword 1 + + dbcblimitlno212: + + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? + jz pi24bit12 + jmp pi32bit12 + + pi24bit12: + + cld + push eax + push ebx + push edx + xor edx,edx + mov eax,ecx + mov ebx,3 + div ebx + mov ecx,eax + pop edx + pop ebx + pop eax + + newpi12: + + push edi + push esi + push ecx + push ebx + + xor edx,edx + mov eax,edi + sub eax,[0xfe80] + mov ebx,3 + div ebx + add eax,WinMapAddress + mov ebx,[0x3000] + mov bh,[esp+4*4] + + np2412: + + cmp bl,[eax] + jnz imp24no12 + mov edx,[esi] + cmp bh,0 + jz imp24yes12 +; call dbcplimit +; jnz imp24no12 + + imp24yes12: + + push eax + push edi + mov eax,edi + sub eax,[0xfe80] + shr eax,16 + call set_bank + and edi,0xffff + add edi,0xa0000 + mov [edi],edx + shr edx,2 + mov [edi+2],dl + sti + pop edi + pop eax + + imp24no12: + + inc eax + add esi,3 + add edi,3 + dec ecx + jnz np2412 + + np24d12: + + pop ebx + pop ecx + pop esi + pop edi + + add edi,[0xfe08] + xor eax,eax + mov ax,[esp+4+2+4] + lea eax,[eax+eax*2] + add esi,eax + dec ebx + jz nonewpi12 + jmp newpi12 + + nonewpi12: + + add esp,7*4 + mov eax,0 + ret + + + pi32bit12: + + cld + shr ecx,2 + + newpi3212: + + push edi + push esi + push ecx + push ebx + + mov eax,edi + sub eax,[0xfe80] + shr eax,2 + add eax,WinMapAddress + mov ebx,[0x3000] + mov bh,[esp+4*4] + + np3212: + + cmp bl,[eax] + jnz imp32no12 + mov edx,[esi] + cmp bh,0 + jz imp32yes12 +; call dbcplimit +; jnz imp32no12 + + imp32yes12: + + push eax + push edi + mov eax,edi + sub eax,[0xfe80] + shr eax,16 + call set_bank + and edi,0xffff + add edi,0xa0000 + mov [edi],edx + sti + pop edi + pop eax + + imp32no12: + + inc eax + add esi,3 + add edi,4 + dec ecx + jnz np3212 + + np32d12: + + pop ebx + pop ecx + pop esi + pop edi + + add edi,[0xfe08] + movzx eax,word [esp+4+2+4] + lea eax,[eax+eax*2] + add esi,eax + dec ebx + jz nonewpi3212 + jmp newpi3212 + + nonewpi3212: + + add esp,7*4 + mov eax,0 + ret + + +vesa12_read_screen_pixel: + + and eax,0x3FFFFF + cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? + jz v12rsp24 + mov edi,eax + shl edi,2 + mov eax,edi + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov eax,[edi] + and eax,0x00ffffff + ret + v12rsp24: + + imul eax,3 + mov edi,eax + shr eax,16 + call set_bank + and edi,65535 + add edi,0xa0000 + mov eax,[edi] + and eax,0x00ffffff + ret + + diff --git a/kernel/tags/kolibri0.6.0.0/video/vesa20.inc b/kernel/tags/kolibri0.6.0.0/video/vesa20.inc new file mode 100644 index 0000000000..c962808d34 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/video/vesa20.inc @@ -0,0 +1,1122 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; VESA20.INC ;; +;; ;; +;; Vesa 2.0 functions for MenuetOS ;; +;; ;; +;; Copyright 2002 Ville Turjanmaa ;; +;; Alexey, kgaz@crosswindws.net ;; +;; - Voodoo compatible graphics ;; +;; Juan M. Caravaca ;; +;; - Graphics optimimizations eg. drawline ;; +;; ;; +;; See file COPYING for details ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; If you're planning to write your own video driver I suggest +; you replace the VESA12.INC file and see those instructions. + +ScreenWidth equ 0xfe00 +ScreenHeight equ 0xfe04 +BytesPerScanLine equ 0xfe08 +LFBAddress equ 0xfe80 +ScreenBPP equ 0xfbf1 +WinMapAddress equ 0x460000 + + + +;************************************************* +; getpixel +; +; in: +; eax = x coordinate +; ebx = y coordinate +; +; ret: +; ecx = 00 RR GG BB + +getpixel: + push eax ebx edx edi + call dword [0xe024] + pop edi edx ebx eax + ret + +Vesa20_getpixel24: + ; eax = x + ; ebx = y + imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + lea edi, [eax+eax*2] ; edi = x*3 + add edi, ebx ; edi = x*3+(y*y multiplier) + add edi, [LFBAddress] ; ebx = where pixel is in memory + mov ecx, [edi] + and ecx, 0xffffff + ret + + +Vesa20_getpixel32: + imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) + add edi, [LFBAddress] ; ebx = where pixel is in memory + mov ecx, [edi] + and ecx, 0xffffff + ret + +;************************************************* + +virtual at esp + putimg: + .real_sx dd ? + .real_sy dd ? + .image_sx dd ? + .image_sy dd ? + .image_cx dd ? + .image_cy dd ? + .pti dd ? + .abs_cx dd ? + .abs_cy dd ? + .line_increment dd ? + .source_bpp dd ? + .winmap_newline dd ? + .screen_newline dd ? + .stack_data = 4*13 +end virtual + +align 4 +; ebx = pointer +; ecx = size [x|y] +; edx = coordinates [x|y] +vesa20_putimage: + pushad + call [disable_mouse] + + sub esp, putimg.stack_data + + mov [putimg.source_bpp], 3 +; test ebx, 0x80000000 +; jz @f +; inc [putimg.source_bpp] +; @@: +; and ebx, 0x7FFFFFFF + + ; save pointer to image + mov [putimg.pti], ebx + + ; unpack the size + mov eax, ecx + and ecx, 0xFFFF + shr eax, 16 + mov [putimg.image_sx], eax + mov [putimg.image_sy], ecx + + ; unpack the coordinates + mov eax, edx + and edx, 0xFFFF + shr eax, 16 + mov [putimg.image_cx], eax + mov [putimg.image_cy], edx + + ; calculate absolute (i.e. screen) coordinates + mov eax, [0x3010] + mov ebx, [eax-twdw + WDATA.box.left] + add ebx, [putimg.image_cx] + mov [putimg.abs_cx], ebx + mov ebx, [eax-twdw + WDATA.box.top] + add ebx, [putimg.image_cy] + mov [putimg.abs_cy], ebx + + ; real_sx = MIN(wnd_sx-image_cx, image_sx); + mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] + sub ebx, [putimg.image_cx] + ja @f + add esp, putimg.stack_data + popad + ret + @@: + cmp ebx, [putimg.image_sx] + jbe .end_x + mov ebx, [putimg.image_sx] + .end_x: + mov [putimg.real_sx], ebx + + ; init real_sy + mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond}[20.08.2006] + sub ebx, [putimg.image_cy] + ja @f + add esp, putimg.stack_data + popad + ret + @@: + cmp ebx, [putimg.image_sy] + jbe .end_y + mov ebx, [putimg.image_sy] + .end_y: + mov [putimg.real_sy], ebx + + ; line increment + mov eax, [putimg.image_sx] + sub eax, [putimg.real_sx] +;; imul eax, [putimg.source_bpp] + lea eax, [eax + eax * 2] + mov [putimg.line_increment], eax + + ; winmap new line increment + mov eax, [ScreenWidth] + inc eax + sub eax, [putimg.real_sx] + mov [putimg.winmap_newline], eax + + ; screen new line increment + mov eax, [BytesPerScanLine] + mov ecx, [putimg.real_sx] + movzx ebx, byte [ScreenBPP] + shr ebx, 3 + imul ecx, ebx + sub eax, ecx + mov [putimg.screen_newline], eax + + ; pointer to image + mov ecx, [putimg.pti] + + ; pointer to screen + mov edx, [putimg.abs_cy] + imul edx, [BytesPerScanLine] + mov eax, [putimg.abs_cx] + movzx ebx, byte [ScreenBPP] + shr ebx, 3 + imul eax, ebx + add edx, eax + add edx, [LFBAddress] + + ; pointer to pixel map + mov eax, [putimg.abs_cy] + imul eax, [ScreenWidth] + add eax, [putimg.abs_cy] + add eax, [putimg.abs_cx] + add eax, WinMapAddress + xchg eax, ebp + + ; get process number + mov ebx, [0x3000] + + cmp byte [ScreenBPP], 32 + je put_image_end_32 + +;put_image_end_24: + mov edi, [putimg.real_sy] + align 4 + .new_line: + mov esi, [putimg.real_sx] + +; push ebp edx + align 4 + .new_x: + + cmp [ebp], bl + jne .skip + mov eax, [ecx] ; ecx = RRBBGGRR + mov [edx], ax + shr eax, 16 + mov [edx+2], al + .skip: + + add ecx, 3 ;[putimg.source_bpp] + add edx, 3 + inc ebp + + dec esi + jnz .new_x +; pop edx ebp + + add ecx, [putimg.line_increment] + add edx, [putimg.screen_newline] ;[BytesPerScanLine] + add ebp, [putimg.winmap_newline] ;[ScreenWidth] + ;inc ebp + + dec edi + jnz .new_line + .finish: + add esp, putimg.stack_data + popad +ret + +put_image_end_32: + mov edi, [putimg.real_sy] + align 4 + .new_line: + mov esi, [putimg.real_sx] + +; push ebp edx + align 4 + .new_x: + + cmp [ebp], bl + jne .skip + mov eax, [ecx] ; ecx = RRBBGGRR + mov [edx], eax + .skip: + + add ecx, [putimg.source_bpp] + add edx, 4 + inc ebp + + dec esi + jnz .new_x +; pop edx ebp + + add ecx, [putimg.line_increment] + add edx, [putimg.screen_newline] ;[BytesPerScanLine] + add ebp, [putimg.winmap_newline] ;[ScreenWidth] + ;inc ebp + + dec edi + jnz .new_line + .finish: + add esp, putimg.stack_data + popad + call VGA__putimage + mov [EGA_counter],1 +ret + + +;************************************************* +align 4 +__sys_putpixel: + +; eax = x coordinate +; ebx = y coordinate +; ecx = ?? RR GG BB ; 0x01000000 negation +; edi = 0x00000001 force + +;;; mov [novesachecksum], dword 0 + + pushad + test edi,1 ; force ? + jnz .forced + ; not forced: + push ecx ; save 24th bit in case negative pixel wanted + call checkpixel + test ecx,ecx + pop ecx + jnz .exit + .forced: + cmp [ScreenWidth], eax + jb .exit + cmp [ScreenHeight], ebx + jb .exit + .ok: + ; check if negation + test ecx,0x01000000 + jz .noneg + call getpixel + not ecx + mov [esp+32-8],ecx + .noneg: + ; OK to set pixel + call dword [0xe020] ; call the real put_pixel function + .exit: + popad + + ret + +align 4 +Vesa20_putpixel24: + + ; eax = x + ; ebx = y + + imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + lea edi, [eax+eax*2] ; edi = x*3 + mov eax, [esp+32-8+4] + add edi, [LFBAddress] + add edi, ebx ; ebx = where to put pixel in memory + mov [edi], ax + shr eax, 16 + mov [edi+2], al + + ret + + +align 4 +Vesa20_putpixel32: + + ; eax = x + ; ebx = y + + imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier + lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier) + mov eax, [esp+32-8+4] ; eax = color + add edi, [LFBAddress] ; ebx = where to put pixel in memory + mov [edi], eax + + ret + + +;************************************************* + +;align 4 +calculate_edi: + mov edi, ebx + imul edi, [ScreenWidth] + add edi, ebx + add edi, eax +ret + +;************************************************* + +; DRAWLINE + +align 4 +__sys_draw_line: +; inc [mouse_pause] + call [disable_mouse] + +; draw a line +; eax = HIWORD = x1 +; LOWORD = x2 +; ebx = HIWORD = y1 +; LOWORD = y2 +; ecx = color +; edi = force ? + pusha + +dl_x1 equ esp+20 +dl_y1 equ esp+16 +dl_x2 equ esp+12 +dl_y2 equ esp+8 +dl_dx equ esp+4 +dl_dy equ esp+0 + + xor edx, edx ; clear edx + xor esi, esi ; unpack arguments + xor ebp, ebp + mov si, ax ; esi = x2 + mov bp, bx ; ebp = y2 + shr eax, 16 ; eax = x1 + shr ebx, 16 ; ebx = y1 + + push eax ; save x1 + push ebx ; save y1 + push esi ; save x2 + push ebp ; save y2 + + ; checking x-axis... + sub esi, eax ; esi = x2-x1 + push esi ; save y2-y1 + jl .x2lx1 ; is x2 less than x1 ? + jg .no_vline ; x1 > x2 ? + mov edx, ebp ; else (if x1=x2) + call vline + push edx ; necessary to rightly restore stack frame at .exit + jmp .exit +.x2lx1: + neg esi ; get esi absolute value +.no_vline: + + ; checking y-axis... + sub ebp, ebx ; ebp = y2-y1 + push ebp ; save y2-y1 + jl .y2ly1 ; is y2 less than y1 ? + jg .no_hline ; y1 > y2 ? + mov edx, [dl_x2] ; else (if y1=y2) + call hline + jmp .exit +.y2ly1: + neg ebp ; get ebp absolute value +.no_hline: + + + cmp ebp, esi + jle .x_rules ; |y2-y1| < |x2-x1| ? + + cmp [dl_y2], ebx ; make sure y1 is at the begining + jge .no_reverse1 + + neg dword [dl_dx] + mov edx, [dl_x2] + mov [dl_x2], eax + mov [dl_x1], edx + mov edx, [dl_y2] + mov [dl_y2], ebx + mov [dl_y1], edx + +.no_reverse1: + + mov eax, [dl_dx] + cdq ; extend eax sing to edx + shl eax, 16 ; using 16bit fix-point maths + idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1) + mov edx, ebp ; edx = counter (number of pixels to draw) + mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0 + mov esi, eax ; esi = dx + + jmp .y_rules +.x_rules: + + cmp [dl_x2], eax ; make sure x1 is at the begining + jge .no_reverse2 + + neg dword [dl_dy] + mov edx, [dl_x2] + mov [dl_x2], eax + mov [dl_x1], edx + mov edx, [dl_y2] + mov [dl_y2], ebx + mov [dl_y1], edx + +.no_reverse2: + + xor edx, edx + mov eax, [dl_dy] + cdq ; extend eax sing to edx + shl eax, 16 ; using 16bit fix-point maths + idiv esi ; eax = ((y2-y1)*65536)/(x2-x1) + mov edx, esi ; edx = counter (number of pixels to draw) + mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0 + mov ebp, eax ; ebp = dy + +.y_rules: + + mov eax, [dl_x1] + mov ebx, [dl_y1] + shl eax, 16 + shl ebx, 16 + +align 4 + +.draw: + push eax ebx + shr eax, 16 + shr ebx, 16 + call [putpixel] + pop ebx eax + + add ebx, ebp ; y = y+dy + add eax, esi ; x = x+dx + + dec edx + jnz .draw + + ; force last drawn pixel to be at (x2,y2) + mov eax, [dl_x2] + mov ebx, [dl_y2] + call [putpixel] +.exit: + add esp, 6*4 + popa +; dec [mouse_pause] + call [draw_pointer] +ret + + +hline: +; draw an horizontal line +; eax = x1 +; edx = x2 +; ebx = y +; ecx = color +; edi = force ? + push eax edx + + cmp edx, eax ; make sure x2 is above x1 + jge @f + xchg eax, edx + align 4 + @@: + call [putpixel] + inc eax + cmp eax, edx + jle @b + + pop edx eax +ret + + +vline: +; draw a vertical line +; eax = x +; ebx = y1 +; edx = y2 +; ecx = color +; edi = force ? + push ebx edx + + cmp edx, ebx ; make sure y2 is above y1 + jge @f + xchg ebx, edx + align 4 + @@: + call [putpixel] + inc ebx + cmp ebx, edx + jle @b + + pop edx ebx +ret + + +;************************************************* + + +virtual at esp + drbar: + .bar_sx dd ? + .bar_sy dd ? + .bar_cx dd ? + .bar_cy dd ? + .abs_cx dd ? + .abs_cy dd ? + .real_sx dd ? + .real_sy dd ? + .color dd ? + .line_inc_scr dd ? + .line_inc_map dd ? + .stack_data = 4*11 +end virtual + +align 4 +; eax cx +; ebx cy +; ecx xe +; edx ye +; edi color +vesa20_drawbar: + + pushad + call [disable_mouse] + + sub esp, drbar.stack_data + + mov [drbar.color], edi + + sub edx, ebx + jle .exit ;// mike.dld, 2005-01-29 + sub ecx, eax + jle .exit ;// mike.dld, 2005-01-29 + mov [drbar.bar_sy], edx + mov [drbar.bar_sx], ecx + + mov [drbar.bar_cx], eax + mov [drbar.bar_cy], ebx + + mov edi, [0x3010] + add eax, [edi-twdw + WDATA.box.left] ; win_cx + add ebx, [edi-twdw + WDATA.box.top] ; win_cy + mov [drbar.abs_cx], eax + mov [drbar.abs_cy], ebx + + ; real_sx = MIN(wnd_sx-bar_cx, bar_sx); + mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx +; \begin{diamond}[20.08.2006] +; note that WDATA.box.width is one pixel less than real window x-size + inc ebx +; \end{diamond}[20.08.2006] + sub ebx, [drbar.bar_cx] + ja @f + .exit: ;// mike.dld, 2005-01-29 + add esp, drbar.stack_data + popad + xor eax, eax + inc eax + + ret + @@: + cmp ebx, [drbar.bar_sx] + jbe .end_x + mov ebx, [drbar.bar_sx] + .end_x: + mov [drbar.real_sx], ebx + + ; real_sy = MIN(wnd_sy-bar_cy, bar_sy); + mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy +; \begin{diamond}[20.08.2006] + inc ebx +; \end{diamond} + sub ebx, [drbar.bar_cy] + ja @f + add esp, drbar.stack_data + popad + xor eax, eax + inc eax + + ret + @@: + cmp ebx, [drbar.bar_sy] + jbe .end_y + mov ebx, [drbar.bar_sy] + .end_y: + mov [drbar.real_sy], ebx + + ; line_inc_map + mov eax, [ScreenWidth] + sub eax, [drbar.real_sx] + inc eax + mov [drbar.line_inc_map], eax + + ; line_inc_scr + mov eax, [drbar.real_sx] + movzx ebx, byte [ScreenBPP] + shr ebx, 3 + imul eax, ebx + neg eax + add eax, [BytesPerScanLine] + mov [drbar.line_inc_scr], eax + + ; pointer to screen + mov edx, [drbar.abs_cy] + imul edx, [BytesPerScanLine] + mov eax, [drbar.abs_cx] +; movzx ebx, byte [ScreenBPP] +; shr ebx, 3 + imul eax, ebx + add edx, eax + add edx, [LFBAddress] + + ; pointer to pixel map + mov eax, [drbar.abs_cy] + imul eax, [ScreenWidth] + add eax, [drbar.abs_cy] + add eax, [drbar.abs_cx] + add eax, WinMapAddress + xchg eax, ebp + + ; get process number + mov ebx, [0x3000] + + cmp byte [ScreenBPP], 24 + jne draw_bar_end_32 +draw_bar_end_24: + mov eax, [drbar.color] ;; BBGGRR00 + mov bh, al ;; bh = BB + shr eax, 8 ;; eax = RRGG +; eax - color high RRGG +; bl - process num +; bh - color low BB +; ecx - temp +; edx - pointer to screen +; esi - counter +; edi - counter + + mov esi, [drbar.real_sy] + align 4 + .new_y: + mov edi, [drbar.real_sx] + align 4 + .new_x: + + cmp byte [ebp], bl + jne .skip + mov [edx], bh + mov [edx + 1], ax + .skip: + + ; add pixel + add edx, 3 + inc ebp + + dec edi + jnz .new_x + + ; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] + + ; drawing gradient bars + test eax, 0x00800000 + jz @f + test bh, bh + jz @f + dec bh + @@: + ; + + dec esi + jnz .new_y + + add esp, drbar.stack_data + popad + xor eax, eax +ret + +draw_bar_end_32: + mov eax, [drbar.color] ;; BBGGRR00 + + mov esi, [drbar.real_sy] + align 4 + .new_y: + mov edi, [drbar.real_sx] + align 4 + .new_x: + + cmp byte [ebp], bl + jne .skip + mov [edx], eax + .skip: + + ; add pixel + add edx, 4 + inc ebp + + dec edi + jnz .new_x + + ; add line + add edx, [drbar.line_inc_scr] + add ebp, [drbar.line_inc_map] + + ; drawing gradient bars + test eax, 0x80000000 + jz @f + test al, al + jz @f + dec al + @@: + ; + + dec esi + jnz .new_y + + add esp, drbar.stack_data + popad + call VGA_draw_bar + xor eax, eax + mov [EGA_counter],1 +ret + + +;voodoodbcplimit: + +; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer + + +; pusha + +; xor edx,edx +; mov eax,ebp +; mov ebx,[ScreenWidth] ; Screen_X_size +; inc ebx ; +1 +; sub eax,WinMapAddress ; -AddrBuffer +; div ebx ; +; mov ebx,eax ; ebx:=Y +; mov eax,edx ; eax:=X +; call cplimit + +; test ecx,ecx +; jne dbcpl12 +; popa +; clc +; ret +; dbcpl12: +; popa +; stc +; ret + + + + +;dbcplimit: + +; pusha + +; xor edx,edx +; mov ebx,[ScreenWidth] +; inc ebx +; sub eax,WinMapAddress +; div ebx +; mov ebx,eax +; mov eax,edx +; call cplimit + +; test ecx,ecx +; jne dbcpl1 +; popa +; clc +; ret +; dbcpl1: +; popa +; stc +; ret + + + + + + +;--------------vbe voodoo ------------------------------------------------ +vesa20_drawbackground_tiled: + + call [disable_mouse] + + push ebp + push eax + push ebx + push ecx + push edx + + mov edx,dword [WinMapAddress-8] ; B + add edx,dword [WinMapAddress-8] ; +B + add edx,dword [WinMapAddress-8] ; +B + push edx + + mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) + mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X + add ebp, eax ; +X + + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + + dp3: ; MAIN LOOP + + cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) +; je ybgp +; +; jmp nbgp +; +; ybgp: + jne nbgp + + push eax + push ebx + + mov ecx,dword [WinMapAddress-8] ; B + xor edx,edx ; edx:=0 + div ecx ; Xstart/B + + ; eax=Int(qn) edx:=Rem + + lea esi,[edx+edx*2] ; esi:=edx*3 + + mov ecx,dword [WinMapAddress-4] ; ecx:=H + mov eax,[esp+0] ; eax:=Ystart + xor edx,edx ; + div ecx ; Ystart/H + + mov eax,edx ; eax:=Rem + xor edx,edx ; + mov ebx,[esp+8] ; ebx:=B*3 + mul ebx ; + add esi,eax ; + mov eax,[esi+0x300000] + and eax,0xffffff + + xchg edi, ebp + stosw + shr eax,16 + stosb + xchg ebp, edi ; ebp+=3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + pop ebx + pop eax + + jmp hook1 + + nbgp: + add ebp,3 ; +3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + hook1: + + inc edi ; ptrBuffer++ + add esi,3 ; ptrImage+=3 + inc eax + cmp eax,[draw_data+32+RECT.right] ; X > xend? +; jg nodp3 +; jmp dp3 +; +; nodp3: + jle dp3 + + mov ebp,[draw_data+32+RECT.left] + + inc ebx + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X=X*2 + add ebp, eax ; +X=X*3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X=X*4 + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + cmp ebx,[draw_data+32+RECT.bottom] +; jg dp4 +; +; jmp dp3 +; +; dp4: + jle dp3 + + add esp,4 + + pop edx + pop ecx + pop ebx + pop eax + pop ebp + mov [EGA_counter],1 + call VGA_drawbackground + ret + +; ---------- + + +vesa20_drawbackground_stretch: + + call [disable_mouse] + + push ebp + push eax + push ebx + push ecx + push edx + + mov edx,dword [WinMapAddress-8] ; B + add edx,dword [WinMapAddress-8] ; +B + add edx,dword [WinMapAddress-8] ; +B + push edx + + mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin) + mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin) + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X + add ebp, eax ; +X + + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + + sdp3: ; MAIN LOOP + + cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1) + jne snbgp + + push eax + push ebx + + mov eax,dword [WinMapAddress-8] + imul eax, [esp+4] ;4 + xor edx,edx + mov ebx,[ScreenWidth] + div ebx + lea esi,[eax+eax*2] + mov eax,dword [WinMapAddress-4] + imul eax, [esp+0] ;0 + xor edx,edx + mov ebx,[ScreenHeight] + div ebx + imul eax, [esp+8] ;8 + add esi,eax + + mov eax,[esi+0x300000] + and eax,0xffffff + + xchg edi, ebp + stosw + shr eax,16 + stosb + xchg ebp, edi ; ebp+=3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + pop ebx + pop eax + + jmp shook1 + + snbgp: + add ebp,3 ; +3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + inc ebp ; +1 + @@: + + shook1: + + inc edi ; ptrBuffer++ + add esi,3 ; ptrImage+=3 + inc eax + cmp eax,[draw_data+32+RECT.right] ; X > xend? + jle sdp3 + + mov ebp,[draw_data+32+RECT.left] + + inc ebx + + mov eax,[BytesPerScanLine] + mul ebx + xchg ebp, eax ; BytesPerScanLine*(Ywin+y) + add ebp, eax ; +X + add ebp, eax ; +X=X*2 + add ebp, eax ; +X=X*3 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size + jz @f + add ebp,eax ; +X=X*4 + @@: + add ebp,[LFBAddress] ; +LFB + + ; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB + + call calculate_edi + + cmp ebx,[draw_data+32+RECT.bottom] + jle sdp3 + + add esp,4 + + pop edx + pop ecx + pop ebx + pop eax + pop ebp + mov [EGA_counter],1 + call VGA_drawbackground + ret diff --git a/kernel/tags/kolibri0.6.0.0/video/vga.inc b/kernel/tags/kolibri0.6.0.0/video/vga.inc new file mode 100644 index 0000000000..3de0d0efbc --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/video/vga.inc @@ -0,0 +1,446 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; VGA.INC ;; +;; ;; +;; 640x480 mode 0x12 VGA functions for MenuetOS ;; +;; ;; +;; Paul Butcher, paul.butcher@asa.co.uk ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +paletteVGA: + +;16 colour palette + mov dx,0x3c8 + mov al,0 + out dx,al + + mov ecx,16 + mov dx,0x3c9 + xor eax,eax + + palvganew: + + mov al,0 + test ah,4 + jz palvgalbl1 + add al,31 + test ah,8 + jz palvgalbl1 + add al,32 + palvgalbl1: + out dx,al ; red 0,31 or 63 + mov al,0 + test ah,2 + jz palvgalbl2 + add al,31 + test ah,8 + jz palvgalbl2 + add al,32 + palvgalbl2: + out dx,al ; blue 0,31 or 63 + mov al,0 + test ah,1 + jz palvgalbl3 + add al,31 + test ah,8 + jz palvgalbl3 + add al,32 + palvgalbl3: + out dx,al ; green 0,31 or 63 + add ah,1 + loop palvganew +; mov dx, 3ceh +; mov ax, 0005h +; out dx, ax + ret + +palette320x200: + + mov edx,0x3c8 + xor eax, eax + out dx,al + mov ecx,256 + mov edx,0x3c9 + xor eax,eax + + palnew: + mov al,0 + test ah,64 + jz pallbl1 + add al,21 + pallbl1: + test ah,128 + jz pallbl2 + add al,42 + pallbl2: + out dx,al + mov al,0 + test ah,8 + jz pallbl3 + add al,8 + pallbl3: + test ah,16 + jz pallbl4 + add al,15 + pallbl4: + test ah,32 + jz pallbl5 + add al,40 + pallbl5: + out dx,al + mov al,0 + test ah,1 + jz pallbl6 + add al,8 + pallbl6: + test ah,2 + jz pallbl7 + add al,15 + pallbl7: + test ah,4 + jz pallbl8 + add al,40 + pallbl8: + out dx,al + add ah,1 + loop palnew + + ret + +uglobal + novesachecksum dd 0x0 + EGA_counter db 0 + VGA_drawing_screen db 0 + VGA_8_pixels: + rb 16 + temp: + .cx dd 0 +endg + +checkVga_N13: + + cmp [0xfe0c],dword 0x13 + jne @f + +; cnvl: + pushad + cmp [EGA_counter],1 + je novesal + mov ecx,[0xfb0a] + cmp ecx,[novesachecksum] + jne novesal + popad + @@: + ret + + novesal: + mov [novesachecksum],ecx + mov ecx,0 + movzx eax,word [0xfb0c] + cmp eax,100 + jge m13l3 + mov eax,100 + m13l3: + cmp eax,480-100 + jbe m13l4 + mov eax,480-100 + m13l4: + sub eax,100 + imul eax,640*4 + add ecx,eax + movzx eax,word [0xfb0a] + cmp eax,160 + jge m13l1 + mov eax,160 + m13l1: + cmp eax,640-160 + jbe m13l2 + mov eax,640-160 + m13l2: + sub eax,160 + shl eax,2 + add ecx,eax + mov esi,[0xfe80] + add esi,ecx + mov edi,0xa0000 + mov edx,200 + mov ecx,320 + cld + m13pix: + lodsd + cmp eax,0 + je .save_pixel + push eax + mov ebx,eax + and eax,(128+64+32) ; blue + shr eax,5 + and ebx,(128+64+32)*256 ; green + shr ebx,8+2 + add eax,ebx + pop ebx + and ebx,(128+64)*256*256 ; red + shr ebx,8+8 + add eax,ebx + .save_pixel: + stosb + loop m13pix + mov ecx,320 + add esi,4*(640-320) + dec edx + jnz m13pix + mov [EGA_counter],0 + popad + ret + +VGA_drawbackground: +; draw all + cmp [0xfe0c],dword 0x12 + jne .end + pushad + mov esi,[0xfe80] + mov edi,0xa0000 + mov ebx,640/32 ; 640*480/(8*4) + mov edx,480 + @@: + push ebx edx esi edi + shl edx,9 + lea edx,[edx+edx*4] + add esi,edx + shr edx,5 + add edi,edx + call VGA_draw_long_line + pop edi esi edx ebx + dec edx + jnz @r + call VGA_draw_long_line_1 + popad + .end: + ret + +VGA_draw_long_line: + mov dx,3ceh + mov ax,0ff08h + cli + out dx, ax + mov ax,0005h + out dx, ax + m12pix: + call VGA_draw_32_pixels + dec ebx + jnz m12pix + mov dx,3c4h + mov ax,0ff02h + out dx,ax + mov dx,3ceh + mov ax,0205h + out dx,ax + mov dx,3ceh + mov al,08h + out dx,al + sti + ret + +VGA_draw_32_pixels: + xor eax,eax + mov ebp,VGA_8_pixels + mov [ebp],eax + mov [ebp+4],eax + mov [ebp+8],eax + mov [ebp+12],eax + mov ch,4 + .main_loop: + mov cl,8 + .convert_pixels_to_VGA: + lodsd ; eax = 24bit colour + cmp eax,0 + je .end + rol eax,8 + mov al,ch + ror eax,8 + mov ch,1 + dec cl + shl ch,cl + cmp al,85 + jbe .p13green + or [ebp],ch + cmp al,170 + jbe .p13green + or [ebp+12],ch + .p13green: + cmp ah,85 + jbe .p13red + or [ebp+4],ch + cmp ah,170 + jbe .p13red + or [ebp+12],ch + .p13red: + shr eax,8 + cmp ah,85 + jbe .p13cont + or [ebp+8],ch + cmp ah,170 + jbe .p13cont + or [ebp+12],ch + .p13cont: + ror eax,8 + mov ch,ah + inc cl + .end: + dec cl + jnz .convert_pixels_to_VGA + inc ebp + dec ch + jnz .main_loop + push esi + sub ebp,4 + mov esi,ebp + mov dx, 3c4h + mov ah, 1h + @@: + mov al, 02h + out dx,ax + xchg ax,bp + lodsd + mov [edi],eax + xchg ax,bp + shl ah, 1 + cmp ah, 10h + jnz @r + add edi,4 + pop esi + ret + +VGA_putpixel: + ; eax = x + ; ebx = y + mov ecx,eax + mov eax, [esp+32-8+4] ; color + shl ebx,9 + lea ebx,[ebx+ebx*4] ; умножение на 5 + lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32) + mov edi,edx + add edi, [0xfe80] ; + LFB address + mov [edi], eax ; write to LFB for Vesa2.0 + shr edx,5 ; change BytesPerPixel to 1/8 + mov edi,edx + add edi, 0x0a0000 ; address of pixel in VGA area + and ecx,0x07 ; bit no. (modulo 8) + pushfd + ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) + xor edx,edx + cmp eax,0 + je .p13cont + cmp al,85 + jbe .p13green + or dl,0x01 + cmp al,170 + jbe .p13green + or dl,0x08 +.p13green: + cmp ah,85 + jbe .p13red + or dl,0x02 + cmp ah,170 + jbe .p13red + or dl,0x08 +.p13red: + shr eax,8 + cmp ah,85 + jbe .p13cont + or dl,0x04 + cmp ah,170 + jbe .p13cont + or dl,0x08 +.p13cont: + ror edx,8 + inc cl + xor eax,eax + inc ah + shr ax,cl + mov dx,3cfh + cli + out dx,al + mov al,[edi] ; dummy read + rol edx,8 + mov [edi],dl + popfd +;.end: + ret + +VGA__putimage: +; ecx = size [x|y] +; edx = coordinates [x|y] + cmp [0xfe0c],dword 0x12 + jne @f + pushad + rol edx,16 + movzx eax,dx + rol edx,16 + movzx ebx,dx + movzx edx,cx + rol ecx,16 + movzx ecx,cx + call VGA_draw_bar_1 + popad +@@: + ret + +VGA_draw_bar: +; eax cx +; ebx cy +; ecx xe +; edx ye + cmp [0xfe0c],dword 0x12 + jne @f + pushad + sub ecx,eax + sub edx,ebx + and eax,0xffff + and ebx,0xffff + and ecx,0xffff + and edx,0xffff + call VGA_draw_bar_1 + popad +@@: + ret + +VGA_draw_bar_1: + mov [temp.cx],eax + mov eax, [0x3010] + add ebx, [eax-twdw + 4] + mov eax, [eax-twdw + 0] + add eax, [temp.cx] + and eax,0xfff8 + shl ebx,9 + lea ebx,[ebx+ebx*4] ; умножение на 5 + lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) + mov esi,ebx + add esi, [0xfe80] ; + LFB address + shr ebx,5 ; change BytesPerPixel to 1/8 + mov edi,ebx + add edi, 0x0a0000 ; address of pixel in VGA area + mov ebx,ecx + shr ebx,5 + inc ebx +.main_loop: + call VGA_draw_long_line_1 + dec edx + jnz .main_loop + call VGA_draw_long_line_1 + ret + +VGA_draw_long_line_1: + push ebx edx esi edi + shl edx,9 + lea edx,[edx+edx*4] + add esi,edx + shr edx,5 + add edi,edx + call VGA_draw_long_line + pop edi esi edx ebx + ret + + diff --git a/kernel/tags/kolibri0.6.0.0/vmodeint.inc b/kernel/tags/kolibri0.6.0.0/vmodeint.inc new file mode 100644 index 0000000000..fed819ca3f --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/vmodeint.inc @@ -0,0 +1,47 @@ +; +; Call of videomode driver's functions +; +; (Add in System function 21 (and/or 26) as a subfunction 13) +; +; Author: Trans +; Date: 19.07.2003 +; +; Include in MeOS kernel and compile with FASM +; + +uglobal + old_screen_width dd ? + old_screen_height dd ? +endg + + cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS + jne .no_vmode_drv_access + pushd [0x0000fe00] [0x0000fe04] + popd [old_screen_height] [old_screen_width] + or eax,-1 ; If driver is absent then eax does not change + call 0x760100 ; Entry point of video driver + mov [esp+36],eax + mov [esp+24],ebx + mov [esp+32],ecx +; mov [esp+28],edx + mov eax,[old_screen_width] + mov ebx,[old_screen_height] + sub eax,[0x0000fe00] + jnz @f + sub ebx,[0x0000fe04] + jz .resolution_wasnt_changed + jmp .lp1 + @@: sub ebx,[0x0000fe04] + .lp1: sub [screen_workarea.right],eax + sub [screen_workarea.bottom],ebx + + call repos_windows + mov eax, 0 + mov ebx, 0 + mov ecx, [0xfe00] + mov edx, [0xfe04] + call calculatescreen + + .resolution_wasnt_changed: + ret + .no_vmode_drv_access: diff --git a/kernel/tags/kolibri0.6.0.0/vmodeld.inc b/kernel/tags/kolibri0.6.0.0/vmodeld.inc new file mode 100644 index 0000000000..0382221070 --- /dev/null +++ b/kernel/tags/kolibri0.6.0.0/vmodeld.inc @@ -0,0 +1,27 @@ +; +; Load of videomode driver in memory +; +; (driver is located at 0x760000-0x768000 - 32kb) // if this area not occuped anything +; +; Author: Trans +; Date: 19.07.2003 +; +; Include in MeOS kernel and compile with FASM +; + + +;vmode db 'VMODE MDR' ; MDR - Menuet Driver +; must be located after fonts filenames in kernel.asm + +; LOAD VIDEOMODE DRIVER + ; If vmode.mdr file not found + or eax,-1 ; Driver ID = -1 (not present in system) + mov [0x760000],eax ; + mov [0x760100],byte 0xC3 ; Instruction RETN - driver loop + + mov eax,vmode ; File name of driver + mov esi,12 + mov ebx,0 + mov ecx,26000 + mov edx,0x760000 ; Memory position of driver + call fileread \ No newline at end of file