diff --git a/kernel/branches/gfx_kernel/blkdev/cdrom.inc b/kernel/branches/gfx_kernel/blkdev/cdrom.inc index 1b6b256d3..9327544b7 100644 --- a/kernel/branches/gfx_kernel/blkdev/cdrom.inc +++ b/kernel/branches/gfx_kernel/blkdev/cdrom.inc @@ -18,7 +18,7 @@ sys_cd_audio: cmp eax,2 jnz nocdtl - mov edi,[0x3010] + mov edi,[TASK_BASE] add edi,TASKDATA.mem_start add ebx,[edi] call sys_cdtracklist diff --git a/kernel/branches/gfx_kernel/blkdev/fdc.inc b/kernel/branches/gfx_kernel/blkdev/fdc.inc index 6b4e438d3..1a1efd6e6 100644 --- a/kernel/branches/gfx_kernel/blkdev/fdc.inc +++ b/kernel/branches/gfx_kernel/blkdev/fdc.inc @@ -41,8 +41,8 @@ save_image: jne unnecessary_save_image mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона - mov [FDD_Sector],1 ; Сектор - mov esi,0x100000 + mov [FDD_Sector],1 ; Сектор + mov esi,RAMDISK call SeekTrack save_image_1: push esi @@ -57,7 +57,7 @@ save_image_1: cmp [FDD_Sector],19 jne save_image_1 mov [FDD_Sector],1 - inc [FDD_Head] + inc [FDD_Head] cmp [FDD_Head],2 jne save_image_1 mov [FDD_Head],0 diff --git a/kernel/branches/gfx_kernel/blkdev/flp_drv.inc b/kernel/branches/gfx_kernel/blkdev/flp_drv.inc index c969d7a87..a60c43598 100644 --- a/kernel/branches/gfx_kernel/blkdev/flp_drv.inc +++ b/kernel/branches/gfx_kernel/blkdev/flp_drv.inc @@ -4,24 +4,24 @@ ; Автор исходного текста Кулаков Владимир Геннадьевич. ; Адаптация и доработка Mario79 -give_back_application_data: ; переслать приложению - mov edi,[0x3010] +give_back_application_data: ; переслать приложению + mov edi,[TASK_BASE] mov edi,[edi+TASKDATA.mem_start] add edi,ecx give_back_application_data_1: - mov esi,0xD000 ;FDD_DataBuffer ;0x40000 + mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000 xor ecx,ecx mov cx,128 cld rep movsd ret -take_data_from_application: ; взять из приложения - mov esi,[0x3010] +take_data_from_application: ; взять из приложени + mov esi,[TASK_BASE] mov esi,[esi+TASKDATA.mem_start] add esi,ecx take_data_from_application_1: - mov edi,0xD000 ;FDD_DataBuffer ;0x40000 + mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000 xor ecx,ecx mov cx,128 cld @@ -66,7 +66,7 @@ FDC_C DB ? FDC_H DB ? FDC_R DB ? FDC_N DB ? -; Счетчик повторения операции чтения +; Счетчик повторения операции чтени ReadRepCounter DB ? ; Счетчик повторения операции рекалибровки RecalRepCounter DB ? @@ -136,7 +136,7 @@ FDCDataOutput: out DX,AL @@End_5: ; popa - pop edx ecx eax + pop edx ecx eax ret ;****************************************** @@ -174,7 +174,7 @@ FDCDataInput: ;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * ;********************************************* FDCInterrupt: -; Установить флаг прерывания +; Установить флаг прерывани mov [FDD_IntFlag],1 ret @@ -194,7 +194,7 @@ WaitFDCInterrupt: pusha ; Сбросить байт состояния операции mov [FDC_Status],FDC_Normal -; Сбросить флаг прерывания +; Сбросить флаг прерывани mov [FDD_IntFlag],0 ; Обнулить счетчик тиков mov eax,[timer_ticks] @@ -352,7 +352,7 @@ SeekTrack: ; Подать команду "Поиск" mov AL,0Fh call FDCDataOutput - ; Передать байт номера головки/накопителя + ; Передать байт номера головки/накопител mov AL,[FDD_Head] shl AL,2 call FDCDataOutput @@ -467,15 +467,15 @@ ReadSectWithRetr: ; Обнулить счетчик повторения операции рекалибровки 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 - ; Троекратное повторение чтения + je @@Err_3 + ; Троекратное повторение чтени inc [ReadRepCounter] cmp [ReadRepCounter],3 jb @@ReadSector_1 @@ -565,7 +565,7 @@ WriteSectWithRetr: ; Обнулить счетчик повторения операции рекалибровки mov [RecalRepCounter],0 @@TryAgain_1: -; Обнулить счетчик повторения операции чтения +; Обнулить счетчик повторения операции чтени mov [ReadRepCounter],0 @@WriteSector_1: call WriteSector @@ -573,7 +573,7 @@ WriteSectWithRetr: je @@Exit_4 cmp [FDC_Status],1 je @@Err_4 - ; Троекратное повторение чтения + ; Троекратное повторение чтени inc [ReadRepCounter] cmp [ReadRepCounter],3 jb @@WriteSector_1 diff --git a/kernel/branches/gfx_kernel/blkdev/hd_drv.inc b/kernel/branches/gfx_kernel/blkdev/hd_drv.inc new file mode 100644 index 000000000..46a3551fd --- /dev/null +++ b/kernel/branches/gfx_kernel/blkdev/hd_drv.inc @@ -0,0 +1,863 @@ +; Low-level driver for HDD access +; DMA support by Mario79 + +;************************************************************************** +; +; 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 +; +;************************************************************************** + +align 4 +hd_read: +;----------------------------------------------------------- +; input : eax = block to read +; ebx = destination +;----------------------------------------------------------- + and [hd_error], 0 + 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 + cmp [dma_hdd], 1 + jnz .nodma + call hd_read_dma + jmp @f +.nodma: + call hd_read_pio +@@: + + 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 + +align 4 +hd_read_pio: + push eax edx + + 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 + + pop edx eax + ret + +disable_ide_int: +; mov edx,[hdbase] +; add edx,0x206 +; mov al,2 +; out dx,al + cli + ret + +enable_ide_int: +; mov edx,[hdbase] +; add edx,0x206 +; mov al,0 +; out dx,al + sti + ret + +align 4 +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 .write_chain + + 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 + + cmp [allow_dma_write], 1 + jnz .nodma + cmp [dma_hdd], 1 + jnz .nodma +; ЋЎкҐ¤Ё­пҐ¬ § ЇЁбм 楯®зЄЁ Ї®б«Ґ¤®ў вҐ«м­ле ᥪв®а®ў ў ®¤­® ®Ўа йҐ­ЁҐ Є ¤ЁбЄг + cmp ecx, 1 + jz .nonext + cmp dword [esi+8+4], 2 + jnz .nonext + push eax + inc eax + cmp eax, [esi+8] + pop eax + jnz .nonext + cmp [cache_chain_started], 1 + jz @f + mov [cache_chain_started], 1 + mov [cache_chain_size], 0 + mov [cache_chain_pos], edi + mov [cache_chain_ptr], esi +@@: + inc [cache_chain_size] + cmp [cache_chain_size], 64 + jnz .continue + jmp .write_chain +.nonext: + call flush_cache_chain + mov [cache_chain_size], 1 + mov [cache_chain_ptr], esi + call write_cache_sector + jmp .continue +.nodma: + call cache_write_pio +.write_chain: + call flush_cache_chain + +.continue: + danger: + + add esi,8 + inc edi + dec ecx + jnz write_cache_more + call flush_cache_chain + return_02: + pop edi esi edx ecx eax + ret + +flush_cache_chain: + cmp [cache_chain_started], 0 + jz @f + call write_cache_chain + mov [cache_chain_started], 0 +@@: + ret + +align 4 +cache_write_pio: + 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 + + call enable_ide_int + pop esi ecx + + ret + +align 4 +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: + ret + +align 4 +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 + +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 + +align 4 +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',0 +; hd_read_str db 'K : FS - HD read error',0 +; hd_write_str db 'K : FS - HD write error',0 +; hd_lba_str db 'K : FS - HD LBA error',0 +;endg + +hd_timeout_error: + +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_timeout_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD timeout\n" +; 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 + DEBUGF 1,"K : FS - HD read error\n" + pop edx eax + ret + +hd_write_error: + +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_write_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD write error\n" + ret + +hd_write_error_dma: +; call clear_hd_cache +; call clear_application_table_status +; mov esi, hd_write_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD read error\n" + pop esi + ret + +hd_lba_error: +; call clear_hd_cache +; call clear_application_table_status +; mov esi,hd_lba_str +; call sys_msg_board_str + DEBUGF 1,"K : FS - HD LBA error\n" + jmp LBA_read_ret + + +align 4 +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 + + +align 4 +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 + +; \begin{Mario79} +align 4 +wait_for_sector_dma_ide0: + push eax + push edx + call save_hd_wait_timeout +.wait: + call change_task + cmp [irq14_func], hdd_irq14 + jnz .done + call check_hd_wait_timeout + cmp [hd_error], 0 + jz .wait + mov [irq14_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + mov al, 0 + out dx, al +.done: + pop edx + pop eax + ret + +align 4 +wait_for_sector_dma_ide1: + push eax + push edx + call save_hd_wait_timeout +.wait: + call change_task + cmp [irq15_func], hdd_irq15 + jnz .done + call check_hd_wait_timeout + cmp [hd_error], 0 + jz .wait + mov [irq15_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + add dx, 8 + mov al, 0 + out dx, al +.done: + pop edx + pop eax + ret + +iglobal +align 4 +; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary +IDE_descriptor_table: + dd 284000h + dw 2000h + dw 8000h + +dma_cur_sector dd not 40h +irq14_func dd hdd_irq_null +irq15_func dd hdd_irq_null +endg + +uglobal +; all uglobals are zeroed at boot +dma_process dd 0 +dma_slot_ptr dd 0 +cache_chain_pos dd 0 +cache_chain_ptr dd 0 +cache_chain_size db 0 +cache_chain_started db 0 +dma_task_switched db 0 +dma_hdd db 0 +allow_dma_write db 0 +endg + +align 4 +hdd_irq14: + pushfd + cli + pushad + mov [irq14_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + mov al, 0 + out dx, al + call update_counters + mov ebx, [dma_process] + cmp [0x3000], ebx + jz .noswitch + mov [dma_task_switched], 1 + mov edi, [dma_slot_ptr] + mov eax, [0x3000] + mov [dma_process], eax + mov eax, [0x3010] + mov [dma_slot_ptr], eax + mov [0x3000], ebx + mov [0x3010], edi + mov byte [0xFFFF], 1 + call do_change_task +.noswitch: + popad + popfd +align 4 +hdd_irq_null: + ret + +align 4 +hdd_irq15: + pushfd + cli + pushad + mov [irq15_func], hdd_irq_null + mov dx, [IDEContrRegsBaseAddr] + add dx, 8 + mov al, 0 + out dx, al + call update_counters + mov ebx, [dma_process] + cmp [0x3000], ebx + jz .noswitch + mov [dma_task_switched], 1 + mov edi, [dma_slot_ptr] + mov eax, [0x3000] + mov [dma_process], eax + mov eax, [0x3010] + mov [dma_slot_ptr], eax + mov [0x3000], ebx + mov [0x3010], edi + mov byte [0xFFFF], 1 + call do_change_task +.noswitch: + popad + popfd + ret + +align 4 +hd_read_dma: + push eax + push edx + mov edx, [dma_cur_sector] + cmp eax, edx + jb .notread + add edx, 15 + cmp [esp+4], edx + ja .notread + mov eax, [esp+4] + sub eax, [dma_cur_sector] + shl eax, 9 + add eax, 0x284000 + push ecx esi edi + mov esi, eax + shl edi, 9 + add edi, 0x610000 + mov ecx, 512/4 + cld + rep movsd + pop edi esi ecx + pop edx + pop eax + ret +.notread: + mov eax, IDE_descriptor_table + mov dword [eax], 0x284000 + mov word [eax+4], 0x2000 + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add edx, 8 +@@: + push edx + add edx, 4 + out dx, eax + pop edx + mov al, 0 + out dx, al + add edx, 2 + mov al, 6 + out dx, al + call wait_for_hd_idle + cmp [hd_error], 0 + jnz hd_read_error + call disable_ide_int + xor eax, eax + mov edx, [hdbase] + inc edx + out dx, al + inc edx + mov eax, 10h + 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, 0xF + add al, byte [hdid] + add al, 11100000b + out dx, al + inc edx + mov al, 0xC8 + out dx, al + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add dx, 8 +@@: + mov al, 9 + out dx, al + mov eax, [0x3000] + mov [dma_process], eax + mov eax, [0x3010] + mov [dma_slot_ptr], eax + cmp [hdbase], 0x1F0 + jnz .ide1 + mov [irq14_func], hdd_irq14 + jmp @f +.ide1: + mov [irq15_func], hdd_irq15 +@@: + call enable_ide_int + cmp [hdbase], 0x1F0 + jnz .wait_ide1 + call wait_for_sector_dma_ide0 + jmp @f +.wait_ide1: + call wait_for_sector_dma_ide1 +@@: + cmp [hd_error], 0 + jnz hd_read_error + pop edx + pop eax + mov [dma_cur_sector], eax + jmp hd_read_dma + +align 4 +write_cache_chain: + push esi + mov eax, IDE_descriptor_table + mov edx, [cache_chain_pos] + shl edx, 9 + add edx, 0x610000 + mov [eax], edx + movzx edx, [cache_chain_size] + shl edx, 9 + mov [eax+4], dx + jmp do_write_dma +write_cache_sector: + push esi + mov eax, IDE_descriptor_table + mov edx, edi + shl edx, 9 + add edx, 0x610000 + mov [eax], edx + mov word [eax+4], 0x200 +do_write_dma: + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add edx, 8 +@@: + push edx + add edx, 4 + out dx, eax + pop edx + mov al, 0 + out dx, al + add edx, 2 + mov al, 6 + out dx, al + call wait_for_hd_idle + cmp [hd_error], 0 + jnz hd_write_error_dma + call disable_ide_int + xor eax, eax + mov edx, [hdbase] + inc edx + out dx, al + inc edx + mov al, [cache_chain_size] + out dx, al + inc edx + mov esi, [cache_chain_ptr] + mov eax, [esi] + 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, 0xF + add al, byte [hdid] + add al, 11100000b + out dx, al + inc edx + mov al, 0xCA + out dx, al + mov dx, [IDEContrRegsBaseAddr] + cmp [hdbase], 0x1F0 + jz @f + add dx, 8 +@@: + mov al, 1 + out dx, al + mov eax, [0x3000] + mov [dma_process], eax + mov eax, [0x3010] + mov [dma_slot_ptr], eax + cmp [hdbase], 0x1F0 + jnz .ide1 + mov [irq14_func], hdd_irq14 + jmp @f +.ide1: + mov [irq15_func], hdd_irq15 +@@: + call enable_ide_int + mov [dma_cur_sector], not 0x40 + cmp [hdbase], 0x1F0 + jnz .wait_ide1 + call wait_for_sector_dma_ide0 + jmp @f +.wait_ide1: + call wait_for_sector_dma_ide1 +@@: + cmp [hd_error], 0 + jnz hd_write_error_dma + pop esi + ret + +uglobal +IDEContrRegsBaseAddr dw ? +endg +; \end{Mario79} diff --git a/kernel/branches/gfx_kernel/blkdev/rd.inc b/kernel/branches/gfx_kernel/blkdev/rd.inc index 0a9f87644..75f4e835b 100644 --- a/kernel/branches/gfx_kernel/blkdev/rd.inc +++ b/kernel/branches/gfx_kernel/blkdev/rd.inc @@ -12,8 +12,8 @@ calculatefatchain: pushad - mov esi,0x100000+512 - mov edi,0x280000 + mov esi,RAMDISK+512 + mov edi,RAMDISK_FAT fcnew: mov eax,dword [esi] @@ -38,7 +38,7 @@ calculatefatchain: add edi,16 add esi,12 - cmp edi,0x280000+2856*2 ;2849 clusters + cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters jnz fcnew popad @@ -49,8 +49,8 @@ restorefatchain: ; restore fat chain pushad - mov esi,0x280000 - mov edi,0x100000+512 + mov esi,RAMDISK_FAT + mov edi,RAMDISK+512 fcnew2: mov eax,dword [esi] @@ -66,11 +66,11 @@ restorefatchain: ; restore fat chain add edi,6 add esi,8 - cmp edi,0x100000+512+4278 ;4274 bytes - all used FAT + cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT jb fcnew2 - mov esi,0x100000+512 ; duplicate fat chain - mov edi,0x100000+512+0x1200 + mov esi,RAMDISK+512 ; duplicate fat chain + mov edi,RAMDISK+512+0x1200 mov ecx,1069 ;4274/4 cld rep movsd @@ -88,7 +88,7 @@ ramdisk_free_space: push eax ebx ecx - mov edi,0x280000 ;start of FAT + mov edi,RAMDISK_FAT ;start of FAT xor ax,ax ;Free cluster=0x0000 in FAT xor ebx,ebx ;counter mov ecx,2849 ;2849 clusters @@ -102,7 +102,7 @@ ramdisk_free_space: rdfs2: shl ebx,9 ;free clusters*512 mov edi,ebx - + pop ecx ebx eax ret @@ -193,7 +193,7 @@ fileread: mov edi,edx dec ebx push edx - mov edx,ecx + mov edx,ecx add edx,ebx cmp edx,15 ;ebx+ecx=14+1 pushf @@ -202,7 +202,7 @@ fileread: sub ecx,edx fr_do1: shl ebx,9 - mov esi,0x100000+512*19 + mov esi,RAMDISK+512*19 add esi,ebx shl ecx,7 cld @@ -246,7 +246,7 @@ fileread: add eax,31 ;bootsector+2*fat+filenames shl eax,9 ;*512 - add eax,0x100000 ;image base + add eax,RAMDISK ;image base mov ebx,[esp+8] mov ecx,512 ;[esp+4] @@ -260,7 +260,7 @@ fileread: frfl7: dec dword [esp+16] frfl8: - movzx eax,word [edi*2+0x280000] ; find next cluster from FAT + movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT mov edi,eax cmp edi,4095 ;eof - cluster jz frnoread2 @@ -308,7 +308,7 @@ filedelete: 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 @@ -326,7 +326,7 @@ filedelete: frnewd: shl edi,1 ;find next cluster from FAT - add edi,0x280000 + add edi,RAMDISK_FAT movzx eax,word [edi] mov [edi],word 0x0 ;clear fat chain cluster mov edi,eax @@ -338,7 +338,7 @@ filedelete: xor eax,eax ; file found ret - + filesave: ;---------------------------------------------------------- @@ -375,7 +375,7 @@ filesave: push eax ebx ecx edx esi edi - mov edi,0x100000+512*18+512 ;Point at directory + mov edi,RAMDISK+512*18+512 ;Point at directory mov edx,224 +1 ; find an empty spot for filename in the root dir l20ds: @@ -407,7 +407,7 @@ 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 edi,RAMDISK_FAT ;pointer to first cluster mov ecx,2849 cld frnewds: @@ -423,7 +423,7 @@ mov [edi+22],ax ; time pusha ; move save to floppy cluster add ebx,31 shl ebx,9 - add ebx,0x100000 + add ebx,RAMDISK mov eax,[esp+32+16] mov ecx,512 call memmove @@ -458,7 +458,7 @@ mov [edi+22],ax ; time ;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 + mov edi,RAMDISK+512*18+512 ;Point at directory cld rd_newsearch: mov esi,eax @@ -467,13 +467,13 @@ mov [edi+22],ax ; time je rd_ff add cl,21 add edi,ecx - cmp edi,0x100000+512*33 + cmp edi,RAMDISK+512*33 jb rd_newsearch mov eax,5 ;if file not found - eax=5 xor ebx,ebx - dec ebx ;ebx=0xffffffff and zf=0 + dec ebx ;ebx=0xffffffff and zf=0 rd_ff: - ret + ret ; \begin{diamond} @@ -599,45 +599,42 @@ fat_get_name: cmp byte [edi+11], 0xF jz .longname push ecx - mov ecx, 8 - push edi ebp ecx + push edi ebp test byte [ebp-4], 1 jnz .unicode_short + + mov eax, [edi] + mov ecx, [edi+4] + mov [ebp], eax + mov [ebp+4], ecx + + mov ecx, 8 @@: - 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 + cmp byte [ebp+ecx-1], ' ' + loope @b + + mov eax, [edi+8] + cmp al, ' ' + je .done + shl eax, 8 + mov al, '.' + + lea ebp, [ebp+ecx+1] + mov [ebp], eax 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 + rol eax, 8 + cmp al, ' ' + jne .done + loop @b + dec ebp +.done: + and byte [ebp+ecx+1], 0 ; CF=0 pop ebp edi ecx ret .unicode_short: + mov ecx, 8 + push ecx @@: mov al, [edi] inc edi @@ -905,12 +902,12 @@ bdfe_to_fat_entry: ret ramdisk_root_first: - mov edi, 0x100000+512*19 + mov edi, RAMDISK+512*19 clc ret ramdisk_root_next: add edi, 0x20 - cmp edi, 0x100000+512*33 + cmp edi, RAMDISK+512*33 cmc ret @@ -918,6 +915,12 @@ ramdisk_root_extend_dir: stc ret +uglobal +; this is for delete support +rd_prev_sector dd ? +rd_prev_prev_sector dd ? +endg + ramdisk_notroot_next: add edi, 0x20 test edi, 0x1FF @@ -926,7 +929,10 @@ ramdisk_notroot_next: ramdisk_notroot_next_sector: push ecx mov ecx, [eax] - mov ecx, [ecx*2+0x280000] + push [rd_prev_sector] + pop [rd_prev_prev_sector] + mov [rd_prev_sector], ecx + mov ecx, [ecx*2+RAMDISK_FAT] and ecx, 0xFFF cmp ecx, 2849 jae ramdisk_notroot_first.err2 @@ -939,7 +945,7 @@ ramdisk_notroot_first: cmp eax, 2849 jae .err shl eax, 9 - lea edi, [eax+(31 shl 9)+0x100000] + lea edi, [eax+(31 shl 9)+RAMDISK] clc ret .err2: @@ -956,20 +962,20 @@ ramdisk_root_next_write: ramdisk_notroot_extend_dir: pusha xor eax, eax - mov edi, 0x280000 + mov edi, RAMDISK_FAT mov ecx, 2849 repnz scasw jnz .notfound mov word [edi-2], 0xFFF - sub edi, 0x280000 + sub edi, RAMDISK_FAT shr edi, 1 dec edi mov eax, [esp+28] mov ecx, [eax] - mov [0x280000+ecx*2], di + mov [RAMDISK_FAT+ecx*2], di mov [eax], edi shl edi, 9 - add edi, (31 shl 9)+0x100000 + add edi, (31 shl 9)+RAMDISK mov [esp], edi xor eax, eax mov ecx, 128 @@ -1073,7 +1079,7 @@ fs_RamdiskRead: jae .eof lea eax, [edi+31] ; bootsector+2*fat+filenames shl eax, 9 ; *512 - add eax, 0x100000 ; image base + add eax, RAMDISK ; image base ; now eax points to data of cluster sub ebx, 512 jae .skip @@ -1091,7 +1097,7 @@ fs_RamdiskRead: pop ecx xor ebx, ebx .skip: - movzx edi, word [edi*2+0x280000] ; find next cluster from FAT + movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT jmp .new .eof: mov ebx, edx @@ -1162,7 +1168,7 @@ fs_RamdiskReadFolder: .main_loop: mov edi, eax shl edi, 9 - add edi, 0x100000 + add edi, RAMDISK push eax .l1: call fat_get_name @@ -1178,7 +1184,7 @@ fs_RamdiskReadFolder: jz .done jns @f ; read next sector from FAT - mov eax, [(eax-31-1)*2+0x280000] + mov eax, [(eax-31-1)*2+RAMDISK_FAT] and eax, 0xFFF cmp eax, 0xFF8 jae .done @@ -1187,7 +1193,7 @@ fs_RamdiskReadFolder: @@: mov edi, eax shl edi, 9 - add edi, 0x100000 + add edi, RAMDISK push eax .do_bdfe: inc dword [edx+8] ; new file found @@ -1207,7 +1213,7 @@ fs_RamdiskReadFolder: jz .done jns @f ; read next sector from FAT - mov eax, [(eax-31-1)*2+0x280000] + mov eax, [(eax-31-1)*2+RAMDISK_FAT] and eax, 0xFFF cmp eax, 0xFF8 jae .done @@ -1460,12 +1466,13 @@ fat_gen_short_name: ;---------------------------------------------------------------- ; -; fs_RamdiskRewrite - LFN variant for writing sys floppy +; fs_RamdiskRewrite - LFN variant for writing ramdisk +; fs_RamdiskCreateFolder - create folder on ramdisk ; -; esi points to filename +; esi points to file/folder name ; ebx ignored (reserved) -; ecx number of bytes to write, 0+ -; edx mem location to data +; ecx number of bytes to write, 0+ (ignored for folders) +; edx mem location to data (ignored for folders) ; ; ret ebx = number of written bytes ; eax = 0 ok read or other = errormsg @@ -1476,7 +1483,13 @@ fat_gen_short_name: xor ebx, ebx ret +fs_RamdiskCreateFolder: + mov al, 1 ; create folder + jmp fs_RamdiskRewrite.common + fs_RamdiskRewrite: + xor eax, eax ; create file +.common: cmp byte [esi], 0 jz @b pushad @@ -1501,6 +1514,9 @@ fs_RamdiskRewrite: push ramdisk_root_next jmp .common1 .noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 ; check existence mov byte [ebp], 0 call rd_find_lfn @@ -1531,8 +1547,24 @@ fs_RamdiskRewrite: .common1: call fat_find_lfn jc .notfound -; found; must not be directory +; found test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 20 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+20+28], 0 jz @f add esp, 20 popad @@ -1550,7 +1582,7 @@ fs_RamdiskRewrite: @@: cmp eax, 0xFF8 jae .done1 - lea edi, [0x280000 + eax*2] ; position in FAT + lea edi, [RAMDISK_FAT + eax*2] ; position in FAT xor eax, eax xchg ax, [edi] jmp @b @@ -1742,6 +1774,12 @@ fs_RamdiskRewrite: 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 + cmp byte [esp+20+28], 0 + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov ecx, 32*2 + mov edx, edi .doit: push edx push ecx @@ -1750,7 +1788,7 @@ fs_RamdiskRewrite: push edi jecxz .done mov ecx, 2849 - mov edi, 0x280000 + mov edi, RAMDISK_FAT .write_loop: ; allocate new cluster xor eax, eax @@ -1758,7 +1796,7 @@ fs_RamdiskRewrite: jnz .disk_full2 dec edi dec edi - lea eax, [edi-0x280000] + lea eax, [edi-(RAMDISK_FAT)] shr eax, 1 ; eax = cluster mov word [edi], 0xFFF ; mark as last cluster xchg edi, [esp] @@ -1767,8 +1805,11 @@ fs_RamdiskRewrite: push edi inc ecx ; write data + cmp byte [esp+16+20+28], 0 + jnz .writedir shl eax, 9 - add eax, 0x100000+31*512 + add eax, RAMDISK+31*512 +.writefile: mov ebx, edx xchg eax, ebx push ecx @@ -1803,6 +1844,34 @@ fs_RamdiskRewrite: push ERROR_DISK_FULL pop eax ret +.writedir: + mov edi, eax + shl edi, 9 + add edi, RAMDISK+31*512 + mov esi, edx + mov ecx, 32/4 + push ecx + rep movsd + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov word [edi-32+26], ax + mov esi, edx + pop ecx + rep movsd + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov eax, [esp+16+8] + mov word [edi-32+26], ax + pop edi edi ecx edx + add esp, 20 + popad + xor eax, eax + xor ebx, ebx + ret .read_symbol: or ax, -1 @@ -1924,7 +1993,7 @@ fs_RamdiskWrite: @@: mov eax, edi shl eax, 9 - add eax, 0x100000+31*512+0x200 + add eax, RAMDISK+31*512+0x200 sub eax, ebx mov ebx, eax mov eax, edx @@ -1935,7 +2004,7 @@ fs_RamdiskWrite: pop ecx jz .ret .next_cluster: - movzx edi, word [edi*2+0x280000] + movzx edi, word [edi*2+RAMDISK_FAT] jmp .write_loop ramdisk_extend_file.zero_size: @@ -1955,7 +2024,7 @@ ramdisk_extend_file: @@: sub ecx, 0x200 jbe @f - mov eax, [eax*2+0x280000] + mov eax, [eax*2+RAMDISK_FAT] and eax, 0xFFF jz .fat_err cmp eax, 0xFF8 @@ -1968,7 +2037,7 @@ ramdisk_extend_file: ret @@: push eax - mov eax, [eax*2+0x280000] + mov eax, [eax*2+RAMDISK_FAT] and eax, 0xFFF cmp eax, 0xFF8 pop eax @@ -1978,7 +2047,7 @@ ramdisk_extend_file: push eax edi mov edi, eax shl edi, 9 - lea edi, [edi+0x100000+31*512+0x200+ecx] + lea edi, [edi+RAMDISK+31*512+0x200+ecx] neg ecx xor eax, eax rep stosb @@ -1987,7 +2056,7 @@ ramdisk_extend_file: pop ecx ; now do extend push edx esi - mov esi, 0x280000+2*2 ; start scan from cluster 2 + mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2 mov edx, 2847 ; number of clusters to scan .extend_loop: cmp [edi+28], ecx @@ -2006,12 +2075,12 @@ ramdisk_extend_file: mov word [edi-2], 0xFFF mov esi, edi mov edx, ecx - sub edi, 0x280000 + sub edi, RAMDISK_FAT shr edi, 1 dec edi ; now edi=new cluster test eax, eax jz .first_cluster - mov [0x280000+eax*2], di + mov [RAMDISK_FAT+eax*2], di jmp @f .first_cluster: pop eax ; eax->direntry @@ -2020,7 +2089,7 @@ ramdisk_extend_file: @@: push edi shl edi, 9 - add edi, 0x100000+31*512 + add edi, RAMDISK+31*512 xor eax, eax mov ecx, 512/4 rep stosd @@ -2117,21 +2186,21 @@ fs_RamdiskSetFileEnd: @@: sub eax, 0x200 jbe @f - movzx ecx, word [0x280000+ecx*2] + movzx ecx, word [RAMDISK_FAT+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] + lea edi, [edi+RAMDISK+31*512+eax+0x200] mov ecx, eax neg ecx xor eax, eax rep stosb pop ecx ; terminate FAT chain - lea ecx, [0x280000+ecx+ecx] + lea ecx, [RAMDISK_FAT+ecx+ecx] push dword [ecx] mov word [ecx], 0xFFF pop ecx @@ -2144,7 +2213,7 @@ fs_RamdiskSetFileEnd: ; mark all clusters as free cmp ecx, 0xFF8 jae .deleted - lea ecx, [0x280000+ecx+ecx] + lea ecx, [RAMDISK_FAT+ecx+ecx] push dword [ecx] and word [ecx], 0 pop ecx @@ -2265,7 +2334,7 @@ fs_RamdiskExecute: mov edx, [eax+4] ; cluster lea esi, [edx+31] shl esi, 9 - add esi, 0x100000 + add esi, RAMDISK mov ecx, 512/4 rep movsd mov ecx, [eax] @@ -2279,7 +2348,7 @@ fs_RamdiskExecute: pop eax @@: mov [eax], ecx - mov dx, [edx*2+0x280000] + mov dx, [edx*2+RAMDISK_FAT] mov [eax+4], dx ; high word is already zero popad xor eax, eax @@ -2289,4 +2358,107 @@ fs_RamdiskExecute: mov eax, 6 ret +;---------------------------------------------------------------- +; +; fs_RamdiskDelete - delete file or empty folder from ramdisk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_RamdiskDelete: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED +.pop_ret: + pop eax + ret +@@: + and [rd_prev_sector], 0 + and [rd_prev_prev_sector], 0 + push edi + call rd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + movzx eax, word [edi+26] + push ebx + mov ebx, eax + shl ebx, 9 + add ebx, RAMDISK + 31*0x200 + 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + test ebx, 0x1FF + jnz .checkempty + movzx eax, word [RAMDISK_FAT + eax*2] + test eax, eax + jz .empty + mov ebx, eax + shl ebx, 9 + add ebx, RAMDISK + 31*0x200 + jmp .checkempty +.notempty: + pop ebx +.access_denied2: + pop edi + jmp .access_denied +.empty: + pop ebx +.dodel: + movzx eax, word [edi+26] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + test edi, 0x1FF + jnz @f + cmp [rd_prev_sector], 0 + jz @f + cmp [rd_prev_sector], -1 + jz .lfndone + mov edi, [rd_prev_sector] + push [rd_prev_prev_sector] + pop [rd_prev_sector] + or [rd_prev_prev_sector], -1 + shl edi, 9 + add edi, RAMDISK + 31*0x200 + 0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: +; delete FAT chain + test eax, eax + jz .done + lea eax, [RAMDISK_FAT + eax*2] + push dword [eax] + and word [eax], 0 + pop eax + and eax, 0xFFF + jmp .lfndone +.done: + pop edi + xor eax, eax + ret + ; \end{diamond} diff --git a/kernel/branches/gfx_kernel/blkdev/rdsave.inc b/kernel/branches/gfx_kernel/blkdev/rdsave.inc index 8fe849c5f..6b85a27fe 100644 --- a/kernel/branches/gfx_kernel/blkdev/rdsave.inc +++ b/kernel/branches/gfx_kernel/blkdev/rdsave.inc @@ -1,25 +1,22 @@ -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 +iglobal +saverd_fileinfo: + dd 2 ; subfunction: write + dd 0 ; (reserved) + dd 0 ; (reserved) + dd 1440*1024 ; size 1440 Kb + dd 0x100000 - std_application_base_address ; base address + db 0 +.name: + dd ? +endg +sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) + call restorefatchain + mov eax, saverd_fileinfo - std_application_base_address + mov [saverd_fileinfo.name], ebx + pushad + push eax + call file_system_lfn + pop eax + popad + mov [esp+36], eax + ret diff --git a/kernel/branches/gfx_kernel/boot/ETFONT.FNT b/kernel/branches/gfx_kernel/boot/ETFONT.FNT new file mode 100644 index 000000000..ca248381d Binary files /dev/null and b/kernel/branches/gfx_kernel/boot/ETFONT.FNT differ diff --git a/kernel/branches/gfx_kernel/boot/bootcode.inc b/kernel/branches/gfx_kernel/boot/bootcode.inc index 42169a74e..521af0cf9 100644 --- a/kernel/branches/gfx_kernel/boot/bootcode.inc +++ b/kernel/branches/gfx_kernel/boot/bootcode.inc @@ -17,6 +17,108 @@ include 'drawtext.inc' +; 16-bit data + org $+0x10000 + +old_ints_h: + dw 0x400 + dd 0 + dw 0 + +kernel_restart_bootblock: + db 1 ; version + dw 1 ; floppy image is in memory + dd 0 ; cannot save parameters + + +align 32 + +; GDT TABLE + +gdts: + + dw gdte-$-1 + dd gdts + dw 0 + +; Attention! The order first four selectors not to change, is used in Fast System Call +; must be : os_code, os_data, app_code, app_data, .... + +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 + +app_code_l: + dw 0xFFFF + dw 0 + db 0 + db cpl3 + dw G32+D32+0x8000+0x7; + +app_data_l: + dw 0xFFFF + dw 0 + db 0 + db drw3 + dw G32+D32+0x8000+0x7; + +; --------------- APM --------------------- +apm_code_32: + dw 0x0f ; limit 64kb + db 0, 0, 0 + dw 11010000b *256 +10011010b + db 0x00 +apm_code_16: + dw 0x0f + db 0, 0, 0 + dw 10010000b *256 +10011010b + db 0x00 +apm_data_16: + dw 0x0f + db 0, 0, 0 + dw 10010000b *256 +10010010b + db 0x00 +; ----------------------------------------- + +graph_data_l: + + dw 0x7ff + dw 0x0000 + db 0x00 + dw 11010000b *256 +11110010b + db 0x00 + +tss0_l: +; times (max_processes+10) dd 0,0 +gdte = $ + (max_processes+10)*8 + + +; 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 + putchar: ; in: al=character mov ah, 0Eh @@ -141,16 +243,16 @@ macro _setcursor row,column call setcursor } -pagetable_set: +;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 +; or al, 7 +;@@: +; stosd +; add eax, 1000h +; loop @b +; ret boot_read_floppy: push si @@ -172,21 +274,6 @@ sayerr_plain: pop si ret - org $+0x10000 - -; 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 include 'bootvesa.inc' ;========================================================================= @@ -236,6 +323,13 @@ if lang eq ru mov ax,1100h int 10h ; End set VGA russian font +else if lang eq et + mov bp,ET_FNT-10000h ; ET_FNT1 + mov bx,1000h ; + mov cx,255 ; 256 symbols + mov dx,0h ; 0 - position of first symbol + mov ax,1100h + int 10h end if ; draw frames @@ -351,14 +445,57 @@ sayerr: ; test al,2 ;проверка бита готовности ; loopnz test_kbd + push 0 + pop es + and word [es:0x9031], 0 +; \begin{Mario79} +; find HDD IDE DMA PCI device +; check for PCI BIOS + mov ax, 0xB101 + int 0x1A + jc .nopci + cmp edx, 'PCI ' + jnz .nopci +; find PCI class code +; class 1 = mass storage +; subclass 1 = IDE controller +; a) class 1, subclass 1, programming interface 0x80 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x80 + mov si, 0 ; device index = 0 + int 0x1A + jnc .found +; b) class 1, subclass 1, programming interface 0x8A + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x8A + mov si, 0 ; device index = 0 + int 0x1A + jnc .found +; c) class 1, subclass 1, programming interface 0x85 + mov ax, 0xB103 + mov ecx, 1*10000h + 1*100h + 0x85 + mov si, 0 + int 0x1A + jc .nopci +.found: +; get memory base + mov ax, 0xB10A + mov di, 0x20 ; memory base is config register at 0x20 + int 0x1A + jc .nopci + and cx, 0xFFF0 ; clear address decode type + mov [es:0x9031], cx +.nopci: +; \end{Mario79} + mov al,0xf6 ; Сброс клавиатуры, разрешить сканирование out 0x60,al xor cx,cx wait_loop: ; variant 2 ; reading state of port of 8042 controller - in al,64h + in al,64h and al,00000010b ; ready flag -; wait until 8042 controller is ready +; wait until 8042 controller is ready loopnz wait_loop ; --------------- APM --------------------- @@ -373,7 +510,7 @@ wait_loop: ; variant 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' @@ -384,7 +521,7 @@ wait_loop: ; variant 2 call printplain _setcursor d80x25_top_num,0 ; ------------------ - + mov ax, 0x5304 ; Disconnect interface xor bx, bx int 0x15 @@ -409,7 +546,7 @@ wait_loop: ; variant 2 mov [apm_data_16 - 0x10000 + 4], dl mov [es : 0x9040], ebx ; offset of APM entry point apm_end: -; ----------------------------------------- +; ----------------------------------------- ; DISPLAY VESA INFORMATION @@ -420,12 +557,12 @@ cfgmanager: ; settings: ; a) preboot_graph = graphical mode ; preboot_gprobe = probe this mode? -; b) preboot_mtrr = use hardware acceleration? +; b) preboot_dma_write = use DMA write? ; c) preboot_vrrm = use VRR? ; d) preboot_device = from what boot? mov di, preboot_graph-0x10000 ; check bootloader block - cmp [.loader_block-0x10000], 0 + cmp [.loader_block-0x10000], -1 jz .noloaderblock les bx, [.loader_block-0x10000] cmp byte [es:bx], 1 @@ -443,8 +580,8 @@ cfgmanager: mov [.bSettingsChanged-0x10000], 0 call calc_vmodes_table .preboot_gr_end: - cmp [di+preboot_mtrr-preboot_graph], 1 - adc [di+preboot_mtrr-preboot_graph], 0 + cmp [di+preboot_dma_write-preboot_graph], 1 + adc [di+preboot_dma_write-preboot_graph], 0 cmp [di+preboot_vrrm-preboot_graph], 1 adc [di+preboot_vrrm-preboot_graph], 0 cmp [di+preboot_device-preboot_graph], 1 @@ -470,8 +607,8 @@ cfgmanager: call draw_current_vmode mov si, linef-0x10000 call printplain - mov si, mtrr_msg-0x10000 - cmp [preboot_mtrr-0x10000], 1 + mov si, dma_msg-0x10000 + cmp [preboot_dma_write-0x10000], 1 call .say_on_off mov si, vrrm_msg-0x10000 cmp [preboot_vrrm-0x10000], 1 @@ -589,11 +726,11 @@ cfgmanager: jmp .d .change_b: _setcursor 15,0 - mov si, gr_acc-0x10000 + mov si, ask_dma-0x10000 call print mov bx, '12' call getkey - mov [preboot_mtrr-0x10000], al + mov [preboot_dma_write-0x10000], al _setcursor 11,0 jmp .d .change_c: @@ -622,7 +759,7 @@ virtual at novesa .timer dd ? end virtual org $+0x10000 -.loader_block dd 0 +.loader_block dd -1 org $-0x10000 .gettime: mov ah, 0 @@ -657,6 +794,12 @@ if lang eq ru jz @f mov cl, 'л' @@: mov [time_str+9-0x10000], cl +else if lang eq et + cmp al, 1 + ja @f + mov [time_str+9-0x10000], ' ' + mov [time_str+10-0x10000],' ' +@@: else ; wait 5/4/3/2 seconds, 1 second cmp al, 1 @@ -692,7 +835,7 @@ end if _setcursor 15,0 cmp [.bSettingsChanged-0x10000], 0 jz .load - cmp [.loader_block-0x10000], 0 + cmp [.loader_block-0x10000], -1 jz .load les bx, [.loader_block-0x10000] mov eax, [es:bx+3] @@ -738,8 +881,8 @@ end if ; GRAPHICS ACCELERATION - mov al, [preboot_mtrr-0x10000] - mov [es:0x901C],al + mov al, [preboot_dma_write-0x10000] + mov [es:0x901F],al ; VRR_M USE @@ -966,8 +1109,8 @@ sayerr_floppy: cmp di, 2880-31 jnz .read_loop -; mov cx,0x0001 ; startcyl,startsector -; xor dx, dx ; starthead,drive +; mov cx, 0x0001 ; startcyl,startsector +; xor dx, dx ; starthead,drive ; push word 80*2 ; read no of sect ; reads: ; pusha @@ -1045,44 +1188,44 @@ sayerr_floppy: mov al,0 out dx,al - push es +; push es ; PAGE TABLE - push dword [es:0x9018] - - map_mem equ 64 ; amount of memory to map - +; push dword [es:0x9018] +; +; mmap_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 - - +; xor di,di +; mov cx,256*mmap_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] - 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 +; mov eax, 0x7F000 +8+16 ; Page directory and enable caches +; mov cr3, eax ; SET GRAPHICS - pop es +; pop es push 0 pop es - mov ax,[es:0x9008] ; vga & 320x200 + mov ax,[es:0x9008] ; vga & 320x200 mov bx, ax cmp ax,0x13 je setgr diff --git a/kernel/branches/gfx_kernel/boot/booteng.inc b/kernel/branches/gfx_kernel/boot/booteng.inc index 6fb6437c5..8776a8a7f 100644 --- a/kernel/branches/gfx_kernel/boot/booteng.inc +++ b/kernel/branches/gfx_kernel/boot/booteng.inc @@ -26,22 +26,22 @@ macro line_space { } d80x25_top: - line_full_top + line_full_top verstr2: -; line_space +; 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 + db 186,32 + repeat 78 + load a byte from version+%-1 + if a = 13 + break + end if + db a + end repeat repeat 78 - ($-verstr2) - db ' ' - end repeat - db 32,186 + db ' ' + end repeat + db 32,186 verstr: line_half space_msg: line_space @@ -67,11 +67,11 @@ s_bpp db 13,10,186," Bits per pixel: " 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 -gr_acc db "Vesa 2.0+ : MTRR graphics acceleration [1-yes/2-no] ? ",0 -bdev db "Load ramdisk from [1-floppy; 2-C:\menuet.img (FAT32);" - db " 3-use preloaded ram-image from kernel restart]: ",0 +ask_dma db "Use DMA for HDD writing? [1-yes/2-no]: ",0 +bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" + db "3-use preloaded ram-image from kernel restart]: ",0 not386 db "Fatal - CPU 386+ required.",0 -fatalsel db 13,10,"Error - Selected mode is not supported.",0 +fatalsel db 13,10,"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" @@ -90,14 +90,14 @@ 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 -mtrr_msg db " [b] Use MTRR for graphics acceleration:",0 +dma_msg db " [b] Use DMA for HDD writing:",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 +pdm2 db "C:\kolibri.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 diff --git a/kernel/branches/gfx_kernel/boot/bootet.inc b/kernel/branches/gfx_kernel/boot/bootet.inc new file mode 100644 index 000000000..f1d67a767 --- /dev/null +++ b/kernel/branches/gfx_kernel/boot/bootet.inc @@ -0,0 +1,133 @@ +;====================================================================== +; +; 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 "Ekraan: EGA/CGA",13,10,0 +vervesa db "Vesa versioon: Vesa x.x",13,10,0 +vervesa_off=20 +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 vдrvi: [9] 320x200, " + db "VGA 16 vдrvi: [0] 640x480",13,10 + db 186," Vali reziim: ",0 +bt24 db "Bitti pikseli kohta: 24",13,10,0 +bt32 db "Bitti pikseli kohta: 32",13,10,0 +vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" + db " ainult:",13,10 + db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 +;askmouse db " Hiir:" +; db " [1] PS/2 (USB), [2] Com1, [3] Com2." +; db " Vali port [1-3]: ",0 +;no_com1 db 13,10,186, " No COM1 mouse",0 +;no_com2 db 13,10,186, " No COM2 mouse",0 +ask_dma db "Use DMA for HDD writing? [1-jah/2-ei]: ",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 "Paigalda mдluketas [1-diskett; 2-C:\kolibri.img (FAT32);" + db 13,10,186," " + db "3-kasuta eellaaditud mдluketast kerneli restardist]: ",0 +probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, " + db "2-leia biosist (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 "Fataalne - Videoreziimi ei leitud.",0 +;modena db "Fataalne - VBE 0x112+ on vajalik.",0 +not386 db "Fataalne - CPU 386+ on vajalik.",0 +btns db "Fataalne - Ei suuda vдrvisьgavust mддratleda.",0 +fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 +badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 +memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaхnnestus.",0 +okt db " ... OK" +linef db 13,10,0 +diskload db "Loen disketti: 00 %",8,8,8,8,0 +pros db "00" +backspace2 db 8,8,0 +boot_dev db 0 ; 0=floppy, 1=hd +start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jдtkamiseks",13,10,0 +time_msg db " vхi oota " +time_str db " 5 sekundit" + db " automaatseks jдtkamiseks",13,10,0 +current_cfg_msg db "Praegused seaded:",13,10,0 +curvideo_msg db " [a] Videoreziim: ",0 +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 " koos LFB",0 +modevesa12 db ", VESA 1.2 Bnk",0 +mode9 db "320x200, EGA/CGA 256 vдrvi",0 +mode10 db "640x480, VGA 16 vдrvi",0 +probeno_msg db " (standard reziim)",0 +probeok_msg db " (kontrolli ebastandardseid reziime)",0 +dma_msg db " [b] Use DMA for HDD writing:",0 +on_msg db " sees",13,10,0 +off_msg db " vдljas",13,10,0 +vrrm_msg db " [c] Kasuta VRR:",0 +preboot_device_msg db " [d] Disketi kujutis: ",0 +preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 +pdm1 db "reaalne diskett",13,10,0 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 +pdm3 db "kasuta juba laaditud kujutist",13,10,0 +loading_msg db "Laadin KolibriOS...",0 +save_quest db "Jдta meelde praegused seaded? [y/n]: ",0 +loader_block_error db "Alglaaduri andmed vigased, ei saa jдtkata. Peatatud.",0 diff --git a/kernel/branches/gfx_kernel/boot/bootge.inc b/kernel/branches/gfx_kernel/boot/bootge.inc new file mode 100644 index 000000000..0c0f20df6 --- /dev/null +++ b/kernel/branches/gfx_kernel/boot/bootge.inc @@ -0,0 +1,138 @@ +;====================================================================== +; +; 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 +ask_dma db "Nutze DMA zum HDD Aufschreiben? [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:\kolibri.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 +dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",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:\kolibri.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/branches/gfx_kernel/boot/bootru.inc b/kernel/branches/gfx_kernel/boot/bootru.inc index 9fc3049b5..6f5d18d81 100644 --- a/kernel/branches/gfx_kernel/boot/bootru.inc +++ b/kernel/branches/gfx_kernel/boot/bootru.inc @@ -24,7 +24,6 @@ macro line_space { times 78 db 32 db 186 } - d80x25_top: line_full_top verstr2: @@ -67,9 +66,8 @@ s_bpp db 13,10,186," vrrmprint db "€бЇ®«м§®ў вм VRR? (з бв®в  Є ¤а®ў ўлиҐ 60 ѓж" db " в®«мЄ® ¤«п ЇҐаҐе®¤®ў:",13,10 db 186," 1024*768>800*600 Ё 800*600>640*480) [1-¤ , 2-­Ґв]: ",0 -gr_acc db "Vesa 2.0+: ‚Є«озЁвм MTRR ¤«п г᪮७Ёп Ја дЁЄЁ? " - db "[1-¤ /2-­Ґв]: ",0 -bdev db "‡ Јаг§Ёвм ®Ўа § Ё§ [1-¤ЁбЄҐв ; 2-C:\menuet.img (FAT32);" +ask_dma db "€бЇ®«м§®ў вм DMA ¤«п § ЇЁбЁ ­  HDD? [1-¤ /2-­Ґв]: ",0 +bdev db "‡ Јаг§Ёвм ®Ўа § Ё§ [1-¤ЁбЄҐв ; 2-C:\kolibri.img (FAT32);" db 13,10,186," " db "3-ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §]: ",0 probetext db 13,10,13,10,186," ‘в ­¤ ав­л© ўЁ¤Ґ®аҐ¦Ё¬? [1-¤ , " @@ -104,14 +102,14 @@ 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 +dma_msg db " [b] €бЇ®«м§®ў ­ЁҐ DMA ¤«п § ЇЁбЁ ­  HDD:",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 +pdm2 db "C:\kolibri.img (FAT32)",13,10,0 pdm3 db "ЁбЇ®«м§®ў вм 㦥 § Ја㦥­­л© ®Ўа §",13,10,0 loading_msg db "€¤св § Јаг§Є  KolibriOS...",0 save_quest db "‡ Ї®¬­Ёвм ⥪гйЁҐ ­ бва®©ЄЁ? [y/n]: ",0 diff --git a/kernel/branches/gfx_kernel/boot/bootvesa.inc b/kernel/branches/gfx_kernel/boot/bootvesa.inc index 750ba2a5c..3a43c0728 100644 --- a/kernel/branches/gfx_kernel/boot/bootvesa.inc +++ b/kernel/branches/gfx_kernel/boot/bootvesa.inc @@ -557,7 +557,7 @@ set_vmode: ; .l0: mov al,[es:mi.BitsPerPixel];di+0x19] ; mov [es:0x9000],al ; ---- vbe voodoo - BytesPerScanLine equ 0x10 + ;BytesPerScanLine equ 0x10 push ax mov ax, [es:mi.BytesPerScanLine];di+BytesPerScanLine] mov [es:0x9001],ax @@ -1016,7 +1016,7 @@ macro sdfawgsgwaew { .l0: mov al,[es:mi.BitsPerPixel];di+0x19] mov [es:0x9000],al ; ---- vbe voodoo - BytesPerScanLine equ 0x10 + ;BytesPerScanLine equ 0x10 push ax mov ax, [es:mi.BytesPerScanLine];di+BytesPerScanLine] mov [es:0x9001],ax diff --git a/kernel/branches/gfx_kernel/boot/et.inc b/kernel/branches/gfx_kernel/boot/et.inc new file mode 100644 index 000000000..f03bc292b --- /dev/null +++ b/kernel/branches/gfx_kernel/boot/et.inc @@ -0,0 +1,6 @@ +; Full ASCII code font +; only х and д added +; Kaitz +ET_FNT: + fontfile file "ETFONT.FNT" + diff --git a/kernel/branches/gfx_kernel/boot/preboot.inc b/kernel/branches/gfx_kernel/boot/preboot.inc index d38c76a59..ddad6f567 100644 --- a/kernel/branches/gfx_kernel/boot/preboot.inc +++ b/kernel/branches/gfx_kernel/boot/preboot.inc @@ -1,26 +1,23 @@ -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_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 ) +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 +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_dma_write db 0 ; use DMA for writing to HDD (1-yes, 2-no) +preboot_device db 0 ; boot device + ; (1-floppy 2-harddisk 3-kernel restart) + ;!!!! 0 - autodetect !!!! +preboot_blogesc db 1 ; start immediately after bootlog - if $>10200h + 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 + end if +hdsysimage db 'KOLIBRI IMG' ; load from +image_save db 'KOLIBRI IMG' ; save to diff --git a/kernel/branches/gfx_kernel/boot/rdload.inc b/kernel/branches/gfx_kernel/boot/rdload.inc index cc98ec19c..e0fd73080 100644 --- a/kernel/branches/gfx_kernel/boot/rdload.inc +++ b/kernel/branches/gfx_kernel/boot/rdload.inc @@ -65,7 +65,6 @@ 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 @@ -83,13 +82,13 @@ read_image: mov eax, hdsysimage mov ebx, 1474560/512 - mov ecx, 0x100000 + mov ecx, RAMDISK mov esi, 0 mov edi, 12 call file_read - ret + ret -image_retrieved db 0 +image_retrieved db 0 counter_of_partitions db 0 no_sys_on_hd: yes_sys_on_hd: diff --git a/kernel/branches/gfx_kernel/boot/shutdown.inc b/kernel/branches/gfx_kernel/boot/shutdown.inc index 03cab4b63..6ae25c081 100644 --- a/kernel/branches/gfx_kernel/boot/shutdown.inc +++ b/kernel/branches/gfx_kernel/boot/shutdown.inc @@ -9,6 +9,7 @@ system_shutdown: ; shut down the system + call stop_all_services push 3 ; stop playing cd pop eax @@ -51,7 +52,7 @@ system_shutdown: ; shut down the system lea esi,[eax+220] ; x end sub eax,220 ; x start - mov ebx,[0xfe04] + mov ebx,[ScreenHeight] shr ebx,1 mov [shutdownpos],ebx lea ebp,[ebx+105] ; y end @@ -136,7 +137,10 @@ system_shutdown: ; shut down the system nrl: call dtext - sub ebx,0x050000 +; sub ebx,0x050000 + ror ebx, 16 + sub bl, 0x05 + ror ebx, 16 add eax,8 add ecx,31 cmp cx,word 0x0001+25*31 @@ -167,6 +171,10 @@ system_shutdown: ; shut down the system call restorefatchain + mov al, 0xFF + out 0x21, al + out 0xA1, al + mov word [0x467+0],pr_mode_exit-0x10000 mov word [0x467+2],0x1000 @@ -199,30 +207,31 @@ org $-0x10000 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 + + mov al,0xB8 out 0x21,al call rdelay + mov al,0xBD out 0xA1,al sti @@ -234,7 +243,7 @@ org $-0x10000 jl nbw cmp al,4 jle nbw32 - + nbw: in al,0x60 call pause_key @@ -276,7 +285,7 @@ org $-0x10000 jnz restart_kernel ; 4 = restart kernel push 0x40 pop ds - mov word[0x0072],0x1234 + mov word[0x0072],0x1234 jmp 0xF000:0xFFF0 pause_key: @@ -284,12 +293,6 @@ org $-0x10000 pause_key_1: loop pause_key_1 ret -org $+0x10000 -old_ints_h: - dw 0x400 - dd 0 - dw 0 -org $-0x10000 rdelay: ret @@ -365,18 +368,20 @@ restart_kernel_4000: jcxz $+2 sti +; (hint by Black_mirror) +; We must read data from keyboard port, +; because there may be situation when previous keyboard interrupt is lost +; (due to return to real mode and IRQ reprogramming) +; and next interrupt will not be generated (as keyboard waits for handling) + in al, 0x60 + ; bootloader interface push 0x1000 pop ds - mov si, .bootloader_block;-0x10000 + mov si, kernel_restart_bootblock-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 @@ -506,8 +511,8 @@ shutdowntext: db '1) SAVE RAMDISK TO FLOPPY ' db '2) APM - POWEROFF ' db '3) REBOOT ' - db '4) RESTART KERNEL ' -else + db '4) RESTART KERNEL ' +else if lang eq ru shutdowntext: db "ЃҐ§®Ї б­®Ґ ўлЄ«о祭ЁҐ Є®¬ЇмовҐа  Ё«Ё " db ' ' @@ -515,6 +520,14 @@ shutdowntext: 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' diff --git a/kernel/branches/gfx_kernel/build.bat b/kernel/branches/gfx_kernel/build.bat new file mode 100644 index 000000000..671f29616 --- /dev/null +++ b/kernel/branches/gfx_kernel/build.bat @@ -0,0 +1,114 @@ +@echo off + +set languages=en ru ge et +set drivers=sound sis infinity ati2d +set targets=all kernel drivers skins clean + +call :Check_Target %1 +for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 +call :Target_%target% + +if ERRORLEVEL 0 goto Exit_OK + +echo Probably at runing has been created error +echo For help send a report... +pause +goto :eof + + + + +:Check_Lang + set res=%1 + :Check_Lang_loop + for %%a in (%languages%) do if %%a==%res% set lang=%res% + if defined lang goto :eof + + echo Language "%res%" is not founded + echo Enter valide languege + echo [%languages%] + + set /P res="> + goto Check_Lang_loop +goto :eof + +:Check_Target + set res=%1 + :Check_Target_loop + for %%a in (%targets%) do if %%a==%res% set target=%res% + if defined target goto :eof + + echo Target "%res%" is not valide + echo Enter valide target + echo [%targets%] + + set /P res="> + goto Check_Target_loop +goto :eof + + +:Target_kernel + echo building kernel with language %lang% ... + + if not exist bin mkdir bin + echo lang fix %lang% > lang.inc + fasm -m 65536 kernel.asm bin\kernel.mnt + if not %errorlevel%==0 goto :Error_FasmFailed + erase lang.inc +goto :eof + + +:Target_all + echo building all ... + call :Target_kernel + call :Target_drivers + call :Target_skins +goto :eof + + +:Target_drivers + echo building drivers ... + + if not exist bin\drivers mkdir bin\drivers + cd drivers + for %%a in (%drivers%) do ( + fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj + if not %errorlevel%==0 goto :Error_FasmFailed + ) + cd .. +goto :eof + + +:Target_skins + echo building skins ... + + if not exist bin\skins mkdir bin\skins + cd skin + fasm -m 65536 default.asm ..\bin\skins\default.skn + if not %errorlevel%==0 goto :Error_FasmFailed + cd .. +goto :eof + + +:Target_clean + echo cleaning ... + + del /Q bin\drivers\*.* + del /Q bin\skins\*.* + del /Q bin\*.* + rmdir bin\drivers + rmdir bin\skins + rmdir bin +goto :Exit_OK + + +:Error_FasmFailed +echo error: fasm execution failed +erase lang.inc +pause +exit 1 + +:Exit_OK +echo all operations has been done +pause +exit 0 \ No newline at end of file diff --git a/kernel/branches/gfx_kernel/build_en.bat b/kernel/branches/gfx_kernel/build_en.bat deleted file mode 100644 index ff112543e..000000000 --- a/kernel/branches/gfx_kernel/build_en.bat +++ /dev/null @@ -1,5 +0,0 @@ -@erase lang.inc -@echo lang fix en >lang.inc -@fasm kernel.asm kernel.mnt -@erase lang.inc -@pause \ No newline at end of file diff --git a/kernel/branches/gfx_kernel/build_ru.bat b/kernel/branches/gfx_kernel/build_ru.bat deleted file mode 100644 index a8cd530f0..000000000 --- a/kernel/branches/gfx_kernel/build_ru.bat +++ /dev/null @@ -1,5 +0,0 @@ -@erase lang.inc -@echo lang fix ru >lang.inc -@fasm kernel.asm kernel.mnt -@erase lang.inc -@pause \ No newline at end of file diff --git a/kernel/branches/gfx_kernel/const.inc b/kernel/branches/gfx_kernel/const.inc new file mode 100644 index 000000000..427934cd1 --- /dev/null +++ b/kernel/branches/gfx_kernel/const.inc @@ -0,0 +1,571 @@ + + +drw0 equ 10010010b ; data read/write dpl0 +drw3 equ 11110010b ; data read/write dpl3 +cpl0 equ 10011010b ; code read dpl0 +cpl3 equ 11111010b ; code read dpl3 + +D32 equ 01000000b ; 32bit segment +G32 equ 10000000b ; page gran + + +;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; + +CPU_386 equ 3 +CPU_486 equ 4 +CPU_PENTIUM equ 5 +CPU_P6 equ 6 +CPU_PENTIUM4 equ 0x0F + +CAPS_FPU equ 00 ;on-chip x87 floating point unit +CAPS_VME equ 01 ;virtual-mode enhancements +CAPS_DE equ 02 ;debugging extensions +CAPS_PSE equ 03 ;page-size extensions +CAPS_TSC equ 04 ;time stamp counter +CAPS_MSR equ 05 ;model-specific registers +CAPS_PAE equ 06 ;physical-address extensions +CAPS_MCE equ 07 ;machine check exception +CAPS_CX8 equ 08 ;CMPXCHG8B instruction +CAPS_APIC equ 09 ;on-chip advanced programmable + ; interrupt controller +; 10 ;unused +CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions +CAPS_MTRR equ 12 ;memory-type range registers +CAPS_PGE equ 13 ;page global extension +CAPS_MCA equ 14 ;machine check architecture +CAPS_CMOV equ 15 ;conditional move instructions +CAPS_PAT equ 16 ;page attribute table + +CAPS_PSE36 equ 17 ;page-size extensions +CAPS_PSN equ 18 ;processor serial number +CAPS_CLFLUSH equ 19 ;CLFUSH instruction + +CAPS_DS equ 21 ;debug store +CAPS_ACPI equ 22 ;thermal monitor and software + ;controlled clock supported +CAPS_MMX equ 23 ;MMX instructions +CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions +CAPS_SSE equ 25 ;SSE instructions +CAPS_SSE2 equ 26 ;SSE2 instructions +CAPS_SS equ 27 ;self-snoop +CAPS_HTT equ 28 ;hyper-threading technology +CAPS_TM equ 29 ;thermal monitor supported +CAPS_IA64 equ 30 ;IA64 capabilities +CAPS_PBE equ 31 ;pending break enable + +;ecx +CAPS_SSE3 equ 32 ;SSE3 instructions +; 33 +; 34 +CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions +CAPS_DS_CPL equ 36 ; +CAPS_VMX equ 37 ;virtual mode extensions +; 38 ; +CAPS_EST equ 39 ;enhansed speed step +CAPS_TM2 equ 40 ;thermal monitor2 supported +; 41 +CAPS_CID equ 42 ; +; 43 +; 44 +CAPS_CX16 equ 45 ;CMPXCHG16B instruction +CAPS_xTPR equ 46 ; +; +;reserved +; +;ext edx /ecx +CAPS_SYSCAL equ 64 ; +CAPS_XD equ 65 ;execution disable +CAPS_FFXSR equ 66 ; +CAPS_RDTSCP equ 67 ; +CAPS_X64 equ 68 ; +CAPS_3DNOW equ 69 ; +CAPS_3DNOWEXT equ 70 ; +CAPS_LAHF equ 71 ; +CAPS_CMP_LEG equ 72 ; +CAPS_SVM equ 73 ;secure virual machine +CAPS_ALTMOVCR8 equ 74 ; + +; CPU MSR names +MSR_SYSENTER_CS equ 0x174 +MSR_SYSENTER_ESP equ 0x175 +MSR_SYSENTER_EIP equ 0x176 +MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register +MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register + +CR0_PE equ 0x00000001 ;protected mode +CR0_MP equ 0x00000002 ;monitor fpu +CR0_EM equ 0x00000004 ;fpu emulation +CR0_TS equ 0x00000008 ;task switch +CR0_ET equ 0x00000010 ;extension type hardcoded to 1 +CR0_NE equ 0x00000020 ;numeric error +CR0_WP equ 0x00010000 ;write protect +CR0_AM equ 0x00040000 ;alignment check +CR0_NW equ 0x20000000 ;not write-through +CR0_CD equ 0x40000000 ;cache disable +CR0_PG equ 0x80000000 ;paging + + +CR4_VME equ 0x0001 +CR4_PVI equ 0x0002 +CR4_TSD equ 0x0004 +CR4_DE equ 0x0008 +CR4_PSE equ 0x0010 +CR4_PAE equ 0x0020 +CR4_MCE equ 0x0040 +CR4_PGE equ 0x0080 +CR4_PCE equ 0x0100 +CR4_OSFXSR equ 0x0200 +CR4_OSXMMEXPT equ 0x0400 + +SSE_IE equ 0x0001 +SSE_DE equ 0x0002 +SSE_ZE equ 0x0004 +SSE_OE equ 0x0008 +SSE_UE equ 0x0010 +SSE_PE equ 0x0020 +SSE_DAZ equ 0x0040 +SSE_IM equ 0x0080 +SSE_DM equ 0x0100 +SSE_ZM equ 0x0200 +SSE_OM equ 0x0400 +SSE_UM equ 0x0800 +SSE_PM equ 0x1000 +SSE_FZ equ 0x8000 + +SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) + +OS_BASE equ 0 + +window_data equ (OS_BASE+0x0000000) + +CURRENT_TASK equ (OS_BASE+0x0003000) +TASK_COUNT equ (OS_BASE+0x0003004) +TASK_BASE equ (OS_BASE+0x0003010) +TASK_DATA equ (OS_BASE+0x0003020) +TASK_EVENT equ (OS_BASE+0x0003020) + +;mouseunder equ (OS_BASE+0x0006900) +FLOPPY_BUFF equ (OS_BASE+0x0008000) +ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused +idts equ (OS_BASE+0x000B100) +WIN_STACK equ (OS_BASE+0x000C000) +WIN_POS equ (OS_BASE+0x000C400) +FDD_BUFF equ (OS_BASE+0x000D000) + +;unused ? only one reference +ENABLE_TASKSWITCH equ (OS_BASE+0x000E000) + +PUTPIXEL equ (OS_BASE+0x000E020) +GETPIXEL equ (OS_BASE+0x000E024) + +;unused ? only one reference +BANK_SWITCH equ (OS_BASE+0x000E030) +VESA_VER_MAJOR equ (OS_BASE+0x000E034) +GFX_CARD_VENDOR equ (OS_BASE+0x000E035) + +;unused ? store mousepointer +MOUSE_PICTURE equ (OS_BASE+0x000F200) + +MOUSE_VISIBLE equ (OS_BASE+0x000F204) +WIN_TEMP_XY equ (OS_BASE+0x000F300) +KEY_COUNT equ (OS_BASE+0x000F400) +KEY_BUFF equ (OS_BASE+0x000F401) + +BTN_COUNT equ (OS_BASE+0x000F500) +BTN_BUFF equ (OS_BASE+0x000F501) + +CPU_FREQ equ (OS_BASE+0x000F600) + +;unused ? no active references +MOUSE_PORT equ (OS_BASE+0x000F604) + +;unused +PS2_CHUNK equ (OS_BASE+0x000FB00) + +MOUSE_X equ (OS_BASE+0x000FB0A) +MOUSE_Y equ (OS_BASE+0x000FB0C) + +MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10) +COLOR_TEMP equ (OS_BASE+0x000FB30) +BTN_DOWN equ (OS_BASE+0x000FB40) +MOUSE_DOWN equ (OS_BASE+0x000FB44) +X_UNDER equ (OS_BASE+0x000FB4A) +Y_UNDER equ (OS_BASE+0x000FB4C) +ScreenBPP equ (OS_BASE+0x000FBF1) + +;unused ? only one reference +MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) + +LFBAddress equ (OS_BASE+0x000FE80) +MEM_AMOUNT equ (OS_BASE+0x000FE8C) +;LFBSize equ (OS_BASE+0x02f9050) + +ScreenWidth equ (OS_BASE+0x000FE00) +ScreenHeight equ (OS_BASE+0x000FE04) +BytesPerScanLine equ (OS_BASE+0x000FE08) +SCR_MODE equ (OS_BASE+0x000FE0C) + +BTN_ADDR equ (OS_BASE+0x000FE88) +SYS_SHUTDOWN equ (OS_BASE+0x000FF00) +TASK_ACTIVATE equ (OS_BASE+0x000FF01) + +REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0) +BANK_RW equ (OS_BASE+0x000FFF2) +MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) +DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) +DONT_SWITCH equ (OS_BASE+0x000FFFF) + +TMP_STACK_TOP equ 0x003EC00 + +FONT_II equ (OS_BASE+0x003EC00) +FONT_I equ (OS_BASE+0x003F600) +DRIVE_DATA equ (OS_BASE+0x0040000) +SLOT_BASE equ (OS_BASE+0x0080000) + +;unused +TMP_BUFF equ (OS_BASE+0x0090000) + +VGABasePtr equ (OS_BASE+0x00A0000) + +RAMDISK equ (OS_BASE+0x0100000) +RAMDISK_FAT equ (OS_BASE+0x0280000) +FLOPPY_FAT equ (OS_BASE+0x0282000) + +; unused? +SB16_Status equ (OS_BASE+0x02B0000) + +BUTTON_INFO equ (OS_BASE+0x02C0000) +RESERVED_PORTS equ (OS_BASE+0x02D0000) +IRQ_SAVE equ (OS_BASE+0x02E0000) +SYS_VAR equ (OS_BASE+0x02f0000) +IMG_BACKGROUND equ (OS_BASE+0x0300000) +WinMapAddress equ (OS_BASE+0x0460000) +display_data equ (OS_BASE+0x0460000) + +;unused ? +HD_CACHE equ (OS_BASE+0x0600000) + +stack_data_start equ (OS_BASE+0x0700000) +eth_data_start equ (OS_BASE+0x0700000) +stack_data equ (OS_BASE+0x0704000) +stack_data_end equ (OS_BASE+0x071ffff) +VMODE_BASE equ (OS_BASE+0x0760000) +resendQ equ (OS_BASE+0x0770000) + +skin_data equ (OS_BASE+0x0778000) + + +tss_data equ (OS_BASE+0x780000) +draw_data equ (OS_BASE+0x988000) + +HEAP_BASE equ (OS_BASE+0x98B000) + +LFB_BASE equ 0x7DC00000 + +page_tabs equ 0x7FC00000 +master_tab equ 0x7FDFF000 +app_page_tabs equ 0x7FE00000 + +sys_pgdir equ OS_BASE+0x00050000 +sys_master_tab equ OS_BASE+0x00051000 +sys_pgmap equ OS_BASE+0x00052000 + + + +new_app_base equ 0x80000000 + +twdw equ (CURRENT_TASK-window_data) + +std_application_base_address equ new_app_base +RING0_STACK_SIZE equ 0x2000 - 512 ;512 байт для контекста FPU + +;PAGES_USED equ 4 + +PG_UNMAP equ 0x000 +PG_MAP equ 0x001 +PG_WRITE equ 0x002 +PG_SW equ 0x003 +PG_USER equ 0x005 +PG_UW equ 0x007 +PG_NOCACHE equ 0x018 +PG_LARGE equ 0x080 +PG_GLOBAL equ 0x100 + +;;;;;;;;;;;boot time variables + +;BOOT_BPP equ 0x9000 ;byte bits per pixel +BOOT_SCANLINE equ 0x9001 ;word scanline length +BOOT_VESA_MODE equ 0x9008 ;word vesa video mode +;;BOOT_X_RES equ 0x900A ;word X res +;;BOOT_Y_RES equ 0x900C ;word Y res +;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used +BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch +BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address +BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration +BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) +BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled +BOOT_PCI_DATA equ 0x9020 ;8bytes pci data +BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no +BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr +BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount + +TMP_FILE_NAME equ 0 +TMP_CMD_LINE equ 1024 +TMP_ICON_OFFS equ 1280 + + +EVENT_REDRAW equ 0x00000001 +EVENT_KEY equ 0x00000002 +EVENT_BUTTON equ 0x00000004 +EVENT_BACKGROUND equ 0x00000010 +EVENT_MOUSE equ 0x00000020 +EVENT_IPC equ 0x00000040 +EVENT_NETWORK equ 0x00000080 +EVENT_DEBUG equ 0x00000100 +EVENT_EXTENDED equ 0x00000200 + +EV_INTR equ 1 + +struc SYS_VARS +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .cpu_caps dd ? + dd ? + dd ? + dd ? +} + +struc APPOBJ ;common object header +{ + .magic dd ? ; + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id +}; + +virtual at 0 + APPOBJ APPOBJ +end virtual + +APP_OBJ_OFFSET equ 48 +APP_EV_OFFSET equ 40 + +struc CURSOR +{;common object header + .magic dd ? ;'CURS' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + ;cursor data + .base dd ? ;allocated memory + .hot_x dd ? ;hotspot coords + .hot_y dd ? +} +virtual at 0 + CURSOR CURSOR +end virtual + +CURSOR_SIZE equ 32 + +struc EVENT +{ + .magic dd ? ;'EVNT' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .id dd ? ;event uid + .state dd ? ;internal flags + .code dd ? + rd 5 +} +EVENT_SIZE equ 52 + +virtual at 0 + EVENT EVENT +end virtual + + + +struc HEAP_DATA +{ + .mutex rd 1 + .refcount rd 1 + .heap_base rd 1 + .heap_top rd 1 + .app_mem rd 1 +} + +HEAP_DATA_SIZE equ 20 +virtual at 0 + HEAP_DATA HEAP_DATA +end virtual + +struc BOOT_DATA +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .mouse_port dd ? + .bank_switch dd ? + .lfb dd ? + .vesa_mem dd ? + .log dd ? + .direct_lfb dd ? + .pci_data dd ? +; dd ? + .vrr dd ? + .ide_base dd ? + .mem_amount dd ? + .pages_count dd ? + .pagemap_size dd ? + .kernel_max dd ? + .kernel_pages dd ? + .kernel_tables dd ? + + .cpu_vendor dd ? + dd ? + dd ? + .cpu_sign dd ? + .cpu_info dd ? + .cpu_caps dd ? + dd ? + dd ? +} + +virtual at 0 + BOOT_DATA BOOT_DATA +end virtual + +struc MEM_STATE +{ .mutex rd 1 + .smallmap rd 1 + .treemap rd 1 + .topsize rd 1 + .top rd 1 + .smallbins rd 4*32 + .treebins rd 32 +} + +struc PG_DATA +{ .mem_amount dd ? + .vesa_mem dd ? + .pages_count dd ? + .pages_free dd ? + .pages_faults dd ? + .pagemap_size dd ? + .kernel_max dd ? + .kernel_pages dd ? + .kernel_tables dd ? + .sys_page_dir dd ? + .pg_mutex dd ? +} + +;struc LIB +;{ .lib_name rb 16 +; .lib_base dd ? +; .lib_start dd ? +; .export dd ? +; .import dd ? +;} + +struc SRV +{ .srv_name rb 16 ;ASCIIZ string + .magic dd ? ;+0x10 ;'SRV ' + .size dd ? ;+0x14 ;size of structure SRV + .fd dd ? ;+0x18 ;next SRV descriptor + .bk dd ? ;+0x1C ;prev SRV descriptor + .base dd ? ;+0x20 ;service base address + .entry dd ? ;+0x24 ;service START function + .srv_proc dd ? ;+0x28 ;main service handler +} + +SRV_FD_OFFSET equ 0x18 +SRV_SIZE equ 44 + +struc COFF_HEADER +{ .machine dw ? + .nSections dw ? + .DataTime dd ? + .pSymTable dd ? + .nSymbols dd ? + .optHeader dw ? + .flags dw ? +}; + + +struc COFF_SECTION +{ .Name rb 8 + .VirtualSize dd ? + .VirtualAddress dd ? + .SizeOfRawData dd ? + .PtrRawData dd ? + .PtrReloc dd ? + .PtrLinenumbers dd ? + .NumReloc dw ? + .NumLinenum dw ? + .Characteristics dd ? +} +COFF_SECTION_SIZE equ 40 + +struc COFF_RELOC +{ .VirtualAddress dd ? + .SymIndex dd ? + .Type dw ? +} + +struc COFF_SYM +{ .Name rb 8 + .Value dd ? + .SectionNumber dw ? + .Type dw ? + .StorageClass db ? + .NumAuxSymbols db ? +} +CSYM_SIZE equ 18 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +;virtual at 0 +; LIB LIB +;end virtual + +virtual at 0 + SRV SRV +end virtual + +virtual at 0 + CFH COFF_HEADER +end virtual + +virtual at 0 + CFS COFF_SECTION +end virtual + +virtual at 0 + CRELOC COFF_RELOC +end virtual + +virtual at 0 + CSYM COFF_SYM +end virtual + diff --git a/kernel/branches/gfx_kernel/core/debug.inc b/kernel/branches/gfx_kernel/core/debug.inc index d8d1c02c9..c71cd874a 100644 --- a/kernel/branches/gfx_kernel/core/debug.inc +++ b/kernel/branches/gfx_kernel/core/debug.inc @@ -19,9 +19,9 @@ sys_debug_services_table: debug_set_event_data: ; in: ebx = pointer ; destroys eax - mov eax, [0x3000] + mov eax, [CURRENT_TASK] shl eax, 8 - mov [eax+0x80000+APPDATA.dbg_event_mem], ebx + mov [eax+SLOT_BASE+APPDATA.dbg_event_mem], ebx ret get_debuggee_slot: @@ -36,8 +36,8 @@ get_debuggee_slot: jz .ret_bad shl eax, 5 push ebx - mov ebx, [0x3000] - cmp [0x80000+eax*8+APPDATA.debugger_slot], ebx + mov ebx, [CURRENT_TASK] + cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx pop ebx jnz .ret_bad ; clc ; automatically @@ -51,7 +51,7 @@ debug_detach: ; destroys eax,ebx call get_debuggee_slot jc .ret - and dword [eax*8+0x80000+APPDATA.debugger_slot], 0 + and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 call do_resume .ret: sti @@ -72,13 +72,13 @@ debug_suspend: ; destroys eax,ebx call get_debuggee_slot jc .ret - mov bl, [0x3000+eax+TASKDATA.state] ; process state + mov bl, [CURRENT_TASK+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 +.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl .ret: sti ret @@ -87,13 +87,13 @@ debug_suspend: jmp .2 do_resume: - mov bl, [0x3000+eax+TASKDATA.state] + mov bl, [CURRENT_TASK+eax+TASKDATA.state] cmp bl, 1 jz .1 cmp bl, 2 jnz .ret mov bl, 5 -.2: mov [0x3000+eax+TASKDATA.state], bl +.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl .ret: ret .1: dec ebx jmp .2 @@ -127,16 +127,16 @@ debug_getcontext: imul eax, tss_step/32 add eax, tss_data mov edi, edx - cmp [l.cs - tss_sceleton + eax], app_code + cmp [eax+TSS._cs], app_code jnz .ring0 - lea esi, [l.eip - tss_sceleton + eax] + lea esi, [eax+TSS._eip] 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] + mov esi, [eax+TSS._esp0] ; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad sub esi, 8+12+8+20h lodsd @@ -186,14 +186,14 @@ debug_setcontext: imul eax, tss_step/32 add eax, tss_data mov esi, edx - cmp [l.cs - tss_sceleton + eax], app_code + cmp [eax+TSS._cs], app_code jnz .ring0 - lea edi, [l.eip - tss_sceleton + eax] + lea edi, [eax+TSS._eip] shr ecx, 2 rep movsd jmp .stiret .ring0: - mov edi, [l.esp0 - tss_sceleton + eax] + mov edi, [eax+TSS._esp0] sub edi, 8+12+8+20h mov eax, [esi+24h] stosd @@ -227,7 +227,7 @@ debug_set_drx: call get_debuggee_slot jc .errret mov ebp, eax - lea eax, [eax*8+0x80000+APPDATA.dbg_regs] + lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 ; [eax+10]=dr7 add edx, std_application_base_address @@ -249,7 +249,7 @@ debug_set_drx: test byte [eax+10h], 55h jnz .okret imul eax, ebp, tss_step/32 - and byte [eax + tss_data + l.trap - tss_sceleton], not 1 + and byte [eax + tss_data + TSS._trap], not 1 .okret: and dword [esp+36], 0 sti @@ -291,7 +291,7 @@ debug_set_drx: 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 + or byte [eax + tss_data + TSS._trap], 1 jmp .okret debug_read_process_memory: @@ -358,7 +358,7 @@ debugger_notify: .1: mov eax, ebp shl eax, 8 - mov edx, [0x80000+eax+APPDATA.dbg_event_mem] + mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] test edx, edx jz .ret ; read buffer header @@ -380,7 +380,7 @@ debugger_notify: pop ecx pop ecx pop ecx - cmp dword [0x3000], 1 + cmp dword [CURRENT_TASK], 1 jnz .notos cmp [timer_ticks], edi jae .ret @@ -414,7 +414,7 @@ debugger_notify: ; new debug event mov eax, ebp shl eax, 8 - or byte [0x80000+eax+APPDATA.event_mask+1], 1 ; set flag 100h + or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h .ret: ret @@ -430,9 +430,9 @@ debug_exc: jns @f ; this is exception from task switch ; set DRx registers for task and continue - mov eax, [0x3000] + mov eax, [CURRENT_TASK] shl eax, 8 - add eax, 0x80000+APPDATA.dbg_regs + add eax, SLOT_BASE+APPDATA.dbg_regs mov ecx, [eax+0] mov dr0, ecx mov ecx, [eax+4] @@ -453,9 +453,9 @@ debug_exc: mov dr6, eax ; test if debugging cli - mov eax, [0x3000] + mov eax, [CURRENT_TASK] shl eax, 8 - mov eax, [0x80000+eax+APPDATA.debugger_slot] + mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot] test eax, eax jnz .debug sti @@ -463,7 +463,7 @@ debug_exc: add esp, 28h+4 mov [error_interrupt], 1 call show_error_parameters - mov edx, [0x3010] + mov edx, [TASK_BASE] mov byte [edx+TASKDATA.state], 4 jmp change_task .debug: @@ -483,7 +483,7 @@ debug_exc: cmp cl, not 10h jnz .l1 push edx ; DR6 image - mov ecx, [0x3010] + mov ecx, [TASK_BASE] push dword [ecx+TASKDATA.pid] ; PID push 12 pop ecx @@ -492,7 +492,7 @@ debug_exc: pop ecx pop ecx pop ecx - mov edx, [0x3010] + mov edx, [TASK_BASE] mov byte [edx+TASKDATA.state], 1 ; suspended call change_task restore_ring3_context diff --git a/kernel/branches/gfx_kernel/core/dll.inc b/kernel/branches/gfx_kernel/core/dll.inc new file mode 100644 index 000000000..2db407c3d --- /dev/null +++ b/kernel/branches/gfx_kernel/core/dll.inc @@ -0,0 +1,1058 @@ + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +DRV_COMPAT equ 4 ;minimal required drivers version +DRV_CURRENT equ 4 ;current drivers model version + +DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT + +align 4 +proc attach_int_handler stdcall, irq:dword, handler:dword + + mov ebx, [irq] ;irq num + test ebx, ebx + jz .err + mov eax, [handler] + test eax, eax + jz .err + mov [irq_tab+ebx*4], eax + stdcall enable_irq, [irq] + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc detach_int_handler + + ret +endp + +align 4 +proc enable_irq stdcall, irq_line:dword + mov ebx, [irq_line] + mov edx, 0x21 + cmp ebx, 8 + jb @F + mov edx, 0xA1 + sub ebx,8 +@@: + in al,dx + btr eax, ebx + out dx, al + ret +endp + +align 16 +;; proc irq_serv + +irq_serv: + +.irq_1: + push eax + mov eax, 1 + jmp .main +align 4 +.irq_2: + push eax + mov eax, 2 + jmp .main +align 4 +.irq_3: + push eax + mov eax, 3 + jmp .main +align 4 +.irq_4: + push eax + mov eax, 4 + jmp .main +align 4 +.irq_5: + push eax + mov eax, 5 + jmp .main +align 4 +.irq_6: + push eax + mov eax, 6 + jmp .main +align 4 +.irq_7: + push eax + mov eax, 7 + jmp .main +align 4 +.irq_8: + push eax + mov eax, 8 + jmp .main +align 4 +.irq_9: + push eax + mov eax, 9 + jmp .main +align 4 +.irq_10: + push eax + mov eax, 10 + jmp .main +align 4 +.irq_11: + push eax + mov eax, 11 + jmp .main +align 4 +.irq_12: + push eax + mov eax, 12 + jmp .main +align 4 +.irq_13: + push eax + mov eax, 13 + jmp .main +align 4 +.irq_14: + push eax + mov eax, 14 + jmp .main +align 4 +.irq_15: + push eax + mov eax, 15 + jmp .main + +align 16 +.main: + save_ring3_context + mov bx, os_data + mov ds, bx + mov es, bx + + mov ebx, [irq_tab+eax*4] + test ebx, ebx + jz .exit + + call ebx + +.exit: + restore_ring3_context + + cmp eax, 8 + mov al, 0x20 + jb @f + out 0xa0, al +@@: + out 0x20, al + + pop eax + iret + +align 4 +proc get_notify stdcall, p_ev:dword + +.wait: + mov ebx,[CURRENT_TASK] + shl ebx,8 + test dword [ebx+SLOT_BASE+0xA8],EVENT_NOTIFY + jz @f + and dword [ebx+SLOT_BASE+0xA8], not EVENT_NOTIFY + mov edi, [p_ev] + mov dword [edi], EV_INTR + mov eax, [ebx+SLOT_BASE+APPDATA.event] + mov dword [edi+4], eax + ret +@@: + call change_task + jmp .wait +endp + +align 4 +proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 6 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + ret +endp + +align 4 +proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 4 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + ret +endp + +align 4 +proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 8 + mov bh, byte [devfn] + mov bl, byte [reg] + mov ecx, [val] + call pci_write_reg + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + + +align 4 +proc srv_handler stdcall, ioctl:dword + mov esi, [ioctl] + test esi, esi + jz .err + + mov edi, [esi+handle] + cmp [edi+SRV.magic], ' SRV' + jne .fail + + cmp [edi+SRV.size], SRV_SIZE + jne .fail + + stdcall [edi+SRV.srv_proc], esi + ret +.fail: + xor eax, eax + not eax + mov [esi+output], eax + mov [esi+out_size], 4 + ret +.err: + xor eax, eax + not eax + ret +endp + +; param +; ebx= io_control +; +; retval +; eax= error code + +align 4 +srv_handlerEx: + test ebx, ebx + jz .fail + add ebx, new_app_base + + mov eax, [ebx+handle] + cmp [eax+SRV.magic], ' SRV' + jne .fail + + cmp [eax+SRV.size], SRV_SIZE + jne .fail + + add [ebx+input], new_app_base + add [ebx+output], new_app_base + + stdcall [eax+SRV.srv_proc], ebx + ret +.fail: + or eax, -1 + ret + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc get_service stdcall, sz_name:dword + mov eax, [sz_name] + test eax, eax + jnz @F + ret +@@: + mov edx, [srv.fd] +@@: + cmp edx, srv.fd-SRV_FD_OFFSET + je .not_load + + stdcall strncmp, edx, [sz_name], 16 + test eax, eax + je .ok + + mov edx, [edx+SRV.fd] + jmp @B +.not_load: + pop ebp + jmp load_driver +.ok: + mov eax, edx + ret +endp + +align 4 +reg_service: +.sz_name equ esp+4 +.handler equ esp+8 + mov eax, [.sz_name] + test eax, eax + jz .fail + + mov ebx, [.handler] + test ebx, ebx + jz .fail + + mov eax, SRV_SIZE + call malloc ;call alloc_service + test eax, eax + jz .fail + + mov edi, eax + mov esi, [.sz_name] + mov ecx, 16/4 + rep movsd + + mov [eax+SRV.magic], ' SRV' + mov [eax+SRV.size], SRV_SIZE + + mov ebx, srv.fd-SRV_FD_OFFSET + mov edx, [ebx+SRV.fd] + mov [eax+SRV.fd], edx + mov [eax+SRV.bk], ebx + mov [ebx+SRV.fd], eax + mov [edx+SRV.bk], eax + + mov ecx, [.handler] + mov [eax+SRV.srv_proc], ecx + ret 8 +.fail: + xor eax, eax + ret 8 + +align 4 +proc get_proc stdcall, exp:dword, sz_name:dword + + mov edx, [exp] +.next: + mov eax, [edx] + test eax, eax + jz .end + + push edx + stdcall strncmp, eax, [sz_name], 16 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.ok: + mov eax, [edx+4] +.end: + ret +endp + +align 4 +proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword + +@@: + stdcall strncmp, [pSym], [sz_sym], 8 + test eax,eax + jz .ok + add [pSym], 18 + dec [count] + jnz @b + xor eax, eax + ret +.ok: + mov ebx, [pSym] + mov eax, [ebx+8] + ret +endp + +align 4 +proc get_curr_task + mov eax,[CURRENT_TASK] + shl eax, 8 + ret +endp + +align 4 +proc get_fileinfo stdcall, file_name:dword, info:dword + locals + cmd dd ? + offset dd ? + dd ? + count dd ? + buff dd ? + db ? + name dd ? + endl + + xor eax, eax + mov ebx, [file_name] + sub ebx, new_app_base + mov ecx, [info] + sub ecx, new_app_base + + mov [cmd], 5 + mov [offset], eax + mov [offset+4], eax + mov [count], eax + mov [buff], ecx + mov byte [buff+4], al + mov [name], ebx + + mov eax, 70 + lea ebx, [cmd] + sub ebx, new_app_base + int 0x40 + ret +endp + +align 4 +proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ + bytes:dword + locals + cmd dd ? + offset dd ? + dd ? + count dd ? + buff dd ? + db ? + name dd ? + endl + + xor eax, eax + mov ebx, [file_name] + mov ecx, [off] + mov edx, [bytes] + mov esi, [buffer] + sub ebx, new_app_base + sub esi, new_app_base + + mov [cmd], eax + mov [offset], ecx + mov [offset+4], eax + mov [count], edx + mov [buff], esi + mov byte [buff+4], al + mov [name], ebx + + mov eax, 70 + lea ebx, [cmd] + sub ebx, new_app_base + int 0x40 + ret +endp + +; description +; allocate kernel memory and loads the specified file +; +; param +; file_name= full path to file +; +; retval +; eax= file image in kernel memory +; ebx= size of file +; +; warging +; You mast call kernel_free() to delete each file +; loaded by the load_file() function + +align 4 +proc load_file stdcall, file_name:dword + locals + attr dd ? + flags dd ? + cr_time dd ? + cr_date dd ? + acc_time dd ? + acc_date dd ? + mod_time dd ? + mod_date dd ? + file_size dd ? + + file dd ? + file2 dd ? + endl + + lea eax, [attr] + stdcall get_fileinfo, [file_name], eax + test eax, eax + jnz .fail + + mov eax, [file_size] + cmp eax, 1024*1024*16 + ja .fail + + stdcall kernel_alloc, [file_size] + mov [file], eax + + stdcall read_file, [file_name], eax, dword 0, [file_size] + cmp ebx, [file_size] + jne .cleanup + + mov eax, [file] + cmp dword [eax], 0x4B43504B + jne .exit + mov ebx, [eax+4] + mov [file_size], ebx + stdcall kernel_alloc, ebx + + test eax, eax + jz .cleanup + + mov [file2], eax + stdcall unpack, [file], eax + stdcall kernel_free, [file] + mov eax, [file2] + mov ebx, [file_size] +.exit: + push eax + lea edi, [eax+ebx] ;cleanup remain space + mov ecx, 4096 ;from file end + and ebx, 4095 + sub ecx, ebx + xor eax, eax + cld + rep stosb + mov ebx, [file_size] + pop eax + ret +.cleanup: + stdcall kernel_free, [file] +.fail: + xor eax, eax + xor ebx, ebx + ret +endp + +align 4 +proc get_proc_ex stdcall, proc_name:dword, imports:dword + +.look_up: + mov edx, [imports] + test edx, edx + jz .end + mov edx, [edx] + test edx, edx + jz .end +.next: + mov eax, [edx] + test eax, eax + jz .next_table + + push edx + stdcall strncmp, eax, [proc_name], 16 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.next_table: + add [imports], 4 + jmp .look_up +.ok: + mov eax, [edx+4] + ret +.end: + xor eax, eax + ret +endp + +align 4 +proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\ + sym_count:dword, strings:dword, imports:dword + locals + retval dd ? + endl + + mov edi, [symbols] + mov [retval], 1 +.fix: + movzx ebx, [edi+CSYM.SectionNumber] + test ebx, ebx + jnz .internal + mov eax, dword [edi+CSYM.Name] + test eax, eax + jnz @F + + mov edi, [edi+4] + add edi, [strings] +@@: + push edi + stdcall get_proc_ex, edi,[imports] + pop edi + + xor ebx, ebx + test eax, eax + jnz @F + + mov esi, msg_unresolved + call sys_msg_board_str + mov esi, edi + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str + + mov [retval],0 +@@: + mov edi, [symbols] + mov [edi+CSYM.Value], eax + jmp .next +.internal: + dec ebx + shl ebx, 3 + lea ebx, [ebx+ebx*4] + add ebx, [sec] + + mov eax, [ebx+CFS.VirtualAddress] + add [edi+CSYM.Value], eax +.next: + add edi, CSYM_SIZE + mov [symbols], edi + dec [sym_count] + jnz .fix + mov eax, [retval] + ret +endp + +align 4 +proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword + locals + n_sec dd ? + endl + + mov eax, [coff] + movzx ebx, [eax+CFH.nSections] + mov [n_sec], ebx +.fix_sec: + mov esi, [sec] + mov edi, [esi+CFS.PtrReloc] + add edi, [coff] + + movzx ecx, [esi+CFS.NumReloc] + test ecx, ecx + jz .next +.next_reloc: + mov ebx, [edi+CRELOC.SymIndex] + add ebx,ebx + lea ebx,[ebx+ebx*8] + add ebx, [sym] + + mov edx, [ebx+CSYM.Value] + + cmp [edi+CRELOC.Type], 6 + je .dir_32 + + cmp [edi+CRELOC.Type], 20 + jne .next_reloc +.rel_32: + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [esi+CFS.VirtualAddress] + sub edx, eax + sub edx, 4 + jmp .fix +.dir_32: + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [esi+CFS.VirtualAddress] +.fix: + add [eax], edx + add edi, 10 + dec ecx + jnz .next_reloc +.next: + add [sec], COFF_SECTION_SIZE + dec [n_sec] + jnz .fix_sec +.exit: + ret +endp + +align 4 +proc load_driver stdcall, driver_name:dword + locals + coff dd ? + sym dd ? + strings dd ? + img_size dd ? + img_base dd ? + start dd ? + + exports dd ? ;fake exports table + dd ? + file_name rb 14+16+4+1 ; '/rd/1/drivers/.obj' + endl + + lea edx, [file_name] + mov dword [edx], '/rd/' + mov dword [edx+4], '1/dr' + mov dword [edx+8], 'iver' + mov word [edx+12], 's/' + mov esi, [driver_name] + lea edi, [edx+14] + mov ecx, 16 +@@: + lodsb + test al, al + jz @f + stosb + loop @b +@@: + mov dword [edi], '.obj' + mov byte [edi+4], 0 + stdcall load_file, edx + + test eax, eax + jz .exit + + mov [coff], eax + + movzx ecx, [eax+CFH.nSections] + xor ebx, ebx + + lea edx, [eax+20] +@@: + add ebx, [edx+CFS.SizeOfRawData] + add ebx, 15 + and ebx, not 15 + add edx, COFF_SECTION_SIZE + dec ecx + jnz @B + mov [img_size], ebx + + stdcall kernel_alloc, ebx + test eax, eax + jz .fail + mov [img_base], eax + + mov edi, eax + xor eax, eax + mov ecx, [img_size] + add ecx, 4095 + and ecx, not 4095 + shr ecx, 2 + cld + rep stosd + + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, [img_base] + lea eax, [edx+20] +@@: + mov [eax+CFS.VirtualAddress], edi + mov esi, [eax+CFS.PtrRawData] + test esi, esi + jnz .copy + add edi, [eax+CFS.SizeOfRawData] + jmp .next +.copy: + add esi, edx + mov ecx, [eax+CFS.SizeOfRawData] + cld + rep movsb +.next: + add edi, 15 + and edi, not 15 + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + mov ebx, [edx+CFH.pSymTable] + add ebx, edx + mov [sym], ebx + mov ecx, [edx+CFH.nSymbols] + add ecx,ecx + lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE + add ecx, [sym] + mov [strings], ecx + + lea ebx, [exports] + mov dword [ebx], kernel_export + mov dword [ebx+4], 0 + lea eax, [edx+20] + + stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ + [strings], ebx + test eax, eax + jz .link_fail + + mov ebx, [coff] + add ebx, 20 + stdcall fix_coff_relocs, [coff], ebx, [sym] + + mov ebx, [coff] + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion + test eax, eax + jz .link_fail + + mov eax, [eax] + shr eax, 16 + cmp eax, DRV_COMPAT + jb .ver_fail + + cmp eax, DRV_CURRENT + ja .ver_fail + + mov ebx, [coff] + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART + mov [start], eax + + stdcall kernel_free, [coff] + + mov ebx, [start] + stdcall ebx, DRV_ENTRY + test eax, eax + jnz .ok + + stdcall kernel_free, [img_base] + xor eax, eax + ret +.ok: + mov ebx, [img_base] + mov [eax+SRV.base], ebx + mov ecx, [start] + mov [eax+SRV.entry], ecx + ret + +.ver_fail: + mov esi, msg_CR + call sys_msg_board_str + mov esi, [driver_name] + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str + mov esi, msg_version + call sys_msg_board_str + mov esi, msg_www + call sys_msg_board_str + jmp .cleanup + +.link_fail: + mov esi, msg_module + call sys_msg_board_str + mov esi, [driver_name] + call sys_msg_board_str + mov esi, msg_CR + call sys_msg_board_str +.cleanup: + stdcall kernel_free,[img_base] +.fail: + stdcall kernel_free, [coff] +.exit: + xor eax, eax + ret +endp + +align 4 +proc load_library stdcall, file_name:dword + locals + coff dd ? + sym dd ? + strings dd ? + img_size dd ? + img_base dd ? + exports dd ? + endl + + cli + + stdcall load_file, [file_name] + test eax, eax + jz .fail + + mov [coff], eax + movzx ecx, [eax+CFH.nSections] + xor ebx, ebx + + lea edx, [eax+20] +@@: + add ebx, [edx+CFS.SizeOfRawData] + add ebx, 15 + and ebx, not 15 + add edx, COFF_SECTION_SIZE + dec ecx + jnz @B + mov [img_size], ebx + + call init_heap + stdcall user_alloc, [img_size] + + test eax, eax + jz .fail + mov [img_base], eax + + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, [img_base] + lea eax, [edx+20] +@@: + mov [eax+CFS.VirtualAddress], edi + mov esi, [eax+CFS.PtrRawData] + test esi, esi + jnz .copy + add edi, [eax+CFS.SizeOfRawData] + jmp .next +.copy: + add esi, edx + add edi, new_app_base + mov ecx, [eax+CFS.SizeOfRawData] + cld + rep movsb +.next: + add edi, 15-new_app_base + and edi, not 15 + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + mov ebx, [edx+CFH.pSymTable] + add ebx, edx + mov [sym], ebx + mov ecx, [edx+CFH.nSymbols] + add ecx,ecx + lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE + add ecx, [sym] + mov [strings], ecx + + lea eax, [edx+20] + + stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ + [strings], dword 0 + test eax, eax + jnz @F + +@@: + mov edx, [coff] + movzx ebx, [edx+CFH.nSections] + mov edi, new_app_base + lea eax, [edx+20] +@@: + add [eax+CFS.VirtualAddress], edi ;patch user space offset + add eax, COFF_SECTION_SIZE + dec ebx + jnz @B + + add edx, 20 + stdcall fix_coff_relocs, [coff], edx, [sym] + + mov ebx, [coff] + stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS + mov [exports], eax + + stdcall kernel_free, [coff] + mov eax, [exports] + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc stop_all_services + + mov edx, [srv.fd] +.next: + cmp edx, srv.fd-SRV_FD_OFFSET + je .done + cmp [edx+SRV.magic], ' SRV' + jne .next + cmp [edx+SRV.size], SRV_SIZE + jne .next + mov ebx, [edx+SRV.entry] + mov edx, [edx+SRV.fd] + push edx + stdcall ebx, dword -1 + pop edx + jmp .next +.done: + ret +endp + +; param +; eax= size +; ebx= pid + +align 4 +create_kernel_object: + + push ebx + call malloc + pop ebx + test eax, eax + jz .fail + + mov ecx,[CURRENT_TASK] + shl ecx,8 + add ecx, SLOT_BASE+APP_OBJ_OFFSET + + pushfd + cli + mov edx, [ecx+APPOBJ.fd] + mov [eax+APPOBJ.fd], edx + mov [eax+APPOBJ.bk], ecx + mov [eax+APPOBJ.pid], ebx + + mov [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + popfd +.fail: + ret + +; param +; eax= object + +align 4 +destroy_kernel_object: + + pushfd + cli + mov ebx, [eax+APPOBJ.fd] + mov ecx, [eax+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx + popfd + + xor edx, edx ;clear common header + mov [eax], edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax+16], edx + + call free ;release object memory + ret + + +;szSound db 'SOUND',0 +;szInfinity db 'INFINITY',0 +szHwMouse db 'ATI2D',0 + +szSTART db 'START',0 +szEXPORTS db 'EXPORTS',0 +szIMPORTS db 'IMPORTS',0 + +msg_unresolved db 'unresolved ',0 +msg_module db 'in module ',0 +msg_version db 'incompatible driver version',13,10,0 +msg_www db 'please visit www.kolibrios.org',13,10,0 +msg_CR db 13,10,0 + +align 4 +create_cursor dd 0 +set_hw_cursor dd 0 +hw_restore dd 0 diff --git a/kernel/branches/gfx_kernel/core/exports.inc b/kernel/branches/gfx_kernel/core/exports.inc new file mode 100644 index 000000000..e8afc0da3 --- /dev/null +++ b/kernel/branches/gfx_kernel/core/exports.inc @@ -0,0 +1,110 @@ + +iglobal + szKernel db 'KERNEL', 0 + szVersion db 'version',0 + + szRegService db 'RegService',0 + szGetService db 'GetService',0 + szServiceHandler db 'ServiceHandler',0 + szAttachIntHandler db 'AttachIntHandler',0 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 + + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',0 + + szAllocPage db 'AllocPage',0 + szAllocPages db 'AllocPages',0 + szFreePage db 'FreePage',0 + szGetPgAddr db 'GetPgAddr',0 + szMapPage db 'MapPage',0 + szMapSpace db 'MapSpace',0 + szCommitPages db 'CommitPages',0 + szReleasePages db 'ReleasePages',0 + + szAllocKernelSpace db 'AllocKernelSpace',0 + szFreeKernelSpace db 'FreeKernelSpace',0 + szKernelAlloc db 'KernelAlloc',0 + szKernelFree db 'KernelFree',0 + szUserAlloc db 'UserAlloc',0 + szUserFree db 'UserFree',0 + szKmalloc db 'Kmalloc',0 + szKfree db 'Kfree',0 + + szCreateObject db 'CreateObject',0 + szDestroyObject db 'DestroyObject',0 + szCreateEvent db 'CreateEvent',0 + szRaiseEvent db 'RaiseEvent',0 + szWaitEvent db 'WaitEvent',0 + szDestroyEvent db 'DestroyEvent',0 + szClearEvent db 'ClearEvent',0 + + szLoadCursor db 'LoadCursor',0 + szSetHwCursor db 'SetHwCursor',0 + szHwCursorRestore db 'HwCursorRestore', 0 + szHwCursorCreate db 'HwCursorCreate', 0 + + szSysMsgBoardStr db 'SysMsgBoardStr', 0 + szGetCurrentTask db 'GetCurrentTask',0 + szLFBAddress db 'LFBAddress',0 + szLoadFile db 'LoadFile',0 + szSendEvent db 'SendEvent',0 + + +align 16 +kernel_export: + dd szRegService , reg_service + dd szGetService , get_service + dd szServiceHandler , srv_handler + dd szAttachIntHandler, attach_int_handler + dd szFpuSave , fpu_save + dd szFpuRestore , fpu_restore + + dd szPciApi , pci_api + dd szPciRead32 , pci_read32 + dd szPciRead8 , pci_read8 + dd szPciWrite8 , pci_write8 + + dd szAllocPage , alloc_page + dd szAllocPages , alloc_pages + dd szFreePage , free_page + dd szMapPage , map_page + dd szMapSpace , map_space + dd szGetPgAddr , get_pg_addr + dd szCommitPages , commit_pages ;not implemented + dd szReleasePages , release_pages + + dd szAllocKernelSpace, alloc_kernel_space + dd szFreeKernelSpace , free_kernel_space + dd szKernelAlloc , kernel_alloc + dd szKernelFree , kernel_free + dd szUserAlloc , user_alloc + dd szUserFree , user_free + dd szKmalloc , malloc + dd szKfree , free + + dd szCreateObject , create_kernel_object + dd szDestroyObject , destroy_kernel_object + dd szCreateEvent , create_event + dd szRaiseEvent , raise_event + dd szWaitEvent , wait_event + dd szDestroyEvent , destroy_event + dd szClearEvent , clear_event + + dd szLoadCursor , load_cursor + dd szSetHwCursor , set_hw_cursor + dd szHwCursorRestore , hw_restore + dd szHwCursorCreate , create_cursor + + dd szSysMsgBoardStr , sys_msg_board_str + dd szGetCurrentTask , get_curr_task + dd szLoadFile , load_file + dd szSendEvent , send_event +exp_lfb: + dd szLFBAddress , 0 + dd 0 + +endg + diff --git a/kernel/branches/gfx_kernel/core/fpu.inc b/kernel/branches/gfx_kernel/core/fpu.inc new file mode 100644 index 000000000..c6c68cc77 --- /dev/null +++ b/kernel/branches/gfx_kernel/core/fpu.inc @@ -0,0 +1,270 @@ + +init_fpu: + clts + fninit + + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + mov ebx, cr4 + mov ecx, cr0 + or ebx, CR4_OSFXSR+CR4_OSXMMEXPT + mov cr4, ebx + + and ecx, not (CR0_MP+CR0_EM) + or ecx, CR0_NE + mov cr0, ecx + + mov dword [esp-4], SSE_INIT + ldmxcsr [esp-4] + + xorps xmm0, xmm0 + xorps xmm1, xmm1 + xorps xmm2, xmm2 + xorps xmm3, xmm3 + xorps xmm4, xmm4 + xorps xmm5, xmm5 + xorps xmm6, xmm6 + xorps xmm7, xmm7 + fxsave [fpu_data] ;[eax] + ret +.no_SSE: + mov ecx, cr0 + and ecx, not CR0_EM + or ecx, CR0_MP+CR0_NE + mov cr0, ecx + fnsave [fpu_data] + ret + +; param +; eax= 512 bytes memory area + +align 4 +fpu_save: + push ecx + push esi + push edi + + pushfd + cli + + clts + mov edi, eax + + mov ecx, [fpu_owner] + mov eax, [CURRENT_TASK] + cmp ecx, eax + jne .save +.copy: + shl eax, 8 + mov esi, [eax+SLOT_BASE+APPDATA.fpu_state] + mov ecx, 512/4 + cld + rep movsd + fninit + + popfd + pop edi + pop esi + pop ecx + ret +.save: + mov [fpu_owner], eax + + shl ecx, 8 + mov ecx, [ecx+SLOT_BASE+APPDATA.fpu_state] + + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxsave [ecx] + jmp .copy +.no_SSE: + fnsave [ecx] + jmp .copy + +align 4 +fpu_restore: + push ecx + push esi + + mov esi, eax + + pushfd + cli + + mov ecx, [fpu_owner] + mov eax, [CURRENT_TASK] + cmp ecx, eax + jne .copy + + clts + + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxrstor [esi] + popfd + pop esi + pop ecx + ret +.no_SSE: + fnclex ;fix possible problems + frstor [esi] + popfd + pop esi + pop ecx + ret +.copy: + shl eax, 8 + mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] + mov ecx, 512/4 + cld + rep movsd + popfd + pop esi + pop ecx + ret + +align 4 +e7: ;#NM exception handler + save_ring3_context + clts + mov ax, os_data + mov ds, ax + mov es, ax + + mov ebx, [fpu_owner] + cmp ebx, [CURRENT_TASK] + je .exit + + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + + fxsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + fxrstor [eax] +.exit: + restore_ring3_context + iret + +.no_SSE: + fnsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] + frstor [eax] + restore_ring3_context + iret + +iglobal + fpu_owner dd 1 + endg + +reg_eip equ ebp+4 +reg_cs equ ebp+8 +reg_eflags equ ebp+12 +reg_esp equ ebp+16 +reg_ss equ ebp+20 + +align 4 +except_16: ;fpu native exceptions handler + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [ss:CURRENT_TASK] + shl ebx, 8 + + mov eax, [ss:ebx+SLOT_BASE+APPDATA.fpu_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [ss:edx+new_app_base], ecx + mov [reg_esp], edx + mov dword [reg_eip], eax + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + +.default: + pop edx + pop ecx + pop ebx + pop eax + leave + + save_ring3_context ;debugger support + + mov bl, 16 + jmp exc_c + +align 4 +except_19: ;sse exceptions handler + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov ebx, [ss:CURRENT_TASK] + shl ebx, 8 + + mov eax, [ss:ebx+SLOT_BASE+APPDATA.sse_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [ss:edx+new_app_base], ecx + mov [reg_esp], edx + mov dword [reg_eip], eax + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + +.default: + pop edx + pop ecx + pop ebx + pop eax + leave + + save_ring3_context ;debugger support + + mov bl, 19 + jmp exc_c + +restore reg_eip +restore reg_cs +restore reg_eflags +restore reg_esp +restore reg_ss + + diff --git a/kernel/branches/gfx_kernel/core/heap.inc b/kernel/branches/gfx_kernel/core/heap.inc new file mode 100644 index 000000000..0cf60c6ac --- /dev/null +++ b/kernel/branches/gfx_kernel/core/heap.inc @@ -0,0 +1,841 @@ + +struc MEM_BLOCK +{ .next_block dd ? + .prev_block dd ? ;+4 + .list_fd dd ? ;+8 + .list_bk dd ? ;+12 + .base dd ? ;+16 + .size dd ? ;+20 + .flags dd ? ;+24 + .handle dd ? ;+28 +} + +MEM_LIST_OFFSET equ 8 +FREE_BLOCK equ 4 +USED_BLOCK equ 8 + +virtual at 0 + MEM_BLOCK MEM_BLOCK +end virtual + +MEM_BLOCK_SIZE equ 8*4 + +block_next equ MEM_BLOCK.next_block +block_prev equ MEM_BLOCK.prev_block +list_fd equ MEM_BLOCK.list_fd +list_bk equ MEM_BLOCK.list_bk +block_base equ MEM_BLOCK.base +block_size equ MEM_BLOCK.size +block_flags equ MEM_BLOCK.flags + +macro calc_index op +{ shr op, 12 + dec op + cmp op, 63 + jna @f + mov op, 63 +@@: +} + +macro remove_from_list op +{ mov edx, [op+list_fd] + mov ecx, [op+list_bk] + test edx, edx + jz @f + mov [edx+list_bk], ecx +@@: + test ecx, ecx + jz @f + mov [ecx+list_fd], edx +@@: + mov [op+list_fd],0 + mov [op+list_bk],0 +} + +macro remove_from_free op +{ + remove_from_list op + + mov eax, [op+block_size] + calc_index eax + cmp [mem_block_list+eax*4], op + jne @f + mov [mem_block_list+eax*4], edx +@@: + cmp [mem_block_list+eax*4], 0 + jne @f + btr [mem_block_mask], eax +@@: +} + +macro remove_from_used op +{ + mov edx, [op+list_fd] + mov ecx, [op+list_bk] + mov [edx+list_bk], ecx + mov [ecx+list_fd], edx + mov [op+list_fd], 0 + mov [op+list_bk], 0 +} + +align 4 +proc init_kernel_heap + + mov ecx, 64/4 + mov edi, mem_block_list + xor eax, eax + cld + rep stosd + + mov ecx, 512/4 + mov edi, mem_block_map + not eax + rep stosd + + mov [mem_block_start], mem_block_map + mov [mem_block_end], mem_block_map+512 + mov [mem_block_arr], HEAP_BASE + + mov eax, mem_used.fd-MEM_LIST_OFFSET + mov [mem_used.fd], eax + mov [mem_used.bk], eax + + stdcall alloc_pages, dword 32 + mov ecx, 32 + mov edx, eax + mov edi, HEAP_BASE +.l1: + stdcall map_page,edi,edx,PG_SW + add edi, 0x1000 + add edx, 0x1000 + dec ecx + jnz .l1 + + mov edi, HEAP_BASE + mov ebx, HEAP_BASE+MEM_BLOCK_SIZE + xor eax, eax + mov [edi+block_next], ebx + mov [edi+block_prev], eax + mov [edi+list_fd], eax + mov [edi+list_bk], eax + mov [edi+block_base], HEAP_BASE + mov [edi+block_size], 4096*MEM_BLOCK_SIZE + mov [edi+block_flags], USED_BLOCK + + mov [ebx+block_next], eax + mov [ebx+block_prev], eax + mov [ebx+list_fd], eax + mov [ebx+list_bk], eax + mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE + + mov ecx, [MEM_AMOUNT] + sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE + mov [heap_size], ecx + mov [heap_free], ecx + mov [ebx+block_size], ecx + mov [ebx+block_flags], FREE_BLOCK + + mov [mem_block_mask], eax + mov [mem_block_mask+4],0x80000000 + + mov [mem_block_list+63*4], ebx + mov byte [mem_block_map], 0xFC + and [heap_mutex], 0 + mov [heap_blocks], 4095 + mov [free_blocks], 4095 + ret +endp + +; param +; eax= required size +; +; retval +; edi= memory block descriptor +; ebx= descriptor index + +align 4 +get_block: + mov ecx, eax + shr ecx, 12 + dec ecx + cmp ecx, 63 + jle .get_index + mov ecx, 63 +.get_index: + lea esi, [mem_block_mask] + xor ebx, ebx + or edx, -1 + + cmp ecx, 32 + jb .bit_test + + sub ecx, 32 + add ebx, 32 + add esi, 4 +.bit_test: + shl edx, cl + and edx, [esi] +.find: + bsf edi, edx + jz .high_mask + add ebx, edi + mov edi, [mem_block_list+ebx*4] +.check_size: + cmp eax, [edi+block_size] + ja .next + ret + +.high_mask: + add esi, 4 + cmp esi, mem_block_mask+8 + jae .err + add ebx, 32 + mov edx, [esi] + jmp .find +.next: + mov edi, [edi+list_fd] + test edi, edi + jnz .check_size +.err: + xor edi, edi + ret + +align 4 +proc alloc_mem_block + + mov ebx, [mem_block_start] + mov ecx, [mem_block_end] +.l1: + bsf eax,[ebx]; + jnz found + add ebx,4 + cmp ebx, ecx + jb .l1 + xor eax,eax + ret + +found: + btr [ebx], eax + mov [mem_block_start],ebx + sub ebx, mem_block_map + lea eax,[eax+ebx*8] + shl eax, 5 + add eax, [mem_block_arr] + dec [free_blocks] + ret +endp + +proc free_mem_block + mov dword [eax], 0 + mov dword [eax+4], 0 + mov dword [eax+8], 0 + mov dword [eax+12], 0 + mov dword [eax+16], 0 +; mov dword [eax+20], 0 + mov dword [eax+24], 0 + mov dword [eax+28], 0 + + sub eax, [mem_block_arr] + shr eax, 5 + + mov ebx, mem_block_map + bts [ebx], eax + inc [free_blocks] + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [mem_block_start], eax + ja @f + ret +@@: + mov [mem_block_start], eax + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc alloc_kernel_space stdcall, size:dword + local block_ind:DWORD + + mov eax, [size] + add eax, 4095 + and eax, not 4095 + mov [size], eax + + mov ebx, heap_mutex + call wait_mutex ;ebx + + cmp eax, [heap_free] + ja .error + + call get_block ; eax + test edi, edi + jz .error + + cmp [edi+block_flags], FREE_BLOCK + jne .error + + mov [block_ind], ebx ;index of allocated block + + mov eax, [edi+block_size] + cmp eax, [size] + je .m_eq_size + + call alloc_mem_block + and eax, eax + jz .error + + mov esi, eax ;esi - splitted block + + mov [esi+block_next], edi + mov eax, [edi+block_prev] + mov [esi+block_prev], eax + mov [edi+block_prev], esi + mov [esi+list_fd], 0 + mov [esi+list_bk], 0 + and eax, eax + jz @f + mov [eax+block_next], esi +@@: + mov ebx, [edi+block_base] + mov [esi+block_base], ebx + mov edx, [size] + mov [esi+block_size], edx + add [edi+block_base], edx + sub [edi+block_size], edx + + mov eax, [edi+block_size] + shr eax, 12 + sub eax, 1 + cmp eax, 63 + jna @f + mov eax, 63 +@@: + cmp eax, [block_ind] + je .m_eq_ind + + remove_from_list edi + + mov ecx, [block_ind] + mov [mem_block_list+ecx*4], edx + + test edx, edx + jnz @f + btr [mem_block_mask], ecx +@@: + mov edx, [mem_block_list+eax*4] + mov [edi+list_fd], edx + test edx, edx + jz @f + mov [edx+list_bk], edi +@@: + mov [mem_block_list+eax*4], edi + bts [mem_block_mask], eax +.m_eq_ind: + mov ecx, mem_used.fd-MEM_LIST_OFFSET + mov edx, [ecx+list_fd] + mov [esi+list_fd], edx + mov [esi+list_bk], ecx + mov [ecx+list_fd], esi + mov [edx+list_bk], esi + + mov [esi+block_flags], USED_BLOCK + mov eax, [esi+block_base] + mov ebx, [size] + sub [heap_free], ebx + and [heap_mutex], 0 + ret +.m_eq_size: + remove_from_list edi + mov [mem_block_list+ebx*4], edx + and edx, edx + jnz @f + btr [mem_block_mask], ebx +@@: + mov ecx, mem_used.fd-MEM_LIST_OFFSET + mov edx, [ecx+list_fd] + mov [edi+list_fd], edx + mov [edi+list_bk], ecx + mov [ecx+list_fd], edi + mov [edx+list_bk], edi + + mov [edi+block_flags], USED_BLOCK + mov eax, [edi+block_base] + mov ebx, [size] + sub [heap_free], ebx + and [heap_mutex], 0 + ret +.error: + xor eax, eax + mov [heap_mutex], eax + ret +endp + +align 4 +proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword + + mov ebx, heap_mutex + call wait_mutex ;ebx + + mov eax, [base] + mov esi, [mem_used.fd] +@@: + cmp esi, mem_used.fd-MEM_LIST_OFFSET + je .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_fd] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + mov eax, [esi+block_size] + add [heap_free], eax + + mov edi, [esi+block_next] + test edi, edi + jz .prev + + cmp [edi+block_flags], FREE_BLOCK + jne .prev + + remove_from_free edi + + mov edx, [edi+block_next] + mov [esi+block_next], edx + test edx, edx + jz @f + + mov [edx+block_prev], esi +@@: + mov ecx, [edi+block_size] + add [esi+block_size], ecx + + mov eax, edi + call free_mem_block +.prev: + mov edi, [esi+block_prev] + test edi, edi + jz .insert + + cmp [edi+block_flags], FREE_BLOCK + jne .insert + + remove_from_used esi + + mov edx, [esi+block_next] + mov [edi+block_next], edx + test edx, edx + jz @f + mov [edx+block_prev], edi +@@: + mov eax, esi + call free_mem_block + + mov ecx, [edi+block_size] + mov eax, [esi+block_size] + add eax, ecx + mov [edi+block_size], eax + + calc_index eax + calc_index ecx + cmp eax, ecx + je .m_eq + + push ecx + remove_from_list edi + pop ecx + + cmp [mem_block_list+ecx*4], edi + jne @f + mov [mem_block_list+ecx*4], edx +@@: + cmp [mem_block_list+ecx*4], 0 + jne @f + btr [mem_block_mask], ecx +@@: + mov esi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], edi + mov [edi+list_fd], esi + test esi, esi + jz @f + mov [esi+list_bk], edi +@@: + bts [mem_block_mask], eax +.m_eq: + xor eax, eax + mov [heap_mutex], eax + dec eax + ret +.insert: + remove_from_used esi + + mov eax, [esi+block_size] + calc_index eax + + mov edi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], esi + mov [esi+list_fd], edi + test edi, edi + jz @f + mov [edi+list_bk], esi +@@: + bts [mem_block_mask], eax + mov [esi+block_flags],FREE_BLOCK + xor eax, eax + mov [heap_mutex], eax + dec eax + ret +.fail: + xor eax, eax + mov [heap_mutex], eax + ret +endp + +align 4 +proc kernel_alloc stdcall, size:dword + locals + lin_addr dd ? + pages_count dd ? + endl + + mov eax, [size] + add eax, 4095 + and eax, not 4095; + mov [size], eax + and eax, eax + jz .err + mov ebx, eax + shr ebx, 12 + mov [pages_count], ebx + + stdcall alloc_kernel_space, eax + test eax, eax + jz .err + mov [lin_addr], eax + + mov ecx, [pages_count] + mov edx, eax + mov ebx, ecx + + shr ecx, 3 + jz .next + + and ebx, not 7 + push ebx + stdcall alloc_pages, ebx + pop ecx ; yes ecx!!! + and eax, eax + jz .err + + mov edi, eax + mov edx, [lin_addr] +@@: + stdcall map_page,edx,edi,dword PG_SW + add edx, 0x1000 + add edi, 0x1000 + dec ecx + jnz @B +.next: + mov ecx, [pages_count] + and ecx, 7 + jz .end +@@: + push ecx + call alloc_page + pop ecx + test eax, eax + jz .err + + stdcall map_page,edx,eax,dword PG_SW + add edx, 0x1000 + dec ecx + jnz @B +.end: + mov eax, [lin_addr] + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc kernel_free stdcall, base:dword + push ebx esi + + mov ebx, heap_mutex + call wait_mutex ;ebx + + mov eax, [base] + mov esi, [mem_used.fd] +@@: + cmp esi, mem_used.fd-MEM_LIST_OFFSET + je .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_fd] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + and [heap_mutex], 0 + + push ecx + mov ecx, [esi+block_size]; + shr ecx, 12 + call release_pages ;eax, ecx + pop ecx + stdcall free_kernel_space, [base] + pop esi ebx + ret +.fail: + and [heap_mutex], 0 + pop esi ebx + ret +endp + +restore block_next +restore block_prev +restore block_list +restore block_base +restore block_size +restore block_flags + +;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; + +HEAP_TOP equ 0x5FC00000 + +align 4 +proc init_heap + + mov ebx,[CURRENT_TASK] + shl ebx,8 + mov eax, [SLOT_BASE+APPDATA.heap_top+ebx] + test eax, eax + jz @F + sub eax,[SLOT_BASE+APPDATA.heap_base+ebx] + sub eax, 4096 + ret +@@: + mov esi, [SLOT_BASE+APPDATA.mem_size+ebx] + add esi, 4095 + and esi, not 4095 + mov [SLOT_BASE+APPDATA.mem_size+ebx], esi + mov eax, HEAP_TOP + mov [SLOT_BASE+APPDATA.heap_base+ebx], esi + mov [SLOT_BASE+APPDATA.heap_top+ebx], eax + + sub eax, esi + add esi, new_app_base + shr esi, 10 + mov ecx, eax + sub eax, 4096 + or ecx, FREE_BLOCK + mov [page_tabs+esi], ecx + ret +.exit: + xor eax, eax + ret +endp + +align 4 +proc user_alloc stdcall, alloc_size:dword + + mov ecx, [alloc_size] + add ecx, (4095+4096) + and ecx, not 4095 + + mov ebx, [CURRENT_TASK] + shl ebx, 8 + mov esi, dword [ebx+SLOT_BASE+APPDATA.heap_base]; heap_base + mov edi, dword [ebx+SLOT_BASE+APPDATA.heap_top]; heap_top + add esi, new_app_base + add edi, new_app_base +l_0: + cmp esi, edi + jae m_exit + + mov ebx, esi + shr ebx, 12 + mov eax, [page_tabs+ebx*4] + test eax, FREE_BLOCK + jz test_used + and eax, 0xFFFFF000 + cmp eax, ecx ;alloc_size + jb m_next + jz @f + + mov edx, esi + add edx, ecx + sub eax, ecx; + or eax, FREE_BLOCK + shr edx, 12 + mov [page_tabs+edx*4], eax + +@@: + or ecx, USED_BLOCK + mov [page_tabs+ebx*4], ecx + shr ecx, 12 + dec ecx + inc ebx +@@: + mov dword [page_tabs+ebx*4], 2 + inc ebx + dec ecx + jnz @B + + mov edx, [CURRENT_TASK] + shl edx, 8 + mov ebx, [alloc_size] + add ebx, 0xFFF + and ebx, not 0xFFF + add ebx, [SLOT_BASE+APPDATA.mem_size+edx] + call update_mem_size + + mov eax, esi + add eax, 4096 + sub eax, new_app_base + ret +m_next: + add esi, eax + jmp l_0 +test_used: + test eax, USED_BLOCK + jz m_exit + + and eax, 0xFFFFF000 + add esi, eax + jmp l_0 +m_exit: + xor eax, eax + ret +endp + +align 4 +proc user_free stdcall, base:dword + + mov esi, [base] + test esi, esi + jz .exit + + xor ebx, ebx + sub esi, 4096 + shr esi, 12 + mov eax, [page_tabs+esi*4] + test eax, USED_BLOCK + jz .not_used + + and eax, not 4095 + mov ecx, eax + or eax, FREE_BLOCK + mov [page_tabs+esi*4], eax + inc esi + sub ecx, 4096 + shr ecx, 12 + mov ebx, ecx +.release: + xor eax, eax + xchg eax, [page_tabs+esi*4] + test eax, 1 + jz @F + call free_page +@@: + inc esi + dec ecx + jnz .release +.not_used: + mov edx, [CURRENT_TASK] + shl edx, 8 + mov esi, dword [edx+SLOT_BASE+APPDATA.heap_base]; heap_base + mov edi, dword [edx+SLOT_BASE+APPDATA.heap_top]; heap_top + sub ebx, [edx+SLOT_BASE+APPDATA.mem_size] + neg ebx + call update_mem_size + add esi, new_app_base + add edi, new_app_base + shr esi, 12 + shr edi, 12 +@@: + mov eax, [page_tabs+esi*4] + test eax, USED_BLOCK + jz .test_free + shr eax, 12 + add esi, eax + jmp @B +.test_free: + test eax, FREE_BLOCK + jz .err + mov edx, eax + shr edx, 12 + add edx, esi + cmp edx, edi + jae .exit + + mov ebx, [page_tabs+edx*4] + test ebx, USED_BLOCK + jz .next_free + + shr ebx, 12 + add edx, ebx + mov esi, edx + jmp @B +.next_free: + test ebx, FREE_BLOCK + jz .err + and dword [page_tabs+edx*4], 0 + add eax, ebx + and eax, not 4095 + or eax, FREE_BLOCK + mov [page_tabs+esi*4], eax + jmp @B +.exit: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret +endp + +if 0 +align 4 +proc alloc_dll + pushf + cli + bsf eax, [dll_map] + jnz .find + popf + xor eax, eax + ret +.find: + btr [dll_map], eax + popf + shl eax, 5 + add eax, dll_tab + ret +endp + +align 4 +proc alloc_service + pushf + cli + bsf eax, [srv_map] + jnz .find + popf + xor eax, eax + ret +.find: + btr [srv_map], eax + popf + shl eax,0x02 + lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 + ret +endp + +end if diff --git a/kernel/branches/gfx_kernel/core/malloc.inc b/kernel/branches/gfx_kernel/core/malloc.inc new file mode 100644 index 000000000..bd313b2ee --- /dev/null +++ b/kernel/branches/gfx_kernel/core/malloc.inc @@ -0,0 +1,993 @@ +; Small heap based on malloc/free/realloc written by Doug Lea +; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) +; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c +; License http://creativecommons.org/licenses/publicdomain. + + +; eax= size + +; temp +; esi= nb +; ebx= idx +; +malloc: + push esi + +; nb = ((size+7)&~7)+8; + + mov esi, eax ;size + add esi, 7 + and esi, -8 + add esi, 8 + + mov ebx, mst.mutex + call wait_mutex ;ebx + + cmp esi, 256 + jae .large + + mov ecx, esi + shr ecx, 3 + or eax, -1 + shl eax, cl + and eax, [mst.smallmap] + jz .small + + push ebp + push edi + + bsf eax, eax + mov ebx, eax + +; psize= idx<<3; +; B = &ms.smallbins[idx]; +; p = B->fd; +; F = p->fd; +; rsize= psize-nb; + + lea ebp, [eax*8] ;ebp= psize + shl eax, 4 + lea edi, [mst.smallbins+eax] ;edi= B + mov edx, [edi+8] ;edx= p + mov eax, [edx+8] ;eax= F + mov ecx, ebp + sub ecx, esi ;ecx= rsize + +; if (B == F) + cmp edi, eax + jne @F + + btr [mst.smallmap], ebx +@@: + +; B->fd = F; +; F->bk = B; +; if(rsize<16) + + cmp ecx, 16 + mov [edi+8], eax + mov [eax+12], edi + jae .split + +; p->head = psize|PINUSE_BIT|CINUSE_BIT; +; (p + psize)->head |= PINUSE_BIT; + + lea eax, [edx+8] + or dword [edx+ebp+4], 1 + + or ebp, 3 + mov [edx+4], ebp + + pop edi + pop ebp +.done: + pop esi + mov [mst.mutex], 0 + ret +.split: + lea ebx, [edx+8] ;ebx=mem + +; r = chunk_plus_offset(p, nb); +; p->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; + + lea eax, [edx+esi] ;eax= r + or esi, 3 + mov [edx+4], esi + + mov edx, ecx + or edx, 1 + mov [eax+4], edx + +; (r + rsize)->prev_foot = rsize; + + mov [eax+ecx], ecx + +; I = rsize>>3; + + shr ecx, 3 + +; ms.smallmap |= 1<< I; + bts [mst.smallmap], ecx + +; B = &ms.smallbins[I]; + + shl ecx, 4 + pop edi + pop ebp + add ecx, mst.smallbins ;ecx= B + + mov edx, [ecx+8] ; F = B->fd; + mov [ecx+8], eax ; B->fd = r; + mov [edx+12], eax ; F->bk = r; + mov [eax+8], edx ; r->fd = F; + mov [eax+12], ecx ; r->bk = B; + mov eax, ebx + pop esi + ret +.small: + +; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) + + cmp [mst.treemap], 0 + je .from_top + mov eax, esi + call malloc_small + test eax, eax + jz .from_top + pop esi + and [mst.mutex], 0 + ret +.large: + +; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) + + cmp [mst.treemap], 0 + je .from_top + + call malloc_large ;esi= nb + test eax, eax + jne .done +.from_top: + +; if (nb < ms.topsize) + + mov eax, [mst.topsize] + cmp esi, eax + jae .fail + +; rsize = ms.topsize -= nb; +; p = ms.top; + + mov ecx, [mst.top] + sub eax, esi + mov [mst.topsize], eax + +; r = ms.top = chunk_plus_offset(p, nb); +; r->head = rsize | PINUSE_BIT; +; p->head = nb |PINUSE_BIT|CINUSE_BIT; + + lea edx, [ecx+esi] + or eax, 1 + mov [mst.top], edx + or esi, 3 + mov [edx+4], eax + mov [ecx+4], esi + lea eax, [ecx+8] + pop esi + and [mst.mutex], 0 + ret +.fail: + xor eax, eax + pop esi + and [mst.mutex], 0 + ret + +; param +; eax= mem + +align 4 +free: + push edi + mov edi, eax + add edi, -8 + +; if(p->head & CINUSE_BIT) + + test byte [edi+4], 2 + je .fail + + mov ebx, mst.mutex + call wait_mutex ;ebx + +; psize = p->head & (~3); + + mov eax, [edi+4] + push esi + mov esi, eax + and esi, -4 + +; next = chunk_plus_offset(p, psize); +; if(!(p->head & PINUSE_BIT)) + + test al, 1 + lea ebx, [esi+edi] + jne .next + +; prevsize = p->prev_foot; +; prev=p - prevsize; +; psize += prevsize; +; p = prev; + + mov ecx, [edi] ;ecx= prevsize + add esi, ecx ;esi= psize + sub edi, ecx ;edi= p + +; if (prevsize < 256) + + cmp ecx, 256 + jae .unlink_large + + mov eax, [edi+8] ;F = p->fd; + mov edx, [edi+12] ;B = p->bk; + +; if (F == B) +; ms.smallmap &= ~(1<< I); + shr ecx, 3 + cmp eax, edx + jne @F + and [mst.smallmap], ecx +@@: + mov [eax+12], edx ;F->bk = B; + mov [edx+8], eax ;B->fd = F + jmp .next +.unlink_large: + mov edx, edi + call unlink_large_chunk +.next: + +; if(next->head & PINUSE_BIT) + + mov eax, [ebx+4] + test al, 1 + jz .fail2 + +; if (! (next->head & CINUSE_BIT)) + + test al, 2 + jnz .fix_next + +; if (next == ms.top) + + cmp ebx, [mst.top] + jne @F + +; tsize = ms.topsize += psize; + + mov eax, [mst.topsize] + add eax, esi + mov [mst.topsize], eax + +; ms.top = p; +; p->head = tsize | PINUSE_BIT; + + or eax, 1 + mov [mst.top], edi + mov [edi+4], eax +.fail2: + and [mst.mutex], 0 + pop esi +.fail: + pop edi + ret +@@: + +; nsize = next->head & ~INUSE_BITS; + + and eax, -4 + add esi, eax ;psize += nsize; + +; if (nsize < 256) + + cmp eax, 256 + jae .unl_large + + mov edx, [ebx+8] ;F = next->fd + mov ebx, [ebx+12] ;B = next->bk + +; if (F == B) + + cmp edx, ebx + jne @F + mov ecx, eax + shr ecx, 3 + btr [mst.smallmap], ecx +@@: + mov [edx+12], ebx ;F->bk = B + +; p->head = psize|PINUSE_BIT; + + mov ecx, esi + mov [ebx+8], edx + or ecx, 1 + mov [edi+4], ecx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi + +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk +.unl_large: + +; unlink_large_chunk((tchunkptr)next); + + mov edx, ebx + call unlink_large_chunk +; p->head = psize|PINUSE_BIT; + + mov ecx, esi + or ecx, 1 + mov [edi+4], ecx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi + +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk +.fix_next: + +; (p+psize)->prev_foot = psize; +; next->head &= ~PINUSE_BIT; +; p->head = psize|PINUSE_BIT; + + and eax, -2 + mov edx, esi + mov [ebx+4], eax + or edx, 1 + mov [edi+4], edx + +; (p+psize)->prev_foot = psize; + + mov [esi+edi], esi +; insert_chunk(p,psize); + + mov eax, esi + pop esi + mov ecx, edi + pop edi + jmp insert_chunk + +; param +; ecx = chunk +; eax = size + +align 4 +insert_chunk: + + cmp eax, 256 + push esi + mov esi, ecx + jae .large + +; I = S>>3; +; ms.smallmap |= 1<< I; + + shr eax, 3 + bts [mst.smallmap], eax + +; B = &ms.smallbins[I]; + + shl eax, 4 + add eax, mst.smallbins + mov edx, [eax+8] ;F = B->fd + mov [eax+8], esi ;B->fd = P + mov [edx+12], esi ;F->bk = P + mov [esi+8], edx ;P->fd = F + mov [esi+12], eax ;P->bk = B + pop esi + and [mst.mutex], 0 + ret +.large: + mov ebx, eax + call insert_large_chunk + pop esi + and [mst.mutex], 0 + ret + +align 4 + +; param +; esi= chunk +; ebx= size + +align 4 +insert_large_chunk: + +; I = compute_tree_index(S); + + mov edx, ebx + shr edx, 8 + bsr eax, edx + lea ecx, [eax+7] + mov edx, ebx + shr edx, cl + and edx, 1 + lea ecx, [edx+eax*2] + +; X->index = I; + mov dword [esi+28], ecx + +; X->child[0] = X->child[1] = 0; + and dword [esi+20], 0 + and dword [esi+16], 0 + +; H = &ms.treebins[I]; + + mov eax, ecx + lea edx, [mst.treebins+eax*4] + +; if (!(ms.treemap & 1<child[(K >> 31) & 1]); + mov ecx, eax + shr ecx, 31 + lea ecx, [edx+ecx*4+16] + +; K <<= 1; +; if (*C != 0) + mov edi, [ecx] + add eax, eax + test edi, edi + jz .insert_child + +; T = *C; + mov edx, edi +.loop: + +; for (;;) +; if ((T->head & ~INUSE_BITS) != S) + + mov ecx, [edx+4] + and ecx, not 3 + cmp ecx, ebx + jne .not_eq_size + +; F = T->fd; + mov eax, [edx+8] + +; T->fd = F->bk = X; + mov [eax+12], esi + mov [edx+8], esi + +; X->fd = F; +; X->bk = T; +; X->parent = 0; + + and dword [esi+24], 0 + mov [esi+8], eax + mov [esi+12], edx + ret + +.insert_child: + +; *C = X; + mov [ecx], esi +.done: + +; X->parent = T; + mov [esi+24], edx + +; X->fd = X->bk = X; + mov [esi+12], esi + mov [esi+8], esi + ret + + +; param +; edx= chunk + +align 4 +unlink_large_chunk: + + mov eax, [edx+12] + cmp eax, edx + push edi + mov edi, [edx+24] + je @F + + mov ecx, [edx+8] ;F = X->fd + mov [ecx+12], eax ;F->bk = R; + mov [eax+8], ecx ;R->fd = F + jmp .parent +@@: + mov eax, [edx+20] + test eax, eax + push esi + lea esi, [edx+20] + jne .loop + + mov eax, [edx+16] + test eax, eax + lea esi, [edx+16] + je .l2 +.loop: + cmp dword [eax+20], 0 + lea ecx, [eax+20] + jne @F + + cmp dword [eax+16], 0 + lea ecx, [eax+16] + je .l1 +@@: + mov eax, [ecx] + mov esi, ecx + jmp .loop +.l1: + mov dword [esi], 0 +.l2: + pop esi +.parent: + test edi, edi + je .done + + mov ecx, [edx+28] + cmp edx, [mst.treebins+ecx*4] + lea ecx, [mst.treebins+ecx*4] + jne .l3 + + test eax, eax + mov [ecx], eax + jne .l5 + + mov ecx, [edx+28] + btr [mst.treemap], ecx + pop edi + ret +.l3: + cmp [edi+16], edx + jne @F + + mov [edi+16], eax + jmp .l4 +@@: + mov [edi+20], eax +.l4: + test eax, eax + je .done +.l5: + mov [eax+24], edi + mov ecx, [edx+16] + test ecx, ecx + je .l6 + + mov [eax+16], ecx + mov [ecx+24], eax +.l6: + mov edx, [edx+20] + test edx, edx + je .done + + mov [eax+20], edx + mov [edx+24], eax +.done: + pop edi + ret + +; param +; esi= nb + +align 4 +malloc_small: + push ebp + mov ebp, esi + + push edi + + bsf eax,[mst.treemap] + mov ecx, [mst.treebins+eax*4] + +; rsize = (t->head & ~INUSE_BITS) - nb; + + mov edi, [ecx+4] + and edi, -4 + sub edi, esi +.loop: + mov ebx, ecx +.loop_1: + +; while ((t = leftmost_child(t)) != 0) + + mov eax, [ecx+16] + test eax, eax + jz @F + mov ecx, eax + jmp .l1 +@@: + mov ecx, [ecx+20] +.l1: + test ecx, ecx + jz .unlink + +; trem = (t->head & ~INUSE_BITS) - nb; + + mov eax, [ecx+4] + and eax, -4 + sub eax, ebp + +; if (trem < rsize) + + cmp eax, edi + jae .loop_1 + +; rsize = trem; + + mov edi, eax + jmp .loop +.unlink: + + +; r = chunk_plus_offset((mchunkptr)v, nb); +; unlink_large_chunk(v); + + mov edx, ebx + lea esi, [ebx+ebp] + call unlink_large_chunk + +; if (rsize < 16) + + cmp edi, 16 + jae .split + +; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; + + lea ecx, [edi+ebp] + +; (v+rsize + nb)->head |= PINUSE_BIT; + + add edi, ebx + lea eax, [edi+ebp+4] + pop edi + or ecx, 3 + mov [ebx+4], ecx + or dword [eax], 1 + pop ebp + + lea eax, [ebx+8] + ret +.split: + +; v->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; +; (r+rsize)->prev_foot = rsize; + + or ebp, 3 + mov edx, edi + or edx, 1 + + cmp edi, 256 + mov [ebx+4], ebp + mov [esi+4], edx + mov [esi+edi], edi + jae .large + + shr edi, 3 + bts [mst.smallmap], edi + + mov eax, edi + shl eax, 4 + add eax, mst.smallbins + + mov edx, [eax+8] + mov [eax+8], esi + mov [edx+12], esi + pop edi + mov [esi+12], eax + mov [esi+8], edx + pop ebp + lea eax, [ebx+8] + ret +.large: + lea eax, [ebx+8] + push eax + mov ebx, edi + call insert_large_chunk + pop eax + pop edi + pop ebp + ret + + +; param +; esi= nb + +align 4 +malloc_large: +.idx equ esp+4 +.rst equ esp + + push ebp + push edi + sub esp, 8 +; v = 0; +; rsize = -nb; + + mov edi, esi + mov ebx, esi + xor ebp, ebp + neg edi + +; idx = compute_tree_index(nb); + + mov edx, esi + shr edx, 8 + bsr eax, edx + lea ecx, [eax+7] + shr esi, cl + and esi, 1 + lea ecx, [esi+eax*2] + mov [.idx], ecx + +; if ((t = ms.treebins[idx]) != 0) + + mov eax, [mst.treebins+ecx*4] + test eax, eax + jz .l3 + +; sizebits = nb << leftshift_for_tree_index(idx); + + cmp ecx, 31 + jne @F + xor ecx, ecx + jmp .l1 +@@: + mov edx, ecx + shr edx, 1 + mov ecx, 37 + sub ecx, edx +.l1: + mov edx, ebx + shl edx, cl + +; rst = 0; + mov [.rst], ebp +.loop: + +; trem = (t->head & ~INUSE_BITS) - nb; + + mov ecx, [eax+4] + and ecx, -4 + sub ecx, ebx + +; if (trem < rsize) + + cmp ecx, edi + jae @F +; v = t; +; if ((rsize = trem) == 0) + + test ecx, ecx + mov ebp, eax + mov edi, ecx + je .l2 +@@: + +; rt = t->child[1]; + + mov ecx, [eax+20] + +; t = t->child[(sizebits >> 31) & 1]; + + mov esi, edx + shr esi, 31 + +; if (rt != 0 && rt != t) + + test ecx, ecx + mov eax, [eax+esi*4+16] + jz @F + cmp ecx, eax + jz @F + +; rst = rt; + mov [.rst], ecx +@@: +; if (t == 0) + + test eax, eax + jz @F + +; sizebits <<= 1; + + add edx, edx + jmp .loop +@@: +; t = rst; + mov eax, [.rst] +.l2: +; if (t == 0 && v == 0) + + test eax, eax + jne .l4 + test ebp, ebp + jne .l7 + mov ecx, [.idx] +.l3: + +; leftbits = (-1<head & ~INUSE_BITS) - nb; + + mov ecx, [eax+4] + and ecx, -4 + sub ecx, ebx + +; if (trem < rsize) + + cmp ecx, edi + jae @F +; rsize = trem; + + mov edi, ecx +; v = t; + mov ebp, eax +@@: + +; t = leftmost_child(t); + + mov ecx, [eax+16] + test ecx, ecx + je @F + mov eax, ecx + jmp .l6 +@@: + mov eax, [eax+20] +.l6: + +; while (t != 0) + + test eax, eax + jne .l4 +.l5: + +; if (v != 0) + + test ebp, ebp + jz .done +.l7: + +; r = chunk_plus_offset((mchunkptr)v, nb); +; unlink_large_chunk(v); + + mov edx, ebp + lea esi, [ebx+ebp] + call unlink_large_chunk + +; if (rsize < 16) + + cmp edi, 16 + jae .large + +; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; + + lea ecx, [edi+ebx] + +; (v+rsize + nb)->head |= PINUSE_BIT; + + add edi, ebp + lea eax, [edi+ebx+4] + or ecx, 3 + mov [ebp+4], ecx + or dword [eax], 1 + lea eax, [ebp+8] + add esp, 8 + pop edi + pop ebp + ret +.large: + +; v->head = nb|PINUSE_BIT|CINUSE_BIT; +; r->head = rsize|PINUSE_BIT; + + mov edx, edi + or ebx, 3 + mov [ebp+4], ebx + or edx, 1 + mov [esi+4], edx + +; (r+rsize)->prev_foot = rsize; +; insert_large_chunk((tchunkptr)r, rsize); + + mov [esi+edi], edi + mov eax, edi + mov ecx, esi + call insert_chunk + + lea eax, [ebp+8] + add esp, 8 + pop edi + pop ebp + ret +.done: + add esp, 8 + pop edi + pop ebp + xor eax, eax + ret + +align 4 +init_malloc: + + stdcall kernel_alloc, 0x20000 + + mov [mst.top], eax + mov [mst.topsize], 128*1024 + mov dword [eax+4], (128*1024) or 1 + mov eax, mst.smallbins +@@: + mov [eax+8], eax + mov [eax+12], eax + add eax, 16 + cmp eax, mst.smallbins+512 + jl @B + + ret + + + + diff --git a/kernel/branches/gfx_kernel/core/mem.inc b/kernel/branches/gfx_kernel/core/mem.inc deleted file mode 100644 index 16aed7c3c..000000000 --- a/kernel/branches/gfx_kernel/core/mem.inc +++ /dev/null @@ -1,469 +0,0 @@ -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/branches/gfx_kernel/core/memmanag.inc b/kernel/branches/gfx_kernel/core/memmanag.inc deleted file mode 100644 index 7055213ac..000000000 --- a/kernel/branches/gfx_kernel/core/memmanag.inc +++ /dev/null @@ -1,833 +0,0 @@ -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 - ipc blocked now + + mov ebx, dword [edi+4] + mov edx, ebx + add ebx, 8 + add ebx, [msg_size] + cmp ebx, [buf_size] + ja .buffer_overflow ;esi<0 - not enough memory in buffer + + mov dword [edi+4], ebx + mov eax,[TASK_BASE] + mov eax, [eax+0x04] ;eax - our PID + mov edi, [dst_offset] + add edi, [ipc_tmp] + add edi, edx + mov [edi], eax + mov ecx, [msg_size] + + mov [edi+4], ecx + add edi, 8 + mov esi, [msg_addr] + add esi, new_app_base + cld + rep movsb + + mov ebx, [ipc_tmp] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_pdir] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_ptab] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [page_tabs+ebx*4], eax + invlpg [edx] + + mov eax, [dst_slot] + shl eax, 8 + or [eax+SLOT_BASE+0xA8],dword 0x40 + cmp dword [check_idle_semaphore],20 + jge .ipc_no_cis + + mov dword [check_idle_semaphore],5 +.ipc_no_cis: + popf + xor eax, eax + ret +.no_pid: + popf + mov eax, 4 + ret +.no_ipc_area: + popf + xor eax, eax + inc eax + ret +.ipc_blocked: + popf + mov eax, 2 + ret +.buffer_overflow: + popf + mov eax, 3 + ret +endp + +align 4 +sysfn_meminfo: + + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + + mov eax, [pg_data.pages_count] + mov [ebx], eax + shl eax, 12 + mov [esp+36], eax + mov ecx, [pg_data.pages_free] + mov [ebx+4], ecx + mov edx, [pg_data.pages_faults] + mov [ebx+8], edx + mov esi, [heap_size] + mov [ebx+12], esi + mov edi, [heap_free] + mov [ebx+16], edi + mov eax, [heap_blocks] + mov [ebx+20], eax + mov ecx, [free_blocks] + mov [ebx+24], ecx + ret +.fail: + mov dword [esp+36], -1 + ret + +align 4 +new_services: + + cmp eax,4 + jle sys_sheduler + + cmp eax, 11 + jb .fail + ja @f + + call init_heap + mov [esp+36], eax + ret +@@: + cmp eax, 12 + ja @f + + stdcall user_alloc, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 13 + ja @f + add ebx, new_app_base + stdcall user_free, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 14 + ja @f + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + stdcall get_event_ex, ebx, ecx + mov [esp+36], eax + ret +@@: + cmp eax, 15 + ja @f + mov ecx, [CURRENT_TASK] + shl ecx, 8 + mov eax, [ecx+SLOT_BASE+APPDATA.fpu_handler] + mov [ecx+SLOT_BASE+APPDATA.fpu_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 16 + ja @f + + test ebx, ebx + jz .fail + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + stdcall get_service, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 17 + ja @f + call srv_handlerEx ;ebx + mov [esp+36], eax + ret +@@: + cmp eax, 18 + ja @f + mov ecx, [CURRENT_TASK] + shl ecx, 8 + mov eax, [ecx+SLOT_BASE+APPDATA.sse_handler] + mov [ecx+SLOT_BASE+APPDATA.sse_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 19 + ja .fail + add ebx, new_app_base + cmp ebx, new_app_base + jb .fail + stdcall load_library, ebx + mov [esp+36], eax + ret + +.fail: + xor eax, eax + mov [esp+36], eax + ret + +align 4 +proc strncmp stdcall, str1:dword, str2:dword, count:dword + + mov ecx,[count] + jecxz .end + + mov ebx,ecx + + mov edi,[str1] + mov esi,edi + xor eax,eax + repne scasb + neg ecx ; cx = count - strlen + add ecx,ebx ; strlen + count - strlen + +.okay: + mov edi,esi + mov esi,[str2] + repe cmpsb + mov al,[esi-1] + xor ecx,ecx + + cmp al,[edi-1] + ja .str2_big + je .end + +.str1_big: + sub ecx,2 + +.str2_big: + not ecx +.end: + mov eax,ecx + ret +endp + +align 4 +proc test_cpu + locals + cpu_type dd ? + cpu_id dd ? + cpu_Intel dd ? + cpu_AMD dd ? + endl + + mov [cpu_type], 0 + xor eax, eax + mov [cpu_caps], eax + mov [cpu_caps+4], eax + + pushfd + pop eax + mov ecx, eax + xor eax, 0x40000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov [cpu_type], CPU_386 + jz .end_cpuid + push ecx + popfd + + mov [cpu_type], CPU_486 + mov eax, ecx + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + je .end_cpuid + mov [cpu_id], 1 + + xor eax, eax + cpuid + mov [cpu_vendor], ebx + mov [cpu_vendor+4], edx + mov [cpu_vendor+8], ecx + cmp ebx, dword [intel_str] + jne .check_AMD + cmp edx, dword [intel_str+4] + jne .check_AMD + cmp ecx, dword [intel_str+8] + jne .check_AMD + mov [cpu_Intel], 1 + cmp eax, 1 + jl .end_cpuid + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + + shr eax, 8 + and eax, 0x0f + ret +.end_cpuid: + mov eax, [cpu_type] + ret + +.check_AMD: + cmp ebx, dword [AMD_str] + jne .unknown + cmp edx, dword [AMD_str+4] + jne .unknown + cmp ecx, dword [AMD_str+8] + jne .unknown + mov [cpu_AMD], 1 + cmp eax, 1 + jl .unknown + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + ret +.unknown: + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + ret +endp + +MEM_WB equ 6 ;write-back memory +MEM_WC equ 1 ;write combined memory +MEM_UC equ 0 ;uncached memory + +align 4 +proc init_mtrr + + cmp [0x2f0000+0x901c],byte 2 + je .exit + + bt [cpu_caps], CAPS_MTRR + jnc .exit + + mov eax, cr0 + or eax, 0x60000000 ;disable caching + mov cr0, eax + wbinvd ;invalidate cache + + mov ecx, 0x2FF + rdmsr ; + push eax + + xor edx, edx + xor eax, eax + mov ecx, 0x2FF + wrmsr ;disable all MTRR + + stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB + stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC + xor edx, edx + xor eax, eax + mov ecx, 0x204 + mov ebx, 6 +@@: + wrmsr ;disable unused MTRR + inc ecx + wrmsr + inc ecx + dec ebx + jnz @b + + wbinvd ;again invalidate + + pop eax + or eax, 0x800 ;set default memtype to UC + and al, 0xF0 + mov ecx, 0x2FF + wrmsr ;and enable MTRR + + mov eax, cr0 + and eax, not 0x60000000 + mov cr0, eax ; enable caching +.exit: + ret +endp + +align 4 +proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword + + xor edx, edx + mov eax, [base] + or eax, [mem_type] + mov ecx, [reg] + lea ecx, [0x200+ecx*2] + wrmsr + + mov ebx, [size] + dec ebx + mov eax, 0xFFFFFFFF + mov edx, 0x0000000F + sub eax, ebx + sbb edx, 0 + or eax, 0x800 + inc ecx + wrmsr + ret +endp + +align 4 +proc stall stdcall, delay:dword + push ecx + push edx + push ebx + push eax + + mov eax, [delay] + mul [stall_mcs] + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + jb @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +iglobal +align 4 + intel_str db "GenuineIntel",0 + AMD_str db "AuthenticAMD",0 +endg + +uglobal +align 16 + irq_tab rd 16 + + MEM_FreeSpace rd 1 + + ipc_tmp rd 1 + ipc_pdir rd 1 + ipc_ptab rd 1 + + proc_mem_map rd 1 + proc_mem_pdir rd 1 + proc_mem_tab rd 1 + + tmp_task_pdir rd 1 + tmp_task_ptab rd 1 + + fdd_buff rd 1 + LFBSize rd 1 + + stall_mcs rd 1 +;;CPUID information + + cpu_vendor rd 3 + cpu_sign rd 1 + cpu_info rd 1 + +;;;;; cursors data + +align 16 +cur_saved_data rb 4096 + +def_cursor rd 1 +hw_cursor rd 1 + +scr_width rd 1 +scr_height rd 1 + +cur_def_interl rd 1 +cur_saved_base rd 1 +cur_saved_interl rd 1 +cur_saved_w rd 1 +cur_saved_h rd 1 + +endg + +uglobal +align 16 + fpu_data: + rb 512 + + mst MEM_STATE + + mem_block_map rb 512 + event_map rb 64 + mem_block_list rd 64 + mem_block_mask rd 2 + + srv.fd rd 1 + srv.bk rd 1 + + mem_used.fd rd 1 + mem_used.bk rd 1 + + mem_block_arr rd 1 + mem_block_start rd 1 + mem_block_end rd 1 + + heap_mutex rd 1 + heap_size rd 1 + heap_free rd 1 + heap_blocks rd 1 + free_blocks rd 1 + + page_start rd 1 + page_end rd 1 + events rd 1 + event_start rd 1 + event_end rd 1 + event_uid rd 1 + sys_page_map rd 1 + os_stack rd 1 +endg + +if 0 + push eax + push edx + mov edx, 0x400 ;bocsh + mov al,0xff ;bocsh + out dx, al ;bocsh + pop edx + pop eax +end if + +align 4 +k_strrchr: + push eax + xor eax,eax + or ecx,-1 + repne scasb + add ecx,1 + neg ecx + sub edi,1 + pop eax + std + repne scasb + cld + add edi,1 + + cmp [edi],al + jne @F + mov eax,edi + ret +@@: + xor eax,eax + ret + +align 4 +proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword + mov eax, [dest] + mov esi, [src] + mov ecx, [maxlen] + test eax, eax + jz .L9 + test esi, esi + jz .L9 + test ecx, ecx + jz .L9 + + sub esi, eax + jmp .L1 + +align 4 +.L2: + mov edx, [esi+eax] + mov [eax], dl + test dl, dl + jz .L7 + + mov [eax+1], dh + test dh, dh + jz .L6 + + shr edx, 16 + mov [eax+2],dl + test dl, dl + jz .L5 + + mov [eax+3], dh + test dh, dh + jz .L4 + add eax, 4 +.L1: + sub ecx, 4 + jae .L2 + + add ecx, 4 + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + dec ecx + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + dec ecx + jz .L9 + + mov dl, [eax+esi] + mov [eax], dl + test dl, dl + jz .L3 + + inc eax + jmp .L9 + +.L4: dec ecx + inc eax + +.L5: dec ecx + inc eax + +.L6: dec ecx + inc eax +.L7: + add ecx,3 + jz .L9 +.L8: + mov byte [ecx+eax], 0 +.L3: + dec ecx + jnz .L8 +.L9: + ret +endp + +if 0 + +magic equ 0xfefefeff + +k_strlen: + mov eax,[esp+4] + mov edx, 3 + + and edx, eax + jz .L1 + jp .L0 + + cmp dh, byte [eax] + je .L2 + + inc eax + cmp dh, byte [eax] + + je .L2 + + inc eax + xor edx, 2 + + jz .L1 +.L0: + cmp dh, [eax] + je .L2 + + inc eax + xor edx, edx + +.L1: + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + dec edx + jnc .L3 + + xor edx, ecx + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + + and edx, not magic + jne .L3 + + mov ecx, [eax] + add eax, 4 + + sub edx, ecx + add ecx, magic + + dec edx + jnc .L3 + + xor edx, ecx + + and edx, not magic + je .L1 + +.L3: sub eax ,4 + sub ecx, magic + + cmp cl, 0 + jz .L2 + + inc eax + test ch, ch + jz .L2 + + shr ecx, 16 + inc eax + + cmp cl,0 + jz .L2 + + inc eax + +.L2: + sub eax, [esp+4] + ret + +end if diff --git a/kernel/branches/gfx_kernel/core/newproce.inc b/kernel/branches/gfx_kernel/core/newproce.inc deleted file mode 100644 index 70ed4b0e1..000000000 --- a/kernel/branches/gfx_kernel/core/newproce.inc +++ /dev/null @@ -1,1651 +0,0 @@ -if ~defined newprocess_inc -newprocess_inc_fix: -newprocess_inc fix newprocess_inc_fix -include "mem.inc" -include "memmanag.inc" -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;Working with new types of processes. -;;Author: Khalyavin Andrey halyavin@land.ru -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -iglobal - new_process_loading db 'K : New Process - loading',13,10,0 - new_process_running db 'K : New Process - done',13,10,0 - start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 -endg -;----------------------------------------------------------------------------- - -find_new_process_place: -;input: -; none -;result: -; eax=[new_process_place]<>0 - 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_start_application_floppy: -;input: -; eax - pointer to filename -; ebx - parameters to pass -; edx - flags -;result: -; eax - pid of new process -; or 0 if call fails. - mov [appl_path],edi - pushad - mov esi,new_process_loading - call sys_msg_board_str ;write to debug board - -;wait 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 -;we can change system tables now - push edi - push ebx - push eax - call find_new_process_place ;find empty process slot - sti - test eax,eax - mov ecx, -0x20 ; too many processes - jz .failed - - mov edi,eax - shl edi,8 - add edi,0x80000 - mov ecx,256/4 - xor eax,eax - cld - rep stosd ;clean extended information about process - -;set new process name - mov [appl_path_size],eax - pop eax - push eax -.find_last_byte: - cmp byte [eax],0 - jz .find_last_byte_end - inc eax - inc [appl_path_size] - jmp .find_last_byte -.find_last_byte_end: - add [appl_path_size],24 - sub eax,11 ;last 11 bytes = application name -; mov eax,[esp] ;eax - pointer to file name - mov ebx,[new_process_place] - shl ebx,8 - add ebx,0x80000 + APPDATA.app_name - mov ecx,11 - call memmove - -;read header of file - mov eax,[esp] - mov ebx,1 ;index of first block - mov ecx,2 ;number of blocks - mov edx,0x90000 ;temp area - mov esi,12 ;file name length - mov edi,[esp+8] -; cli - call floppy_fileread ;read file from FD -; sti - mov ecx, eax - neg ecx - jnz .cleanfailed -;check MENUET signature - mov ecx, -0x1F ; not Menuet/Kolibri executable - cmp [0x90000],dword 'MENU' - jnz .cleanfailed - cmp [0x90004],word 'ET' - jnz .cleanfailed - - call get_app_params ;parse header fields - jc .cleanfailed - - mov eax,[new_process_place] - inc ecx ; -0x1E = no memory - call create_app_cr3_table ;create page directory for new process - test eax,eax - jz .cleanfailed_mem - - call MEM_Get_Linear_Address ;calculate linear address of it - - mov ebx,std_application_base_address - mov ecx,[app_mem] - add ecx,4095 - shr ecx,12 - mov edx,eax - call mem_alloc_specified_region ;allocate memory for application - test eax,eax - mov ecx, -0x1E - jz .cleanfailed_mem1 - - mov eax,[edx+(std_application_base_address shr 20)] - and eax,not (4096-1) ;eax - physical address of first (for application memory) page table - call MEM_Get_Linear_Address - mov edx,eax - -;read file - mov ebx,1 - mov esi,12 ;length of file name -.loop1: -;edx = linear address of current page table entry -;ebx = index of current block in file - push edx - mov eax,[edx] - and eax,not (4096-1) - call MEM_Get_Linear_Address - mov edx,eax ;read file block to current page - mov eax,[esp+4] ;restore pointer to file name - mov ecx,8 ;number of blocks read - mov ebp,edx ;save buffer address for .endofimage - push ebx - mov edi,[esp+16] -; cli - call floppy_fileread -;ebx=file size -; sti - pop ecx - add ecx,8 - test eax,eax - jnz .endloop1 ;check io errors - mov eax,[app_i_end] - add eax,511 - shr eax,9 - cmp ecx,eax - jg .endofimage ;we have loaded whole program - add ebx,511 - shr ebx,9 - cmp ecx,ebx - jg .endloop1 ;if end of file? - mov ebx,ecx - pop edx - add edx,4 - jmp .loop1 - -.endofimage: ;set to zero memory at end of page - mov ecx,[app_i_end] - and ecx,4096-1 - jz .endloop1 - lea edi,[ebp+ecx] - neg ecx - add ecx,4096 - xor eax,eax - cld - rep stosb -.endloop1: - add esp,8+4 ;pop linear address of page table entry and pointer to file name - call new_start_application_fl.add_app_parameters - mov [esp+28],eax - popad - ret - -.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+APPDATA.dir_table] - 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: ;clean process name - push ecx ; save error code -;can't read file, clean process name. -;this avoid problems with panel application. - mov edi,[new_process_place] - shl edi,8 - add edi,0x80000 + APPDATA.app_name - mov ecx,11 - mov eax,' ' - cld - rep stosb - pop eax -.failed: -;no more slots - add esp,8+4 - mov [application_table_status],0 - mov [esp+1Ch], eax - popad - sti - ret - -;----------------------------------------------------------------------------- -new_start_application_fl: -;input: -; eax - pointer to filename -; ebx - parameters to pass -; edx - flags -;result: -; eax - pid of new process -; or 0 if call fails. - mov [appl_path],edi - mov [appl_path_size],36 - pushad - mov esi,new_process_loading - call sys_msg_board_str ;write to debug board - -;wait 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 -;we can change system tables now - push ebx - push eax - call find_new_process_place ;find empty process slot - call safe_sti - test eax,eax - mov ecx, -0x20 ; too many processes - jz .failed - - mov edi,eax - shl edi,8 - add edi,0x80000 - mov ecx,256/4 - xor eax,eax - cld - rep stosd ;clean extended information about process - -;set new process name - mov eax,[esp] ;eax - pointer to file name - mov ebx,[new_process_place] - shl ebx,8 - add ebx,0x80000 + APPDATA.app_name - mov ecx,11 - call memmove - -;read header of file - mov ebx,1 ;index of first block - mov ecx,2 ;number of blocks - mov edx,0x90000 ;temp area - mov esi,12 ;file name length - cli - call fileread ;read file from RD - call safe_sti - mov ecx, eax - neg ecx - jnz .cleanfailed -;check MENUET signature - mov ecx, -0x1F ; not Menuet/Kolibri executable - cmp [0x90000],dword 'MENU' - jnz .cleanfailed - cmp [0x90004],word 'ET' - jnz .cleanfailed - - call get_app_params ;parse header fields - jc .cleanfailed - - mov eax,[new_process_place] - inc ecx ; -0x1E = no memory - call create_app_cr3_table ;create page directory for new process - test eax,eax - jz .cleanfailed_mem - - call MEM_Get_Linear_Address ;calculate linear address of it - - mov ebx,std_application_base_address - mov ecx,[app_mem] - add ecx,4095 - shr ecx,12 - mov edx,eax - call mem_alloc_specified_region ;allocate memory for application - test eax,eax - mov ecx, -0x1E - jz .cleanfailed_mem1 - - mov eax,[edx+(std_application_base_address shr 20)] - and eax,not (4096-1) ;eax - physical address of first (for application memory) page table - call MEM_Get_Linear_Address - mov edx,eax - -;read file - mov ebx,1 - mov esi,12 ;length of file name -.loop1: -;edx = linear address of current page table entry -;ebx = index of current block in file - push edx - mov eax,[edx] - and eax,not (4096-1) - call MEM_Get_Linear_Address - mov edx,eax ;read file block to current page - mov eax,[esp+4] ;restore pointer to file name - mov ecx,8 ;number of blocks read - mov ebp,edx ;save buffer address for .endofimage - push ebx - cli - call fileread -;ebx=file size - call safe_sti - pop ecx - add ecx,8 - test eax,eax - jnz .endloop1 ;check io errors - mov eax,[app_i_end] - add eax,511 - shr eax,9 - cmp ecx,eax - jg .endofimage ;we have loaded whole program - add ebx,511 - shr ebx,9 - cmp ecx,ebx - jg .endloop1 ;if end of file? - mov ebx,ecx - pop edx - add edx,4 - jmp .loop1 - -.endofimage: ;set to zero memory at end of page - mov ecx,[app_i_end] - and ecx,4096-1 - jz .endloop1 - lea edi,[ebp+ecx] - neg ecx - add ecx,4096 - xor eax,eax - cld - rep stosb -.endloop1: - add esp,8 ;pop linear address of page table entry and pointer to file name - call .add_app_parameters - mov [esp+28],eax - popad - ret - -.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+APPDATA.dir_table] - 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: ;clean process name - push ecx ; save error code -;can't read file, clean process name. -;this avoid problems with panel application. - mov edi,[new_process_place] - shl edi,8 - add edi,0x80000+APPDATA.app_name - mov ecx,11 - mov eax,' ' - cld - rep stosb - pop eax -.failed: -;no more slots - add esp,8 - mov [application_table_status],0 - mov [esp+1Ch], eax - popad - call safe_sti - ret - -.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 - 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 window state to 'normal' (non-minimized/maximized/rolled-up) state - mov [ecx+WDATA.fl_wstate],WSTATE_NORMAL -;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 -;----------------------------------------------------------------------------- -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 new_start_application_fl.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 -;----------------------------------------------------------------------------- -new_start_application_hd: -;eax - file name (kernel address) -;ebx - file name length -;ecx - work area (kernel address) -;edx - flags -;ebp - parameters - mov [appl_path],edi - pushad - - 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 ebp - push ebx - push eax - push ecx - call find_new_process_place ;find new process slot - sti - test eax,eax - mov ecx, -0x20 ; too many processes - jz .failed - -;write application name - xor eax,eax - mov [appl_path_size],eax - mov eax,[esp+4] -.find_last_byte: - cmp byte [eax],0 - jz .find_last_byte_end - inc eax - inc [appl_path_size] - jmp .find_last_byte -.find_last_byte_end: - add [appl_path_size],24 - lea esi,[eax-11] ;last 11 bytes = application name - mov edi,[new_process_place] - shl edi,8 - add edi,0x80000+APPDATA.app_name - mov ecx,11 - cld - rep movsb ;copy name to extended information about process - -;read header - mov eax,[esp+4] ;file name - mov esi,[esp] ;work area - mov ecx,1 ;read from first block - mov edx,1 ;read 1 block - call read_hd_file - mov ecx, eax - neg ecx - jnz .cleanfailed - - pop esi - push esi -;check menuet signature - mov ecx, -0x1F ; not Menuet/Kolibri executable - cmp [esi+1024+0],dword 'MENU' ;read_hd_file function write file to +1024 offset - jnz .cleanfailed - cmp [esi+1024+4],word 'ET' - jnz .cleanfailed - add esi,1024 - mov edi,0x90000 - mov ecx,512/4 - cld - rep movsd ;copy first block to 0x90000 address for get_app_params function - call get_app_params - mov ecx, -0x1F ; not Menuet/Kolibri executable - jc .cleanfailed - - mov eax,[new_process_place] - inc ecx ; -0x1E = no memory - call create_app_cr3_table ;create page directory - test eax,eax - jz .cleanfailed_mem - - call MEM_Get_Linear_Address - - mov ebx,std_application_base_address - mov ecx,[app_mem] - add ecx,4096-1 - shr ecx,12 - mov edx,eax ;edx - linear address of page directory - call mem_alloc_specified_region ;allocate memory for application - 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 (4096-1) - call MEM_Get_Linear_Address - push edx ;save pointer to first page table - mov edx,eax -;read file - mov ecx,1 - xor ebp,ebp -.loop1: -;[esp] - pointer to current page directory entry -;edx - pointer to current page table -;ebp - offset in page -;ecx - current cluster - push edx - mov eax,[esp+12] ;file name - mov ebx,[esp+16] ;file name length - mov esi,[esp+8] ;work area - mov edx,1 ;number of blocks to read - push ecx - push ebp - cli - call read_hd_file - sti - pop ebp - test eax,eax - jnz .endloop1 ;check io errors - - mov esi,[esp+8+4] ;work area - add esi,1024 - mov eax,[esp+4] ;current page table - mov eax,[eax] - and eax,not (4096-1) - call MEM_Get_Linear_Address;calculate linear page address - lea edi,[eax+ebp] ;add page offset - mov ecx,512/4 - cld - rep movsd ;copy data - - pop ecx - inc ecx ;next block - mov eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096 - add eax,512-1 - shr eax,9 ;calculate application image size - cmp ecx,eax - jg .endloop11 - pop edx - add ebp,512 ;new offset - test ebp,4096 - jz .loop1 - xor ebp,ebp - add edx,4 ;go to next page - test edx,(4096-1) - jnz .loop1 - add dword [esp],4 ;go to next directory entry - mov eax,[esp] - mov eax,[eax] - and eax,not (4096-1) - call MEM_Get_Linear_Address - mov edx,eax - jmp .loop1 -.endloop1: - add esp,4 ;pop ecx -.endloop11: - add esp,4+4 ;pop edx, pop edx - -;add_app_parameters - add esp,12 ;now pointer to parameters is on the top of the stack - call new_start_application_fl.add_app_parameters ;start process - mov [esp+28],eax - popad - ret - -.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+APPDATA.dir_table] - 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: ;clean process name - push ecx -;can't read file, clean process name. -;this avoid problems with panel application. - mov edi,[new_process_place] - shl edi,8 - add edi,0x80000+APPDATA.app_name - mov ecx,11 - mov eax,' ' - cld - rep stosb - pop eax -.failed: -;no more slots - add esp,16 - mov [esp+1Ch], eax - popad - mov [application_table_status],0 - sti - ret -end if - -; \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 new_start_application_fl.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} diff --git a/kernel/branches/gfx_kernel/core/physmem.inc b/kernel/branches/gfx_kernel/core/physmem.inc deleted file mode 100644 index 90d08ab29..000000000 --- a/kernel/branches/gfx_kernel/core/physmem.inc +++ /dev/null @@ -1,220 +0,0 @@ -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/branches/gfx_kernel/core/sched.inc b/kernel/branches/gfx_kernel/core/sched.inc index 5effb54a4..cae8711ea 100644 --- a/kernel/branches/gfx_kernel/core/sched.inc +++ b/kernel/branches/gfx_kernel/core/sched.inc @@ -22,14 +22,14 @@ irq0: call updatecputimes .nocounter: - cmp [0xffff], byte 1 + cmp [DONT_SWITCH], byte 1 jne .change_task mov al,0x20 ; send End Of Interrupt signal mov dx,0x20 out dx,al - mov [0xffff], byte 0 + mov [DONT_SWITCH], byte 0 restore_ring3_context iret @@ -48,7 +48,7 @@ irq0: jnz .return call do_change_task - + .return: restore_ring3_context iret @@ -62,11 +62,24 @@ change_task: pushad call update_counters +; \begin{Mario79} + cmp [dma_task_switched], 1 + jne .find_next_task + mov [dma_task_switched], 0 + mov ebx, [dma_process] + cmp [CURRENT_TASK], ebx + je .return + mov edi, [dma_slot_ptr] + mov [CURRENT_TASK], ebx + mov [TASK_BASE], edi + jmp @f +.find_next_task: +; \end{Mario79} call find_next_task test eax, eax ; the same task -> skip switch jnz .return - - mov [0xffff],byte 1 +@@: + mov [DONT_SWITCH],byte 1 call do_change_task .return: @@ -90,7 +103,7 @@ endg update_counters: - mov edi, [0x3010] + mov edi, [TASK_BASE] mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add call _rdtsc sub eax, ebx @@ -106,17 +119,17 @@ ret ; [0x3000] = ebx and [0x3010] = edi ; corrupts other regs find_next_task: - mov ebx, [0x3000] - mov edi, [0x3010] + mov ebx, [CURRENT_TASK] + mov edi, [TASK_BASE] mov [prev_slot], ebx .waiting_for_termination: .waiting_for_reuse: .waiting_for_event: .suspended: - cmp ebx, [0x3004] + cmp ebx, [TASK_COUNT] jb @f - mov edi, 0x3000 + mov edi, CURRENT_TASK xor ebx, ebx @@: @@ -137,8 +150,8 @@ find_next_task: cmp al, 9 je .waiting_for_reuse - mov [0x3000],ebx - mov [0x3010],edi + mov [CURRENT_TASK],ebx + mov [TASK_BASE],edi cmp al, 5 jne .noevents @@ -149,8 +162,8 @@ find_next_task: mov [edi+TASKDATA.state], byte 0 .noevents: .found: - mov [0x3000],ebx - mov [0x3010],edi + mov [CURRENT_TASK],ebx + mov [TASK_BASE],edi call _rdtsc mov [edi+TASKDATA.counter_add],eax @@ -178,8 +191,8 @@ updatecputimes: mov eax,[idleuse] mov [idleusesec],eax mov [idleuse],dword 0 - mov ecx, [0x3004] - mov edi, 0x3020 + mov ecx, [TASK_COUNT] + mov edi, TASK_DATA .newupdate: mov ebx,[edi+TASKDATA.counter_sum] mov [edi+TASKDATA.cpu_usage],ebx diff --git a/kernel/branches/gfx_kernel/core/sync.inc b/kernel/branches/gfx_kernel/core/sync.inc index c5f04a37f..147d13c3b 100644 --- a/kernel/branches/gfx_kernel/core/sync.inc +++ b/kernel/branches/gfx_kernel/core/sync.inc @@ -17,7 +17,7 @@ macro SimpleMutex name macro WaitSimpleMutex name { local start_wait,ok -start_wait=$ +start_wait=$ cli cmp [name],dword 0 jz ok @@ -26,7 +26,7 @@ start_wait=$ jmp start_wait ok=$ push eax - mov eax,dword [0x3010+second_base_address] + mov eax,dword [TASK_BASE+second_base_address] mov eax,[eax+TASKDATA.pid] mov [name],eax pop eax @@ -60,7 +60,7 @@ macro WaitSimpleCriticalSection name { local start_wait,first_wait,inc_counter,end_wait push eax - mov eax,[0x3010+second_base_address] + mov eax,[TASK_BASE+second_base_address] mov eax,[eax+TASKDATA.pid] start_wait=$ cli @@ -74,7 +74,7 @@ start_wait=$ first_wait=$ mov [name],eax mov [name+4],dword 1 - jmp end_wait + jmp end_wait inc_counter=$ inc dword [name+4] end_wait=$ @@ -92,7 +92,7 @@ release_end=$ macro TryWaitSimpleCriticalSection name ;result in eax and in flags { local ok,try_end - mov eax,[0x3000+second_base_address] + mov eax,[CURRENT_TASK+second_base_address] mov eax,[eax+TASKDATA.pid] cmp [name],eax jz ok diff --git a/kernel/branches/gfx_kernel/core/sys32.inc b/kernel/branches/gfx_kernel/core/sys32.inc index af0c5b85b..0c3fa16ee 100644 --- a/kernel/branches/gfx_kernel/core/sys32.inc +++ b/kernel/branches/gfx_kernel/core/sys32.inc @@ -7,119 +7,9 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -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: @@ -140,7 +30,6 @@ build_process_gdt_tss_pointer: ret - build_interrupt_table: mov edi, idts+8 @@ -157,7 +46,7 @@ build_interrupt_table: 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 @@ -166,16 +55,20 @@ build_interrupt_table: 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 e0,debug_exc,e2,e3 + dd e4,e5,e6,e7 + dd e8,e9,e10,e11 + dd e12,e13,page_fault_handler,e15 - 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 + dd except_16, e17,e18, except_19 + times 12 dd unknown_interrupt + + dd irq0 , irq_serv.irq_1, p_irq2 , p_irq3 ;irq_serv.irq_3 + dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7 + dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 + dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15 times 16 dd unknown_interrupt @@ -216,7 +109,7 @@ macro exc_w_code [num] jmp exc_c } -exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 16 ; 18, 19 +exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 18 exc_w_code 8, 10, 11, 12, 13, 14, 17 exc_c: @@ -226,21 +119,21 @@ exc_c: ; test if debugging cli - mov eax, [0x3000] + mov eax, [CURRENT_TASK] shl eax, 8 - mov eax, [0x80000+eax+APPDATA.debugger_slot] + mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot] test eax, eax jnz .debug sti ; not debuggee => say error and terminate add esp, 28h - movzx eax, bl + movzx eax, bl mov [error_interrupt], eax call show_error_parameters - - mov edx, [0x3010] + + mov edx, [TASK_BASE] mov [edx + TASKDATA.state], byte 4 - + jmp change_task .debug: @@ -249,7 +142,7 @@ exc_c: cld movzx ecx, bl push ecx - mov ecx, [0x3010] + mov ecx, [TASK_BASE] push dword [ecx+TASKDATA.pid] ; PID of current process push 12 pop ecx @@ -258,49 +151,15 @@ exc_c: pop ecx pop ecx pop ecx - mov edx, [0x3010] + mov edx, [TASK_BASE] 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 @@: @@ -334,13 +193,13 @@ uglobal endg show_error_parameters: - + mov [write_error_to],process_pid+43 - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax, 5 - mov eax,[0x3000+TASKDATA.pid+eax] + mov eax,[CURRENT_TASK+TASKDATA.pid+eax] call writehex - + mov [write_error_to],process_error+43 mov eax,[error_interrupt] call writehex @@ -380,7 +239,7 @@ macro irqh [num] jmp irq_c } -irqh 2,5,7,8,9,10,11,14,15 +irqh 2,5,7,8,9,10,11 irq_c: mov ax, os_data @@ -412,7 +271,7 @@ p_irq3: old_irq3_handler: mov edi,3 call irqhandler - p_irq3_1: + p_irq3_1: restore_ring3_context iret @@ -428,7 +287,7 @@ p_irq4: old_irq4_handler: mov edi,4 call irqhandler - p_irq4_1: + p_irq4_1: restore_ring3_context iret @@ -441,6 +300,25 @@ p_irq12: restore_ring3_context iret +p_irq14: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call [irq14_func] + call ready_for_next_irq_1 + restore_ring3_context + iret +p_irq15: + save_ring3_context + mov ax, os_data + mov ds, ax + mov es, ax + call [irq15_func] + call ready_for_next_irq_1 + restore_ring3_context + iret + ready_for_next_irq: mov [check_idle_semaphore],5 mov al, 0x20 @@ -459,7 +337,7 @@ irqD: mov ax, os_data mov ds, ax mov es, ax - + mov dx,0xf0 mov al,0 out dx,al @@ -471,7 +349,7 @@ irqD: out dx,al restore_ring3_context - + iret @@ -483,7 +361,7 @@ irqhandler: shl esi,6 ; 1 add esi,irq00read ; 1 shl edi,12 ; 1 - add edi,0x2E0000 + add edi,IRQ_SAVE mov ecx,16 mov [check_idle_semaphore],5 @@ -554,9 +432,9 @@ irqhandler: set_application_table_status: push eax - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax, 5 - add eax,0x3000+TASKDATA.pid + add eax,CURRENT_TASK+TASKDATA.pid mov eax,[eax] mov [application_table_status],eax @@ -569,9 +447,9 @@ set_application_table_status: clear_application_table_status: push eax - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax, 5 - add eax,0x3000+TASKDATA.pid + add eax,CURRENT_TASK+TASKDATA.pid mov eax,[eax] cmp eax,[application_table_status] @@ -583,121 +461,19 @@ clear_application_table_status: 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: + stdcall new_mem_resize, ebx + mov [esp+36], eax 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 - - -start_application_fl: - jmp new_start_application_fl - -;************************************************************************ - -start_application_floppy: - jmp new_start_application_floppy - -;******************************************************************** - -start_application_hd: - jmp new_start_application_hd - -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 - -;iglobal - ;hd_app_string db 'HDAPP ' - ;process_loading db 'K : Process - loading ',13,10,0 - ;process_running db 'K : Process - done',13,10,0 - ;first_gdt_search dd 0x2 -;endg - +.no_application_mem_resize: + ret sys_threads: @@ -712,36 +488,77 @@ jmp new_sys_threads iglobal process_terminating db 'K : Process - terminating',13,10,0 process_terminated db 'K : Process - done',13,10,0 + msg_obj_destroy db 'K : destroy app object',13,10,0 endg +; param +; esi= slot terminate: ; terminate application - push esi - mov esi,process_terminating - call sys_msg_board_str - pop esi + .slot equ esp ;locals + + push esi ;save .slot + + shl esi, 8 + cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 + jne @F + add esp, 4 + ret @@: - cli - cmp [application_table_status],0 - je term9 - sti - call change_task - jmp @b - term9: + mov esi,process_terminating + call sys_msg_board_str +@@: + cli + cmp [application_table_status],0 + je term9 + sti + call change_task + jmp @b +term9: + call set_application_table_status - call set_application_table_status - - mov eax,esi - call dispose_app_cr3_table + mov esi, [.slot] + shl esi,8 + add esi, SLOT_BASE+APP_OBJ_OFFSET +@@: + mov eax, [esi+APPOBJ.fd] + test eax, eax + jz @F - 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: + cmp eax, esi + je @F - mov [0xf400],byte 0 ; empty keyboard buffer - mov [0xf500],byte 0 ; empty button buffer + push esi + call [eax+APPOBJ.destroy] + mov esi, msg_obj_destroy + call sys_msg_board_str + pop esi + jmp @B +@@: + mov eax, [.slot] + shl eax, 8 + mov eax,[SLOT_BASE+eax+APPDATA.dir_table] + stdcall destroy_app_space, eax + + mov esi, [.slot] + cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 + jne @F + + mov [fpu_owner],1 + mov eax, [256+SLOT_BASE+APPDATA.fpu_state] + clts + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + fxrstor [eax] + jmp @F +.no_SSE: + fnclex + frstor [eax] +@@: + + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer ; remove defined hotkeys @@ -780,7 +597,7 @@ terminate: ; terminate application mov ecx,esi ; remove buttons bnewba2: - mov edi,[0xfe88] + mov edi,[BTN_ADDR] mov eax,edi cld movzx ebx,word [edi] @@ -816,12 +633,11 @@ terminate: ; terminate application add eax,[esi+WDATA.box.height] mov [dlye],eax - mov [esi+WDATA.box.left], 0 - mov [esi+WDATA.box.width], 5 - mov eax,[0xFE04] - mov [esi+WDATA.box.top],eax - mov [esi+WDATA.box.height], 5 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 @@ -835,12 +651,12 @@ terminate: ; terminate application pushad mov edi, esi shl edi, 5 - mov eax, [0x80000+edi*8+APPDATA.debugger_slot] + mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot] test eax, eax jz .nodebug push 8 pop ecx - push dword [0x3000+edi+TASKDATA.pid] ; PID + push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID push 2 call debugger_notify pop ecx @@ -848,40 +664,43 @@ terminate: ; terminate application .nodebug: popad - pusha ; at 0x80000+ - mov edi,esi - shl edi,8 - add edi,0x80000 - mov ecx,256/4 - xor eax, eax - rep stosd - popa + mov ebx, [.slot] + shl ebx, 8 + mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] - pusha ; name to spaces - mov edi,esi - shl edi,8 - add edi,0x80000+APPDATA.app_name - mov ecx,11 - mov eax,' ' - rep stosb - popa + stdcall kernel_free, ebx + mov edi, [.slot] + shl edi,8 + add edi,SLOT_BASE + mov eax, 0x20202020 + stosd + stosd + stosd + mov ecx,244/4 + xor eax, eax + rep stosd ; activate window - movzx eax, word [0xC000 + esi*2] - cmp eax, [0x3004] + movzx eax, word [WIN_STACK + esi*2] + cmp eax, [TASK_COUNT] jne .dont_activate pushad .check_next_window: dec eax cmp eax, 1 jbe .nothing_to_activate - lea esi, [0xc400+eax*2] + lea esi, [WIN_POS+eax*2] movzx edi, word [esi] ; edi = process shl edi, 5 - cmp [0x3000 + edi + TASKDATA.state], byte 9 ; skip dead slots + cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots je .check_next_window add edi, window_data +; \begin{diamond}[19.09.2006] +; skip minimized windows + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .check_next_window +; \end{diamond} call waredraw .nothing_to_activate: popad @@ -889,13 +708,15 @@ terminate: ; terminate application push esi ; remove hd1 & cd & flp reservation shl esi, 5 - mov esi, [esi+0x3000+TASKDATA.pid] + mov esi, [esi+CURRENT_TASK+TASKDATA.pid] cmp [hd1_status], esi jnz @f + call free_hd_channel mov [hd1_status], 0 @@: cmp [cd_status], esi jnz @f + call free_cd_channel mov [cd_status], 0 @@: cmp [flp_status], esi @@ -907,7 +728,7 @@ terminate: ; terminate application pusha ; remove all irq reservations mov eax,esi shl eax, 5 - mov eax,[eax+0x3000+TASKDATA.pid] + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] mov edi,irq_owner mov ecx,16 newirqfree: @@ -918,16 +739,15 @@ terminate: ; terminate application loop newirqfree popa - pusha ; remove all port reservations mov edx,esi shl edx, 5 - add edx,0x3000 + add edx,CURRENT_TASK mov edx,[edx+TASKDATA.pid] rmpr0: - mov esi,[0x2d0000] + mov esi,[RESERVED_PORTS] cmp esi,0 je rmpr9 @@ -936,7 +756,7 @@ terminate: ; terminate application mov edi,esi shl edi,4 - add edi,0x2d0000 + add edi,RESERVED_PORTS cmp edx,[edi] je rmpr4 @@ -957,7 +777,7 @@ terminate: ; terminate application cld rep movsb - dec dword [0x2d0000] + dec dword [RESERVED_PORTS] jmp rmpr0 @@ -966,12 +786,12 @@ terminate: ; terminate application popa mov edi,esi ; do not run this process slot shl edi, 5 - mov [edi+0x3000 + TASKDATA.state],byte 9 + mov [edi+CURRENT_TASK + TASKDATA.state],byte 9 ; debugger test - terminate all debuggees mov eax, 2 - mov ecx, 0x80000+2*0x100+APPDATA.debugger_slot + mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot .xd0: - cmp eax, [0x3004] + cmp eax, [TASK_COUNT] ja .xd1 cmp dword [ecx], esi jnz @f @@ -998,14 +818,15 @@ terminate: ; terminate application xor esi, esi call redrawscreen - mov [0xfff4],byte 0 ; no mouse background - mov [0xfff5],byte 0 ; draw mouse + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse mov [application_table_status],0 mov esi,process_terminated call sys_msg_board_str - + add esp, 4 ret +restore .slot iglobal boot_sched_1 db 'Building gdt tss pointer',0 diff --git a/kernel/branches/gfx_kernel/core/syscall.inc b/kernel/branches/gfx_kernel/core/syscall.inc index 7e9a5381d..d3da45d84 100644 --- a/kernel/branches/gfx_kernel/core/syscall.inc +++ b/kernel/branches/gfx_kernel/core/syscall.inc @@ -14,16 +14,13 @@ i40: 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 + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp+28] ; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler sti @@ -31,35 +28,108 @@ i40: and edi,0xff call dword [servetable+edi*4] pop eax - cli - +; 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 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSENTER ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; uglobal - save_syscall_count dd 0x0 +times 100 db ? +sysenter_stack: endg -label save_syscall_data dword at 0x5000 +align 32 +SYSENTER_VAR equ 0 +sysenter_entry: + ; Настраиваем стек + cli + push eax + mov eax, [ss:CURRENT_TASK] + shl eax, 8 + mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack] + lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP + mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + sti + ;------------------ + push ds es + pushad + cld + mov ax, word os_data + mov ds, ax + mov es, ax + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + mov edx, [SYSENTER_VAR] ; eip + mov ecx, [SYSENTER_VAR + 4] ; esp + sysexit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSCALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +syscall_entry: + cli + xchg ecx, [esp] + mov [SYSENTER_VAR + 4], esp + mov [ss:sysenter_stack - 4], eax + mov eax, [ss:CURRENT_TASK] + shl eax, 8 + mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack] + lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP + mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + sti + ;------------------ + push ds es + pushad + cld + + mov ax, word os_data + mov ds, ax + mov es, ax + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + mov esp, [SYSENTER_VAR + 4] + xchg ecx, [esp] + sysret iglobal ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SYSTEM FUNCTIONS TABLE ;; @@ -87,7 +157,7 @@ iglobal dd sys_cachetodiskette ; 16-FlushFloppyCache dd sys_getbutton ; 17-GetButton dd sys_system ; 18-System Services - dd syscall_startapp ; 19-StartApp + dd paleholder;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 @@ -95,16 +165,13 @@ iglobal 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 undefined_syscall ; 27-reserved 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) @@ -127,20 +194,19 @@ iglobal 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 ; 56-reserved 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 undefined_syscall ; 59-reserved + dd 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 syscall_putimage_palette; 65-PutImagePalette 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 new_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 diff --git a/kernel/branches/gfx_kernel/core/taskman.inc b/kernel/branches/gfx_kernel/core/taskman.inc new file mode 100644 index 000000000..3d05099a8 --- /dev/null +++ b/kernel/branches/gfx_kernel/core/taskman.inc @@ -0,0 +1,1131 @@ +GREEDY_KERNEL equ 0 + + +struc APP_HEADER_00 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .i_param dd ? ;+24 +} + +struc APP_HEADER_01 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .stack_top dd ? ;+24 + .i_param dd ? ;+28 + .i_icon dd ? ;+32 +} + +struc TSS +{ + ._back rw 2 + ._esp0 rd 1 + ._ss0 rw 2 + ._esp1 rd 1 + ._ss1 rw 2 + ._esp2 rd 1 + ._ss2 rw 2 + ._cr3 rd 1 + ._eip rd 1 + ._eflags rd 1 + ._eax rd 1 + ._ecx rd 1 + ._edx rd 1 + ._ebx rd 1 + ._esp rd 1 + ._ebp rd 1 + ._esi rd 1 + ._edi rd 1 + ._es rw 2 + ._cs rw 2 + ._ss rw 2 + ._ds rw 2 + ._fs rw 2 + ._gs rw 2 + ._ldt rw 2 + ._trap rw 1 + ._io rw 1 +} + +virtual at 0 + TSS TSS +end virtual + +struc APP_PARAMS +{ .app_cmdline ;0x00 + .app_path ;0x04 + .app_eip ;0x08 + .app_esp ;0x0C + .app_mem ;0x10 +} + +macro _clear_ op +{ mov ecx, op/4 + xor eax, eax + cld + rep stosd +} + + +align 4 +proc fs_execute + +;fn_read:dword, file_size:dword, cluster:dword + +; ebx - cmdline +; edx - flags +; ebp - full filename +; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it + + locals + cmdline rd 64 ;256/4 + filename rd 256 ;1024/4 + flags dd ? + + save_cr3 dd ? + slot dd ? + slot_base dd ? + file_base dd ? + file_size dd ? + ;app header data + hdr_cmdline dd ? ;0x00 + hdr_path dd ? ;0x04 + hdr_eip dd ? ;0x08 + hdr_esp dd ? ;0x0C + hdr_mem dd ? ;0x10 + hdr_i_end dd ? ;0x14 + endl + + pushad + + mov [cmdline], ebx + mov [flags], edx + +; [ebp] pointer to filename + + lea eax, [filename] + mov dword [eax+1020],0 ;force terminate + ;string + stdcall k_strncpy, eax, [ebp], 1023 + + lea eax, [cmdline] + mov dword [eax+252], 0 + stdcall k_strncpy, eax, [cmdline], 255 + + lea eax, [filename] + stdcall load_file, eax + mov ecx, -ERROR_FILE_NOT_FOUND + test eax, eax + jz .err_file + + mov [file_base], eax + mov [file_size], ebx + + lea ebx, [hdr_cmdline] + call test_app_header + mov ecx, -0x1F + test eax, eax + jz .err_hdr + + mov esi, new_process_loading + call sys_msg_board_str ; write message to message board + +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + +; pushfd +; cli + + call set_application_table_status + + call get_new_process_place + test eax, eax + mov ecx, -0x20 ; too many processes + jz .err + + mov [slot], eax + shl eax, 8 + add eax, SLOT_BASE + mov [slot_base], eax + mov edi, eax + _clear_ 256 ;clean extended information about process + +; write application name + lea edi, [filename] + mov al, '/' + call k_strrchr ; now eax points to name without path + + lea esi, [eax+1] + test eax, eax + jnz @F + lea esi, [filename] +@@: + mov ecx, 8 ; 8 chars for name + mov edi, [slot_base] +.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 ebx, cr3 + mov [save_cr3], ebx + + stdcall create_app_space,[hdr_mem],[file_base],[file_size] + mov ecx, -30 ; no memory + test eax, eax + jz .failed + + mov ebx,[slot_base] + mov [ebx+APPDATA.dir_table],eax + mov eax,[hdr_mem] + mov [ebx+APPDATA.mem_size],eax + +if GREEDY_KERNEL +else + mov ecx, [hdr_mem] + mov edi, [file_size] + add edi, 4095 + and edi, not 4095 + sub ecx, edi + jna @F + + xor eax, eax + add edi, new_app_base + cld + rep stosb +@@: +end if + +; release only virtual space, not phisical memory + + stdcall free_kernel_space, [file_base] + lea eax, [hdr_cmdline] + lea ebx, [cmdline] + lea ecx, [filename] + stdcall set_app_params ,[slot],eax,ebx,ecx,[flags] + + mov eax, [save_cr3] + call set_cr3 + + ; popfd + xor ebx, ebx + mov [application_table_status],ebx ;unlock application_table_status mutex + mov eax,[process_number] ;set result + ret +.failed: + mov eax, [save_cr3] + call set_cr3 +.err: + ; popfd +.err_hdr: + stdcall kernel_free,[file_base] +.err_file: + xor eax, eax + mov [application_table_status],eax + mov eax, ecx + ret +endp + +align 4 +test_app_header: + virtual at eax + APP_HEADER_00 APP_HEADER_00 + end virtual + virtual at eax + APP_HEADER_01 APP_HEADER_01 + end virtual + + cmp dword [eax], 'MENU' + jne .fail + cmp word [eax+4],'ET' + jne .fail + + cmp [eax+6], word '00' + jne .check_01_header + + mov ecx,[APP_HEADER_00.start] + mov [ebx+0x08], ecx ;app_eip + mov edx,[APP_HEADER_00.mem_size] + mov [ebx+0x10], edx ;app_mem + shr edx,1 + sub edx,0x10 + mov [ebx+0x0C], edx ;app_esp + mov ecx,[APP_HEADER_00.i_param] + mov [ebx], ecx ;app_cmdline + mov [ebx+4], dword 0 ;app_path + mov edx, [APP_HEADER_00.i_end] + mov [ebx+0x14], edx + ret + + .check_01_header: + + cmp [eax+6],word '01' + jne .fail + + mov ecx,[APP_HEADER_01.start] + mov [ebx+0x08], ecx ;app_eip + mov edx,[APP_HEADER_01.mem_size] + +; \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 edx,[APP_HEADER_01.i_end] + jb .fail +; \end{diamond}[20.08.2006] + + mov [ebx+0x10], edx ;app_mem + mov ecx,[APP_HEADER_01.stack_top] + mov [ebx+0x0C], ecx ;app_esp + mov edx,[APP_HEADER_01.i_param] + mov [ebx], edx ;app_cmdline + mov ecx,[APP_HEADER_01.i_icon] + mov [ebx+4], ecx ;app_path + mov edx, [APP_HEADER_01.i_end] + mov [ebx+0x14], edx + ret +.fail: + xor eax, eax + ret + +align 4 +proc get_new_process_place +;input: +; none +;result: +; eax=[new_process_place]<>0 - ok +; 0 - failed. +;This function find least empty slot. +;It doesn't increase [TASK_COUNT]! + mov eax,CURRENT_TASK + mov ebx,[TASK_COUNT] + 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+0xa],9 ;check process state, 9 means that process slot is empty + jnz .newprocessplace +.endnewprocessplace: + mov ebx,eax + sub eax,CURRENT_TASK + shr eax,5 ;calculate slot index + cmp eax,256 + jge .failed ;it should be <256 + mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) + ; mov [new_process_place], eax + ret + +.failed: + xor eax,eax + ret +endp + +align 4 +proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword + locals + app_pages dd ? + img_pages dd ? + dir_addr dd ? + app_tabs dd ? + endl + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + xor eax, eax + mov [dir_addr], eax + + mov eax, [app_size] + add eax, 4095 + and eax, NOT(4095) + mov [app_size], eax + mov ebx, eax + shr eax, 12 + mov [app_pages], eax + + add ebx, 0x3FFFFF + and ebx, NOT(0x3FFFFF) + shr ebx, 22 + mov [app_tabs], ebx + + mov ecx, [img_size] + add ecx, 4095 + and ecx, NOT(4095) + + mov [img_size], ecx + shr ecx, 12 + mov [img_pages], ecx + + if GREEDY_KERNEL + lea eax, [ecx+ebx+2] ;only image size + else + lea eax, [eax+ebx+2] ;all requested memory + end if + cmp eax, [pg_data.pages_free] + ja .fail + + call alloc_page + test eax, eax + jz .fail + mov [dir_addr], eax + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW + + mov esi, sys_pgdir + mov edi, [tmp_task_pdir] + mov ecx, (page_tabs shr 20)/4 + cld + rep movsd + + mov eax, [dir_addr] + or eax, PG_SW + stosd ; [(page_tabs shr 20)]= eax + + mov ecx, 0x800/4 + xor eax, eax + rep stosd + + mov eax, [dir_addr] + call set_cr3 + + mov edx, [app_tabs] + mov edi, new_app_base +@@: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page_table, edi, eax + add edi, 0x00400000 + dec edx + jnz @B + + mov edi, new_app_base + shr edi, 10 + add edi, page_tabs + + mov ecx, [app_tabs] + shl ecx, 10 + xor eax, eax + rep stosd + + mov ecx, [img_pages] + mov ebx, PG_UW + mov edx, new_app_base + mov esi, [img_base] + mov edi, new_app_base + shr esi, 10 + shr edi, 10 + add esi, page_tabs + add edi, page_tabs +.remap: + lodsd + or eax, ebx ; force user level r/w access + stosd + add edx, 0x1000 + dec [app_pages] + dec ecx + jnz .remap + + mov ecx, [app_pages] + test ecx, ecx + jz .done + +if GREEDY_KERNEL + mov eax, 0x02 +.reserve: + stosd + invlpg [edx] + add edx, 4096 + dec ecx + jnz .reserve +else + +.alloc: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page,edx,eax,dword PG_UW + add edx, 0x1000 + dec [app_pages] + jnz .alloc + +end if + +.done: + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + + dec [pg_data.pg_mutex] + mov eax, [dir_addr] + ret +.fail: + dec [pg_data.pg_mutex] + cmp [dir_addr], 0 + je @f + stdcall destroy_app_space, [dir_addr] +@@: + xor eax, eax + ret +endp + +align 4 +set_cr3: + mov esi, [CURRENT_TASK] + mov ebx, esi + shl esi,8 + mov [SLOT_BASE+esi+0xB8],eax + imul ebx,tss_step + add ebx,tss_data + mov [ebx+28], eax + mov cr3, eax + ret + +align 4 +proc destroy_page_table stdcall, pg_tab:dword + + push esi + + mov esi, [pg_tab] + mov ecx, 1024 +.free: + mov eax, [esi] + test eax, 1 + jz .next + call free_page +.next: + add esi, 4 + dec ecx + jnz .free + pop esi + ret +endp + +align 4 +proc destroy_app_space stdcall, pg_dir:dword + + mov ebx, pg_data.pg_mutex + call wait_mutex ;ebx + + xor edx,edx + mov eax,0x2 + mov ebx, [pg_dir] + +.loop: +;eax = current slot of process + mov ecx,eax + shl ecx,5 + cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running? + jz @f ;skip empty slots + shl ecx,3 + cmp [SLOT_BASE+ecx+0xB8],ebx ;compare page directory addresses + jnz @f + inc edx ;thread found +@@: + inc eax + cmp eax,[TASK_COUNT] ;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 .exit +;if there isn't threads then clear memory. + + mov eax, [pg_dir] + and eax, not 0xFFF + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW + mov esi, [tmp_task_pdir] + add esi, 0x800 + mov edi, 0x800/4 +.destroy: + mov eax, [esi] + test eax, 1 + jz .next + and eax, not 0xFFF + stdcall map_page,[tmp_task_ptab],eax,dword PG_SW + stdcall destroy_page_table, [tmp_task_ptab] + mov eax, [esi] + call free_page +.next: + add esi, 4 + dec edi + jnz .destroy + + mov eax, [pg_dir] + call free_page +.exit: + stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + dec [pg_data.pg_mutex] + ret +endp + +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,[TASK_COUNT] + shl ebx,5 + mov ecx,2*32 + +.loop: +;ecx=offset of current process info entry +;ebx=maximum permitted offset + cmp byte [CURRENT_TASK+ecx+0xa],9 + jz .endloop ;skip empty slots + cmp [CURRENT_TASK+ecx+0x4],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 + +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,[CURRENT_TASK] + 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 [CURRENT_TASK+eax+0xa],0 + jnz .failed + shl eax,3 + mov eax,[SLOT_BASE+eax+0xb8] + test eax,eax + jz .failed + + mov eax,1 + ret + + +; 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 + +align 4 +proc 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. + locals + slot dd ? + buff dd ? + r_count dd ? + offset dd ? + tmp_r_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + mov [r_count], ecx + mov [tmp_r_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_r_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov eax, [slot] + shl eax,8 + mov ebx, [offset] + add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [SLOT_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov esi, [offset] + and esi, 0xfff + add esi, [proc_mem_map] + mov edi, [buff] + mov edx, ecx + rep movsb + + add [offset], edx + sub [tmp_r_cnt], edx + jnz .read_mem + + popad + mov eax, [r_count] + ret +endp + +align 4 +proc 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 + + locals + slot dd ? + buff dd ? + w_count dd ? + offset dd ? + tmp_w_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + mov [w_count], ecx + mov [tmp_w_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_w_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov eax, [slot] + shl eax,8 + mov ebx, [offset] + add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [SLOT_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov edi, [offset] + and edi, 0xfff + add edi, [proc_mem_map] + mov esi, [buff] + mov edx, ecx + rep movsb + + add [offset], edx + sub [tmp_w_cnt], edx + jnz .read_mem + + popad + mov eax, [w_count] + ret +endp + +align 4 +proc new_sys_threads + locals + slot dd ? + app_cmdline dd ? ;0x00 + app_path dd ? ;0x04 + app_eip dd ? ;0x08 + app_esp dd ? ;0x0C + app_mem dd ? ;0x10 + endl + + cmp eax,1 + jne .failed ;other subfunctions + + xor eax,eax + mov [app_cmdline], eax + mov [app_path], eax + mov [app_eip], ebx + mov [app_esp], ecx + + mov esi,new_process_loading + call sys_msg_board_str +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + + call set_application_table_status + + call get_new_process_place + test eax, eax + jz .failed + + mov [slot], eax + + mov esi,[CURRENT_TASK] + shl esi,8 + add esi,SLOT_BASE + mov ebx,esi ;ebx=esi - pointer to extended information about current thread + + mov edi, eax + shl edi,8 + add edi,SLOT_BASE + mov edx,edi ;edx=edi - pointer to extended infomation about new thread + mov ecx,256/4 + xor eax, eax + cld + rep stosd ;clean extended information about new thread + mov esi,ebx + mov edi,edx + mov ecx,11 + rep movsb ;copy process name + + mov eax,[ebx+APPDATA.heap_base] + mov [edx+APPDATA.heap_base], eax + + mov ecx,[ebx+APPDATA.heap_top] + mov [edx+APPDATA.heap_top], ecx + + mov eax,[ebx+APPDATA.mem_size] + mov [edx+APPDATA.mem_size], eax + + mov ecx,[ebx+APPDATA.dir_table] + mov [edx+APPDATA.dir_table],ecx ;copy page directory + + lea eax, [app_cmdline] + stdcall set_app_params ,[slot],eax,dword 0,\ + dword 0,dword 0 + + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + + mov [application_table_status],0 ;unlock application_table_status mutex + mov eax,[process_number] ;set result + ret +.failed: + mov [application_table_status],0 + mov eax,-1 + ret +endp + +; param +; ebx=mutex + +align 4 +wait_mutex: + push eax + push ebx +.do_wait: + cmp dword [ebx],0 + je .get_lock + call change_task + jmp .do_wait +.get_lock: + mov eax, 1 + xchg eax, [ebx] + test eax, eax + jnz .do_wait + pop ebx + pop eax + ret + +align 4 +proc set_app_params stdcall,slot:dword, params:dword,\ + cmd_line:dword, app_path:dword, flags:dword + + locals + pl0_stack dd ? + endl + + stdcall kernel_alloc, 0x2000 + mov [pl0_stack], eax + + lea edi, [eax+0x2000-512] + + mov eax, [slot] + mov ebx, eax + + shl eax, 8 + mov [eax+SLOT_BASE+APPDATA.fpu_state], edi + mov [eax+SLOT_BASE+APPDATA.fpu_handler], 0 + mov [eax+SLOT_BASE+APPDATA.sse_handler], 0 + + mov esi, fpu_data + mov ecx, 512/4 + rep movsd + + cmp ebx,[TASK_COUNT] + jle .noinc + inc dword [TASK_COUNT] ;update number of processes +.noinc: + shl ebx,8 + lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET] + mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx + mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx + + add edx, APP_OBJ_OFFSET-APP_EV_OFFSET + mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx + mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx + + mov ecx, [def_cursor] + mov [SLOT_BASE+APPDATA.cursor+ebx],ecx + mov eax, [pl0_stack] + mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax + + shr ebx,3 + mov eax, new_app_base + mov dword [CURRENT_TASK+ebx+0x10],eax + +.add_command_line: + mov edx,[params] + mov edx,[edx] ;app_cmdline + test edx,edx + jz @F ;application don't need parameters + + mov eax, edx + add eax, 256 + jc @f + + cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] + ja @f + + add edx, new_app_base + stdcall k_strncpy, edx, [cmd_line], 256 +@@: + mov edx,[params] + mov edx, [edx+4] ;app_path + test edx,edx + jz @F ;application don't need path of file + mov eax, edx + add eax, 1024 + jc @f + cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] + ja @f + add edx, new_app_base + stdcall k_strncpy, edx, [app_path], 1024 +@@: + mov ebx,[slot] + mov eax,ebx + shl ebx,5 +; set window state to 'normal' (non-minimized/maximized/rolled-up) state + mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL + mov [ebx+window_data+WDATA.fl_redraw], 1 + add ebx,CURRENT_TASK ;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+4],eax ;set PID + + mov ecx,ebx + add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data +;set draw data to full screen + + mov [ecx+0],dword 0 + mov [ecx+4],dword 0 + mov eax,[ScreenWidth] + mov [ecx+8],eax + mov eax,[ScreenHeight] + mov [ecx+12],eax + + mov edi,[slot] + imul edi,tss_step + add edi,tss_data + mov ecx,128/4 + xor eax, eax + cld + rep stosd +;Add IO access table - bit array of permitted ports + not eax + mov ecx,2048 + rep stosd ; access to 4096*8=65536 ports + sub edi, tss_step + +;set cr3 register in TSS of application + mov ecx, [slot] + shl ecx, 8 + mov eax,[SLOT_BASE+ecx+APPDATA.dir_table] + mov [edi+TSS._cr3],eax + + mov esi,[params] + mov eax, [esi+0x08] ;app_eip + mov [edi+TSS._eip],eax ;set eip in TSS + mov eax, [esi+0x0C] ;app_esp + mov [edi+TSS._esp],eax ;set stack in TSS + mov [edi+TSS._eflags],dword 0x1202 + + mov [edi+TSS._cs],app_code ;selector of code segment + mov [edi+TSS._ss],app_data + mov [edi+TSS._ds],app_data + mov [edi+TSS._es],app_data + mov [edi+TSS._fs],app_data + mov [edi+TSS._gs],graph_data ;selector of graphic segment + mov [edi+TSS._io],word 128 + mov [edi+TSS._ss0], os_data + mov ebx, [pl0_stack] + add ebx, 0x2000-512 + mov [edi+TSS._esp0],ebx + + mov ecx, edi ;ecx - address of application TSS + mov ebx,[slot] + shl ebx,3 +;set TSS descriptor + mov [ebx+gdts+tss0+0],word tss_step ;limit (size) + mov [ebx+gdts+tss0+2],cx ;part of offset + shr ecx,16 + mov [ebx+gdts+tss0+4],cl ;part of offset + mov [ebx+gdts+tss0+7],ch ;part of offset + mov [ebx+gdts+tss0+5],word 01010000b*256+11101001b ;system flags + +;flush keyboard and buttons queue + mov [KEY_COUNT],byte 0 + mov [BTN_COUNT],byte 0 + + mov edi,[slot] + shl edi,5 + add edi,window_data + mov ebx,[slot] + movzx esi,word [WIN_STACK+ebx*2] + lea esi,[WIN_POS+esi*2] + call windowactivate ;gui initialization + + mov ebx,[slot] + shl ebx,5 + mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running +; set if debuggee + mov eax, [flags] + test byte [flags], 1 + jz .no_debug + mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended + mov eax,[CURRENT_TASK] + mov [SLOT_BASE+ebx*8+0xac],eax ;set debugger PID - current +.no_debug: + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + ret +endp + + + +include "debug.inc" + +iglobal + new_process_loading db 'K : New Process - loading',13,10,0 + new_process_running db 'K : New Process - done',13,10,0 + start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 +endg + diff --git a/kernel/branches/gfx_kernel/docs/apm/apm.txt b/kernel/branches/gfx_kernel/docs/apm.txt similarity index 100% rename from kernel/branches/gfx_kernel/docs/apm/apm.txt rename to kernel/branches/gfx_kernel/docs/apm.txt diff --git a/kernel/branches/gfx_kernel/docs/apm/README.TXT b/kernel/branches/gfx_kernel/docs/apm/README.TXT deleted file mode 100644 index 635126560..000000000 --- a/kernel/branches/gfx_kernel/docs/apm/README.TXT +++ /dev/null @@ -1,255 +0,0 @@ -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/branches/gfx_kernel/drivers/ati2d.asm b/kernel/branches/gfx_kernel/drivers/ati2d.asm new file mode 100644 index 000000000..73ce044d7 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/ati2d.asm @@ -0,0 +1,1008 @@ + +format MS COFF + +include 'proc32.inc' +include 'imports.inc' + +DEBUG equ 1 + +VID_ATI equ 0x1002 + +LOAD_FROM_FILE equ 0 +LOAD_FROM_MEM equ 1 +LOAD_INDIRECT equ 2 +LOAD_SYSTEM equ 3 + +VIDEO_FREE equ 2 + +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 +} + +virtual at 0 + BI BITMAPINFOHEADER +end virtual + +struc CURSOR +{;common object header + .magic dd ? ;'CURS' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + ;cursor data + .base dd ? ;allocated memory + .hot_x dd ? ;hotspot coords + .hot_y dd ? +} +virtual at 0 + CURSOR CURSOR +end virtual + +CURSOR_SIZE equ 32 + +R8500 equ 0x514C ;R200 +R9000 equ 0x4966 ;RV250 +R9200 equ 0x5961 ;RV280 +R9500 equ 0x4144 ;R300 +R9500P equ 0x4E45 ;R300 +R9550 equ 0x4153 ;RV350 +R9600 equ 0x4150 ;RV350 +R9600XT equ 0x4152 ;RV360 +R9700P equ 0x4E44 ;R300 +R9800 equ 0x4E49 ;R350 +R9800P equ 0x4E48 ;R350 +R9800XT equ 0x4E4A ;R360 + +OS_BASE equ 0 +new_app_base equ 0x80000000 +SLOT_BASE equ 0x0080000 + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +;MMIO equ 0F9000000h +RD_RB3D_CNTL equ 1c3ch + +RD_MEM_CNTL equ 0140h +RD_CRTC_GEN_CNTL equ 0050h +RD_CRTC_CUR_EN equ 10000h +RD_DISPLAY_BASE_ADDR equ 023ch +RD_DEFAULT_OFFSET equ 16e0h +CUR_HORZ_VERT_OFF equ 0268h +CUR_HORZ_VERT_POSN equ 0264h +CUR_OFFSET equ 0260h +RD_RB3D_CNTL equ 1c3ch +RD_RBBM_STATUS equ 0e40h +RD_RBBM_FIFOCNT_MASK equ 007fh +RD_RBBM_ACTIVE equ 80000000h +RD_TIMEOUT equ 2000000 + +RD_DP_GUI_MASTER_CNTL equ 0146ch +RD_DP_BRUSH_BKGD_CLR equ 01478h +RD_DP_BRUSH_FRGD_CLR equ 0147ch +RD_DP_SRC_BKGD_CLR equ 015dch +RD_DP_SRC_FRGD_CLR equ 015d8h +RD_DP_CNTL equ 016c0h +RD_DP_DATATYPE equ 016c4h +RD_DP_WRITE_MASK equ 016cch +RD_DP_SRC_SOURCE_MEMORY equ (2 shl 24) +RD_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24) +RD_DEFAULT_SC_BOTTOM_RIGHT equ 16e8h +RD_GMC_BRUSH_SOLID_COLOR equ (13 shl 4) +RD_DEFAULT_SC_RIGHT_MAX equ 1fffh +RD_DEFAULT_SC_BOTTOM_MAX equ 1fff0000h +RD_GMC_DST_DATATYPE_SHIFT equ 8 + +RD_ROP3_S equ 00cc0000h +RD_ROP3_P equ 00f00000h + +RD_RB2D_DSTCACHE_MODE equ 03428h +RD_RB2D_DSTCACHE_CTLSTAT equ 0342ch +RD_RB2D_DC_FLUSH_ALL equ 000fh +RD_RB2D_DC_BUSY equ 80000000h + +RD_GMC_BRUSH_SOLID_COLOR equ 000000D0h +RD_GMC_SRC_DATATYPE_COLOR equ (3 shl 12) +RD_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28) +RD_GMC_WR_MSK_DIS equ (1 shl 30) + +cmdSolidFill equ 73f036d0h + +RD_DST_PITCH_OFFSET equ 142ch +RD_SRC_PITCH_OFFSET equ 1428h + +RD_DST_X_LEFT_TO_RIGHT equ 1 +RD_DST_Y_TOP_TO_BOTTOM equ 2 +RD_DST_Y_X equ 1438h +RD_DST_WIDTH_HEIGHT equ 1598h +RD_DST_LINE_START equ 1600h +RD_DST_LINE_END equ 1604h +R300_MEM_NUM_CHANNELS_MASK equ 0003h + +macro rdr op1, op2 +{ + mov edi, [ati_io] + mov op1, [edi+op2] +} + +macro wrr dest, src +{ + mov edi, [ati_io] + mov dword [edi+dest], src +} + + +public START +public service_proc +public version + +CURSOR_IMAGE_OFFSET equ 0x00500000 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_ati + test eax, eax + jz .fail + + call init_ati + test eax, eax + jz .fail + + or eax, -1 + mov [cursor_map], eax + mov [cursor_map+4], eax + mov edx, cursor_map + mov [cursor_start], edx + add edx, 8 + mov [cursor_end], edx + + stdcall RegService, sz_ati_srv, service_proc + test eax, eax + jz .fail + mov dword [SetHwCursor], drvCursorPos ;enable hardware cursor + mov dword [HwCursorRestore], drv_restore + mov dword [HwCursorCreate], ati_cursor + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + +.exit: + xor eax, eax +; mov ebx, SetHwCursor +; mov dword [ebx], eax ;force disable hardware cursor + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov ebx, [edi+io_code] + cmp ebx, VIDEO_FREE + jne .fail + + mov eax, [edi+input] + call video_free +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc detect_ati + locals + last_bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 4 + jmp @B + +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc init_ati + + stdcall AllocKernelSpace, dword 0x10000 + test eax, eax + jz .fail + + mov [ati_io], eax + + stdcall PciRead32, [bus], [devfn], dword 0x18 + and eax, 0xFFFF0000 + mov esi, eax + + mov edi, [ati_io] + mov edx, 16 +@@: + stdcall MapPage,edi,esi,PG_SW+PG_NOCACHE + add edi, 0x1000 + add esi, 0x1000 + dec edx + jnz @B + + mov edi, [ati_io] + mov dword [edi+RD_RB3D_CNTL], 0 + call engRestore + + mov edi, [ati_io] + mov eax, [edi+0x50] + mov ebx,3 + shl ebx,20 + not ebx + and eax,ebx + mov ebx, 2 + shl ebx,20 + or eax, ebx + mov [edi+0x50], eax + + call drvShowCursor + xor eax, eax + inc eax +.fail: + ret +endp + +align 4 +drv_restore: + ret 8 + +align 4 +drvShowCursor: + mov edi, [ati_io] + + mov eax, [edi+RD_CRTC_GEN_CNTL] + bts eax,16 + mov [edi+RD_CRTC_GEN_CNTL], eax + ret + +align 4 +proc drvCursorPos stdcall, hcursor:dword, x:dword, y:dword + pushfd + cli + + xor eax, eax + xor edx, edx + mov esi, [hcursor] + mov ebx, [x] + mov ecx, [y] + + sub ebx, [esi+CURSOR.hot_x] + jnc @F + neg ebx + mov eax, ebx + shl eax, 16 + xor ebx, ebx +@@: + sub ecx, [esi+CURSOR.hot_y] + jnc @F + neg ecx + mov ax, cx + mov edx, ecx + xor ecx, ecx +@@: + or eax, 0x80000000 + wrr CUR_HORZ_VERT_OFF, eax + + shl ebx, 16 + mov bx, cx + or ebx, 0x80000000 + wrr CUR_HORZ_VERT_POSN, ebx + + shl edx, 8 + add edx, [esi+CURSOR.base] + sub edx, LFBAddress + wrr CUR_OFFSET, edx + popfd + ret +endp + +align 4 +proc video_alloc + + pushfd + cli + mov ebx, [cursor_start] + mov ecx, [cursor_end] +.l1: + bsf eax,[ebx]; + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + popfd + + mov [cursor_start],ebx + sub ebx, cursor_map + lea eax,[eax+ebx*8] + + shl eax,14 + add eax, LFBAddress+CURSOR_IMAGE_OFFSET + ret +endp + +align 4 +video_free: + pushfd + cli + sub eax, LFBAddress+CURSOR_IMAGE_OFFSET + shr eax, 14 + mov ebx, cursor_map + bts [ebx], eax + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [cursor_start], eax + ja @f + popfd + ret +@@: + mov [cursor_start], eax + popfd + ret + +; param +; eax= pid +; ebx= src +; ecx= flags + +align 4 +ati_cursor: +.src equ esp +.flags equ esp+4 +.hcursor equ esp+8 + + sub esp, 4 ;space for .hcursor + push ecx + push ebx + + mov ebx, eax + mov eax, CURSOR_SIZE + call CreateObject + test eax, eax + jz .fail + + mov [.hcursor],eax + + xor ebx, ebx + mov [eax+CURSOR.magic], 'CURS' + mov [eax+CURSOR.destroy], destroy_cursor + mov [eax+CURSOR.hot_x], ebx + mov [eax+CURSOR.hot_y], ebx + + call video_alloc + mov edi, [.hcursor] + mov [edi+CURSOR.base], eax + + mov esi, [.src] + mov ebx, [.flags] + cmp bx, LOAD_INDIRECT + je .indirect + + movzx ecx, word [esi+10] + movzx edx, word [esi+12] + mov [edi+CURSOR.hot_x], ecx + mov [edi+CURSOR.hot_y], edx + + stdcall ati_init_cursor, eax, esi + mov eax, [.hcursor] +.fail: + add esp, 12 + ret +.indirect: + shr ebx, 16 + movzx ecx, bh + movzx edx, bl + mov [edi+CURSOR.hot_x], ecx + mov [edi+CURSOR.hot_y], edx + + mov edi, eax + mov ebx, eax + mov ecx, 64*64 + xor eax,eax + cld + rep stosd + mov edi, ebx + + mov esi, [.src] + mov ebx, 32 + cld +@@: + mov ecx, 32 + rep movsd + add edi, 128 + dec ebx + jnz @B + mov eax, [.hcursor] + add esp, 12 + ret + +align 4 +destroy_cursor: + + push eax + mov eax, [eax+CURSOR.base] + call video_free + pop eax + + call DestroyObject + ret + +align 4 +proc ati_init_cursor stdcall, dst:dword, src:dword + locals + rBase dd ? + pQuad dd ? + pBits dd ? + pAnd dd ? + width dd ? + height dd ? + counter dd ? + endl + + mov esi, [src] + add esi,[esi+18] + mov eax,esi + + cmp [esi+BI.biBitCount], 24 + je .img_24 + cmp [esi+BI.biBitCount], 8 + je .img_8 + cmp [esi+BI.biBitCount], 4 + je .img_4 + +.img_2: + add eax, [esi] + mov [pQuad],eax + add eax,8 + mov [pBits],eax + add eax, 128 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, pCursor + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] +.l21: + mov ebx, [pBits] + mov ebx, [ebx] + bswap ebx + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + xor ecx, ecx + shl ebx,1 + setc cl + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + add edi, 4 + dec [counter] + jnz @B + + add [pBits], 4 + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l21 + jmp .copy +.img_4: + add eax, [esi] + mov [pQuad],eax + add eax,64 + mov [pBits],eax + add eax, 0x200 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, pCursor + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] + mov ebx, [pBits] +.l4: + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 16 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + and cl, 0xF0 + shr ecx, 2 + mov ecx, [esi+ecx] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + and cl, 0x0F + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi+4], edx + + inc ebx + add edi, 8 + dec [counter] + jnz @B + + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l4 + jmp .copy +.img_8: + add eax, [esi] + mov [pQuad],eax + add eax,1024 + mov [pBits],eax + add eax, 1024 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, pCursor + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] + mov ebx, [pBits] +.l81: + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + inc ebx + add edi, 4 + dec [counter] + jnz @B + + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l81 + jmp .copy +.img_24: + add eax, [esi] + mov [pQuad],eax + add eax, 0xC00 + mov [pAnd],eax + mov eax,[esi+BI.biWidth] + mov [width],eax + mov ebx,[esi+BI.biHeight] + shr ebx,1 + mov [height],ebx + + mov edi, pCursor + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pAnd] + mov ebx, [pQuad] +.row_24: + mov eax, [esi] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + mov ecx, [ebx] + and ecx, 0x00FFFFFF + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + add ebx, 3 + add edi, 4 + dec [counter] + jnz @B + + add esi, 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .row_24 +.copy: + mov edi, [dst] + mov ecx, 64*64 + xor eax,eax + rep stosd + + mov esi, pCursor + mov edi, [dst] + mov ebx, 32 + cld +@@: + mov ecx, 32 + rep movsd + add edi, 128 + dec ebx + jnz @B + ret +endp + +align 4 +proc engFlush + + mov edi, [ati_io] + + mov eax, [edi+RD_RB2D_DSTCACHE_CTLSTAT] + or eax,RD_RB2D_DC_FLUSH_ALL + mov [edi+RD_RB2D_DSTCACHE_CTLSTAT],eax + + mov ecx, RD_TIMEOUT +@@: + mov eax,[edi+RD_RB2D_DSTCACHE_CTLSTAT] + and eax, RD_RB2D_DC_BUSY + jz .exit + + sub ecx,1 + jnz @B +.exit: + ret +endp + +align 4 +engWaitForFifo: +cnt equ bp+8 + push ebp + mov ebp, esp + + mov edi, [ati_io] + + mov ecx, RD_TIMEOUT +@@: + mov eax, [edi+RD_RBBM_STATUS] + and eax, RD_RBBM_FIFOCNT_MASK + cmp eax, [ebp+8] + jae .exit + + sub ecx,1 + jmp @B + +.exit: + leave + ret 4 + +align 4 +proc engWaitForIdle + + push dword 64 + call engWaitForFifo + + mov edi, [ati_io] + mov ecx ,RD_TIMEOUT +@@: + mov eax, [edi+RD_RBBM_STATUS] + and eax,RD_RBBM_ACTIVE + jz .exit + + sub ecx,1 + jnz @B +.exit: + call engFlush + ret +endp + +align 4 +proc engRestore + +; push dword 1 +; call engWaitForFifo + +; mov dword [MMIO+RD_RB2D_DSTCACHE_MODE], 0 + + push dword 3 + call engWaitForFifo + + mov edi, [ati_io] + + mov eax, [edi+RD_DISPLAY_BASE_ADDR] + shr eax, 10d + or eax,(64d shl 22d) + mov [edi+RD_DEFAULT_OFFSET],eax + mov [edi+RD_SRC_PITCH_OFFSET],eax + mov [edi+RD_DST_PITCH_OFFSET],eax + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov eax, [edi+RD_DP_DATATYPE] + btr eax, 29d + mov [edi+RD_DP_DATATYPE],eax + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov dword [edi+RD_DEFAULT_SC_BOTTOM_RIGHT],\ + (RD_DEFAULT_SC_RIGHT_MAX or RD_DEFAULT_SC_BOTTOM_MAX) + + push dword 1 + call engWaitForFifo + + mov edi, [ati_io] + mov dword [edi+RD_DP_GUI_MASTER_CNTL],\ + (RD_GMC_BRUSH_SOLID_COLOR or \ + RD_GMC_SRC_DATATYPE_COLOR or \ + (6 shl RD_GMC_DST_DATATYPE_SHIFT) or \ + RD_GMC_CLR_CMP_CNTL_DIS or \ + RD_ROP3_P or \ + RD_GMC_WR_MSK_DIS) + + + push dword 7 + call engWaitForFifo + + mov edi, [ati_io] + + mov dword [edi+RD_DST_LINE_START],0 + mov dword [edi+RD_DST_LINE_END], 0 + mov dword [edi+RD_DP_BRUSH_FRGD_CLR], 808000ffh + mov dword [edi+RD_DP_BRUSH_BKGD_CLR], 002020ffh + mov dword [edi+RD_DP_SRC_FRGD_CLR], 808000ffh + mov dword [edi+RD_DP_SRC_BKGD_CLR], 004000ffh + mov dword [edi+RD_DP_WRITE_MASK],0ffffffffh + + call engWaitForIdle + + ret +endp + +align 4 +engSetupSolidFill: + push ebp + mov ebp, esp + + push dword 3 + call engWaitForFifo + + wrr RD_DP_GUI_MASTER_CNTL, cmdSolidFill + + mov eax, [ebp+8] + wrr RD_DP_BRUSH_FRGD_CLR,eax + + mov edi, [ati_io] + mov dword [edi+RD_DP_CNTL],(RD_DST_X_LEFT_TO_RIGHT or RD_DST_Y_TOP_TO_BOTTOM) + leave + ret 4 + + +align 4 +drvSolidFill: +;x:word,y:word,w:word,h:word,color:dword + push ebp + mov ebp, esp +x equ ebp+8 +y equ ebp+12 +w equ ebp+16 +h equ ebp+20 +color equ ebp+24 + + push dword [ebp+24] + call engSetupSolidFill + + push dword 2 + call engWaitForFifo + + mov edi, [ati_io] + + mov eax, [y] + mov ebx, [x] + shl eax,16 + or eax, ebx + + mov ecx, [w] + mov edx, [h] + shl ecx,16 + or ecx, edx + mov [edi+RD_DST_Y_X], eax + mov [edi+RD_DST_WIDTH_HEIGHT], ecx + call engFlush + leave + ret 20 + +align 4 +devices dd (R8500 shl 16)+VID_ATI + dd (R9000 shl 16)+VID_ATI + dd (R9200 shl 16)+VID_ATI + dd (R9500 shl 16)+VID_ATI + dd (R9500P shl 16)+VID_ATI + dd (R9550 shl 16)+VID_ATI + dd (R9600 shl 16)+VID_ATI + dd (R9600XT shl 16)+VID_ATI + dd (R9700P shl 16)+VID_ATI + dd (R9800 shl 16)+VID_ATI + dd (R9800P shl 16)+VID_ATI + dd (R9800XT shl 16)+VID_ATI + dd 0 ;terminator + +version dd 0x00040004 + +sz_ati_srv db 'HWCURSOR',0 + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgFail db 'device not found',13,10,0 +msg_neg db 'neg ecx',13,10,0 +buff db 8 dup(0) + db 13,10, 0 + +section '.data' data readable writable align 16 + +pCursor db 4096 dup(?) + +cursor_map rd 2 +cursor_start rd 1 +cursor_end rd 1 + +bus dd ? +devfn dd ? +ati_io dd ? + + + diff --git a/kernel/branches/gfx_kernel/drivers/codec.inc b/kernel/branches/gfx_kernel/drivers/codec.inc new file mode 100644 index 000000000..f17cd8e1f --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/codec.inc @@ -0,0 +1,220 @@ + +align 4 +proc detect_codec + locals + codec_id dd ? + endl + + stdcall codec_read, dword 0x7C + shl eax, 16 + mov [codec_id], eax + + stdcall codec_read, dword 0x7E + or eax, [codec_id] + + mov [codec.chip_id], eax + and eax, 0xFFFFFF00 + + mov edi, codecs +@@: + mov ebx, [edi] + test ebx, ebx + jz .unknown + + cmp eax, ebx + jne .next + mov eax, [edi+4] + mov [codec.ac_vendor_ids], eax + stdcall detect_chip, [edi+8] + ret +.next: + add edi, 12 + jmp @B +.unknown: + mov [codec.ac_vendor_ids], ac_unknown + mov [codec.chip_ids], chip_unknown + ret +endp + +align 4 +proc detect_chip stdcall, chip_tab:dword + + mov eax, [codec.chip_id] + and eax, 0xFF + + mov edi, [chip_tab] +@@: + mov ebx, [edi] + test ebx, ebx + jz .unknown + + cmp eax,ebx + jne .next + mov eax, [edi+4] + mov [codec.chip_ids], eax + ret +.next: + add edi, 8 + jmp @b +.unknown: + mov [codec.chip_ids], chip_unknown + ret +endp + +align 4 +proc setup_codec + + xor eax, eax + stdcall codec_write, dword CODEC_AUX_VOL + + mov eax, 0x0B0B + stdcall codec_write, dword CODEC_MASTER_VOL_REG + + mov ax, 0x08 + stdcall codec_write, dword 0x0C + + mov ax, 0x0808 + stdcall codec_write, dword CODEC_PCM_OUT_REG + + mov ax, 0x0808 + stdcall codec_write, dword 0x10 + + mov ax, 0x0808 + stdcall codec_write, dword 0x12 + + mov ax, 0x0808 + stdcall codec_write, dword 0x16 + + + stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG + + and eax, 0FFFFh - BIT1 ; clear DRA (BIT1) + or eax, BIT0 ; set VRA (BIT0) + stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG + + stdcall set_sample_rate, dword 48000 + +.init_error: + + xor eax, eax ; exit with error + ret +endp + + +; param +; eax= volume -10000 - 0 for both channels + +align 4 +set_master_vol: + cmp eax, 0 + jl @F + xor eax, eax + jmp .set +@@: + cmp eax, -9450 + jg .set + mov eax, -9450 ;clamp into 6 bits +.set: + cdq + mov ebx, -150 + idiv ebx + mov ah, al + stdcall codec_write, dword CODEC_MASTER_VOL_REG + xor eax, eax + ret + +align 4 +proc get_master_vol stdcall, pvol:dword + + stdcall codec_read, dword CODEC_MASTER_VOL_REG + and eax, 0x3F + imul eax, -150 + mov ebx, [pvol] + mov [ebx], eax + xor eax, eax + ret +endp + +align 4 +proc set_sample_rate stdcall, rate:dword + mov eax, [rate] + stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG + ret +endp + +align 16 +ac_unknown db 'unknown manufacturer',13,10,0 +ac_Realtek db 'Realtek Semiconductor',13,10,0 +ac_Analog db 'Analog Devices',13,10,0 +ac_CMedia db 'C-Media Electronics',13,10,0 +chip_unknown db 'unknown chip', 13,10,0 + +CHIP_ANALOG equ 0x41445300 +CHIP_REALTEK equ 0x414C4700 +CHIP_CMEDIA equ 0x434D4900 + +align 16 +codecs dd CHIP_ANALOG, ac_Analog, chips_Analog + dd CHIP_CMEDIA, ac_CMedia, chips_CMedia + dd CHIP_REALTEK,ac_Realtek, chips_Realtek + dd 0 + +align 16 +chips_Analog dd 0x03, chip_AD1819 + dd 0x40, chip_AD1881 + dd 0x48, chip_AD1881A + dd 0x60, chip_AD1884 + dd 0x61, chip_AD1886 + dd 0x62, chip_AD1887 + dd 0x63, chip_AD1886A + dd 0x70, chip_AD1980 + dd 0x75, chip_AD1985 + dd 0 + +chips_Realtek dd 0x20, chip_ALC650 + dd 0x21, chip_ALC650D + dd 0x22, chip_ALC650E + dd 0x23, chip_ALC650F + dd 0x60, chip_ALC655 + dd 0x80, chip_ALC658 + dd 0x81, chip_ALC658D + dd 0x90, chip_ALC850 + dd 0 + +chips_CMedia dd 0x41, chip_CM9738 + dd 0x61, chip_CM9739 + dd 0x69, chip_CM9780 + dd 0x78, chip_CM9761 + dd 0x82, chip_CM9761 + dd 0x83, chip_CM9761 + dd 0 + +align 16 +;Analog Devices +chip_AD1819 db 'AD1819 ',0dh,0ah,00h +chip_AD1881 db 'AD1881 ',0dh,0ah,00h +chip_AD1881A db 'AD1881A',0dh,0ah,00h +chip_AD1884 db 'AD1885 ',0dh,0ah,00h +chip_AD1885 db 'AD1885 ',0dh,0ah,00h +chip_AD1886 db 'AD1886 ',0dh,0ah,00h +chip_AD1886A db 'AD1886A',0dh,0ah,00h +chip_AD1887 db 'AD1887 ',0dh,0ah,00h +chip_AD1980 db 'AD1980 ',0dh,0ah,00h +chip_AD1985 db 'AD1985 ',0dh,0ah,00h + +;Realtek +chip_ALC650 db 'ALC650 ',0dh,0ah,00h +chip_ALC650D db 'ALC650D',0dh,0ah,00h +chip_ALC650E db 'ALC650E',0dh,0ah,00h +chip_ALC650F db 'ALC650F',0dh,0ah,00h +chip_ALC655 db 'ALC655 ',0dh,0ah,00h +chip_ALC658 db 'ALC658 ',0dh,0ah,00h +chip_ALC658D db 'ALC658D',0dh,0ah,00h +chip_ALC850 db 'ALC850 ',0dh,0ah,00h + +;CMedia +chip_CM9738 db 'CMI9738', 0dh,0ah,0 +chip_CM9739 db 'CMI9739', 0dh,0ah,0 +chip_CM9780 db 'CMI9780', 0dh,0ah,0 +chip_CM9761 db 'CMI9761', 0dh,0ah,0 + diff --git a/kernel/branches/gfx_kernel/drivers/ensoniq.asm b/kernel/branches/gfx_kernel/drivers/ensoniq.asm new file mode 100644 index 000000000..d2509025a --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/ensoniq.asm @@ -0,0 +1,1381 @@ + +;alpha version + +format MS COFF + + +include 'proc32.inc' + +DEBUG equ 1 + +REMAP_IRQ equ 0 + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010101000b + +IRQ_LINE equ 0 + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_INTEL equ 0x8086 +VID_NVIDIA equ 0x10DE + +CTRL_ICH equ 0x2415 +CTRL_ICH0 equ 0x2425 +CTRL_ICH2 equ 0x2435 +CTRL_ICH3 equ 0x2445 +CTRL_ICH4 equ 0x24C5 +CTRL_ICH5 equ 0x24D5 +CTRL_ICH6 equ 0x266E +CTRL_ICH7 equ 0x27DE + +CTRL_NFORCE equ 0x01B1 +CTRL_NFORCE2 equ 0x006A +CTRL_NFORCE3 equ 0x00DA + + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x16 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +OS_BASE equ 0; 0x80400000 +new_app_base equ 0x60400000; 0x01000000 +PROC_BASE equ OS_BASE+0x0080000 + +public START +public STOP +public service_proc + +extrn AttachIntHandler +extrn SysMsgBoardStr +extrn PciApi +extrn PciRead32 +extrn PciRead8 +extrn PciWrite8 +extrn AllocKernelSpace +extrn MapPage +extrn RegService +extrn KernelAlloc +extrn GetPgAddr +extrn GetCurrentTask + +section '.flat' code readable align 16 + +START: + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + + end if + + call init_controller + test eax, eax + jz .fail + + if DEBUG + mov esi, msgInitCodec + call SysMsgBoardStr + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call SysMsgBoardStr + + mov esi, [codec.chip_ids] + call SysMsgBoardStr + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + + call create_primary_buff + +; if REMAP_IRQ + +; call get_LPC_bus +; cmp eax, -1 +; jz .fail + +; mov [lpc_bus], 0 ;eax +; call remap_irq +; end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail + + stdcall AttachIntHandler, ebx, ac97_irq + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax +STOP: + ret + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov ebx, [edi+input] + stdcall set_master_vol, [ebx] + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + test ebx, ebx + jz .fail + + stdcall get_master_vol, ebx + ret +@@: + cmp eax, DEV_GET_INFO + jne @F + mov ebx, [edi+output] + stdcall get_dev_info, ebx + ret +@@: +.fail: + xor eax, eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +align 4 +proc remap_irq ;for Intel chipsets ONLY !!! + mov eax, VALID_IRQ + bt eax, IRQ_LINE + jnc .exit + + mov edx, 0x4D0 + in ax,dx + bts ax, IRQ_LINE + out dx, aX + + stdcall PciWrite8, dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE + mov [ctrl.int_line], IRQ_LINE + +.exit: + ret +endp + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call SysMsgBoardStr +; end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x14 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 2 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + stdcall GetPgAddr, [ctrl.buffer] + + mov ebx, 0xC0002000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov ecx, pcmout_bdl + stdcall GetPgAddr, ecx + and ecx, 0xFFF + add eax, ecx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .no_pci + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B + +.next: inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp ebx, VID_INTEL + jne @F + mov [ctrl.vendor_ids], msg_Intel + ret +@@: + cmp ebx, VID_NVIDIA + jne @F + mov [ctrl.vendor_ids], msg_NVidia +@@: + cmp ebx, 0x1274 + jne @F + mov [ctrl.vendor_ids], msgEnsoniq + ret +@@: + mov [ctrl.vendor_ids], 0 ;something wrong ? + ret +.no_pci: + mov esi, msgPCI + call SysMsgBoardStr +.err: + xor eax, eax + ret +endp + +align 4 +proc get_LPC_bus ;for Intel chipsets ONLY !!! + locals + last_bus dd ? + bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call [PciApi] + cmp eax, -1 + je .err + + mov [last_bus], eax +.next_bus: + stdcall PciRead32, [bus], dword 0xF8, dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + cmp eax, 0x24D08086 + je .found +.next: + mov eax, [bus] + inc eax + cmp eax, [last_bus] + mov [bus], eax + jna .next_bus +.err: + xor eax, eax + dec eax + ret +.found: + mov eax, [bus] + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_ICH + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +align 4 +proc set_ICH4 + stdcall AllocKernelSpace, dword 0x2000 + mov edi, eax + stdcall MapPage, edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.codec_mem_base], edi + add edi, 0x1000 + stdcall MapPage, edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.ctrl_mem_base], edi + + mov [ctrl.codec_read16], codec_mem_r16 ;virtual + mov [ctrl.codec_write16], codec_mem_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call SysMsgBoardStr + end if + + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if + + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + xor eax, eax + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 1000000 ; wait 1 s + call StallExec + + mov eax, 2 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc play + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc stop + mov edx, PCM_OUT_CR_REG + mov ax, 0x14 + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret + +align 4 +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + jb @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEMORY MAPPED IO (os depended) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_mem_r16 + add edx, [ctrl.codec_mem_base] + mov ax, word [edx] + ret +endp + +align 4 +proc codec_mem_w16 + add edx, [ctrl.codec_mem_base] + mov word [edx], ax + ret +endp + +align 4 +proc ctrl_mem_r8 + add edx, [ctrl.ctrl_mem_base] + mov al, [edx] + ret +endp + +align 4 +proc ctrl_mem_r16 + add edx, [ctrl.ctrl_mem_base] + mov ax, [edx] + ret +endp + +align 4 +proc ctrl_mem_r32 + add edx, [ctrl.ctrl_mem_base] + mov eax, [edx] + ret +endp + +align 4 +proc ctrl_mem_w8 + add edx, [ctrl.ctrl_mem_base] + mov [edx], al + + ret +endp + +align 4 +proc ctrl_mem_w16 + add edx, [ctrl.ctrl_mem_base] + mov [edx], ax + ret +endp + +align 4 +proc ctrl_mem_w32 + add edx, [ctrl.ctrl_mem_base] + mov [edx], eax + ret +endp + + +include "codec.inc" + +align 4 +devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH + dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH + dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH + dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH + dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 + dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 + dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 + dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 + + dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH + dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH + dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH + dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH + + dd 0 ;terminator + +msg_ICH db 'Intel ICH', 13,10, 0 +msg_ICH0 db 'Intel ICH0', 13,10, 0 +msg_ICH2 db 'Intel ICH2', 13,10, 0 +msg_ICH3 db 'Intel ICH3', 13,10, 0 +msg_ICH4 db 'Intel ICH4', 13,10, 0 +msg_ICH5 db 'Intel ICH5', 13,10, 0 +msg_ICH6 db 'Intel ICH6', 13,10, 0 +msg_ICH7 db 'Intel ICH7', 13,10, 0 +msg_Intel db 'Intel Corp. ', 0 + +msg_NForce db 'NForce', 13,10, 0 +msg_NForce2 db 'NForce 2', 13,10, 0 +msg_NForce3 db 'NForce 3', 13,10, 0 +msg_NVidia db 'NVidea', 0 + +msgEnsoniq db 'Ensonic 1371',0 + +szKernel db 'KERNEL', 0 +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 + + diff --git a/kernel/branches/gfx_kernel/drivers/imports.inc b/kernel/branches/gfx_kernel/drivers/imports.inc new file mode 100644 index 000000000..28a8ecef2 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/imports.inc @@ -0,0 +1,136 @@ + +; all exported kernel functions and data + +if used RegService + extrn RegService +end if +if used GetService + extrn GetService +end if +if used ServiceHandler + extrn ServiceHandler +end if +if used AttachIntHandler + extrn AttachIntHandler +end if +if used FpuSave + extrn FpuSave +end if +if used FpuRestore + extrn FpuRestore +end if + +if used PciApi + extrn PciApi +end if +if used PciRead32 + extrn PciRead32 +end if +if used PciRead8 + extrn PciRead8 +end if +if used PciWrite8 + extrn PciWrite8 +end if + +if used AllocPage + extrn AllocPage +end if +if used AllocPages + extrn AllocPages +end if +if used FreePage + extrn FreePage +end if +if used MapPage + extrn MapPage +end if +if used MapSpace + extrn MapSpace +end if +if used GetPgAddr + extrn GetPgAddr +end if +if used CommitPages + extrn CommitPages +end if +if used ReleasePages + extrn ReleasePages +end if + +if used AllocKernelSpace + extrn AllocKernelSpace +end if +if used FreeKernelSpace + extrn FreeKernelSpace +end if +if used KernelAlloc + extrn KernelAlloc +end if +if used KernelFree + extrn KernelFree +end if +if used UserAlloc + extrn UserAlloc +end if +if used UserFree + extrn UserFree +end if +if used Kmalloc + extrn Kmalloc +end if +if used Kfree + extrn Kfree +end if + +if used CreateObject + extrn CreateObject +end if +if used DestroyObject + extrn DestroyObject +end if +if used CreateEvent + extrn CreateEvent +end if +if used RaiseEvent + extrn RaiseEvent +end if +if used WaitEvent + extrn WaitEvent +end if +if used DestroyEvent + extrn DestroyEvent +end if +if used ClearEvent + extrn ClearEvent +end if + +if used LoadCursor + extrn LoadCursor +end if +if used SetHwCursor + extrn SetHwCursor +end if +if used HwCursorRestore + extrn HwCursorRestore +end if +if used HwCursorCreate + extrn HwCursorCreate +end if + +if used SysMsgBoardStr + extrn SysMsgBoardStr +end if +if used GetCurrentTask + extrn GetCurrentTask +end if +if used LoadFile + extrn LoadFile +end if +if used SendEvent + extrn SendEvent +end if +if used LFBAddress + extrn LFBAddress +end if + diff --git a/kernel/branches/gfx_kernel/drivers/infinity.asm b/kernel/branches/gfx_kernel/drivers/infinity.asm new file mode 100644 index 000000000..5fe722b78 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/infinity.asm @@ -0,0 +1,1291 @@ +; +; This file is part of the Infinity sound library. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +format MS COFF + +include 'proc32.inc' +include 'main.inc' +include 'imports.inc' + +FORCE_MMX equ 0 ;set to 1 to force use mmx or +FORCE_MMX_128 equ 0 ;integer sse2 extensions + ;and reduce driver size +;USE_SSE equ 0 + +DEBUG equ 1 + + +OS_BASE equ 0 +new_app_base equ 0x80000000 +SLOT_BASE equ OS_BASE+0x0080000 + +CAPS_SSE2 equ 26 +PG_SW equ 0x003 + +public START +public service_proc +public version + +RT_INP_EMPTY equ 0xFF000001 +RT_OUT_EMPTY equ 0xFF000002 +RT_INP_FULL equ 0xFF000003 +RT_OUT_FULL equ 0xFF000004 + +EVENT_WATCHED equ 0x10000000 +EVENT_SIGNALED equ 0x20000000 +MANUAL_RESET equ 0x40000000 +MANUAL_DESTROY equ 0x80000000 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit + + stdcall GetService, szSound + test eax, eax + jz .fail + mov [hSound], eax + + stdcall KernelAlloc, 16*512 + test eax, eax + jz .out_of_mem + mov [mix_buff], eax + + mov eax, str.fd-FD_OFFSET + mov [str.fd], eax + mov [str.bk], eax + +if FORCE_MMX + if FORCE_MMX_128 + display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 + stop + end if + mov [mix_2_core], mmx_mix_2 + mov [mix_3_core], mmx_mix_3 + mov [mix_4_core], mmx_mix_4 +end if + +if FORCE_MMX_128 + if FORCE_MMX + display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 + stop + end if + mov [mix_2_core], mmx128_mix_2 + mov [mix_3_core], mmx128_mix_3 + mov [mix_4_core], mmx128_mix_4 +end if + +if 0 + +if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect + mov eax, 1 + cpuid + bt edx, CAPS_SSE2 + jc .mmx128 + ;old 64-bit mmx + mov [mix_2_core], mmx_mix_2 + mov [mix_3_core], mmx_mix_3 + mov [mix_4_core], mmx_mix_4 + jmp @F +.mmx128: ;128-bit integer sse2 extensions + mov [mix_2_core], mmx128_mix_2 + mov [mix_3_core], mmx128_mix_3 + mov [mix_4_core], mmx128_mix_4 +@@: +end if + +end if + stdcall set_handler, [hSound], new_mix + mov [eng_state], SND_STOP + stdcall RegService, szInfinity, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if +.exit: + xor eax, eax + ret + +.out_of_mem: + if DEBUG + mov esi, msgMem + call SysMsgBoardStr + end if + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + + cmp eax, SRV_GETVERSION + jne @F + mov eax, [edi+output] + mov eax, [eax] + mov [eax+new_app_base], dword SOUND_VERSION + xor eax, eax + ret +@@: + cmp eax, SND_CREATE_BUFF + jne @F + mov ebx, [edi+input] + push edi + stdcall CreateBuffer,[ebx],[ebx+4] + pop edi + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], ebx + ret +@@: + mov ebx, [edi+input] + mov edx, [ebx] + + cmp [edx+STREAM.magic], 'WAVE' + jne .fail + + cmp [edx+STREAM.size], STREAM_SIZE + jne .fail + + cmp eax, SND_DESTROY_BUFF + jne @F + mov eax, edx + call DestroyBuffer ;edx= stream + ret +@@: + cmp eax, SND_SETFORMAT + jne @F + stdcall SetFormat,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETFORMAT + jne @F + + movzx eax, word [edx+STREAM.format] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], eax + xor eax, eax + ret +@@: + cmp eax, SND_RESET + jne @F + stdcall ResetBuffer,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_SETPOS + jne @F + stdcall SetBufferPos,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETPOS + jne @F + push edi + stdcall GetBufferPos, [ebx] + pop edi + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], ebx + ret +@@: + cmp eax, SND_SETBUFF + jne @F + mov eax, [ebx+4] + add eax, new_app_base + stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12] + ret +@@: + cmp eax, SND_SETVOLUME + jne @F + stdcall SetBufferVol,[ebx],[ebx+4],[ebx+8] + ret +@@: + cmp eax, SND_GETVOLUME + jne @F + + mov eax, [edi+output] + mov ecx, [eax] + mov eax, [eax+4] + add ecx, new_app_base + add eax, new_app_base + stdcall GetBufferVol,[ebx],ecx,eax + ret +@@: + cmp eax, SND_SETPAN + jne @F + stdcall SetBufferPan,[ebx],[ebx+4] + ret +@@: + cmp eax, SND_GETPAN + jne @F + mov eax, [edx+STREAM.pan] + mov ebx, [edi+output] + mov ebx, [ebx] + mov [ebx+new_app_base], eax + xor eax, eax + ret +@@: + cmp eax, SND_OUT + jne @F + + mov eax, [ebx+4] + add eax, new_app_base + stdcall wave_out, [ebx],eax,[ebx+8] + ret +@@: + cmp eax, SND_PLAY + jne @F + + stdcall play_buffer, [ebx],[ebx+4] + ret +@@: + cmp eax, SND_STOP + jne @F + + stdcall stop_buffer, [ebx] + ret +@@: + cmp eax, SND_GETBUFFSIZE + jne @F + mov eax, [edx+STREAM.in_size] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx+new_app_base], eax + xor eax, eax + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +TASK_COUNT equ 0x0003004 +CURRENT_TASK equ 0x0003000 + + +align 4 +proc CreateBuffer stdcall, format:dword, size:dword + locals + str dd ? + ring_size dd ? + ring_pages dd ? + endl + + mov eax, [format] + cmp ax, PCM_1_8_8 + ja .fail + + test eax, PCM_OUT + jnz .test_out + test eax, PCM_RING + jnz .test_ring +;staic + test eax, PCM_OUT+PCM_RING + jnz .fail + jmp .test_ok +.test_out: + test eax, PCM_RING+PCM_STATIC + jnz .fail + jmp .test_ok +.test_ring: + test eax, PCM_OUT+PCM_STATIC + jnz .fail +.test_ok: + mov ebx, [CURRENT_TASK] ;hack: direct accsess + shl ebx, 5 ;to kernel data + mov ebx, [CURRENT_TASK+ebx+4] + mov eax, STREAM_SIZE + + call CreateObject + test eax, eax + jz .fail + mov [str], eax + + mov ebx, [format] + mov [eax+STREAM.format], ebx + + xor ecx, ecx + movzx ebx, bx + cmp ebx, 19 + jb @f + mov ecx, 0x80808080 +@@: + mov [eax+STREAM.r_silence], ecx + + shl ebx, 2 + lea ebx, [ebx+ebx*2] ;ebx*=12 + + mov ecx, [resampler_params+ebx] + mov edx, [resampler_params+ebx+4] + mov esi, [resampler_params+ebx+8] + + mov [eax+STREAM.r_size],ecx + mov [eax+STREAM.r_dt], edx + mov [eax+STREAM.resample], esi + xor ecx, ecx + mov [eax+STREAM.l_vol], ecx + mov [eax+STREAM.r_vol], ecx + mov dword [eax+STREAM.l_amp], 0x7FFF7FFF + mov [eax+STREAM.pan], ecx + + test [format], PCM_STATIC + jnz .static + +; ring and waveout + + mov eax, 0x10000 + test [format], PCM_RING + jz .waveout + + mov eax, [eax+STREAM.r_size] + add eax, 4095 + and eax, -4096 + add eax, eax +.waveout: + mov [ring_size], eax + mov ebx, eax + shr ebx, 12 + mov [ring_pages], ebx + + add eax, eax ;double ring size + stdcall AllocKernelSpace, eax + + mov edi, [str] + mov ecx, [ring_size] + mov [edi+STREAM.in_base], eax + mov [edi+STREAM.in_size], ecx + add eax, 128 + sub ecx, 128 + mov [edi+STREAM.in_wp], eax + mov [edi+STREAM.in_rp], eax + mov [edi+STREAM.in_count], 0 + + mov [edi+STREAM.in_free], ecx + add eax, ecx + mov [edi+STREAM.in_top], eax + + mov ebx, [ring_pages] + stdcall AllocPages, ebx + mov edi, [str] + mov ebx, [edi+STREAM.in_base] + mov ecx, [ring_pages] + or eax, PG_SW + push eax + push ebx + call CommitPages ;eax, ebx, ecx + mov ecx, [ring_pages] + pop ebx + pop eax + add ebx, [ring_size] + call CommitPages ;double mapped + + jmp .out_buff +.static: + mov ecx, [size] + add ecx, 128 ;resampler required + mov [eax+STREAM.in_size], ecx + stdcall KernelAlloc, ecx + + mov edi, [str] + mov [edi+STREAM.in_base], eax + add eax, 128 + mov [edi+STREAM.in_wp], eax + mov [edi+STREAM.in_rp], eax + mov ebx, [size] + mov [edi+STREAM.in_count], ebx + mov [edi+STREAM.in_free], ebx + add eax, ebx + mov [edi+STREAM.in_top], eax + +.out_buff: + stdcall AllocKernelSpace, dword 128*1024 + + mov edi, [str] + mov [edi+STREAM.out_base], eax + mov [edi+STREAM.out_wp], eax + mov [edi+STREAM.out_rp], eax + mov [edi+STREAM.out_count], 0 + add eax, 64*1024 + mov [edi+STREAM.out_top], eax + + stdcall AllocPages, dword 64/4 + mov edi, [str] + mov ebx, [edi+STREAM.out_base] + mov ecx, 16 + or eax, PG_SW + push eax + push ebx + call CommitPages ;eax, ebx, ecx + mov ecx, 16 + pop ebx + pop eax + add ebx, 64*1024 + call CommitPages ;double mapped + + mov edi, [str] + mov ecx, [edi+STREAM.in_top] + mov edi, [edi+STREAM.in_base] + sub ecx, edi + xor eax, eax + shr ecx, 2 + cld + rep stosd + + mov edi, [str] + mov edi, [edi+STREAM.out_base] + mov ecx, (64*1024)/4 + rep stosd + + xor edx, edx + mov ebx, MANUAL_DESTROY + call CreateEvent + + mov ebx, [str] + mov [ebx+STREAM.notify_event], eax + mov [ebx+STREAM.notify_id], edx + + mov [ebx+STREAM.magic], 'WAVE' + mov [ebx+STREAM.destroy], DestroyBuffer.destroy + mov [ebx+STREAM.size], STREAM_SIZE + mov [ebx+STREAM.flags], SND_STOP + + pushf + cli + mov eax, str.fd-FD_OFFSET + mov edx, [eax+STREAM.str_fd] + mov [ebx+STREAM.str_fd], edx + mov [ebx+STREAM.str_bk], eax + mov [eax+STREAM.str_fd], ebx + mov [edx+STREAM.str_bk], ebx + popf + + xor eax, eax + ret +.fail: + xor ebx, ebx + or eax, -1 + ret +endp + +;param +; eax= buffer handle + +align 4 +DestroyBuffer: + .handle equ esp ;local + + mov [eax+STREAM.flags], SND_STOP +.destroy: + push eax + + pushfd + cli + mov ebx, [eax+STREAM.str_fd] + mov ecx, [eax+STREAM.str_bk] + mov [ebx+STREAM.str_bk], ecx + mov [ecx+STREAM.str_fd], ebx + popf + + stdcall KernelFree, [eax+STREAM.in_base] + mov eax, [.handle] + stdcall KernelFree, [eax+STREAM.out_base] + + pop eax ;restore stack + call DestroyObject ;eax= stream + xor eax, eax + ret +.fail: + or eax, -1 + ret +restore .handle + +align 4 +proc SetFormat stdcall, str:dword, format:dword + + cmp word [format], PCM_1_8_8 + ja .fail + + mov edx, [str] + mov [edx+STREAM.flags], SND_STOP + + test [edx+STREAM.format], PCM_RING + jnz .fail + +; mov eax,[edx+STREAM.out_base] +; mov [edx+STREAM.out_wp], eax +; mov [edx+STREAM.out_rp], eax +; mov [edx+STREAM.out_count], 0 + + movzx eax, word [format] + mov word [edx+STREAM.format], ax + + xor ebx, ebx + cmp eax, 19 + jb @f + mov ebx, 0x80808080 +@@: + mov [edx+STREAM.r_silence], ebx + + shl eax, 2 + lea eax, [eax+eax*2] ;eax*=12 + + mov edi, [resampler_params+eax] + mov ecx, [resampler_params+eax+4] + mov ebx, [resampler_params+eax+8] + + mov [edx+STREAM.r_size],edi + mov [edx+STREAM.r_dt], ecx + mov [edx+STREAM.resample], ebx + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; for static buffers only +; use waveout for streams + +align 4 +proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_OUT + jnz .fail + + mov esi, [src] + mov edi, [offs] + add edi, [edx+STREAM.in_base] + add edi, 128 + + cmp edi, [edx+STREAM.in_top] + jae .fail + + mov ecx, [size] + lea ebx, [ecx+edi] + sub ebx, [edx+STREAM.in_top] + jb @F + sub ecx, ebx +@@: + shr ecx, 2 + cld + rep movsd + xor eax,eax + ret +.fail: + or eax, -1 + ret +endp + +; for stream buffers only + +align 4 +proc wave_out stdcall, str:dword,src:dword,size:dword + locals + state_saved dd ? + fpu_state rb 528 + endl + + mov edx, [str] + mov eax, [edx+STREAM.format] + test eax, PCM_STATIC+PCM_RING + jnz .fail + + cmp ax, PCM_ALL + je .fail + + mov esi,[src] + test esi, esi + jz .fail + + cmp esi, new_app_base + jb .fail + + mov [state_saved], 0 + +.main_loop: + mov edx, [str] + + mov ebx, [size] + test ebx, ebx + jz .done + + cmp [edx+STREAM.flags], SND_STOP + jne .fill + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + + mov ecx, [edx+STREAM.in_size] + sub ecx, 128 + mov [edx+STREAM.in_wp], edi + mov [edx+STREAM.in_rp], edi + mov [edx+STREAM.in_count], 0 + mov [edx+STREAM.in_free], ecx + + mov eax,[edx+STREAM.out_base] + mov [edx+STREAM.out_wp], eax + mov [edx+STREAM.out_rp], eax + mov [edx+STREAM.out_count], 0 +.fill: + mov ecx, [edx+STREAM.in_free] + test ecx, ecx + jz .wait + + cmp ecx, ebx + jbe @F + + mov ecx, ebx +@@: + sub [size], ecx + add [edx+STREAM.in_count], ecx + sub [edx+STREAM.in_free], ecx + + shr ecx, 2 + mov edi, [edx+STREAM.in_wp] + mov esi, [src] + cld + rep movsd + + mov [src], esi + cmp edi, [edx+STREAM.in_top] + jb @F + sub edi, [edx+STREAM.in_size] +@@: + mov [edx+STREAM.in_wp], edi + + cmp [edx+STREAM.out_count], 32768 + jae .skip + + cmp [state_saved], 0 + jne @F + lea eax, [fpu_state+15] + and eax, -16 + call FpuSave + mov [state_saved], 1 +@@: + stdcall refill, edx +.skip: + mov ebx, [str] + mov [ebx+STREAM.flags], SND_PLAY + cmp [eng_state], SND_PLAY + je .main_loop + + stdcall dev_play, [hSound] + mov [eng_state], SND_PLAY + jmp .main_loop +.wait: + mov edx, [str] + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call WaitEvent ;eax ebx + jmp .main_loop +.done: + cmp [state_saved], 1 + jne @F + + lea eax, [fpu_state+15] + and eax, -16 + call FpuRestore +@@: + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; both static and stream +; reset all but not clear buffers + + +; flags reserved +; RESET_INPUT equ 1 ;reserved reset and clear input buffer +; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer +; RESET_ALL equ 3 + + +align 4 +proc ResetBuffer stdcall, str:dword, flags:dword + + mov edx, [str] + mov [edx+STREAM.flags], SND_STOP + + mov edi, [edx+STREAM.in_base] + mov ecx, 128/4 + mov eax, [edx+STREAM.r_silence] + cld + rep stosd + + mov [edx+STREAM.in_wp], edi + mov [edx+STREAM.in_rp], edi + + mov [edx+STREAM.in_count], 0 + mov eax, [edx+STREAM.in_size] + sub eax, 128 + mov [edx+STREAM.in_free], eax + + xor eax, eax + mov ebx,[edx+STREAM.out_base] + mov [edx+STREAM.out_wp], ebx + mov [edx+STREAM.out_rp], ebx + mov [edx+STREAM.out_count], eax + ret +.fail: + or eax, -1 + ret +endp + +; for static buffers only + +align 4 +proc SetBufferPos stdcall, str:dword, pos:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_OUT+PCM_RING + jnz .fail + + mov [edx+STREAM.flags], SND_STOP + + mov eax, [pos] + add eax, [edx+STREAM.in_base] + mov ebx, [edx+STREAM.in_top] + add eax, 128 + + cmp eax, ebx + jae .fail + + mov [edx+STREAM.in_rp], eax + sub ebx, eax + mov [edx+STREAM.in_count], ebx + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +align 4 +proc GetBufferPos stdcall, str:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_OUT+PCM_RING + jnz .fail + + mov ebx, [edx+STREAM.in_rp] + xor eax, eax + ret +.fail: + xor ebx,ebx + or eax, -1 + ret +endp + +; both + +align 4 +proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword + + mov edx, [str] + stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan] + ret +endp + +proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword + locals + _600 dd ? + _32767 dd ? + state rb 108 + endl + + mov [_600], 0x44160000 ;600.0 + mov [_32767], 32767 + + lea ebx, [state] + fnsave [ebx] + + movq mm0, qword [l_vol] + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movq qword [l_vol], mm0 + movq qword [edx+STREAM.l_vol], mm0 + + movd mm1,[pan] + pminsw mm1, qword [pan_max] + pmaxsw mm1, qword [vol_min] + movd [edx+STREAM.pan], mm1 + + cmp word [edx+STREAM.pan], 0 + jl @F + + psubsw mm0,mm1 + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movd [l_vol],mm0 + jmp .calc_amp +@@: + punpckhdq mm0,mm0 + paddsw mm0,mm1 + pminsw mm0, qword [vol_max] + pmaxsw mm0, qword [vol_min] + movd [r_vol], mm0 +.calc_amp: + emms + fild word [l_vol] + + call .calc + + fistp word [edx+STREAM.l_amp] + fstp st0 + + fild word [r_vol] + + call .calc + + fistp word [edx+STREAM.r_amp] + fstp st0 + + fnclex + lea ebx, [state] + frstor [ebx] + + xor eax, eax + inc eax + ret +.calc: + fdiv dword [_600] + fld st0 + frndint + fxch st1 + fsub st, st1 + f2xm1 + fld1 + faddp st1, st0 + fscale + fimul dword [_32767] + ret 0 +endp + +align 4 +proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword + + mov edx, [str] + mov eax, [p_lvol] + movsx ecx, word [edx+STREAM.l_vol] + mov [eax], ecx + + mov eax, [p_rvol] + movsx ecx, word [edx+STREAM.r_vol] + mov [eax], ecx + xor eax, eax + ret +endp + +align 4 +proc SetBufferPan stdcall, str:dword,pan:dword + + mov edx, [str] + stdcall set_vol_param,[edx+STREAM.l_vol],\ + [edx+STREAM.r_vol],[pan] + ret +endp + +; for static and ring buffers only + +align 4 +proc play_buffer stdcall, str:dword, flags:dword + locals + fpu_state rb 528 + endl + + mov ebx, [str] + mov eax, [ebx+STREAM.format] + test eax, PCM_OUT + jnz .fail + + cmp ax, PCM_ALL + je .fail + + mov [ebx+STREAM.flags], SND_PLAY + cmp [eng_state], SND_PLAY + je .done + + stdcall dev_play, [hSound] + mov [eng_state], SND_PLAY +.done: + test [flags], PLAY_SYNC + jz @F + + mov edx, [str] +.wait: + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call WaitEvent ;eax ebx + + mov edx, [str] + cmp [edx+STREAM.flags], SND_STOP + jne .wait +@@: + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; for static buffers only + +align 4 +proc stop_buffer stdcall, str:dword + + mov edx, [str] + test [edx+STREAM.format], PCM_STATIC+PCM_RING + jz .fail + + mov [edx+STREAM.flags], SND_STOP + +; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 + + mov eax, [edx+STREAM.notify_event] + mov ebx, [edx+STREAM.notify_id] + call ClearEvent ;eax ebx + + xor eax, eax + ret +.fail: + or eax, -1 + ret +endp + +; parm +; eax= mix_list + +align 4 +do_mix_list: + + xor edx, edx + mov esi, str.fd-FD_OFFSET + mov ebx, [esi+STREAM.str_fd] +@@: + cmp ebx, esi + je .done + + cmp [ebx+STREAM.magic], 'WAVE' + jne .next + + cmp [ebx+STREAM.size], STREAM_SIZE + jne .next + + cmp [ebx+STREAM.flags], SND_PLAY; + jne .next + + mov ecx, [ebx+STREAM.out_count] + test ecx, ecx + jnz .l1 + + test [ebx+STREAM.format], PCM_RING + jnz .next + mov [ebx+STREAM.flags], SND_STOP + jmp .next +.l1: + cmp ecx, 512 + jae .add_buff + + mov edi, [ebx+STREAM.out_rp] + add edi, ecx + sub ecx, 512 + neg ecx + push eax + xor eax, eax + cld + rep stosb + pop eax + + mov [ebx+STREAM.out_count], 512 + +.add_buff: + mov ecx, [ebx+STREAM.out_rp] + mov [eax],ecx + mov edi, dword [ebx+STREAM.l_amp] + mov [eax+4], edi + add [ebx+STREAM.out_rp], 512 + sub [ebx+STREAM.out_count], 512 + + add eax, 8 + inc edx +.next: + mov ebx, [ebx+STREAM.str_fd] + jmp @B +.done: + mov eax, edx + ret + +align 4 +prepare_playlist: + + xor edx, edx + mov [play_count], edx + mov esi, str.fd-FD_OFFSET + mov edi, [esi+STREAM.str_fd] +@@: + cmp edi, esi + je .done + + cmp [edi+STREAM.magic], 'WAVE' + jne .next + + cmp [edi+STREAM.size], STREAM_SIZE + jne .next + + cmp [edi+STREAM.flags], SND_PLAY; + jne .next + + mov [play_list+edx], edi + inc [play_count] + add edx, 4 +.next: + mov edi, [edi+STREAM.str_fd] + jmp @B +.done: + ret + +align 4 +proc set_handler stdcall, hsrv:dword, handler_proc:dword + locals + handler dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + lea ecx, [handler_proc] + xor ebx, ebx + + mov [handler], eax + mov [io_code], DEV_CALLBACK + mov [input], ecx + mov [inp_size], 4 + mov [output], ebx + mov [out_size], 0 + + lea eax, [handler] + stdcall ServiceHandler, eax + ret +endp + +align 4 +proc dev_play stdcall, hsrv:dword + locals + handle dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + xor ebx, ebx + + mov [handle], eax + mov [io_code], DEV_PLAY + mov [input], ebx + mov [inp_size], ebx + mov [output], ebx + mov [out_size], ebx + + lea eax, [handle] + stdcall ServiceHandler, eax + ret +endp + +if 0 +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + +end if + +include 'mixer.asm' +include 'mix_mmx.inc' +include 'mix_sse2.inc' + +;if USE_SSE +; include 'mix_sse.inc' +;end if + +align 16 +resampler_params: + ;r_size r_dt resampler_func + dd 0,0,0 ; 0 PCM_ALL + dd 16384, 0, copy_stream ; 1 PCM_2_16_48 + dd 16384, 0, m16_stereo ; 2 PCM_1_16_48 + + dd 16384, 30109, resample_2 ; 3 PCM_2_16_44 + dd 8192, 30109, resample_1 ; 4 PCM_1_16_44 + + dd 16384, 21846, resample_2 ; 5 PCM_2_16_32 + dd 8192, 21846, resample_1 ; 6 PCM_1_16_32 + + dd 16384, 16384, resample_2 ; 7 PCM_2_16_24 + dd 8192, 16384, resample_1 ; 8 PCM_1_16_24 + + dd 8192, 15052, resample_2 ; 9 PCM_2_16_22 + dd 4096, 15052, resample_1 ;10 PCM_1_16_22 + + dd 8192, 10923, resample_2 ;11 PCM_2_16_16 + dd 4096, 10923, resample_1 ;12 PCM_1_16_16 + + dd 8192, 8192, resample_2 ;13 PCM_2_16_12 + dd 4096, 8192, resample_1 ;14 PCM_1_16_12 + + dd 4096, 7527, resample_2 ;15 PCM_2_16_11 + dd 2048, 7527, resample_1 ;16 PCM_1_16_11 + + dd 4096, 5462, resample_2 ;17 PCM_2_16_8 + dd 2048, 5462, resample_1 ;18 PCM_1_16_8 + + dd 16384, 0, s8_stereo ;19 PCM_2_8_48 + dd 8192, 0, m8_stereo ;20 PCM_1_8_48 + + dd 8192, 30109, resample_28 ;21 PCM_2_8_44 + dd 4096, 30109, resample_18 ;22 PCM_1_8_44 + + dd 8192, 21846, resample_28 ;23 PCM_2_8_32 + dd 4096, 21846, resample_18 ;24 PCM_1_8_32 + + dd 8192, 16384, resample_28 ;25 PCM_2_8_24 + dd 4096, 16384, resample_18 ;26 PCM_1_8_24 + + dd 4096, 15052, resample_28 ;27 PCM_2_8_22 + dd 2048, 15052, resample_18 ;28 PCM_1_8_22 + + dd 4096, 10923, resample_28 ;29 PCM_2_8_16 + dd 2048, 10923, resample_18 ;30 PCM_1_8_16 + + dd 4096, 8192, resample_28 ;31 PCM_2_8_12 + dd 2048, 8192, resample_18 ;32 PCM_1_8_12 + + dd 2048, 7527, resample_28 ;33 PCM_2_8_11 + dd 1024, 7527, resample_18 ;34 PCM_1_8_11 + + dd 2048, 5462, resample_28 ;35 PCM_2_8_8 + dd 1024, 5462, resample_18 ;36 PCM_1_8_8 + +m7 dw 0x8000,0x8000,0x8000,0x8000 +mm80 dq 0x8080808080808080 +mm_mask dq 0xFF00FF00FF00FF00 + +vol_max dd 0x00000000,0x00000000 +vol_min dd 0x0000D8F0,0x0000D8F0 +pan_max dd 0x00002710,0x00002710 + +;stream_map dd 0xFFFF ; 16 +version dd (4 shl 16) or (SOUND_VERSION and 0xFFFF) + +szInfinity db 'INFINITY',0 +szSound db 'SOUND',0 + +if DEBUG +msgFail db 'Sound service not loaded',13,10,0 +msgPlay db 'Play buffer',13,10,0 +msgStop db 'Stop',13,10,0 +msgUser db 'User callback',13,10,0 +msgMem db 'Not enough memory',13,10,0 +msgDestroy db 'Destroy sound buffer', 13,10,0 +msgWaveout db 'Play waveout', 13,10,0 +msgSetVolume db 'Set volume',13,10,0 +end if + +section '.data' data readable writable align 16 + +play_list rd 16 +mix_input rd 16 +play_count rd 1 +hSound rd 1 +eng_state rd 1 +mix_buff rd 1 +mix_buff_map rd 1 +str.fd rd 1 +str.bk rd 1 + +mix_2_core rd 1 +mix_3_core rd 1 +mix_4_core rd 1 + diff --git a/kernel/branches/gfx_kernel/drivers/main.inc b/kernel/branches/gfx_kernel/drivers/main.inc new file mode 100644 index 000000000..c0f9a4c9c --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/main.inc @@ -0,0 +1,169 @@ +; +; This file is part of the Infinity sound driver. +; (C) copyright Serge 2006-2007 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + + +SOUND_VERSION equ 0x01000100 + +PLAY_SYNC equ 0x80000000 + + +PCM_ALL equ 0 + +PCM_OUT equ 0x08000000 +PCM_RING equ 0x10000000 +PCM_STATIC equ 0x20000000 +PCM_FLOAT equ 0x40000000 ;reserved +PCM_FILTER equ 0x80000000 ;reserved + +PCM_2_16_48 equ 1 +PCM_1_16_48 equ 2 + +PCM_2_16_44 equ 3 +PCM_1_16_44 equ 4 + +PCM_2_16_32 equ 5 +PCM_1_16_32 equ 6 + +PCM_2_16_24 equ 7 +PCM_1_16_24 equ 8 + +PCM_2_16_22 equ 9 +PCM_1_16_22 equ 10 + +PCM_2_16_16 equ 11 +PCM_1_16_16 equ 12 + +PCM_2_16_12 equ 13 +PCM_1_16_12 equ 14 + +PCM_2_16_11 equ 15 +PCM_1_16_11 equ 16 + +PCM_2_16_8 equ 17 +PCM_1_16_8 equ 18 + +PCM_2_8_48 equ 19 +PCM_1_8_48 equ 20 + +PCM_2_8_44 equ 21 +PCM_1_8_44 equ 22 + +PCM_2_8_32 equ 23 +PCM_1_8_32 equ 24 + +PCM_2_8_24 equ 25 +PCM_1_8_24 equ 26 + +PCM_2_8_22 equ 27 +PCM_1_8_22 equ 28 + +PCM_2_8_16 equ 29 +PCM_1_8_16 equ 30 + +PCM_2_8_12 equ 31 +PCM_1_8_12 equ 32 + +PCM_2_8_11 equ 33 +PCM_1_8_11 equ 34 + +PCM_2_8_8 equ 35 +PCM_1_8_8 equ 36 + +SRV_GETVERSION equ 0 +SND_CREATE_BUFF equ 1 +SND_DESTROY_BUFF equ 2 +SND_SETFORMAT equ 3 +SND_GETFORMAT equ 4 +SND_RESET equ 5 +SND_SETPOS equ 6 +SND_GETPOS equ 7 +SND_SETBUFF equ 8 +SND_OUT equ 9 +SND_PLAY equ 10 +SND_STOP equ 11 +SND_SETVOLUME equ 12 +SND_GETVOLUME equ 13 +SND_SETPAN equ 14 +SND_GETPAN equ 15 +SND_GETBUFFSIZE equ 16 + +struc STREAM +{ + .magic dd ? ;'WAVE' + .destroy dd ? ;internal destructor + .fd dd ? ;next object in list + .bk dd ? ;prev object in list + .pid dd ? ;owner id + + .size dd ? + .str_fd dd ? + .str_bk dd ? + .device dd ? + .format dd ? + .flags dd ? + + .out_base dd ? + .out_wp dd ? + .out_rp dd ? + .out_count dd ? + .out_top dd ? + + .r_size dd ? + .r_dt dd ? + .r_silence dd ? + .resample dd ? + .l_vol dd ? + .r_vol dd ? + .l_amp dw ? + .r_amp dw ? + .pan dd ? + + .in_base dd ? + .in_size dd ? + .in_wp dd ? + .in_rp dd ? + .in_count dd ? + .in_free dd ? + .in_top dd ? + + .notify_event dd ? + .notify_id dd ? +} + +STREAM_SIZE equ 34*4 +FD_OFFSET equ 24 + +virtual at 0 + STREAM STREAM +end virtual + +struc WAVE_HEADER +{ .riff_id dd ? + .riff_size dd ? + .riff_format dd ? + + .fmt_id dd ? + .fmt_size dd ? + .format_tag dw ? + .channels dw ? + .freq dd ? + .bytes_sec dd ? + .block_align dw ? + .bits_sample dw ? + + .data_id dd ? + .data_size dd ? +} + diff --git a/kernel/branches/gfx_kernel/drivers/mix_mmx.inc b/kernel/branches/gfx_kernel/drivers/mix_mmx.inc new file mode 100644 index 000000000..9413c142d --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/mix_mmx.inc @@ -0,0 +1,241 @@ + +; params +; edi= output +; eax= input stream 1 +; ebx= input stream 2 + +if used mmx_mix_2 + +align 4 +mmx_mix_2: + movq mm0, [eax] + movq mm1, [eax+8] + movq mm2, [eax+16] + movq mm3, [eax+24] + movq mm4, [eax+32] + movq mm5, [eax+40] + movq mm6, [eax+48] + movq mm7, [eax+56] + + paddsw mm0, [ebx] + movq [edi], mm0 + paddsw mm1,[ebx+8] + movq [edi+8], mm1 + paddsw mm2, [ebx+16] + movq [edi+16], mm2 + paddsw mm3, [ebx+24] + movq [edi+24], mm3 + paddsw mm4, [ebx+32] + movq [edi+32], mm4 + paddsw mm5, [ebx+40] + movq [edi+40], mm5 + paddsw mm6, [ebx+48] + movq [edi+48], mm6 + paddsw mm7, [ebx+56] + movq [edi+56], mm7 + + movq mm0, [eax+64] + movq mm1, [eax+72] + movq mm2, [eax+80] + movq mm3, [eax+88] + movq mm4, [eax+96] + movq mm5, [eax+104] + movq mm6, [eax+112] + movq mm7, [eax+120] + + paddsw mm0, [ebx+64] + movq [edi+64], mm0 + paddsw mm1, [ebx+72] + movq [edi+72], mm1 + paddsw mm2, [ebx+80] + movq [edi+80], mm2 + paddsw mm3, [ebx+88] + movq [edi+88], mm3 + paddsw mm4, [ebx+96] + movq [edi+96], mm4 + paddsw mm5, [ecx+104] + movq [edx+104], mm5 + paddsw mm6, [ebx+112] + movq [edi+112], mm6 + paddsw mm7, [ebx+120] + movq [edi+120], mm7 + ret + +align 4 +mmx_mix_3: + movq mm0, [eax] + movq mm1, [eax+8] + movq mm2, [eax+16] + movq mm3, [eax+24] + movq mm4, [eax+32] + movq mm5, [eax+40] + movq mm6, [eax+48] + movq mm7, [eax+56] + + paddsw mm0, [ebx] + paddsw mm1, [ebx+8] + paddsw mm2, [ebx+16] + paddsw mm3, [ebx+24] + paddsw mm4, [ebx+32] + paddsw mm5, [ebx+40] + paddsw mm6, [ebx+48] + paddsw mm7, [ebx+56] + paddsw mm0, [ecx] + movq [edi], mm0 + paddsw mm1,[ecx+8] + movq [edi+8], mm1 + paddsw mm2, [ecx+16] + movq [edi+16], mm2 + paddsw mm3, [ecx+24] + movq [edi+24], mm3 + paddsw mm4, [ecx+32] + movq [edi+32], mm4 + paddsw mm5, [ecx+40] + movq [edi+40], mm5 + paddsw mm6, [ecx+48] + movq [edi+48], mm6 + paddsw mm7, [ecx+56] + movq [edi+56], mm7 + + movq mm0, [eax+64] + movq mm1, [eax+72] + movq mm2, [eax+80] + movq mm3, [eax+88] + movq mm4, [eax+96] + movq mm5, [eax+104] + movq mm6, [eax+112] + movq mm7, [eax+120] + paddsw mm0, [ebx+64] + paddsw mm1, [ebx+72] + paddsw mm2, [ebx+80] + paddsw mm3, [ebx+88] + paddsw mm4, [ebx+96] + paddsw mm5, [ebx+104] + paddsw mm6, [ebx+112] + paddsw mm7, [ebx+120] + paddsw mm0, [ecx+64] + movq [edi+64], mm0 + paddsw mm1, [ecx+72] + movq [edi+72], mm1 + paddsw mm2, [ecx+80] + movq [edi+80], mm2 + paddsw mm3, [ecx+88] + movq [edi+88], mm3 + paddsw mm4, [ecx+96] + movq [edi+96], mm4 + paddsw mm5, [ecx+104] + movq [edi+104], mm5 + paddsw mm6, [ecx+112] + movq [edi+112], mm6 + paddsw mm7, [ecx+120] + movq [edi+120], mm7 + ret + +align 4 +mmx_mix_4: + + movq mm0, [eax] + movq mm2, [eax+8] + movq mm4, [eax+16] + movq mm6, [eax+24] + movq mm1, [ebx] + movq mm3, [ebx+8] + movq mm5, [ebx+16] + movq mm7, [ebx+24] + paddsw mm0, [ecx] + paddsw mm2, [ecx+8] + paddsw mm4, [ecx+16] + paddsw mm6, [ecx+24] + paddsw mm1, [edx] + paddsw mm3, [edx+8] + paddsw mm5, [edx+16] + paddsw mm7, [edx+24] + + paddsw mm0, mm1 + movq [edi], mm0 + paddsw mm2, mm3 + movq [edi+8], mm2 + paddsw mm4, mm5 + movq [edi+16], mm4 + paddsw mm5, mm6 + movq [edi+24], mm6 + + movq mm0, [eax+32] + movq mm2, [eax+40] + movq mm4, [eax+48] + movq mm6, [eax+56] + movq mm1, [ebx+32] + movq mm3, [ebx+40] + movq mm5, [ebx+48] + movq mm7, [ebx+56] + paddsw mm0, [ecx+32] + paddsw mm2, [ecx+40] + paddsw mm4, [ecx+48] + paddsw mm6, [ecx+56] + paddsw mm1, [edx+32] + paddsw mm3, [edx+40] + paddsw mm5, [edx+48] + paddsw mm7, [edx+56] + + paddsw mm0, mm1 + movq [edi+32], mm0 + paddsw mm2, mm2 + movq [edi+40], mm2 + paddsw mm4, mm5 + movq [edi+48], mm4 + paddsw mm6, mm7 + movq [edi+56], mm6 + + movq mm0, [eax+64] + movq mm2, [eax+72] + movq mm4, [eax+80] + movq mm6, [eax+88] + movq mm1, [ebx+64] + movq mm3, [ebx+72] + movq mm5, [ebx+80] + movq mm7, [ebx+88] + paddsw mm0, [ecx+64] + paddsw mm2, [ecx+72] + paddsw mm4, [ecx+80] + paddsw mm6, [ecx+88] + paddsw mm1, [edx+64] + paddsw mm3, [edx+72] + paddsw mm5, [edx+80] + paddsw mm7, [edx+88] + + paddsw mm0, mm1 + movq [edi+64], mm0 + paddsw mm2, mm3 + movq [edi+72], mm2 + paddsw mm4, mm5 + movq [edi+80], mm4 + paddsw mm6, mm5 + movq [edi+88], mm7 + + movq mm0, [eax+96] + movq mm2, [eax+104] + movq mm4, [eax+112] + movq mm6, [eax+120] + movq mm1, [ebx+96] + movq mm3, [ebx+104] + movq mm5, [ebx+112] + movq mm7, [ebx+120] + paddsw mm0, [ecx+96] + paddsw mm2, [ecx+104] + paddsw mm4, [ecx+112] + paddsw mm6, [ecx+120] + paddsw mm1, [edx+96] + paddsw mm3, [edx+104] + paddsw mm5, [edx+112] + paddsw mm7, [edx+120] + paddsw mm0, mm1 + movq [eax+96], mm0 + paddsw mm2, mm3 + movq [edi+104], mm2 + paddsw mm4, mm5 + movq [edi+112], mm4 + paddsw mm6, mm7 + movq [edi+120], mm6 + ret + +end if diff --git a/kernel/branches/gfx_kernel/drivers/mix_sse2.inc b/kernel/branches/gfx_kernel/drivers/mix_sse2.inc new file mode 100644 index 000000000..4ca0a9e63 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/mix_sse2.inc @@ -0,0 +1,139 @@ + +if used mmx128_mix_2 + +align 4 +mmx128_mix_2: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + + movaps xmm0, [eax] + movaps xmm1, [eax+16] + movaps xmm2, [eax+32] + movaps xmm3, [eax+48] + movaps xmm4, [eax+64] + movaps xmm5, [eax+80] + movaps xmm6, [eax+96] + movaps xmm7, [eax+112] + + paddsw xmm0, [ebx] + movaps [edi], xmm0 + paddsw xmm1,[ebx+16] + movaps [edi+16], xmm1 + paddsw xmm2, [ebx+32] + movaps [edi+32], xmm2 + paddsw xmm3, [ebx+48] + movaps [edi+48], xmm3 + paddsw xmm4, [ebx+64] + movaps [edi+64], xmm4 + paddsw xmm5, [ebx+80] + movaps [edi+80], xmm5 + paddsw xmm6, [ebx+96] + movaps [edi+96], xmm6 + paddsw xmm7, [ebx+112] + movaps [edi+112], xmm7 + ret + +align 4 +mmx128_mix_3: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + prefetcht1 [ecx+128] + + movaps xmm0, [eax] + movaps xmm1, [eax+16] + movaps xmm2, [eax+32] + movaps xmm3, [eax+48] + movaps xmm4, [eax+64] + movaps xmm5, [eax+80] + movaps xmm6, [eax+96] + movaps xmm7, [eax+112] + + paddsw xmm0, [ebx] + paddsw xmm1, [ebx+16] + paddsw xmm2, [ebx+32] + paddsw xmm3, [ebx+48] + paddsw xmm4, [ebx+64] + paddsw xmm5, [ebx+80] + paddsw xmm6, [ebx+96] + paddsw xmm7, [ebx+112] + + paddsw xmm0, [ecx] + movaps [edi], xmm0 + paddsw xmm1, [ecx+16] + movaps [edi+16], xmm1 + paddsw xmm2, [ecx+32] + movaps [edi+32], xmm2 + paddsw xmm3, [ecx+48] + movaps [edi+48], xmm3 + paddsw xmm4, [ecx+64] + movaps [edi+64], xmm4 + paddsw xmm5, [ecx+80] + movaps [edi+80], xmm5 + paddsw xmm6, [ecx+96] + movaps [edi+96], xmm6 + paddsw xmm7, [ecx+112] + movaps [edi+112], xmm7 + ret + +align 4 +mmx128_mix_4: + prefetcht1 [eax+128] + prefetcht1 [ebx+128] + prefetcht1 [ecx+128] + prefetcht1 [edx+128] + + movaps xmm0, [eax] + movaps xmm2, [eax+16] + movaps xmm4, [eax+32] + movaps xmm6, [eax+48] + movaps xmm1, [ebx] + movaps xmm3, [ebx+16] + movaps xmm5, [ebx+32] + movaps xmm7, [ebx+48] + + paddsw xmm0, [ecx] + paddsw xmm2, [ecx+16] + paddsw xmm4, [ecx+32] + paddsw xmm6, [ecx+48] + paddsw xmm1, [edx] + paddsw xmm3, [edx+16] + paddsw xmm5, [edx+32] + paddsw xmm7, [edx+48] + + paddsw xmm0, xmm1 + movaps [edi], xmm0 + paddsw xmm2, xmm3 + movaps [edi+16], xmm2 + paddsw xmm4, xmm5 + movaps [edi+32], xmm4 + paddsw xmm6, xmm7 + movaps [edi+48], xmm6 + + movaps xmm0, [eax+64] + movaps xmm2, [eax+80] + movaps xmm4, [eax+96] + movaps xmm6, [eax+112] + + movaps xmm1, [ebx+64] + movaps xmm3, [ebx+80] + movaps xmm5, [ebx+96] + movaps xmm7, [ebx+112] + paddsw xmm0, [ecx+64] + paddsw xmm2, [ecx+80] + paddsw xmm4, [ecx+96] + paddsw xmm6, [ecx+112] + + paddsw xmm1, [edx+64] + paddsw xmm3, [edx+80] + paddsw xmm5, [edx+96] + paddsw xmm7, [edx+112] + paddsw xmm0, xmm1 + movaps [edi+64], xmm0 + paddsw xmm2, xmm3 + movaps [edi+80], xmm2 + paddsw xmm4, xmm5 + movaps [edi+96], xmm4 + paddsw xmm6, xmm7 + movaps [edi+112], xmm6 + ret +end if diff --git a/kernel/branches/gfx_kernel/drivers/mixer.asm b/kernel/branches/gfx_kernel/drivers/mixer.asm new file mode 100644 index 000000000..2dbdecad6 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/mixer.asm @@ -0,0 +1,1106 @@ +; +; This file is part of the Infinity sound library. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + + +align 4 + +mix_list rq 32 + +align 4 +proc new_mix stdcall, output:dword + locals + main_count rd 1 + fpu_state rb 528 ;512+16 + endl + + mov [main_count], 32 + call prepare_playlist + cmp [play_count], 0 + je .clear + + lea eax, [fpu_state+16] + and eax, -16 ;must be 16b aligned + call FpuSave + + call update_stream +.mix: + lea eax, [mix_list] + call do_mix_list + test eax, eax + je .done + + ; cmp eax, 1 + ; je .copy + + lea ebx, [mix_list] + stdcall mix_all, [output], ebx, eax +@@: + add [output], 512 + dec [main_count] + jnz .mix +.exit: + lea eax, [fpu_state+16] + and eax, -16 + call FpuRestore + ret +.copy: + lea eax, [mix_list] + stdcall copy_mem, [output], [eax] + jmp @B +.done: + mov ecx, [main_count] + shl ecx, 7 ;ecx*= 512/4 + + mov edi, [output] + xor eax, eax + cld + rep stosd + jmp .exit +.clear: + mov edi, [output] + mov ecx, 4096 + xor eax, eax + cld + rep stosd + ret +endp + +align 4 +proc update_stream + locals + stream_index dd ? + ev_code dd ? ;EVENT + ev_offs dd ? + rd 4 + endl + + mov [stream_index], 0 +.l1: + mov edx, [stream_index] + mov esi, [play_list+edx*4] + + mov eax, [esi+STREAM.out_rp] + cmp eax, [esi+STREAM.out_top] + jb @f + sub eax, 64*1024 +@@: + mov [esi+STREAM.out_rp], eax + + cmp word [esi+STREAM.format], PCM_2_16_48 + je .copy + + cmp [esi+STREAM.out_count], 16384 + ja .skip + + test [esi+STREAM.format], PCM_RING + jnz .ring + + stdcall refill, esi +.skip: + inc [stream_index] + dec [play_count] + jnz .l1 + ret + +.ring: + stdcall refill_ring, esi + jmp .skip +.copy: + mov ebx, esi + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @f + + sub edi, 64*1024 + mov [ebx+STREAM.out_wp], edi +@@: + mov esi, [ebx+STREAM.in_rp] + mov ecx, 16384/4 + cld + rep movsd + + mov [ebx+STREAM.out_wp], edi + + cmp esi, [ebx+STREAM.in_top] + jb @f + + sub esi, 0x10000 +@@: + mov [ebx+STREAM.in_rp], esi + + test eax, eax + jz .l_end + mov eax, [ebx+STREAM.notify_event] + mov ebx, [ebx+STREAM.notify_id] + mov ecx, EVENT_WATCHED + xor edx, edx + call RaiseEvent ;eax, ebx, ecx, edx +.l_end: + inc [stream_index] + dec [play_count] + jnz .l1 + ret +endp + +align 4 +proc refill stdcall, str:dword + locals + r_size rd 1 + event rd 6 + endl + + mov ebx, [str] + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @F + sub edi, 0x10000 + mov [ebx+STREAM.out_wp], edi +@@: + mov eax, [ebx+STREAM.in_count] + test eax, eax + jz .done + + mov ecx, [ebx+STREAM.r_size] + cmp eax, ecx + jle @F + + mov eax, ecx +@@: + mov ecx, eax + cmp word [ebx+STREAM.format], PCM_1_16_8 + ja @F + + shr eax, 1 ;two channles +@@: + test [ebx+STREAM.format], 1 ;even formats mono + jz @F + + shr eax, 1 ;eax= samples +@@: + shl eax, 15 ;eax*=32768 =r_end + + mov [r_size], ecx + + mov esi, [ebx+STREAM.in_rp] + mov edi, [ebx+STREAM.out_wp] + + stdcall [ebx+STREAM.resample], edi, esi, \ + [ebx+STREAM.r_dt], ecx, eax + + mov ebx, [str] + + add [ebx+STREAM.out_count], eax; + add [ebx+STREAM.out_wp], eax; + + mov eax, [ebx+STREAM.in_rp] + mov ecx, [r_size] + add eax, ecx + add [ebx+STREAM.in_free], ecx + sub [ebx+STREAM.in_count], ecx + + cmp eax, [ebx+STREAM.in_top] + jb @f + + sub eax, [ebx+STREAM.in_size] +@@: + mov [ebx+STREAM.in_rp], eax + +.done: + mov eax, [ebx+STREAM.notify_event] + test eax, eax + jz .exit + + mov ebx, [ebx+STREAM.notify_id] + mov ecx, EVENT_WATCHED + xor edx, edx + call RaiseEvent ;eax, ebx, ecx, edx +.exit: + ret +endp + +align 4 +proc refill_ring stdcall, str:dword + locals + event rd 6 + endl + + mov ebx, [str] + mov edi, [ebx+STREAM.out_wp] + cmp edi, [ebx+STREAM.out_top] + jb @F + sub edi, 0x10000 + mov [ebx+STREAM.out_wp], edi +@@: + mov ecx, [ebx+STREAM.r_size] + mov eax, ecx + cmp word [ebx+STREAM.format], PCM_1_16_8 + ja @F + + shr eax, 1 ;two channles +@@: + test [ebx+STREAM.format], 1 ;even formats mono + jz @F + + shr eax, 1 ;eax= samples +@@: + shl eax, 15 ;eax*=32768 =r_end + + mov esi, [ebx+STREAM.in_rp] + mov edi, [ebx+STREAM.out_wp] + + stdcall [ebx+STREAM.resample], edi, esi, \ + [ebx+STREAM.r_dt], ecx, eax + + mov ebx, [str] + + add [ebx+STREAM.out_count], eax; + add [ebx+STREAM.out_wp], eax; + + mov eax, [ebx+STREAM.in_rp] + mov ecx, [ebx+STREAM.r_size] + add eax, ecx + add [ebx+STREAM.in_free], ecx + sub [ebx+STREAM.in_count], ecx + + cmp eax, [ebx+STREAM.in_top] + jb @f + + sub eax, [ebx+STREAM.in_size] +@@: + mov [ebx+STREAM.in_rp], eax + + sub eax, [ebx+STREAM.in_base] + sub eax, 128 + lea edx, [event] + + mov dword [edx], RT_INP_EMPTY + mov dword [edx+4], 0 + mov dword [edx+8], ebx + mov dword [edx+12], eax + + mov eax, [ebx+STREAM.notify_event] + test eax, eax + jz .exit + + mov ebx, [ebx+STREAM.notify_id] + xor ecx, ecx + call RaiseEvent ;eax, ebx, ecx, edx +.exit: + ret +endp + +align 4 +proc mix_all stdcall, dest:dword, list:dword, count:dword + + mov edi, [dest] + mov ebx, 64 +.mix: + mov edx, [list] + mov ecx, [count] + + mov eax, [edx] + movq mm0, [eax] + movd mm1, [edx+4] + punpckldq mm1,mm1 + pmulhw mm0, mm1 + psllw mm0, 1 + +.mix_loop: + add dword [edx], 8 + add edx, 8 + dec ecx + jz @F + + mov eax, [edx] + movq mm1, [eax] + movd mm2, [edx+4] + punpckldq mm2,mm2 + pmulhw mm1, mm2 + psllw mm1, 1 + paddsw mm0, mm1 + jmp .mix_loop +@@: + movq [edi], mm0 + add edi, 8 + dec ebx + jnz .mix + + ret +endp + +align 4 +proc resample_1 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + +; dest equ esp+8 +; src equ esp+12 +; r_dt equ esp+16 +; r_size equ esp+20 +; r_end equ esp+24 + + mov edi, [dest] + mov edx, [src] + sub edx, 32*2 + mov eax, 16 + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movsx ebp, word [esi] + movsx esi, word [esi+2] + mov ebx, 32768 + imul esi, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+esi+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add eax, [esp+16] + cmp eax, [esp+24] + jb .l1 + + mov ebp, esp + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_18 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + + mov edi, [dest] + mov edx, [src] + sub edx, 32 + + mov esi, 16 + +align 4 +.l1: + mov ecx, esi + mov eax, esi + and ecx, 0x7FFF + shr eax, 15 + lea eax, [edx+eax] + + mov bx, word [eax] + sub bh, 0x80 + sub bl, 0x80 + movsx eax, bh + shl eax,8 + movsx ebp, bl + shl ebp,8 + mov ebx, 32768 + imul eax, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+eax+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add esi, [esp+16] + cmp esi, [esp+24] + jb .l1 + + mov ebp, esp + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc copy_stream stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov ecx, [r_size] + mov eax, ecx + shr ecx, 2 + mov esi, [src] + mov edi, [dest] + rep movsd + mov eax, 16384 + ret +endp + +align 4 +proc resample_2 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edx, [src] + sub edx, 32*4 + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*4] + + movq mm0, [esi] + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ;0x8000 + + psubw mm3, mm2 ; ;0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_28 stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edx, [src] + sub edx, 32*2 + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + movq mm7,[mm80] + movq mm6,[mm_mask] + +align 4 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movq mm0, [esi] + psubb mm0,mm7 + punpcklbw mm0,mm0 + pand mm0,mm6 + + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ; // 0x8000 + + psubw mm3, mm2 ; // 0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + + sub edi, [dest] + mov eax, edi + ret +endp + + +proc m16_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx,8 +@@: + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +align 4 +proc s8_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 7 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +proc m8_stereo stdcall, dest:dword,src:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 6 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + add eax, eax + ret +endp + +align 4 +proc alloc_mix_buff + + bsf eax, [mix_buff_map] + jnz .find + xor eax, eax + ret +.find: + btr [mix_buff_map], eax + shl eax, 9 + add eax, [mix_buff] + ret +endp + +align 4 +proc m16_s_mmx + + movq mm0, [esi] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+48], mm0 + movq [edi+56], mm1 + + movq mm0, [esi+32] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+64], mm0 + movq [edi+72], mm1 + + movq mm0, [esi+40] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+80], mm0 + movq [edi+88], mm1 + + + movq mm0, [esi+48] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+96], mm0 + movq [edi+104], mm1 + + movq mm0, [esi+56] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+112], mm0 + movq [edi+120], mm1 + + ret +endp + +align 4 +proc s8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+48], mm0 + movq [edi+56], mm1 + + ret + +endp + +align 4 +proc m8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi], mm0 + movq [edi+8], mm2 + movq [edi+16], mm1 + movq [edi+24], mm3 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi+32], mm0 + movq [edi+40], mm2 + movq [edi+48], mm1 + movq [edi+56], mm3 + + ret +endp + +align 4 +proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword + + mov edi, [output] + mov eax, [str0] + mov ebx, [str1] + mov esi, 128 + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + + add edi, esi + add eax, esi + add ebx, esi + call [mix_2_core] ;edi, eax, ebx + ret +endp + +align 4 +proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword + + mov edi, [output] + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov esi, 128 + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + call [mix_3_core] + ret +endp + +align 4 +proc mix_4_1 stdcall, str0:dword, str1:dword,\ + str2:dword, str3:dword + + local output:DWORD + + call alloc_mix_buff + and eax, eax + jz .err + + mov [output], eax + + mov edi, eax + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov edx, [str3] + mov esi, 128 + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + mov eax, [output] + ret +.err: + xor eax, eax + ret +endp + + +align 4 +proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ + str2:dword, str3:dword + + mov edi, [output] + + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + mov edx, [str3] + mov esi, 128 + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + + add edi, esi + add eax, esi + add ebx, esi + add ecx, esi + add edx, esi + call [mix_4_core] ;edi, eax, ebx, ecx, edx + ret +endp + +align 4 +proc copy_mem stdcall, output:dword, input:dword + + mov edi, [output] + mov esi, [input] + mov ecx, 0x80 +.l1: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + loop .l1 + + ret +endp + +proc memcpy +@@: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + dec ecx + jnz @B + ret +endp + +if 0 + +align 4 +proc new_mix stdcall, output:dword + locals + mixCounter dd ? + mixIndex dd ? + streamIndex dd ? + inputCount dd ? + main_count dd ? + blockCount dd ? + mix_out dd ? + endl + + call prepare_playlist + + cmp [play_count], 0 + je .exit + call FpuSave + mov [main_count], 32; +.l00: + mov [mix_buff_map], 0x0000FFFF; + xor eax, eax + mov [mixCounter], eax + mov [mixIndex],eax + mov [streamIndex], eax; + mov ebx, [play_count] + mov [inputCount], ebx +.l0: + mov ecx, 4 +.l1: + mov ebx, [streamIndex] + mov esi, [play_list+ebx*4] + mov eax, [esi+STREAM.work_read] + add [esi+STREAM.work_read], 512 + + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixCounter] + inc [mixIndex] + inc [streamIndex] + dec [inputCount] + jz .m2 + + dec ecx + jnz .l1 + + cmp [mixCounter], 4 + jnz .m2 + + stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12] + sub [mixIndex],4 + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixIndex] + mov [mixCounter], 0 + + cmp [inputCount], 0 + jnz .l0 +.m2: + cmp [mixIndex], 1 + jne @f + stdcall copy_mem, [output], [mix_input] + jmp .m3 +@@: + cmp [mixIndex], 2 + jne @f + stdcall mix_2_1, [output], [mix_input], [mix_input+4] + jmp .m3 +@@: + cmp [mixIndex], 3 + jne @f + stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8] + jmp .m3 +@@: + stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12] +.m3: + add [output],512 + + dec [main_count] + jnz .l00 + + call update_stream + emms + call FpuRestore + ret +.exit: + mov edi, [output] + mov ecx, 0x1000 + xor eax, eax + cld + rep stosd + ret +endp + +end if + diff --git a/kernel/branches/gfx_kernel/drivers/proc32.inc b/kernel/branches/gfx_kernel/drivers/proc32.inc new file mode 100644 index 000000000..98a1bd334 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/proc32.inc @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/kernel/branches/gfx_kernel/drivers/sceletone.asm b/kernel/branches/gfx_kernel/drivers/sceletone.asm new file mode 100644 index 000000000..a916c8b33 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/sceletone.asm @@ -0,0 +1,157 @@ + +;driver sceletone + +format MS COFF + +include 'proc32.inc' +include 'imports.inc' + +OS_BASE equ 0; +new_app_base equ 0x60400000 +PROC_BASE equ OS_BASE+0x0080000 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +public START +public service_proc +public version + +DEBUG equ 1 + +DRV_ENTRY equ 1 +DRV_EXIT equ -1 +STRIDE equ 4 ;size of row in devices table + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .exit +.entry: + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + stdcall RegService, my_service, service_proc + ret +.fail: +.exit: + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + +; mov edi, [ioctl] +; mov eax, [edi+io_code] + + xor eax, eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc detect + locals + last_bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, STRIDE + jmp @B + +.next: inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret +endp + + +;DEVICE_ID equ ; pci device id +;VENDOR_ID equ ; device vendor id + + +;all initialized data place here + +align 4 +devices dd (DEVICE_ID shl 16)+VENDOR_ID + dd 0 ;terminator + +version dd 0x00030003 + +my_service db 'MY_SERVICE',0 ;max 16 chars include zero + +msgInit db 'detect hardware...',13,10,0 +msgPCI db 'PCI accsess not supported',13,10,0 +msgFail db 'device not found',13,10,0 + +section '.data' data readable writable align 16 + +;all uninitialized data place here + diff --git a/kernel/branches/gfx_kernel/drivers/sis.asm b/kernel/branches/gfx_kernel/drivers/sis.asm new file mode 100644 index 000000000..5e500eb03 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/sis.asm @@ -0,0 +1,1174 @@ + +format MS COFF + +include 'proc32.inc' +include 'imports.inc' + +DEBUG equ 1 + +CPU_FREQ equ 2000d ;cpu freq in MHz + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_SIS equ 0x1039 +CTRL_SIS equ 0x7012 + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x18 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +OS_BASE equ 0; 0x80400000 +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0x80000000 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + end if + + call init_controller + test eax, eax + jz .fail + + if DEBUG + mov esi, msgInitCodec + call SysMsgBoardStr + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call SysMsgBoardStr + + mov esi, [codec.chip_ids] + call SysMsgBoardStr + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + + call create_primary_buff + + stdcall AttachIntHandler, [ctrl.int_line], ac97_irq + + stdcall RegService, sz_sound_srv, service_proc + + mov esi, msgOk + call SysMsgBoardStr + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + add ebx, new_app_base + stdcall get_master_vol, ebx + ret +@@: + cmp eax, DEV_GET_INFO + jne @F + mov ebx, [edi+output] + stdcall get_dev_info, ebx + ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call SysMsgBoardStr +; end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x10 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 1 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + + mov ebx, 0xC0004000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + mov [edi+32], eax + mov [edi+4+32], ebx + mov [edi+64], eax + mov [edi+4+64], ebx + mov [edi+96], eax + mov [edi+4+96], ebx + mov [edi+128], eax + mov [edi+4+128], ebx + mov [edi+160], eax + mov [edi+4+160], ebx + mov [edi+192], eax + mov [edi+4+192], ebx + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr ;eax + and ebx, 0xFFF + add eax, ebx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + and eax, not 0x000000C0 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B + +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov [ctrl.vendor_ids], msg_SIS + + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_SIS + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + + call dword2str + call SysMsgBoardStr + + test eax, CTRL_ST_CREADY + jnz .ready + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + je .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + and eax, not 0x08 + or eax, 0x02 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if +.fail: + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +proc play + xor eax, eax + mov [civ_val], eax + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc stop + mov edx, PCM_OUT_CR_REG + mov ax, 0x0 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + ret +endp + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret + +align 4 +.not_ready: + xor eax, eax + ret +endp + + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx, edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + + +include "codec.inc" + +align 4 +devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS + dd 0 + +version dd 0x00040004 + +msg_AC db '7012 AC97 controller',13,10, 0 +msg_SIS db 'Silicon Integrated Systems',13,10, 0 + +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold resret',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 diff --git a/kernel/branches/gfx_kernel/drivers/sound.asm b/kernel/branches/gfx_kernel/drivers/sound.asm new file mode 100644 index 000000000..045118a29 --- /dev/null +++ b/kernel/branches/gfx_kernel/drivers/sound.asm @@ -0,0 +1,1413 @@ + +format MS COFF + + +include 'proc32.inc' +include 'imports.inc' + +DEBUG equ 1 + +REMAP_IRQ equ 0 + +;irq 0,1,2,8,12,13 недоступны +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010101000b + +IRQ_LINE equ 0 + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_INTEL equ 0x8086 +VID_NVIDIA equ 0x10DE + +CTRL_ICH equ 0x2415 +CTRL_ICH0 equ 0x2425 +CTRL_ICH2 equ 0x2435 +CTRL_ICH3 equ 0x2445 +CTRL_ICH4 equ 0x24C5 +CTRL_ICH5 equ 0x24D5 +CTRL_ICH6 equ 0x266E +CTRL_ICH7 equ 0x27DE + +CTRL_NFORCE equ 0x01B1 +CTRL_NFORCE2 equ 0x006A +CTRL_NFORCE3 equ 0x00DA +CTRL_MCP04 equ 0x003A +CTRL_CK804 equ 0x0059 +CTRL_CK8 equ 0x008A +CTRL_CK8S equ 0x00EA +CTRL_MCP51 equ 0x026B + + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x16 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 +DEV_SET_BUFF equ 4 +DEV_NOTIFY equ 5 +DEV_SET_MASTERVOL equ 6 +DEV_GET_MASTERVOL equ 7 +DEV_GET_INFO equ 8 + +struc AC_CNTRL ;AC controller base class +{ .bus dd ? + .devfn dd ? + + .vendor dd ? + .dev_id dd ? + .pci_cmd dd ? + .pci_stat dd ? + + .codec_io_base dd ? + .codec_mem_base dd ? + + .ctrl_io_base dd ? + .ctrl_mem_base dd ? + .cfg_reg dd ? + .int_line dd ? + + .vendor_ids dd ? ;vendor id string + .ctrl_ids dd ? ;hub id string + + .buffer dd ? + + .notify_pos dd ? + .notify_task dd ? + + .lvi_reg dd ? + .ctrl_setup dd ? + .user_callback dd ? + .codec_read16 dd ? + .codec_write16 dd ? + + .ctrl_read8 dd ? + .ctrl_read16 dd ? + .ctrl_read32 dd ? + + .ctrl_write8 dd ? + .ctrl_write16 dd ? + .ctrl_write32 dd ? +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd ? + .flags dd ? + .status dd ? + + .ac_vendor_ids dd ? ;ac vendor id string + .chip_ids dd ? ;chip model string + + .shadow_flag dd ? + dd ? + + .regs dw ? ; codec registers + .reg_master_vol dw ? ;0x02 + .reg_aux_out_vol dw ? ;0x04 + .reg_mone_vol dw ? ;0x06 + .reg_master_tone dw ? ;0x08 + .reg_beep_vol dw ? ;0x0A + .reg_phone_vol dw ? ;0x0C + .reg_mic_vol dw ? ;0x0E + .reg_line_in_vol dw ? ;0x10 + .reg_cd_vol dw ? ;0x12 + .reg_video_vol dw ? ;0x14 + .reg_aux_in_vol dw ? ;0x16 + .reg_pcm_out_vol dw ? ;0x18 + .reg_rec_select dw ? ;0x1A + .reg_rec_gain dw ? ;0x1C + .reg_rec_gain_mic dw ? ;0x1E + .reg_gen dw ? ;0x20 + .reg_3d_ctrl dw ? ;0X22 + .reg_page dw ? ;0X24 + .reg_powerdown dw ? ;0x26 + .reg_ext_audio dw ? ;0x28 + .reg_ext_st dw ? ;0x2a + .reg_pcm_front_rate dw ? ;0x2c + .reg_pcm_surr_rate dw ? ;0x2e + .reg_lfe_rate dw ? ;0x30 + .reg_pcm_in_rate dw ? ;0x32 + dw ? ;0x34 + .reg_cent_lfe_vol dw ? ;0x36 + .reg_surr_vol dw ? ;0x38 + .reg_spdif_ctrl dw ? ;0x3A + dw ? ;0x3C + dw ? ;0x3E + dw ? ;0x40 + dw ? ;0x42 + dw ? ;0x44 + dw ? ;0x46 + dw ? ;0x48 + dw ? ;0x4A + dw ? ;0x4C + dw ? ;0x4E + dw ? ;0x50 + dw ? ;0x52 + dw ? ;0x54 + dw ? ;0x56 + dw ? ;0x58 + dw ? ;0x5A + dw ? ;0x5C + dw ? ;0x5E + .reg_page_0 dw ? ;0x60 + .reg_page_1 dw ? ;0x62 + .reg_page_2 dw ? ;0x64 + .reg_page_3 dw ? ;0x66 + .reg_page_4 dw ? ;0x68 + .reg_page_5 dw ? ;0x6A + .reg_page_6 dw ? ;0x6C + .reg_page_7 dw ? ;0x6E + dw ? ;0x70 + dw ? ;0x72 + dw ? ;0x74 + dw ? ;0x76 + dw ? ;0x78 + dw ? ;0x7A + .reg_vendor_id_1 dw ? ;0x7C + .reg_vendor_id_2 dw ? ;0x7E + + + .reset dd ? ;virual + .set_master_vol dd ? +} + +struc CTRL_INFO +{ .pci_cmd dd ? + .irq dd ? + .glob_cntrl dd ? + .glob_sta dd ? + .codec_io_base dd ? + .ctrl_io_base dd ? + .codec_mem_base dd ? + .ctrl_mem_base dd ? + .codec_id dd ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +EVENT_NOTIFY equ 0x00000200 + +OS_BASE equ 0; +SLOT_BASE equ OS_BASE+0x0080000 +new_app_base equ 0x80000000 + +public START +public service_proc +public version + +section '.flat' code readable align 16 + +proc START stdcall, state:dword + + cmp [state], 1 + jne .stop + + if DEBUG + mov esi, msgInit + call SysMsgBoardStr + end if + + call detect_controller + test eax, eax + jz .fail + + if DEBUG + mov esi,[ctrl.vendor_ids] + call SysMsgBoardStr + mov esi, [ctrl.ctrl_ids] + call SysMsgBoardStr + + end if + + call init_controller + test eax, eax + jz .fail + + if DEBUG + mov esi, msgInitCodec + call SysMsgBoardStr + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call SysMsgBoardStr + + mov esi, [codec.chip_ids] + call SysMsgBoardStr + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call SysMsgBoardStr + + call create_primary_buff + +; if REMAP_IRQ + +; call get_LPC_bus +; cmp eax, -1 +; jz .fail + +; mov [lpc_bus], 0 ;eax +; call remap_irq +; end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail + + stdcall AttachIntHandler, ebx, ac97_irq + stdcall RegService, sz_sound_srv, service_proc + ret +.fail: + if DEBUG + mov esi, msgFail + call SysMsgBoardStr + end if + xor eax, eax + ret +.stop: + call stop + xor eax, eax + ret +endp + +handle equ IOCTL.handle +io_code equ IOCTL.io_code +input equ IOCTL.input +inp_size equ IOCTL.inp_size +output equ IOCTL.output +out_size equ IOCTL.out_size + +align 4 +proc service_proc stdcall, ioctl:dword + + mov edi, [ioctl] + mov eax, [edi+io_code] + cmp eax, DEV_PLAY + jne @F + if DEBUG + mov esi, msgPlay + call SysMsgBoardStr + end if + call play + ret +@@: + cmp eax, DEV_STOP + jne @F + if DEBUG + mov esi, msgStop + call SysMsgBoardStr + end if + call stop + ret +@@: + cmp eax, DEV_CALLBACK + jne @F + mov ebx, [edi+input] + stdcall set_callback, [ebx] + ret +@@: + cmp eax, DEV_SET_MASTERVOL + jne @F + mov eax, [edi+input] + mov eax, [eax] + call set_master_vol ;eax= vol + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + add ebx, new_app_base + stdcall get_master_vol, ebx + ret +;@@: +; cmp eax, DEV_GET_INFO +; jne @F +; mov ebx, [edi+output] +; stdcall get_dev_info, ebx +; ret +@@: +.fail: + or eax, -1 + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +align 4 +proc remap_irq ;for Intel chipsets ONLY !!! + mov eax, VALID_IRQ + bt eax, IRQ_LINE + jnc .exit + + mov edx, 0x4D0 + in ax,dx + bts ax, IRQ_LINE + out dx, aX + + stdcall PciWrite8, dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE + mov [ctrl.int_line], IRQ_LINE + +.exit: + ret +endp + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call SysMsgBoardStr +; end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x10; 0x10 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 ;0x1D + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 1 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x11 ;0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc create_primary_buff + + stdcall KernelAlloc, 0x10000 + mov [ctrl.buffer], eax + + mov edi, eax + mov ecx, 0x10000/4 + xor eax, eax + cld + rep stosd + + mov eax, [ctrl.buffer] + call GetPgAddr + + mov ebx, 0xC0002000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr ;eax + and ebx, 0xFFF + add eax, ebx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call PciApi + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall PciRead32, [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B + +.next: + inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp ebx, VID_INTEL + jne @F + mov [ctrl.vendor_ids], msg_Intel + ret +@@: + cmp ebx, VID_NVIDIA + jne @F + mov [ctrl.vendor_ids], msg_NVidia +@@: + mov [ctrl.vendor_ids], 0 ;something wrong ? + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc get_LPC_bus ;for Intel chipsets ONLY !!! + locals + last_bus dd ? + bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call [PciApi] + cmp eax, -1 + je .err + + mov [last_bus], eax +.next_bus: + stdcall PciRead32, [bus], dword 0xF8, dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + cmp eax, 0x24D08086 + je .found +.next: + mov eax, [bus] + inc eax + cmp eax, [last_bus] + mov [bus], eax + jna .next_bus +.err: + xor eax, eax + dec eax + ret +.found: + mov eax, [bus] + ret +endp + +align 4 +proc init_controller + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 + mov ebx, eax + and eax, 0xFFFF + mov [ctrl.pci_cmd], eax + shr ebx, 16 + mov [ctrl.pci_stat], ebx + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_ICH + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +align 4 +proc set_ICH4 + stdcall AllocKernelSpace, dword 0x2000 + mov edi, eax + stdcall MapPage, edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.codec_mem_base], edi + add edi, 0x1000 + stdcall MapPage, edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.ctrl_mem_base], edi + + mov [ctrl.codec_read16], codec_mem_r16 ;virtual + mov [ctrl.codec_write16], codec_mem_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + + call dword2str + call SysMsgBoardStr + + test eax, CTRL_ST_CREADY + jnz .ready + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call SysMsgBoardStr + end if + + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call SysMsgBoardStr + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call SysMsgBoardStr + end if + + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + xor eax, eax + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 1000000 ; wait 1 s + call StallExec + + mov eax, 2 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call SysMsgBoardStr + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +play: + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + xor eax, eax + ret + +align 4 +stop: + mov edx, PCM_OUT_CR_REG + mov ax, 0x0 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + xor eax, eax + ret + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + js @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEMORY MAPPED IO (os depended) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_mem_r16 + add edx, [ctrl.codec_mem_base] + mov ax, word [edx] + ret +endp + +align 4 +proc codec_mem_w16 + add edx, [ctrl.codec_mem_base] + mov word [edx], ax + ret +endp + +align 4 +proc ctrl_mem_r8 + add edx, [ctrl.ctrl_mem_base] + mov al, [edx] + ret +endp + +align 4 +proc ctrl_mem_r16 + add edx, [ctrl.ctrl_mem_base] + mov ax, [edx] + ret +endp + +align 4 +proc ctrl_mem_r32 + add edx, [ctrl.ctrl_mem_base] + mov eax, [edx] + ret +endp + +align 4 +proc ctrl_mem_w8 + add edx, [ctrl.ctrl_mem_base] + mov [edx], al + ret +endp + +align 4 +proc ctrl_mem_w16 + add edx, [ctrl.ctrl_mem_base] + mov [edx], ax + ret +endp + +align 4 +proc ctrl_mem_w32 + add edx, [ctrl.ctrl_mem_base] + mov [edx], eax + ret +endp + +align 4 +dword2str: + mov esi, hex_buff + mov ecx, -8 +@@: + rol eax, 4 + mov ebx, eax + and ebx, 0x0F + mov bl, [ebx+hexletters] + mov [8+esi+ecx], bl + inc ecx + jnz @B + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH + dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH + dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH + dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH + dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 + dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 + dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 + dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 + + dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH + dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH + dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH + dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH + dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH + dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH + dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH + dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH + + dd 0 ;terminator + +version dd 0x00040004 + +msg_ICH db 'Intel ICH', 13,10, 0 +msg_ICH0 db 'Intel ICH0', 13,10, 0 +msg_ICH2 db 'Intel ICH2', 13,10, 0 +msg_ICH3 db 'Intel ICH3', 13,10, 0 +msg_ICH4 db 'Intel ICH4', 13,10, 0 +msg_ICH5 db 'Intel ICH5', 13,10, 0 +msg_ICH6 db 'Intel ICH6', 13,10, 0 +msg_ICH7 db 'Intel ICH7', 13,10, 0 +msg_Intel db 'Intel Corp. ', 0 + +msg_NForce db 'NForce', 13,10, 0 +msg_NForce2 db 'NForce 2', 13,10, 0 +msg_NForce3 db 'NForce 3', 13,10, 0 +msg_MCP04 db 'NForce MCP04',13,10, 0 +msg_CK804 db 'NForce CK804',13,10, 0 +msg_CK8 db 'NForce CK8', 13,10, 0 +msg_CK8S db 'NForce CK8S', 13,10, 0 +msg_MCP51 db 'NForce MCP51',13,10, 0 + +msg_NVidia db 'NVidia', 0 + +szKernel db 'KERNEL', 0 +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 +msgStatus db 'global status ',0 +msgControl db 'global control ',0 + +section '.data' data readable writable align 16 + +pcmout_bdl rq 32 +buff_list rd 32 + +codec CODEC +ctrl AC_CNTRL + +lpc_bus rd 1 +civ_val rd 1 + + diff --git a/kernel/branches/gfx_kernel/fdo.inc b/kernel/branches/gfx_kernel/fdo.inc new file mode 100644 index 000000000..028667c8b --- /dev/null +++ b/kernel/branches/gfx_kernel/fdo.inc @@ -0,0 +1,422 @@ +; +; Formatted Debug Output (FDO) +; Copyright (c) 2005-2006, mike.dld +; Created: 2005-01-29, Changed: 2006-11-10 +; +; For questions and bug reports, mail to mike.dld@gmail.com +; +; Available format specifiers are: %s, %d, %u, %x (with partial width support) +; + +; to be defined: +; __DEBUG__ equ 1 +; __DEBUG_LEVEL__ equ 5 + +macro debug_func name { + if used name + name@of@func equ name +} + +macro debug_beginf { + align 4 + name@of@func: +} + +debug_endf fix end if + +macro DEBUGS _sign,[_str] { + common + local tp + tp equ 0 + match _arg:_num,_str \{ + DEBUGS_N _sign,_num,_arg + tp equ 1 + \} + match =0 _arg,tp _str \{ + DEBUGS_N _sign,,_arg + \} +} + +macro DEBUGS_N _sign,_num,[_str] { + common + pushf + pushad + local ..str,..label,is_str + is_str = 0 + forward + if _str eqtype '' + is_str = 1 + end if + common + if is_str = 1 + jmp ..label + ..str db _str,0 + ..label: + add esp,4*8+4 + mov edx,..str + sub esp,4*8+4 + else + mov edx,_str + end if + if ~_num eq + if _num eqtype eax + if _num in + mov esi,_num + else if ~_num eq esi + movzx esi,_num + end if + else if _num eqtype 0 + mov esi,_num + else + local tp + tp equ 0 + match [_arg],_num \{ + mov esi,dword[_arg] + tp equ 1 + \} + match =0 =dword[_arg],tp _num \{ + mov esi,dword[_arg] + tp equ 1 + \} + match =0 =word[_arg],tp _num \{ + movzx esi,word[_arg] + tp equ 1 + \} + match =0 =byte[_arg],tp _num \{ + movzx esi,byte[_arg] + tp equ 1 + \} + match =0,tp \{ + 'Error: specified string width is incorrect' + \} + end if + else + mov esi,0x7FFFFFFF + end if + call fdo_debug_outstr + popad + popf +} + +macro DEBUGD _sign,_dec { + local tp + tp equ 0 + match _arg:_num,_dec \{ + DEBUGD_N _sign,_num,_arg + tp equ 1 + \} + match =0 _arg,tp _dec \{ + DEBUGD_N _sign,,_arg + \} +} + +macro DEBUGD_N _sign,_num,_dec { + pushf + pushad + if (~_num eq) + if (_dec eqtype eax | _dec eqtype 0) + 'Error: precision allowed only for in-memory variables' + end if + if (~_num in <1,2,4>) + if _sign + 'Error: 1, 2 and 4 are only allowed for precision in %d' + else + 'Error: 1, 2 and 4 are only allowed for precision in %u' + end if + end if + end if + if _dec eqtype eax + if _dec in + mov eax,_dec + else if ~_dec eq eax + if _sign = 1 + movsx eax,_dec + else + movzx eax,_dec + end if + end if + else if _dec eqtype 0 + mov eax,_dec + else + add esp,4*8+4 + if _num eq + mov eax,dword _dec + else if _num = 1 + if _sign = 1 + movsx eax,byte _dec + else + movzx eax,byte _dec + end if + else if _num = 2 + if _sign = 1 + movsx eax,word _dec + else + movzx eax,word _dec + end if + else + mov eax,dword _dec + end if + sub esp,4*8+4 + end if + mov cl,_sign + call fdo_debug_outdec + popad + popf +} + +macro DEBUGH _sign,_hex { + local tp + tp equ 0 + match _arg:_num,_hex \{ + DEBUGH_N _sign,_num,_arg + tp equ 1 + \} + match =0 _arg,tp _hex \{ + DEBUGH_N _sign,,_arg + \} +} + +macro DEBUGH_N _sign,_num,_hex { + pushf + pushad + if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>) + 'Error: 1..8 are only allowed for precision in %x' + end if + if _hex eqtype eax + if _hex in + if ~_hex eq eax + mov eax,_hex + end if + else if _hex in + if ~_hex eq ax + movzx eax,_hex + end if + shl eax,16 + if (_num eq) + mov edx,4 + end if + else if _hex in + if ~_hex eq al + movzx eax,_hex + end if + shl eax,24 + if (_num eq) + mov edx,2 + end if + end if + else if _hex eqtype 0 + mov eax,_hex + else + add esp,4*8+4 + mov eax,dword _hex + sub esp,4*8+4 + end if + if ~_num eq + mov edx,_num + else + if ~_hex eqtype eax + mov edx,8 + end if + end if + call fdo_debug_outhex + popad + popf +} + +;----------------------------------------------------------------------------- + +debug_func fdo_debug_outchar +debug_beginf + pushad + movzx ebx,al + mov eax,1 + call sys_msg_board + popad + ret +debug_endf + +debug_func fdo_debug_outstr +debug_beginf + mov eax,1 + .l1: dec esi + js .l2 + movzx ebx,byte[edx] + or bl,bl + jz .l2 + call sys_msg_board + inc edx + jmp .l1 + .l2: ret +debug_endf + +debug_func fdo_debug_outdec +debug_beginf + or cl,cl + jz @f + or eax,eax + jns @f + neg eax + push eax + mov al,'-' + call fdo_debug_outchar + pop eax + @@: push 10 + pop ecx + push -'0' + .l1: xor edx,edx + div ecx + push edx + test eax,eax + jnz .l1 + .l2: pop eax + add al,'0' + jz .l3 + call fdo_debug_outchar + jmp .l2 + .l3: ret +debug_endf + +debug_func fdo_debug_outhex + __fdo_hexdigits db '0123456789ABCDEF' +debug_beginf + mov cl,dl + neg cl + add cl,8 + shl cl,2 + rol eax,cl + .l1: rol eax,4 + push eax + and eax,0x0000000F + mov al,[__fdo_hexdigits+eax] + call fdo_debug_outchar + pop eax + dec edx + jnz .l1 + ret +debug_endf + +;----------------------------------------------------------------------------- + +macro DEBUGF _level,_format,[_arg] { + common + if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__ + local ..f1,f2,a1,a2,c1,c2,c3,..lbl + _debug_str_ equ __debug_str_ # a1 + a1 = 0 + c2 = 0 + c3 = 0 + f2 = 0 + repeat ..lbl-..f1 + virtual at 0 + db _format,0,0 + load c1 word from %-1 + end virtual + if c1 = '%s' + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER S,a1,0,_arg + else if c1 = '%x' + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER H,a1,0,_arg + else if c1 = '%d' | c1 = '%u' + local c4 + if c1 = '%d' + c4 = 1 + else + c4 = 0 + end if + virtual at 0 + db _format,0,0 + store word 0 at %-1 + load c1 from f2-c2 + end virtual + if c1 <> 0 + DEBUGS 0,_debug_str_+f2-c2 + end if + c2 = c2 + 1 + f2 = %+1 + DEBUGF_HELPER D,a1,c4,_arg + else if c1 = '\n' + c3 = c3 + 1 + end if + end repeat + virtual at 0 + db _format,0,0 + load c1 from f2-c2 + end virtual + if (c1<>0)&(f2<>..lbl-..f1-1) + DEBUGS 0,_debug_str_+f2-c2 + end if + virtual at 0 + ..f1 db _format,0 + ..lbl: + __debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3 + end virtual + end if +} + +macro __include_debug_strings dummy,[_id,_fmt,_len] { + common + local c1,a1,a2 + forward + if defined _len & ~_len eq + _id: + a1 = 0 + a2 = 0 + repeat _len + virtual at 0 + db _fmt,0,0 + load c1 word from %+a2-1 + end virtual + if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u') + db 0 + a2 = a2 + 1 + else if (c1='\n') + dw $0A0D + a1 = a1 + 1 + a2 = a2 + 1 + else + db c1 and 0x0FF + end if + end repeat + db 0 + end if +} + +macro DEBUGF_HELPER _letter,_num,_sign,[_arg] { + common + local num + num = 0 + forward + if num = _num + DEBUG#_letter _sign,_arg + end if + num = num+1 + common + _num = _num+1 +} + +macro include_debug_strings { + if __DEBUG__ = 1 + match dbg_str,__debug_strings \{ + __include_debug_strings dbg_str + \} + end if +} diff --git a/kernel/branches/gfx_kernel/fs/fat12.inc b/kernel/branches/gfx_kernel/fs/fat12.inc index c11a75f9f..6931e888c 100644 --- a/kernel/branches/gfx_kernel/fs/fat12.inc +++ b/kernel/branches/gfx_kernel/fs/fat12.inc @@ -31,9 +31,9 @@ reserve_flp: reserve_flp_ok: push eax - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,5 - mov eax,[eax+0x3000+TASKDATA.pid] + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] mov [flp_status],eax pop eax sti @@ -104,7 +104,7 @@ fr_do_1: mov edi,edx dec ebx shl ebx,9 - mov esi,0x8000 + mov esi,FLOPPY_BUFF add esi,ebx shl ecx,9 cld @@ -147,7 +147,7 @@ l.20_1: cmp [FDC_Status],0 jne fdc_status_error_3_1 mov dl,16 - mov edi,0xD000 + mov edi,FDD_BUFF inc [FDD_Sector] l.21_1: mov esi,eax ;Name of file we want @@ -219,7 +219,7 @@ frfl7_1: frfl8_1: mov edi,[n_sector] shl edi,1 ;find next cluster from FAT - add edi,0x282000 + add edi,FLOPPY_FAT mov eax,[edi] and eax,4095 mov edi,eax @@ -274,7 +274,7 @@ read_flp_root: mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор - mov edi,0x8000 + mov edi,FLOPPY_BUFF call SeekTrack read_flp_root_1: call ReadSectWithRetr @@ -303,7 +303,7 @@ read_flp_fat: mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона mov [FDD_Sector],2 ; Сектор - mov edi,0x8000 + mov edi,FLOPPY_BUFF call SeekTrack read_flp_fat_1: call ReadSectWithRetr @@ -332,8 +332,8 @@ unnecessary_flp_fat: calculatefatchain_flp: pushad - mov esi,0x8000 - mov edi,0x282000 + mov esi,FLOPPY_BUFF + mov edi,FLOPPY_FAT fcnew_1: mov eax,dword [esi] @@ -361,7 +361,7 @@ calculatefatchain_flp: add edi,4 add esi,12 - cmp edi,0x282000+2856*2 ;2849 clusters + cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters jnz fcnew_1 popad @@ -384,7 +384,7 @@ check_label: cmp [FDC_Status],0 jne fdc_status_error mov esi,flp_label - mov edi,0xD000+39 + mov edi,FDD_BUFF+39 mov ecx,15 cld rep cmpsb @@ -392,7 +392,7 @@ check_label: mov [root_read],0 mov [flp_fat],0 same_label: - mov esi,0xD000+39 + mov esi,FDD_BUFF+39 mov edi,flp_label mov ecx,15 cld @@ -413,7 +413,7 @@ save_flp_root: mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],1 ; Сторона mov [FDD_Sector],2 ; Сектор - mov esi,0x8000 + mov esi,FLOPPY_BUFF call SeekTrack save_flp_root_1: push esi @@ -442,7 +442,7 @@ save_flp_fat: mov [FDD_Track],0 ; Цилиндр mov [FDD_Head],0 ; Сторона mov [FDD_Sector],2 ; Сектор - mov esi,0x8000 + mov esi,FLOPPY_BUFF call SeekTrack save_flp_fat_1: push esi @@ -471,8 +471,8 @@ unnecessary_flp_fat_save: restorefatchain_flp: ; restore fat chain pushad - mov esi,0x282000 - mov edi,0x8000 + mov esi,FLOPPY_FAT + mov edi,FLOPPY_BUFF fcnew2_1: mov eax,dword [esi] @@ -489,11 +489,11 @@ restorefatchain_flp: ; restore fat chain add edi,2 add esi,8 - cmp edi,0x8000+0x1200 ;4274 bytes - all used FAT + cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT jb fcnew2_1 - mov esi,0x8000 ; duplicate fat chain - mov edi,0x8000+0x1200 + mov esi,FLOPPY_BUFF ; duplicate fat chain + mov edi,FLOPPY_BUFF+0x1200 mov ecx,0x1200/4 cld rep movsd @@ -534,7 +534,7 @@ l.20_2: cmp [FDC_Status],0 jne fdc_status_error_4 mov dl,16 - mov edi,0xD000 + mov edi,FDD_BUFF inc [FDD_Sector] l.21_2: mov esi,eax ;Name of file we want @@ -574,7 +574,7 @@ fifoundd_2_1: movzx edi, word [edi+0xf] ;edi = cluster frnewd_1: shl edi,1 ;find next cluster from FAT - add edi,0x282000 + add edi,FLOPPY_FAT mov eax,[edi] mov [edi],word 0x0 ;clear fat chain cluster and eax,4095 @@ -662,7 +662,7 @@ rd_do_save_1: call read_flp_root cmp [FDC_Status],0 jne fdc_status_error_7 - mov edi,0x8000 ;Point at directory + mov edi,FLOPPY_BUFF ;Point at directory mov edx,224 +1 ; find an empty spot for filename in the root dir l20ds_1: @@ -689,7 +689,7 @@ l.20_3: cmp [FDC_Status],0 jne fdc_status_error_7 mov dl,16 - mov edi,0xD000 + mov edi,FDD_BUFF inc [FDD_Sector] l.21_3: mov esi,eax ;Name of file we want @@ -783,7 +783,7 @@ frnewds_2: add ebx,1 mov edi,ebx ; find free cluster in FAT shl edi,1 - add edi,0x282000 + add edi,FLOPPY_FAT mov eax,[edi] and eax,4095 jnz frnewds_2 @@ -920,7 +920,7 @@ adr56_flp: jne not_found_file_analyze_flp mov ecx,512/32 - mov ebx,0xD000 + mov ebx,FDD_BUFF adr1_analyze_flp: mov esi,edx ;[esp+16] @@ -937,7 +937,7 @@ adr1_analyze_flp: mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT - add eax,0x282000 + add eax,FLOPPY_FAT mov eax,[eax] and eax,4095 cmp eax,0x0ff8 @@ -985,7 +985,7 @@ adr561: jne error_found_file_analyze1 mov ecx,512/32 - mov ebx,0xD000 + mov ebx,FDD_BUFF adr1_analyze1: cmp byte [ebx],0x00 @@ -999,7 +999,7 @@ avanti: mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT - add eax,0x282000 + add eax,FLOPPY_FAT mov eax,[eax] and eax,4095 cmp eax,0x0ff8 @@ -1013,14 +1013,14 @@ avanti: mov eax,[clust_tmp_flp] shl eax,1 ;find next cluster from FAT - add eax,0x282000 - sub edi,0x282000 + add eax,FLOPPY_FAT + sub edi,FLOPPY_FAT mov [eax],di pusha mov ecx,512/4 xor eax,eax - mov edi,0xD000 + mov edi,FDD_BUFF cld rep stosd popa @@ -1032,7 +1032,7 @@ avanti: popa cmp [FDC_Status],0 jne error_found_file_analyze1 - mov ebx,0xD000 + mov ebx,FDD_BUFF found_file_analyze1: @@ -1061,7 +1061,7 @@ check_new_flp: add ebx,1 mov edi,ebx ; find free cluster in FAT shl edi,1 - add edi,0x282000 + add edi,FLOPPY_FAT mov eax,[edi] and eax,4095 cmp eax,0x0 @@ -1114,6 +1114,12 @@ fat_find_lfn: popa ret +uglobal +; this is for delete support +fd_prev_sector dd ? +fd_prev_prev_sector dd ? +endg + flp_root_next: cmp edi, 0xD200-0x20 jae @f @@ -1124,6 +1130,13 @@ flp_root_next: inc dword [eax] cmp dword [eax], 14 jae flp_root_first.readerr + push [fd_prev_sector] + pop [fd_prev_prev_sector] + push eax + mov eax, [eax] + add eax, 19-1 + mov [fd_prev_sector], eax + pop eax flp_root_first: mov eax, [eax] pusha @@ -1132,19 +1145,19 @@ flp_root_first: popa cmp [FDC_Status], 0 jnz .readerr - mov edi, 0xD000 + mov edi, FDD_BUFF ret ; CF=0 .readerr: stc ret flp_rootmem_first: - mov edi, 0x8000 + mov edi, FLOPPY_BUFF clc ret flp_rootmem_next: add edi, 0x20 - cmp edi, 0x8000+14*0x200 + cmp edi, FLOPPY_BUFF+14*0x200 cmc flp_rootmem_next_write: flp_rootmem_begin_write: @@ -1162,7 +1175,11 @@ flp_notroot_next: flp_notroot_next_sector: push ecx mov ecx, [eax] - mov ecx, [ecx*2+0x282000] + push [fd_prev_sector] + pop [fd_prev_prev_sector] + add ecx, 31 + mov [fd_prev_sector], ecx + mov ecx, [(ecx-31)*2+FLOPPY_FAT] and ecx, 0xFFF cmp ecx, 2849 jae flp_notroot_first.err2 @@ -1178,7 +1195,7 @@ flp_notroot_first: add eax, 31 call read_chs_sector popa - mov edi, 0xD000 + mov edi, FDD_BUFF cmp [FDC_Status], 0 jnz .err ret ; CF=0 @@ -1212,25 +1229,25 @@ flp_notroot_extend_dir: ; find free cluster in FAT pusha xor eax, eax - mov edi, 0x282000 + mov edi, FLOPPY_FAT mov ecx, 2849 repnz scasw jnz .notfound mov word [edi-2], 0xFFF ; mark as last cluster - sub edi, 0x282000 + sub edi, FLOPPY_FAT shr edi, 1 dec edi mov eax, [esp+28] mov ecx, [eax] - mov [0x282000+ecx*2], di + mov [FLOPPY_FAT+ecx*2], di mov [eax], edi xor eax, eax - mov edi, 0xD000 + mov edi, FDD_BUFF mov ecx, 128 rep stosd popa call flp_notroot_end_write - mov edi, 0xD000 + mov edi, FDD_BUFF clc ret .notfound: @@ -1341,7 +1358,7 @@ fs_FloppyRead: popa cmp [FDC_Status], 0 jnz .err - lea eax, [0xD000+ebx+512] + lea eax, [FDD_BUFF+ebx+512] neg ebx push ecx cmp ecx, ebx @@ -1355,7 +1372,7 @@ fs_FloppyRead: pop ecx xor ebx, ebx .skip: - movzx edi, word [edi*2+0x282000] + movzx edi, word [edi*2+FLOPPY_FAT] jmp .new .done: mov ebx, edx @@ -1435,7 +1452,7 @@ fs_FloppyReadFolder: popa cmp [FDC_Status], 0 jnz .error - mov edi, 0xD000 + mov edi, FDD_BUFF push eax .l1: call fat_get_name @@ -1451,7 +1468,7 @@ fs_FloppyReadFolder: jz .done jns @f ; read next sector from FAT - mov eax, [(eax-31-1)*2+0x282000] + mov eax, [(eax-31-1)*2+FLOPPY_FAT] and eax, 0xFFF cmp eax, 0xFF8 jae .done @@ -1463,7 +1480,7 @@ fs_FloppyReadFolder: popa cmp [FDC_Status], 0 jnz .error - mov edi, 0xD000 + mov edi, FDD_BUFF push eax .do_bdfe: inc dword [edx+8] ; new file found @@ -1483,7 +1500,7 @@ fs_FloppyReadFolder: jz .done jns @f ; read next sector from FAT - mov eax, [(eax-31-1)*2+0x282000] + mov eax, [(eax-31-1)*2+FLOPPY_FAT] and eax, 0xFFF cmp eax, 0xFF8 jae .done @@ -1533,7 +1550,13 @@ fsfrfe: xor ebx, ebx ret +fs_FloppyCreateFolder: + mov al, 1 + jmp fs_FloppyRewrite.common + fs_FloppyRewrite: + xor eax, eax +.common: cmp byte [esi], 0 jz @b call read_flp_fat @@ -1567,6 +1590,9 @@ fs_FloppyRewrite: push flp_rootmem_next jmp .common1 .noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 ; check existence mov byte [ebp], 0 call fd_find_lfn @@ -1599,8 +1625,24 @@ fs_FloppyRewrite: .common1: call fat_find_lfn jc .notfound -; found; must not be directory +; found test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 28 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+28+28], 0 jz @f add esp, 28 popad @@ -1618,7 +1660,7 @@ fs_FloppyRewrite: @@: cmp eax, 0xFF8 jae .done1 - lea edi, [0x282000 + eax*2] ; position in FAT + lea edi, [FLOPPY_FAT + eax*2] ; position in FAT xor eax, eax xchg ax, [edi] jmp @b @@ -1823,6 +1865,12 @@ fs_FloppyRewrite: 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 + cmp byte [esp+28+28], 0 + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov ecx, 32*2 + mov edx, edi .doit: lea eax, [esp+8] call dword [eax+12] ; flush directory @@ -1830,9 +1878,10 @@ fs_FloppyRewrite: push edi push 0 mov esi, edx - jecxz .done + test ecx, ecx + jz .done mov ecx, 2849 - mov edi, 0x282000 + mov edi, FLOPPY_FAT push 0 ; first cluster .write_loop: ; allocate new cluster @@ -1842,7 +1891,7 @@ fs_FloppyRewrite: jnz .ret dec edi dec edi - lea eax, [edi-0x282000] + lea eax, [edi-(FLOPPY_FAT)] shr eax, 1 ; eax = cluster mov word [edi], 0xFFF ; mark as last cluster xchg edi, [esp+4] @@ -1862,10 +1911,13 @@ fs_FloppyRewrite: jae @f mov ecx, [esp+20] @@: + mov edi, FDD_BUFF + cmp byte [esp+24+28+28], 0 + jnz .writedir push ecx - mov edi, 0xD000 rep movsb pop ecx +.writedircont: push ecx sub ecx, 512 neg ecx @@ -1918,6 +1970,28 @@ fs_FloppyRewrite: mov eax, 11 pop edi ecx jmp .ret +.writedir: + push ecx + mov ecx, 32/4 + push ecx esi + rep movsd + pop esi ecx + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov word [edi-32+26], ax + push esi + rep movsd + pop esi + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov ecx, [esp+28+8] + mov word [edi-32+26], cx + pop ecx + jmp .writedircont ;---------------------------------------------------------------- ; @@ -2042,6 +2116,13 @@ fs_FloppyWrite: jz .ret call SetUserInterrupts .write_loop: +; skip unmodified sectors + cmp dword [esp], 0x200 + jb .modify + sub ebx, 0x200 + jae .skip + add ebx, 0x200 +.modify: lea eax, [edi+31] ; current sector ; get length of data in current sector push ecx @@ -2079,7 +2160,7 @@ fs_FloppyWrite: mov ecx, 0x200 sub ecx, [esp+4+12] jbe @f - mov edi, 0xD000 + mov edi, FDD_BUFF add edi, [esp+4+12] rep stosb @@: @@ -2087,7 +2168,7 @@ fs_FloppyWrite: mov ecx, 0x200 sub ecx, esi jbe @f - mov edi, 0xD000 + mov edi, FDD_BUFF add edi, esi rep stosb @@: @@ -2097,7 +2178,7 @@ fs_FloppyWrite: mov eax, edx neg ebx jecxz @f - add ebx, 0xD000+0x200 + add ebx, FDD_BUFF+0x200 call memmove xor ebx, ebx @@: @@ -2112,8 +2193,9 @@ fs_FloppyWrite: sub [esp], ecx pop ecx jz .done +.skip: .next_cluster: - movzx edi, word [edi*2+0x282000] + movzx edi, word [edi*2+FLOPPY_FAT] sub esi, 0x200 jae @f xor esi, esi @@ -2143,7 +2225,7 @@ floppy_extend_file: @@: sub ecx, 0x200 jbe @f - mov eax, [eax*2+0x282000] + mov eax, [eax*2+FLOPPY_FAT] and eax, 0xFFF jz .fat_err cmp eax, 0xFF8 @@ -2156,7 +2238,7 @@ floppy_extend_file: ret @@: push eax - mov eax, [eax*2+0x282000] + mov eax, [eax*2+FLOPPY_FAT] and eax, 0xFFF cmp eax, 0xFF8 pop eax @@ -2167,7 +2249,7 @@ floppy_extend_file: pop ecx ; now do extend push edx esi - mov esi, 0x282000+2*2 ; start scan from cluster 2 + mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2 mov edx, 2847 ; number of clusters to scan .extend_loop: cmp [edi+28], ecx @@ -2187,12 +2269,12 @@ floppy_extend_file: mov word [edi-2], 0xFFF mov esi, edi mov edx, ecx - sub edi, 0x282000 + sub edi, FLOPPY_FAT shr edi, 1 dec edi ; now edi=new cluster test eax, eax jz .first_cluster - mov [0x282000+eax*2], di + mov [FLOPPY_FAT+eax*2], di jmp @f .first_cluster: pop eax ; eax->direntry @@ -2330,7 +2412,7 @@ fs_FloppySetFileEnd: mov ecx, [esp+4] neg ecx push edi - mov edi, 0xD000+0x200 + mov edi, FDD_BUFF+0x200 add edi, [esp+8] xor eax, eax mov [esp+8], eax @@ -2347,7 +2429,7 @@ fs_FloppySetFileEnd: .next_cluster: sub dword [esp+12], 0x200 jbe .expand_done - movzx edi, word [0x282000+edi*2] + movzx edi, word [FLOPPY_FAT+edi*2] jmp .zero_loop .expand_done: pop eax ecx ecx edi edi @@ -2362,13 +2444,13 @@ fs_FloppySetFileEnd: @@: sub eax, 0x200 jbe @f - movzx ecx, word [0x282000+ecx*2] + movzx ecx, word [FLOPPY_FAT+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] + lea ecx, [FLOPPY_FAT+ecx+ecx] push dword [ecx] mov word [ecx], 0xFFF pop ecx @@ -2382,7 +2464,7 @@ fs_FloppySetFileEnd: ; mark all clusters as free cmp ecx, 0xFF8 jae .deleted - lea ecx, [0x282000+ecx+ecx] + lea ecx, [FLOPPY_FAT+ecx+ecx] push dword [ecx] and word [ecx], 0 pop ecx @@ -2409,8 +2491,8 @@ fs_FloppySetFileEnd: pusha call read_chs_sector popa - add edi, 0xD000 - mov ecx, 0xD000+0x200 + add edi, FDD_BUFF + mov ecx, FDD_BUFF+0x200 sub ecx, edi push eax xor eax, eax @@ -2471,6 +2553,7 @@ fs_FloppySetFileInfo: @@: ret +if 0 ;---------------------------------------------------------------- ; ; fs_FloppyExecute - LFN variant for executing from floppy @@ -2542,7 +2625,7 @@ fs_FloppyExecute: cmp [FDC_Status], 0 jnz .err pop edi - mov esi, 0xD000 + mov esi, FDD_BUFF push edi mov ecx, 512/4 rep movsd @@ -2559,7 +2642,7 @@ fs_FloppyExecute: @@: mov [eax], ecx mov edx, [eax+4] - mov dx, [edx*2+0x282000] + mov dx, [edx*2+FLOPPY_FAT] mov [eax+4], dx ; high word is already zero popad xor eax, eax @@ -2572,5 +2655,135 @@ fs_FloppyExecute: popad mov eax, 11 ret +end if + +;---------------------------------------------------------------- +; +; fs_FloppyDelete - delete file or empty folder from floppy +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_FloppyDelete: + call read_flp_fat + cmp [FDC_Status], 0 + jz @f + push 11 + jmp .pop_ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED +.pop_ret: + pop eax + ret +@@: + and [fd_prev_sector], 0 + and [fd_prev_prev_sector], 0 + push edi + call fd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + push eax + movzx eax, word [edi+26] + push ebx + pusha + add eax, 31 + call read_chs_sector + popa + mov ebx, FDD_BUFF + 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + cmp ebx, FDD_BUFF + 0x200 + jb .checkempty + movzx eax, word [FLOPPY_FAT + eax*2] + pusha + add eax, 31 + call read_chs_sector + popa + mov ebx, FDD_BUFF + jmp .checkempty +.notempty: + pop ebx + pop eax +.access_denied2: + pop edi + jmp .access_denied +.empty: + pop ebx + pop eax + pusha + call read_chs_sector + popa +.dodel: + push eax + movzx eax, word [edi+26] + xchg eax, [esp] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + cmp edi, FDD_BUFF + ja @f + cmp [fd_prev_sector], 0 + jz .lfndone + push [fd_prev_sector] + push [fd_prev_prev_sector] + pop [fd_prev_sector] + and [fd_prev_prev_sector], 0 + pusha + call save_chs_sector + popa + pop eax + pusha + call read_chs_sector + popa + mov edi, FDD_BUFF+0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: + pusha + call save_chs_sector + popa +; delete FAT chain + pop eax + test eax, eax + jz .done +@@: + lea eax, [FLOPPY_FAT + eax*2] + push dword [eax] + and word [eax], 0 + pop eax + and eax, 0xFFF + jnz @b +.done: + call save_flp_fat + pop edi + xor eax, eax + ret ; \end{diamond} diff --git a/kernel/branches/gfx_kernel/fs/fat32.inc b/kernel/branches/gfx_kernel/fs/fat32.inc index dcc04ab67..ed80d6ccb 100644 --- a/kernel/branches/gfx_kernel/fs/fat32.inc +++ b/kernel/branches/gfx_kernel/fs/fat32.inc @@ -7,13 +7,16 @@ ;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; ;; ;; ;; See file COPYING for details ;; +;; 04.02.2007 LFN create folder - diamond ;; +;; 08.10.2006 LFN delete file/folder - diamond ;; +;; 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 ;; +;; 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 ;; @@ -60,6 +63,8 @@ PUSHAD_EBP equ [esp+8] PUSHAD_ESI equ [esp+4] PUSHAD_EDI equ [esp+0] +uglobal +align 4 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 @@ -82,22 +87,18 @@ 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 +fat_in_cache dd -1 +endg + +uglobal +align 4 +fat_cache: times 512 db 0 + Sector512: ; label for dev_hdcd.inc + buffer: times 512 db 0 + fsinfo_buffer: times 512 db 0 endg uglobal @@ -123,14 +124,19 @@ reserve_hd1: reserve_ok1: push eax - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,5 - mov eax,[eax+0x3000+TASKDATA.pid] + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] mov [hd1_status],eax pop eax sti ret ;******************************************** + +uglobal +hd_in_cache db ? +endg + reserve_hd_channel: cmp [hdbase], 0x1F0 jne .IDE_Channel_2 @@ -147,14 +153,27 @@ reserve_hd_channel: je .reserve_ok_2 sti call change_task - jmp .IDE_Channel_1 + jmp .IDE_Channel_2 .reserve_ok_1: - mov [IDE_Channel_1],1 - ret + mov [IDE_Channel_1], 1 + push eax + mov al, 1 + jmp @f .reserve_ok_2: - mov [IDE_Channel_2],1 - ret - + mov [IDE_Channel_2], 1 + push eax + mov al, 3 +@@: + cmp [hdid], 1 + sbb al, -1 + cmp al, [hd_in_cache] + jz @f + mov [hd_in_cache], al + call clear_hd_cache +@@: + pop eax + ret + free_hd_channel: cmp [hdbase], 0x1F0 jne .IDE_Channel_2 @@ -165,21 +184,7 @@ free_hd_channel: 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 +problem_partition db 0 ; used for partitions search include 'part_set.inc' @@ -195,7 +200,7 @@ set_FAT: jb sfc_error cmp eax,[LAST_CLUSTER] ja sfc_error - cmp [fat_type],16 + cmp [fs_type],16 je sfc_1 add eax,eax sfc_1: @@ -220,10 +225,10 @@ set_FAT: call hd_read cmp [hd_error],0 jne sfc_error - + sfc_in_cache: - cmp [fat_type],16 + cmp [fs_type],16 jne sfc_test32 sfc_set16: @@ -259,7 +264,7 @@ get_FAT: ;-------------------------------- push ebx esi - cmp [fat_type],16 + cmp [fs_type],16 je gfc_1 add eax,eax gfc_1: @@ -387,7 +392,7 @@ analyze_directory: jnb adr_data_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne adr_data_cluster mov eax,[ROOT_START] mov edx,[ROOT_SECTORS] @@ -482,7 +487,7 @@ analyze_directory_to_write: jnb adw_data_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne adw_data_cluster mov eax,[ROOT_START] mov edx,[ROOT_SECTORS] @@ -605,7 +610,7 @@ get_data_cluster: jnb gdc_cluster mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir - cmp [fat_type],16 + cmp [fs_type],16 jne gdc_cluster mov eax,[ROOT_START] mov ecx,[ROOT_SECTORS] ; Note: not cluster size @@ -627,7 +632,7 @@ get_data_cluster: gdcl1: call hd_read cmp [hd_error],0 - jne gdc_error + jne gdc_error add ebx,512 ; update pointer dec edx @@ -812,218 +817,6 @@ set_current_time_for_entry: 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: ;----------------------------------------------------- @@ -1033,7 +826,7 @@ add_disk_free_space: ;----------------------------------------------------- test ecx,ecx ; no change je add_dfs_no - cmp [fat_type],32 ; free disk space only used by fat32 + cmp [fs_type],32 ; free disk space only used by fat32 jne add_dfs_no push eax ebx @@ -1074,10 +867,13 @@ file_write: ; 8 - disk full ; 10 - access denied ;-------------------------------------------------------------------------- - cmp [fat_type],0 - jnz fat_ok_for_writing - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz fat_ok_for_writing + cmp [fs_type], 32 + jz fat_ok_for_writing + push ERROR_UNKNOWN_FS + pop eax + ret fat_ok_for_writing: ; call reserve_hd1 @@ -1260,8 +1056,10 @@ file_read: ; 10 - access denied ; ebx = size of file/directory ;-------------------------------------------------------------------------- - cmp [fat_type],0 - jnz fat_ok_for_reading + cmp [fs_type], 16 + jz fat_ok_for_reading + cmp [fs_type], 32 + jz fat_ok_for_reading xor ebx,ebx mov eax,ERROR_UNKNOWN_FS mov [hd1_status], ebx @@ -1382,7 +1180,7 @@ get_dir_size: mov eax,[ROOT_SECTORS] shl eax,9 ; fat16 rootdir size in bytes - cmp [fat_type],16 + cmp [fs_type],16 je dir_size_ret mov eax,[ROOT_CLUSTER] @@ -1417,10 +1215,13 @@ file_delete: ; 5 - file not found ; 10 - access denied ;----------------------------------------------------- - cmp [fat_type],0 - jnz file_del_fat_ok - mov eax,ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz file_del_fat_ok + cmp [fs_type], 32 + jz file_del_fat_ok + push ERROR_UNKNOWN_FS + pop eax + ret file_del_fat_ok: pushad @@ -1434,25 +1235,7 @@ file_delete: 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 + jnz delete_no_access delete_notdir: call delete_entry_name @@ -1514,129 +1297,6 @@ clear_cluster_chain: 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 @@ -1669,7 +1329,7 @@ delete_entry_name: mov ebx,buffer call hd_read ; read previous sector cmp [hd_error],0 - jne delete_name_end + jne delete_name_end mov ebx,buffer+0x1e0 ; start from last entry @@ -1691,169 +1351,6 @@ delete_entry_name: 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 @@ -1863,8 +1360,10 @@ get_hd_info: ; ebx = total clusters on disk ; ecx = free clusters on disk ;----------------------------------------------------------- - cmp [fat_type],0 - jnz info_fat_ok + cmp [fs_type], 16 + jz info_fat_ok + cmp [fs_type], 32 + jz info_fat_ok xor edx,edx xor ebx,ebx xor ecx,ecx @@ -1901,7 +1400,7 @@ get_hd_info: ret info_access_denied: - add esp,4 + add esp,4 xor edx,edx xor ebx,ebx xor ecx,ecx @@ -1925,430 +1424,6 @@ update_disk: 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 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 - - 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 - - -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 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 - - 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: ;----------------------------------------------------------------- ; @@ -2411,7 +1486,7 @@ hd_find_lfn: push fat16_root_first push fat16_root_next mov eax, [ROOT_CLUSTER] - cmp [fat_type], 32 + cmp [fs_type], 32 jz .fat32 .loop: call fat_find_lfn @@ -2462,11 +1537,15 @@ hd_find_lfn: ; ;-------------------------------------------------------------- fs_HdRead: - cmp [fat_type], 0 - jnz @f - or ebx, -1 - mov eax, ERROR_UNKNOWN_FS - ret + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + cmp [fs_type], 1 + jz ntfs_HdRead + or ebx, -1 + mov eax, ERROR_UNKNOWN_FS + ret @@: push edi cmp byte [esi], 0 @@ -2477,7 +1556,7 @@ fs_HdRead: or ebx, -1 mov eax, ERROR_ACCESS_DENIED ret - + .noaccess_3: add esp,4 .noaccess_1: @@ -2550,7 +1629,7 @@ fs_HdRead: mov ebx, edx call hd_read cmp [hd_error],0 - jne .noaccess_1 + jne .noaccess_1 pop ebx add edx, 512 sub ecx, 512 @@ -2617,6 +1696,17 @@ fs_HdRead: ; ;-------------------------------------------------------------- fs_HdReadFolder: + cmp [fs_type], 1 + jz ntfs_HdReadFolder + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNSUPPORTED_FS + pop eax + or ebx, -1 + ret +@@: mov eax, [ROOT_CLUSTER] push edi cmp byte [esi], 0 @@ -2657,7 +1747,7 @@ fs_HdReadFolder: mov [cluster_tmp], eax test eax, eax jnz @f - cmp [fat_type], 32 + cmp [fs_type], 32 jz .notfound mov eax, [ROOT_START] push [ROOT_SECTORS] @@ -2777,8 +1867,14 @@ fat16_root_next: ret ; CF=0 fat16_root_next_sector: ; read next sector + push [longname_sec2] + pop [longname_sec1] push ecx mov ecx, [eax+4] + push ecx + add ecx, [ROOT_START] + mov [longname_sec2], ecx + pop ecx inc ecx mov [eax+4], ecx cmp ecx, [ROOT_SECTORS] @@ -2828,6 +1924,12 @@ fat_notroot_next: add edi, 0x20 ret ; CF=0 fat_notroot_next_sector: + push [longname_sec2] + pop [longname_sec1] + push eax + call fat_get_sector + mov [longname_sec2], eax + pop eax push ecx mov ecx, [eax+4] inc ecx @@ -2974,9 +2076,20 @@ fshrfs: xor ebx, ebx ret +fs_HdCreateFolder: + mov al, 1 + jmp fs_HdRewrite.common + fs_HdRewrite: - cmp [fat_type], 0 - jz fshrfs + xor eax, eax +.common: + cmp [fs_type], 1 + jz ntfs_HdRewrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jnz fshrfs +@@: cmp byte [esi], 0 jz fshrad pushad @@ -2995,7 +2108,7 @@ fs_HdRewrite: test ebp, ebp jnz .noroot mov ebp, [ROOT_CLUSTER] - cmp [fat_type], 32 + cmp [fs_type], 32 jz .pushnotroot push fat16_root_extend_dir push fat16_root_end_write @@ -3008,6 +2121,9 @@ fs_HdRewrite: push fat16_root_next jmp .common1 .noroot: + mov eax, ERROR_ACCESS_DENIED + cmp byte [ebp+1], 0 + jz .ret1 ; check existence mov byte [ebp], 0 call hd_find_lfn @@ -3041,8 +2157,24 @@ fs_HdRewrite: .common1: call fat_find_lfn jc .notfound -; found; must not be directory +; found test byte [edi+11], 10h + jz .exists_file +; found directory; if we are creating directory, return OK, +; if we are creating file, say "access denied" + add esp, 32 + popad + test al, al + mov eax, ERROR_ACCESS_DENIED + jz @f + mov al, 0 +@@: + xor ebx, ebx + ret +.exists_file: +; found file; if we are creating directory, return "access denied", +; if we are creating file, delete existing file and continue + cmp byte [esp+32+28], 0 jz @f add esp, 32 popad @@ -3279,11 +2411,23 @@ fs_HdRewrite: 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 + cmp byte [esp+32+28], cl + jz .doit +; create directory + mov byte [edi+11], 10h ; attributes: folder + mov edx, edi + lea eax, [esp+8] + call dword [eax+16] ; flush directory + push ecx + mov ecx, [SECTORS_PER_CLUSTER] + shl ecx, 9 + jmp .doit2 .doit: lea eax, [esp+8] call dword [eax+16] ; flush directory push ecx mov ecx, [esp+4+32+24] +.doit2: push ecx push edi mov esi, edx @@ -3312,6 +2456,8 @@ fs_HdRewrite: add eax, [DATA_START] ; write data .write_sector: + cmp byte [esp+16+32+28], 0 + jnz .writedir mov ecx, 512 cmp dword [esp+8], ecx jb .writeshort @@ -3325,6 +2471,7 @@ fs_HdRewrite: mov edi, buffer mov ebx, edi rep movsb +.writedircont: mov ecx, buffer+0x200 sub ecx, edi push eax @@ -3391,10 +2538,44 @@ fs_HdRewrite: call update_disk popad ret +.writedir: + push 512 + mov edi, buffer + mov ebx, edi + mov ecx, [SECTORS_PER_CLUSTER] + shl ecx, 9 + cmp ecx, [esp+12] + jnz .writedircont + dec dword [esp+16] + push esi + mov ecx, 32/4 + rep movsd + pop esi + mov dword [edi-32], '. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + push esi + mov ecx, 32/4 + rep movsd + pop esi + mov dword [edi-32], '.. ' + mov dword [edi-32+4], ' ' + mov dword [edi-32+8], ' ' + mov byte [edi-32+11], 10h + mov ecx, [esp+20+8] + cmp ecx, [ROOT_CLUSTER] + jnz @f + xor ecx, ecx +@@: + mov word [edi-32+26], cx + shr ecx, 16 + mov [edi-32+20], cx + jmp .writedircont ;---------------------------------------------------------------- ; -; fs_HdWrite - LFN variant for writing to floppy +; fs_HdWrite - LFN variant for writing to hard disk ; ; esi points to filename ; ebx pointer to 64-bit number = first wanted byte, 0+ @@ -3418,8 +2599,12 @@ fs_HdWrite.ret11: jmp fs_HdWrite.ret0 fs_HdWrite: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdWrite + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f push ERROR_UNKNOWN_FS jmp .ret0 @@: @@ -3529,6 +2714,13 @@ fs_HdWrite: sub ecx, ebx jz .ret .write_loop: +; skip unmodified sectors + cmp dword [esp], 0x200 + jb .modify + sub ebx, 0x200 + jae .skip + add ebx, 0x200 +.modify: ; get length of data in current sector push ecx sub ebx, 0x200 @@ -3585,9 +2777,8 @@ fs_HdWrite: add edi, esi rep stosb @@: - pop edi ecx eax + pop edi ecx ; copy new data - push eax mov eax, edx neg ebx jecxz @f @@ -3607,6 +2798,7 @@ fs_HdWrite: sub [esp], ecx pop ecx jz .ret +.skip: ; next sector inc ebp cmp ebp, [SECTORS_PER_CLUSTER] @@ -3751,8 +2943,12 @@ hd_extend_file: ; ;-------------------------------------------------------------- fs_HdSetFileEnd: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdSetFileEnd + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f push ERROR_UNKNOWN_FS .ret: pop eax @@ -3979,8 +3175,12 @@ fs_HdSetFileEnd: ret fs_HdGetFileInfo: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdGetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f mov eax, ERROR_UNKNOWN_FS ret @@: @@ -4003,8 +3203,12 @@ fs_HdGetFileInfo: jmp fs_GetFileInfo_finish fs_HdSetFileInfo: - cmp [fat_type], 0 - jnz @f + cmp [fs_type], 1 + jz ntfs_HdSetFileInfo + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f mov eax, ERROR_UNKNOWN_FS ret @@: @@ -4039,6 +3243,8 @@ fs_HdSetFileInfo: xor eax, eax ret +if 0 ; starting from revision 237 execute is implemented in taskman.inc + ; through fs_XxxGetFileInfo and fs_XxxRead ;---------------------------------------------------------------- ; ; fs_HdExecute - LFN variant for executing from harddisk @@ -4076,7 +3282,7 @@ fs_HdExecute: .flags: cmp [fat_type], 0 jnz @f - mov eax, ERROR_UNKNOWN_FS + mov eax, -ERROR_UNKNOWN_FS ret @@: cmp byte [esi], 0 @@ -4158,5 +3364,160 @@ fs_HdExecute: popad mov eax, 11 ret +end if + +;---------------------------------------------------------------- +; +; fs_HdDelete - delete file or empty folder from hard disk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +fs_HdDelete: + cmp [fs_type], 1 + jz ntfs_HdDelete + cmp [fs_type], 16 + jz @f + cmp [fs_type], 32 + jz @f + push ERROR_UNKNOWN_FS +.pop_ret: + pop eax + ret +@@: + cmp byte [esi], 0 + jnz @f +; cannot delete root! +.access_denied: + push ERROR_ACCESS_DENIED + jmp .pop_ret +@@: + and [longname_sec1], 0 + and [longname_sec2], 0 + push edi + call hd_find_lfn + jnc .found + pop edi + push ERROR_FILE_NOT_FOUND + jmp .pop_ret +.found: + cmp dword [edi], '. ' + jz .access_denied2 + cmp dword [edi], '.. ' + jz .access_denied2 + test byte [edi+11], 10h + jz .dodel +; we can delete only empty folders! + pushad + mov ebp, [edi+20-2] + mov bp, [edi+26] + xor ecx, ecx + lea eax, [ebp-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jnz .err1 + add ebx, 2*0x20 +.checkempty: + cmp byte [ebx], 0 + jz .empty + cmp byte [ebx], 0xE5 + jnz .notempty + add ebx, 0x20 + cmp ebx, buffer+0x200 + jb .checkempty + inc ecx + cmp ecx, [SECTORS_PER_CLUSTER] + jb @f + mov eax, ebp + call get_FAT + cmp [hd_error], 0 + jnz .err1 + mov ebp, eax + xor ecx, ecx +@@: + lea eax, [ebp-2] + imul eax, [SECTORS_PER_CLUSTER] + add eax, [DATA_START] + add eax, ecx + mov ebx, buffer + call hd_read + cmp [hd_error], 0 + jz .checkempty +.err1: + popad +.err2: + pop edi + push 11 + pop eax + ret +.notempty: + popad +.access_denied2: + pop edi + push ERROR_ACCESS_DENIED + pop eax + ret +.empty: + popad + push ebx + mov ebx, buffer + call hd_read + pop ebx + cmp [hd_error], 0 + jnz .err2 +.dodel: + push eax + mov eax, [edi+20-2] + mov ax, [edi+26] + xchg eax, [esp] +; delete folder entry + mov byte [edi], 0xE5 +; delete LFN (if present) +.lfndel: + cmp edi, buffer + ja @f + cmp [longname_sec2], 0 + jz .lfndone + push [longname_sec2] + push [longname_sec1] + pop [longname_sec2] + and [longname_sec1], 0 + push ebx + mov ebx, buffer + call hd_write + mov eax, [esp+4] + call hd_read + pop ebx + pop eax + mov edi, buffer+0x200 +@@: + sub edi, 0x20 + cmp byte [edi], 0xE5 + jz .lfndone + cmp byte [edi+11], 0xF + jnz .lfndone + mov byte [edi], 0xE5 + jmp .lfndel +.lfndone: + push ebx + mov ebx, buffer + call hd_write + pop ebx +; delete FAT chain + pop eax + call clear_cluster_chain + call update_disk + pop edi + xor eax, eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret ; \end{diamond} diff --git a/kernel/branches/gfx_kernel/fs/fs.inc b/kernel/branches/gfx_kernel/fs/fs.inc index b160f34eb..676cf56ae 100644 --- a/kernel/branches/gfx_kernel/fs/fs.inc +++ b/kernel/branches/gfx_kernel/fs/fs.inc @@ -4,7 +4,6 @@ ;; (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 ;; @@ -37,12 +36,8 @@ file_system: ; ; 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 -; eax = 16 ; start application ; ; OUT: ; @@ -89,16 +84,8 @@ file_system: cmp dword [eax+0],15 ; GET_DISK_INFO je fs_info - cmp dword [eax+0],16 ; RUN - dont care about read&write blocks - je fs_read - 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 + cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests jz no_checks_for_kernel mov edx,eax cmp dword [eax+0],1 @@ -109,7 +96,7 @@ file_system: call check_region test eax,eax jnz area_in_app_mem - + .error_output: mov esi,buffer_failed call sys_msg_board_str @@ -118,7 +105,7 @@ file_system: ret iglobal buffer_failed db 'K : Buffer check failed',13,10,0 -endg +endg .usual_check: cmp dword [eax+0],0 mov ecx,512 @@ -149,11 +136,7 @@ endg ; (execute operation returns eax=-10) cmp dword [eax], 0 jz .read_root - mov ecx, 10 - cmp dword [eax], 16 - jnz @f - neg ecx -@@: mov [esp+36], ecx + mov dword [esp+36], 10 ret .read_root: ; \end{diamond}[18.03.2006] @@ -290,36 +273,8 @@ endg jmp file_system_return fs_noramdisk_write: - - cmp dword [esp+20],16 ; START APPLICATION - jne fs_noramdisk_start_application - - mov eax,[esp+4] ; fname - add eax,2*12+1 - - xor ebx,ebx ; parameters to pass - cmp dword [esp+12],ebx;0 - je no_fl_start_param - mov ebx, [esp+12] - add ebx, std_application_base_address - no_fl_start_param: - mov edx,[esp+16] ; flags - - call start_application_fl - - jmp file_system_startapp_return - - fs_noramdisk_start_application: ;there's new code - Mihasik - 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 ' @@ -334,7 +289,7 @@ endg je fs_give_dir1 mov eax,[edi+1+12] - cmp eax,'1 ' + cmp eax,'1 ' je fs_yesflpdisk_first cmp eax,'FIRS' je fs_yesflpdisk_first @@ -385,43 +340,9 @@ endg 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: - cmp dword [esp+20],16 ; START APPLICATION - jne fs_noflpdisk_start_application - - mov eax,[esp+4] ; fname - add eax,2*12+1 - - xor ebx,ebx ; parameters to pass - cmp dword [esp+12],ebx;0 - je no_flp_start_param - mov ebx,[0x3010] - mov ebx,[ebx+0x10] - add ebx,[esp+12] - - no_flp_start_param: - mov edx,[esp+16] ; flags - - call start_application_floppy - -file_system_startapp_return: - mov ebx, [esp+24+24] ; do not modify ebx in application - jmp file_system_return - - fs_noflpdisk_start_application: - fs_noflpdisk: ;***************************************************************** - + mov eax,[edi+1] cmp eax,'HD0 ' je fs_yesharddisk_IDE0 @@ -456,8 +377,9 @@ fs_yesharddisk_IDE3: mov [hdid],0x10 mov [hdpos],4 fs_yesharddisk_partition: -; call choice_necessity_partition -; jmp fs_yesharddisk_all + call reserve_hd_channel +; call choice_necessity_partition +; jmp fs_yesharddisk_all jmp fs_for_new_semantic choice_necessity_partition: @@ -507,19 +429,17 @@ choice_necessity_partition_1: je fs_give_dir1 call reserve_hd1 fs_for_new_semantic: - call choice_necessity_partition + call choice_necessity_partition fs_yesharddisk_all: mov eax,1 - cmp dword [esp+20], 16 - jnz @f - neg eax -@@: mov ebx, [esp+24+24] + 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: + call free_hd_channel and [hd1_status], 0 jmp file_system_return @@: @@ -544,6 +464,8 @@ hd_err_return: mov edi,[esp+0] mov byte [edi],'/' + call free_hd_channel + and [hd1_status], 0 jmp file_system_return fs_noharddisk_read: @@ -568,130 +490,22 @@ hd_err_return: ; eax=0 ok - eax=1 not enough free space + call free_hd_channel + and [hd1_status], 0 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: - - cmp dword [esp+20],16 ; START APPLICATION - jne fs_noharddisk_start_application - - mov eax,[esp+4] ; fname - add eax,12*2 - - mov ebx,[esp+0] ; length - sub ebx,eax - add ebx,12 - - mov ecx,[esp+4] ; work area - add ecx,512 - - xor ebp,ebp ; parameters to pass - cmp dword [esp+12],ebp;0 - je no_hd_start_param - mov ebp, [esp+12] - add ebp, std_application_base_address - no_hd_start_param: - mov edx,[esp+16] ; flags - - call start_application_hd - - jmp file_system_startapp_return - - fs_noharddisk_start_application: + call free_hd_channel + and [hd1_status], 0 fs_noharddisk: ; \begin{diamond}[18.03.2006] mov eax, 5 ; file not found ; а может быть, возвращать другой код ошибки? - cmp dword [esp+20], 16 - jnz @f - neg eax -@@: mov ebx, [esp+24+24] ; do not change ebx in application + mov ebx, [esp+24+24] ; do not change ebx in application ; \end{diamond}[18.03.2006] file_system_return: @@ -713,11 +527,7 @@ hd_err_return: jz .read add esp, 20 pop ecx - mov eax, 10 - cmp ecx, 16 - jnz @f - neg eax -@@: mov [esp+36], eax + mov dword [esp+36], 10 ret .read: ; \end{diamond}[18.03.2006] @@ -769,7 +579,7 @@ LBA_read_ramdisk: mov esi,eax shl esi,9 - add esi,0x100000 + add esi,RAMDISK mov ecx,512/4 ; cld rep movsd @@ -982,7 +792,7 @@ StringToNumber: mov [partition_string],eax mov edi,partition_string xor cx,cx -i1: +i1: mov al,[edi] cmp al,32 ;13 je i_exit diff --git a/kernel/branches/gfx_kernel/fs/fs_lfn.inc b/kernel/branches/gfx_kernel/fs/fs_lfn.inc index 889020980..0ac6f0b4a 100644 --- a/kernel/branches/gfx_kernel/fs/fs_lfn.inc +++ b/kernel/branches/gfx_kernel/fs/fs_lfn.inc @@ -41,7 +41,7 @@ rootdirs: db 3,'cd3' dd fs_OnCd3 dd fs_NextCd -;*********************************************** +;*********************************************** db 0 @@ -82,9 +82,8 @@ file_system_lfn: ; 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 +; 8 : delete file +; 9 : create directory add eax, std_application_base_address ; parse file name @@ -98,6 +97,18 @@ file_system_lfn: add esi, std_application_base_address mov ebp, esi lodsb +@@: + cmp dword [ebx], 7 + jne @F + mov edx, [ebx+4] + mov ebx, [ebx+8] + test ebx, ebx + jz .l1 + add ebx, new_app_base +.l1: + call fs_execute ; ebp, ebx, edx + mov [esp+36], eax + ret @@: cmp al, '/' jz @f @@ -351,7 +362,9 @@ fs_RamdiskServices: dd fs_RamdiskSetFileEnd dd fs_RamdiskGetFileInfo dd fs_RamdiskSetFileInfo - dd fs_RamdiskExecute + dd 0 ;fs_RamdiskExecute + dd fs_RamdiskDelete + dd fs_RamdiskCreateFolder fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 fs_OnFloppy: @@ -380,7 +393,9 @@ fs_FloppyServices: dd fs_FloppySetFileEnd dd fs_FloppyGetFileInfo dd fs_FloppySetFileInfo - dd fs_FloppyExecute + dd 0 ;fs_FloppyExecute + dd fs_FloppyDelete + dd fs_FloppyCreateFolder fs_NumFloppyServices = ($ - fs_FloppyServices)/4 fs_OnHd0: @@ -451,7 +466,9 @@ fs_HdServices: dd fs_HdSetFileEnd dd fs_HdGetFileInfo dd fs_HdSetFileInfo - dd fs_HdExecute + dd 0 ;fs_HdExecute + dd fs_HdDelete + dd fs_HdCreateFolder fs_NumHdServices = ($ - fs_HdServices)/4 ;******************************************************* @@ -535,30 +552,30 @@ fs_HasRamdisk: ret fs_HasFloppy: - cmp byte [0x40000], 0 + cmp byte [DRIVE_DATA], 0 setnz al ret fs_HasHd0: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 11000000b cmp al, 01000000b setz al ret fs_HasHd1: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00110000b cmp al, 00010000b setz al ret fs_HasHd2: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00001100b cmp al, 00000100b setz al ret fs_HasHd3: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00000011b cmp al, 00000001b setz al @@ -566,30 +583,30 @@ fs_HasHd3: ;******************************************************* fs_HasCd0: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 11000000b cmp al, 10000000b setz al ret fs_HasCd1: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00110000b cmp al, 00100000b setz al ret fs_HasCd2: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00001100b cmp al, 00001000b setz al ret fs_HasCd3: - mov al, [0x40001] + mov al, [DRIVE_DATA+1] and al, 00000011b cmp al, 00000010b setz al ret -;******************************************************* +;******************************************************* ; fs_NextXXX functions: ; in: eax = partition number, from which start to scan @@ -607,15 +624,15 @@ fs_NextRamdisk: ret fs_NextFloppy: -; we have /fd/1 iff (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0) - test byte [0x40000], 0xF0 +; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0) + test byte [DRIVE_DATA], 0xF0 jz .no1 test eax, eax jnz .no1 inc eax ret ; CF cleared .no1: - test byte [0x40000], 0x0F + test byte [DRIVE_DATA], 0x0F jz .no2 cmp al, 2 jae .no2 @@ -640,13 +657,13 @@ fs_NextHd3: push 3 fs_NextHd: pop ecx - movzx ecx, byte [0x40002+ecx] + movzx ecx, byte [DRIVE_DATA+2+ecx] cmp eax, ecx jae fs_NextFloppy.no2 inc eax clc ret - + ;******************************************************* fs_NextCd: ; we always have /cdX/1 diff --git a/kernel/branches/gfx_kernel/fs/fs_phys.inc b/kernel/branches/gfx_kernel/fs/fs_phys.inc deleted file mode 100644 index 418945d02..000000000 --- a/kernel/branches/gfx_kernel/fs/fs_phys.inc +++ /dev/null @@ -1,111 +0,0 @@ -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/branches/gfx_kernel/fs/iso9660.inc b/kernel/branches/gfx_kernel/fs/iso9660.inc index 882007295..641c62a1c 100644 --- a/kernel/branches/gfx_kernel/fs/iso9660.inc +++ b/kernel/branches/gfx_kernel/fs/iso9660.inc @@ -23,9 +23,9 @@ reserve_cd: reserve_ok2: push eax - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,5 - mov eax,[eax+0x3000+TASKDATA.pid] + mov eax,[eax+CURRENT_TASK+TASKDATA.pid] mov [cd_status],eax pop eax sti @@ -59,13 +59,15 @@ free_cd_channel: cmp [ChannelNumber],1 jne .IDE_Channel_2 .IDE_Channel_1: - mov [IDE_Channel_1],0 + mov [IDE_Channel_1],0 ret .IDE_Channel_2: mov [IDE_Channel_2],0 ret - + +uglobal cd_status dd 0 +endg ;---------------------------------------------------------------- ; @@ -91,7 +93,7 @@ fs_CdRead: or ebx, -1 mov eax, ERROR_ACCESS_DENIED ret - + .noaccess_3: pop eax edx ecx edi jmp .noaccess_2 @@ -159,7 +161,7 @@ fs_CdRead: mov [CDDataBuf_pointer],CDDataBuf call ReadCDWRetr ; читаем сектор файла cmp [DevErrorCode],0 - jne .noaccess_3 + jne .noaccess_3 push ecx add ecx, ebx cmp ecx, 2048 @@ -178,7 +180,7 @@ fs_CdRead: pop ecx xor ebx, ebx jmp .next - + .done: mov ebx, edx pop eax edx ecx edi @@ -210,14 +212,14 @@ fs_CdReadFolder: call cd_find_lfn jnc .found pop edi - cmp [DevErrorCode],0 + 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 + mov edi, [cd_current_pointer_of_input] + test byte [edi+25], 10b ; do not allow read directories jnz .found_dir pop edi .noaccess_1: @@ -225,9 +227,9 @@ fs_CdReadFolder: mov eax, ERROR_ACCESS_DENIED ret .found_dir: - mov eax,[edi+2] ; eax=cluster - mov [CDSectorAddress],eax - mov eax,[edi+10] ; размер директрории + mov eax, [edi+2] ; eax=cluster + mov [CDSectorAddress], eax + mov eax, [edi+10] ; размер директрории .doit: ; init header push eax ecx @@ -237,33 +239,36 @@ fs_CdReadFolder: rep stosd pop ecx eax mov byte [edx], 1 ; version - mov [cd_mem_location],edx - add [cd_mem_location],32 + mov [cd_mem_location], edx + add [cd_mem_location], 32 ; начинаем переброску БДВК в УСВК ;.mainloop: - mov [cd_counter_block],dword 0 - dec dword [CDSectorAddress] - push ecx + 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 + 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 + ja .read_to_buffer + mov edi, [cd_counter_block] + mov [edx+8], edi + mov edi, [ebx] + sub [edx+4], edi + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: pop ecx edi mov ebx, [edx+4] - mov eax,ERROR_SUCCESS - ret - + ret + .get_names_from_buffer: mov [cd_current_pointer_of_input_2],CDDataBuf push eax esi edi edx @@ -277,7 +282,7 @@ fs_CdReadFolder: test ecx, ecx jz .get_names_from_buffer_1 mov edi,[cd_counter_block] - mov [edx+4],edi + mov [edx+4],edi dec ecx mov esi,ebp mov edi,[cd_mem_location] @@ -372,7 +377,7 @@ cd_get_parameters_of_file: cd_get_parameters_of_file_1: ; получаем атрибуты файла xor eax,eax -; файл не архивировался +; файл не архивировалс inc al shl eax,1 ; это каталог? @@ -444,7 +449,7 @@ cd_get_parameters_of_file_1: ; ; fs_CdGetFileInfo - LFN variant for CD ; get file/directory attributes structure -; +; ;---------------------------------------------------------------- fs_CdGetFileInfo: cmp byte [esi], 0 @@ -549,7 +554,7 @@ fs_CdExecute: cmp [eax+8],dword 0 jne @f mov ecx,[eax+4] - inc dword [eax+4] + inc dword [eax+4] mov [CDSectorAddress],ecx mov [CDDataBuf_pointer],CDDataBuf ;edi call ReadCDWRetr @@ -559,7 +564,7 @@ fs_CdExecute: push esi edi ecx mov esi,512 imul esi,[eax+8] - add esi,CDDataBuf + add esi,CDDataBuf mov ecx,512/4 cld rep movsd @@ -594,7 +599,7 @@ fs_CdExecute: .err: popad mov eax, 11 - ret + ret cd_find_lfn: ; in: esi->name @@ -616,10 +621,10 @@ cd_find_lfn: jne .access_denied ; сектор является терминатором набор дескрипторов томов? cmp [CDDataBuf],byte 0xff - je .access_denied + je .access_denied ; сектор является дополнительным и улучшенным дескриптором тома? cmp [CDDataBuf],byte 0x2 - jne .start + jne .start ; сектор является дополнительным дескриптором тома? cmp [CDDataBuf+6],byte 0x1 jne .start @@ -658,18 +663,16 @@ cd_find_lfn: 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] ; размер директории + push dword [eax+2] + pop dword [CDSectorAddress] ; начало директории + mov eax,[eax+2+8] ; размер директории jmp .mainloop ; указатель файла найден .done: pop esi eax clc ret - + cd_find_name_in_buffer: mov [cd_current_pointer_of_input_2],CDDataBuf .start: @@ -677,9 +680,9 @@ cd_find_name_in_buffer: jc .not_found call cd_compare_name jc .start -.found: +.found: clc - ret + ret .not_found: stc ret @@ -710,7 +713,7 @@ cd_compare_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 + push esi eax edi mov edi,ebp .loop: cld @@ -726,7 +729,7 @@ cd_compare_name: call char_toupper call ansi2uni_char xchg ah,al - cld + cld sub edi,2 scasw jne .name_not_coincide @@ -749,7 +752,7 @@ cd_compare_name: add eax,ebp sub eax,34 cmp edi,eax - je .done_1 + je .done_1 ; проверка конца папки movzx eax,byte [ebp-1] add eax,ebp @@ -761,7 +764,7 @@ cd_compare_name: inc esi clc ret - + char_todown: ; convert character to uppercase, using cp866 encoding ; in: al=symbol @@ -785,7 +788,7 @@ char_todown: .az: add al, 0x20 ret - + uni2ansi_char: ; convert UNICODE character in al to ANSI character in ax, using cp866 encoding ; in: ax=UNICODE character diff --git a/kernel/branches/gfx_kernel/fs/ntfs.inc b/kernel/branches/gfx_kernel/fs/ntfs.inc new file mode 100644 index 000000000..29c09965d --- /dev/null +++ b/kernel/branches/gfx_kernel/fs/ntfs.inc @@ -0,0 +1,1790 @@ +ntfs_test_bootsec: +; in: ebx->buffer, edx=size of partition +; out: CF set <=> invalid +; 1. Name=='NTFS ' + cmp dword [ebx+3], 'NTFS' + jnz .no + cmp dword [ebx+7], ' ' + jnz .no +; 2. Number of bytes per sector is the same as for physical device +; (that is, 0x200 for hard disk) + cmp word [ebx+11], 0x200 + jnz .no +; 3. Number of sectors per cluster must be power of 2 + movzx eax, byte [ebx+13] + dec eax + js .no + test al, [ebx+13] + jnz .no +; 4. FAT parameters must be zero + cmp word [ebx+14], 0 + jnz .no + cmp dword [ebx+16], 0 + jnz .no + cmp byte [ebx+20], 0 + jnz .no + cmp word [ebx+22], 0 + jnz .no + cmp dword [ebx+32], 0 + jnz .no +; 5. Number of sectors <= partition size + cmp dword [ebx+0x2C], 0 + ja .no + cmp [ebx+0x28], edx + ja .no +; 6. $MFT and $MFTMirr clusters must be within partition + cmp dword [ebx+0x34], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x30] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no + cmp dword [ebx+0x3C], 0 + ja .no + push edx + movzx eax, byte [ebx+13] + mul dword [ebx+0x38] + test edx, edx + pop edx + jnz .no + cmp eax, edx + ja .no +; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 + movsx eax, byte [ebx+0x40] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x40], al + jnz .no +@@: +; 8. Same for clusters per IndexAllocationBuffer + movsx eax, byte [ebx+0x44] + cmp al, -31 + jl .no + cmp al, -9 + jle @f + dec eax + js .no + test [ebx+0x44], al + jnz .no +@@: +; OK, this is correct NTFS bootsector + clc + ret +.no: +; No, this bootsector isn't NTFS + stc + ret + +ntfs_setup: ; CODE XREF: part_set.inc +; By given bootsector, initialize some NTFS variables + call ntfs_test_bootsec + jc problem_fat_dec_count + movzx eax, byte [ebx+13] + mov [ntfs_data.sectors_per_cluster], eax + mov eax, [ebx+0x28] + add eax, [PARTITION_START] + dec eax + mov [PARTITION_END], eax + mov [fs_type], 1 + mov eax, [ebx+0x30] + mov [ntfs_data.mft_cluster], eax + mov eax, [ebx+0x38] + mov [ntfs_data.mftmirr_cluster], eax + movsx eax, byte [ebx+0x40] + test eax, eax + js .1 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .2 +.1: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.2: + mov [ntfs_data.frs_size], eax + movsx eax, byte [ebx+0x44] + test eax, eax + js .3 + mul [ntfs_data.sectors_per_cluster] + shl eax, 9 + jmp .4 +.3: + neg eax + mov ecx, eax + mov eax, 1 + shl eax, cl +.4: + mov [ntfs_data.iab_size], eax +; allocate space for buffers + add eax, [ntfs_data.frs_size] + push eax + call kernel_alloc + test eax, eax + jz problem_fat_dec_count + mov [ntfs_data.frs_buffer], eax + add eax, [ntfs_data.frs_size] + mov [ntfs_data.iab_buffer], eax +; read $MFT disposition + mov eax, [ntfs_data.mft_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz .usemirr + cmp dword [ebx], 'FILE' + jnz .usemirr + call ntfs_restore_usa_frs + jnc .mftok +.usemirr: + and [hd_error], 0 + mov eax, [ntfs_data.mftmirr_cluster] + mul [ntfs_data.sectors_per_cluster] + call ntfs_read_frs_sector + cmp [hd_error], 0 + jnz @f + cmp dword [ebx], 'FILE' + jnz @f + call ntfs_restore_usa_frs + jnc .mftok +@@: +; $MFT and $MFTMirr invalid! +.fail_free_frs: + push [ntfs_data.frs_buffer] + call kernel_free + jmp problem_fat_dec_count +.fail_free_mft: + push [ntfs_data.mft_retrieval] + call kernel_free + jmp .fail_free_frs +.mftok: +; read $MFT table retrieval information +; start with one page, increase if not enough (when MFT too fragmented) + push ebx + push 0x1000 + call kernel_alloc + pop ebx + test eax, eax + jz .fail_free_frs + mov [ntfs_data.mft_retrieval], eax + and [ntfs_data.mft_retrieval_size], 0 + mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 +; $MFT base record must contain unnamed non-resident $DATA attribute + movzx eax, word [ebx+14h] + add eax, ebx +.scandata: + cmp dword [eax], -1 + jz .fail_free_mft + cmp dword [eax], 0x80 + jnz @f + cmp byte [eax+9], 0 + jz .founddata +@@: + add eax, [eax+4] + jmp .scandata +.founddata: + cmp byte [eax+8], 0 + jz .fail_free_mft +; load first portion of $DATA attribute retrieval information + mov edx, [eax+0x18] + mov [ntfs_data.mft_retrieval_end], edx + mov esi, eax + movzx eax, word [eax+0x20] + add esi, eax + sub esp, 10h +.scanmcb: + call ntfs_decode_mcb_entry + jnc .scanmcbend + call .get_mft_retrieval_ptr + mov edx, [esp] ; block length + mov [eax], edx + mov edx, [esp+8] ; block addr (relative) + mov [eax+4], edx + inc [ntfs_data.mft_retrieval_size] + jmp .scanmcb +.scanmcbend: + add esp, 10h +; there may be other portions of $DATA attribute in auxiliary records; +; if they will be needed, they will be loaded later + + mov [ntfs_data.cur_index_size], 0x1000/0x200 + push 0x1000 + call kernel_alloc + test eax, eax + jz .fail_free_mft + mov [ntfs_data.cur_index_buf], eax + + popad + call free_hd_channel + and [hd1_status], 0 + ret + +.get_mft_retrieval_ptr: + pushad + mov eax, [ntfs_data.mft_retrieval_size] + cmp eax, [ntfs_data.mft_retrieval_alloc] + jnz .ok + add eax, 0x1000/8 + mov [ntfs_data.mft_retrieval_alloc], eax + shl eax, 3 + push eax + call kernel_alloc + test eax, eax + jnz @f + popad + add esp, 14h + jmp .fail_free_mft +@@: + mov esi, [ntfs_data.mft_retrieval] + mov edi, eax + mov ecx, [ntfs_data.mft_retrieval_size] + add ecx, ecx + rep movsd + push [ntfs_data.mft_retrieval] + mov [ntfs_data.mft_retrieval], eax + call kernel_free + mov eax, [ntfs_data.mft_retrieval_size] +.ok: + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + mov [esp+28], eax + popad + ret + +ntfs_read_frs_sector: + push eax ecx + add eax, [PARTITION_START] + mov ecx, [ntfs_data.frs_size] + shr ecx, 9 + mov ebx, [ntfs_data.frs_buffer] + push ebx +@@: + call hd_read + cmp [hd_error], 0 + jnz .fail + add ebx, 0x200 + inc eax + loop @b +.fail: + pop ebx + pop ecx eax + ret + +uglobal +align 4 +ntfs_cur_attr dd ? +ntfs_cur_iRecord dd ? +ntfs_cur_offs dd ? ; in sectors +ntfs_cur_size dd ? ; in sectors +ntfs_cur_buf dd ? +ntfs_cur_read dd ? ; [output] +ntfs_bCanContinue db ? + rb 3 + +ntfs_attrlist_buf rb 0x400 +ntfs_attrlist_mft_buf rb 0x400 +ntfs_bitmap_buf rb 0x400 + +ntfs_attr_iRecord dd ? +ntfs_attr_iBaseRecord dd ? +ntfs_attr_offs dd ? +ntfs_attr_list dd ? +ntfs_attr_size dq ? +ntfs_cur_tail dd ? +endg + +ntfs_read_attr: +; in: global variables +; out: [ntfs_cur_read] + pushad + and [ntfs_cur_read], 0 + cmp [ntfs_cur_iRecord], 0 + jnz .nomft + cmp [ntfs_cur_attr], 0x80 + jnz .nomft + mov eax, [ntfs_data.mft_retrieval_end] + inc eax + mul [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + jbe .nomft +; precalculated part of $Mft $DATA + mov esi, [ntfs_data.mft_retrieval] + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] +; eax = VCN, edx = offset in sectors from beginning of cluster + xor ecx, ecx ; ecx will contain LCN +.mftscan: + add ecx, [esi+4] + sub eax, [esi] + jb @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jnz .mftscan + jmp .nomft +@@: + push ecx + add ecx, eax + add ecx, [esi] + push eax + push edx + mov eax, [ntfs_data.sectors_per_cluster] + mul ecx +; eax = sector on partition + add eax, [PARTITION_START] + pop edx + add eax, edx + mov ebx, [ntfs_cur_buf] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: +; ecx = number of sequential sectors to read + call hd_read + cmp [hd_error], 0 + jnz .errread + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + loop @b + pop ecx + xor eax, eax + xor edx, edx + cmp [ntfs_cur_size], eax + jz @f + add esi, 8 + push eax + mov eax, [ntfs_data.mft_retrieval_end] + shl eax, 3 + add eax, [ntfs_data.mft_retrieval] + cmp eax, esi + pop eax + jz .nomft + jmp .mftscan +@@: + popad + ret +.errread: + pop ecx +.errret: + stc + popad + ret +.nomft: +; 1. Read file record. +; N.B. This will do recursive call of read_attr for $MFT::$Data. + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iRecord], eax + and [ntfs_attr_list], 0 + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + or [ntfs_attr_iBaseRecord], -1 + call ntfs_read_file_record + test eax, eax + jz .errret +; 2. Find required attribute. + mov eax, [ntfs_data.frs_buffer] +; a) For auxiliary records, read base record +; N.B. If base record is present, +; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero + cmp dword [eax+24h], 0 + jz @f + mov eax, [eax+20h] +; test eax, eax +; jz @f +.beginfindattr: + mov [ntfs_attr_iRecord], eax + call ntfs_read_file_record + test eax, eax + jz .errret +@@: +; b) Scan for required attribute and for $ATTR_LIST + mov eax, [ntfs_data.frs_buffer] + movzx ecx, word [eax+14h] + add eax, ecx + mov ecx, [ntfs_cur_attr] + and [ntfs_attr_offs], 0 +.scanattr: + cmp dword [eax], -1 + jz .scandone + cmp dword [eax], ecx + jz .okattr + cmp [ntfs_attr_iBaseRecord], -1 + jnz .scancont + cmp dword [eax], 0x20 ; $ATTR_LIST + jnz .scancont + mov [ntfs_attr_list], eax + jmp .scancont +.okattr: +; ignore named $DATA attributes (aka NTFS streams) + cmp ecx, 0x80 + jnz @f + cmp byte [eax+9], 0 + jnz .scancont +@@: + mov [ntfs_attr_offs], eax +.scancont: + add eax, [eax+4] + jmp .scanattr +.continue: + pushad + and [ntfs_cur_read], 0 +.scandone: +; c) Check for required offset and length + mov ecx, [ntfs_attr_offs] + jecxz .noattr + push [ntfs_cur_size] + push [ntfs_cur_read] + call .doreadattr + pop edx + pop eax + jc @f + cmp [ntfs_bCanContinue], 0 + jz @f + sub edx, [ntfs_cur_read] + neg edx + shr edx, 9 + sub eax, edx + mov [ntfs_cur_size], eax + jnz .not_in_cur +@@: + popad + ret +.noattr: +.not_in_cur: + cmp [ntfs_cur_attr], 0x20 + jz @f + mov ecx, [ntfs_attr_list] + test ecx, ecx + jnz .lookattr +.ret_is_attr: + cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 + popad + ret +.lookattr: +; required attribute or required offset was not found in base record; +; it may be present in auxiliary records; +; scan $ATTR_LIST + mov eax, [ntfs_attr_iBaseRecord] + cmp eax, -1 + jz @f + call ntfs_read_file_record + test eax, eax + jz .errret + or [ntfs_attr_iBaseRecord], -1 +@@: + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + push dword [ntfs_attr_size] + push dword [ntfs_attr_size+4] + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 2 + and [ntfs_cur_read], 0 + mov eax, ntfs_attrlist_buf + cmp [ntfs_cur_iRecord], 0 + jnz @f + mov eax, ntfs_attrlist_mft_buf +@@: + mov [ntfs_cur_buf], eax + push eax + call .doreadattr + pop esi + mov edx, 1 + pop dword [ntfs_attr_size+4] + pop dword [ntfs_attr_size] + mov ebp, [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + or edi, -1 + lea ebp, [ebp+esi-1Ah] +.scanliststart: + mov eax, [ntfs_cur_attr] +.scanlist: + cmp esi, ebp + jae .scanlistdone + cmp eax, [esi] + jz @f +.scanlistcont: + movzx ecx, word [esi+4] + add esi, ecx + jmp .scanlist +@@: +; ignore named $DATA attributes (aka NTFS streams) + cmp eax, 0x80 + jnz @f + cmp byte [esi+6], 0 + jnz .scanlistcont +@@: + push eax + mov eax, [esi+8] + test eax, eax + jnz .testf + mov eax, dword [ntfs_attr_size] + and eax, dword [ntfs_attr_size+4] + cmp eax, -1 + jnz .testfz +; if attribute is in auxiliary records, its size is defined only in first + mov eax, [esi+10h] + call ntfs_read_file_record + test eax, eax + jnz @f +.errret_pop: + pop eax + jmp .errret +@@: + mov eax, [ntfs_data.frs_buffer] + movzx ecx, word [eax+14h] + add eax, ecx + mov ecx, [ntfs_cur_attr] +@@: + cmp dword [eax], -1 + jz .errret_pop + cmp dword [eax], ecx + jz @f +.l1: + add eax, [eax+4] + jmp @b +@@: + cmp eax, 0x80 + jnz @f + cmp byte [eax+9], 0 + jnz .l1 +@@: + cmp byte [eax+8], 0 + jnz .sdnores + mov eax, [eax+10h] + mov dword [ntfs_attr_size], eax + and dword [ntfs_attr_size+4], 0 + jmp .testfz +.sdnores: + mov ecx, [eax+30h] + mov dword [ntfs_attr_size], ecx + mov ecx, [eax+34h] + mov dword [ntfs_attr_size+4], ecx +.testfz: + xor eax, eax +.testf: + imul eax, [ntfs_data.sectors_per_cluster] + cmp eax, [ntfs_cur_offs] + pop eax + ja @f + mov edi, [esi+10h] ; keep previous iRecord + jmp .scanlistcont +@@: +.scanlistfound: + cmp edi, -1 + jnz @f + popad + ret +@@: + mov eax, [ntfs_cur_iRecord] + mov [ntfs_attr_iBaseRecord], eax + mov eax, edi + jmp .beginfindattr +.sde: + popad + stc + ret +.scanlistdone: + sub ebp, ntfs_attrlist_buf-1Ah + cmp [ntfs_cur_iRecord], 0 + jnz @f + sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf +@@: + cmp ebp, 0x400 + jnz .scanlistfound + inc edx + push esi edi + mov esi, ntfs_attrlist_buf+0x200 + mov edi, ntfs_attrlist_buf + cmp [ntfs_cur_iRecord], 0 + jnz @f + mov esi, ntfs_attrlist_mft_buf+0x200 + mov edi, ntfs_attrlist_mft_buf +@@: + mov ecx, 0x200/4 + rep movsd + mov eax, edi + pop edi esi + sub esi, 0x200 + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_read] + push [ntfs_cur_buf] + push dword [ntfs_attr_size] + push dword [ntfs_attr_size+4] + or dword [ntfs_attr_size], -1 + or dword [ntfs_attr_size+4], -1 + mov [ntfs_cur_offs], edx + mov [ntfs_cur_size], 1 + and [ntfs_cur_read], 0 + mov [ntfs_cur_buf], eax + mov ecx, [ntfs_attr_list] + push esi edx + call .doreadattr + pop edx esi + mov ebp, [ntfs_cur_read] + pop dword [ntfs_attr_size+4] + pop dword [ntfs_attr_size] + pop [ntfs_cur_buf] + pop [ntfs_cur_read] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + jc .errret + add ebp, ntfs_attrlist_buf+0x200-0x1A + cmp [ntfs_cur_iRecord], 0 + jnz .scanliststart + add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf + jmp .scanliststart + +.doreadattr: + mov [ntfs_bCanContinue], 0 + cmp byte [ecx+8], 0 + jnz .nonresident + mov eax, [ecx+10h] ; length + mov esi, eax + mov edx, [ntfs_cur_offs] + shr eax, 9 + cmp eax, edx + jb .okret + shl edx, 9 + sub esi, edx + movzx eax, word [ecx+14h] + add edx, eax + add edx, ecx ; edx -> data + mov eax, [ntfs_cur_size] + cmp eax, (0xFFFFFFFF shr 9)+1 + jbe @f + mov eax, (0xFFFFFFFF shr 9)+1 +@@: + shl eax, 9 + cmp eax, esi + jbe @f + mov eax, esi +@@: +; eax = length, edx -> data + mov [ntfs_cur_read], eax + mov ecx, eax + mov eax, edx + mov ebx, [ntfs_cur_buf] + call memmove + and [ntfs_cur_size], 0 ; CF=0 + ret +.nonresident: +; Not all auxiliary records contain correct FileSize info + mov eax, dword [ntfs_attr_size] + mov edx, dword [ntfs_attr_size+4] + push eax + and eax, edx + cmp eax, -1 + pop eax + jnz @f + mov eax, [ecx+30h] ; FileSize + mov edx, [ecx+34h] + mov dword [ntfs_attr_size], eax + mov dword [ntfs_attr_size+4], edx +@@: + add eax, 0x1FF + adc edx, 0 + shrd eax, edx, 9 + sub eax, [ntfs_cur_offs] + ja @f +; return with nothing read + and [ntfs_cur_size], 0 +.okret: + clc + ret +@@: +; reduce read length + and [ntfs_cur_tail], 0 + cmp [ntfs_cur_size], eax + jb @f + mov [ntfs_cur_size], eax + mov eax, dword [ntfs_attr_size] + and eax, 0x1FF + mov [ntfs_cur_tail], eax +@@: + cmp [ntfs_cur_size], 0 + jz .okret + mov eax, [ntfs_cur_offs] + xor edx, edx + div [ntfs_data.sectors_per_cluster] + sub eax, [ecx+10h] ; first_vbo + jb .okret +; eax = cluster, edx = starting sector + sub esp, 10h + movzx esi, word [ecx+20h] ; mcb_info_ofs + add esi, ecx + xor ebp, ebp +.readloop: + call ntfs_decode_mcb_entry + jnc .break + add ebp, [esp+8] + sub eax, [esp] + jae .readloop + push ecx + push eax + add eax, [esp+8] + add eax, ebp + imul eax, [ntfs_data.sectors_per_cluster] + add eax, edx + add eax, [PARTITION_START] + pop ecx + neg ecx + imul ecx, [ntfs_data.sectors_per_cluster] + sub ecx, edx + cmp ecx, [ntfs_cur_size] + jb @f + mov ecx, [ntfs_cur_size] +@@: + mov ebx, [ntfs_cur_buf] +@@: + call hd_read + cmp [hd_error], 0 + jnz .errread2 + add ebx, 0x200 + mov [ntfs_cur_buf], ebx + inc eax + add [ntfs_cur_read], 0x200 + dec [ntfs_cur_size] + inc [ntfs_cur_offs] + loop @b + pop ecx + xor eax, eax + xor edx, edx + cmp [ntfs_cur_size], 0 + jnz .readloop + add esp, 10h + mov eax, [ntfs_cur_tail] + test eax, eax + jz .okret + sub eax, 0x200 + add [ntfs_cur_read], eax + jmp .okret +.errread2: + pop ecx + add esp, 10h + jmp .errret +.break: + add esp, 10h ; CF=0 + mov [ntfs_bCanContinue], 1 + ret + +ntfs_read_file_record: +; in: eax=iRecord +; out: [ntfs_data.frs_buffer] contains information +; eax=0 - failed, eax=1 - success +; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] + push ecx edx + mov ecx, [ntfs_data.frs_size] + mul ecx + shrd eax, edx, 9 + shr edx, 9 + jnz .err + push [ntfs_attr_iRecord] + push [ntfs_attr_iBaseRecord] + push [ntfs_attr_offs] + push [ntfs_attr_list] + push dword [ntfs_attr_size+4] + push dword [ntfs_attr_size] + push [ntfs_cur_iRecord] + push [ntfs_cur_attr] + push [ntfs_cur_offs] + push [ntfs_cur_size] + push [ntfs_cur_buf] + push [ntfs_cur_read] + mov [ntfs_cur_attr], 0x80 ; $DATA + and [ntfs_cur_iRecord], 0 ; $Mft + mov [ntfs_cur_offs], eax + shr ecx, 9 + mov [ntfs_cur_size], ecx + mov eax, [ntfs_data.frs_buffer] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + mov eax, [ntfs_cur_read] + pop [ntfs_cur_read] + pop [ntfs_cur_buf] + pop [ntfs_cur_size] + pop [ntfs_cur_offs] + pop [ntfs_cur_attr] + pop [ntfs_cur_iRecord] + pop dword [ntfs_attr_size] + pop dword [ntfs_attr_size+4] + pop [ntfs_attr_list] + pop [ntfs_attr_offs] + pop [ntfs_attr_iBaseRecord] + pop [ntfs_attr_iRecord] + pop edx ecx + jc .errret + cmp eax, [ntfs_data.frs_size] + jnz .errret + mov eax, [ntfs_data.frs_buffer] + cmp dword [eax], 'FILE' + jnz .errret + push ebx + mov ebx, eax + call ntfs_restore_usa_frs + pop ebx + setnc al + movzx eax, al +.ret: + ret +.err: + pop edx ecx +.errret: + xor eax, eax + ret + +ntfs_restore_usa_frs: + mov eax, [ntfs_data.frs_size] +ntfs_restore_usa: + pushad + shr eax, 9 + mov ecx, eax + inc eax + cmp [ebx+6], ax + jnz .err + movzx eax, word [ebx+4] + lea esi, [eax+ebx] + lodsw + mov edx, eax + lea edi, [ebx+0x1FE] +@@: + cmp [edi], dx + jnz .err + lodsw + stosw + add edi, 0x1FE + loop @b + popad + clc + ret +.err: + popad + stc + ret + +ntfs_decode_mcb_entry: + push eax ecx edi + lea edi, [esp+16] + xor eax, eax + lodsb + test al, al + jz .end + mov ecx, eax + and ecx, 0xF + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + jae .end + push eax + xor eax, eax + rep stosb + pop ecx + shr ecx, 4 + cmp ecx, 8 + ja .end + push ecx + rep movsb + pop ecx + sub ecx, 8 + neg ecx + cmp byte [esi-1], 80h + cmc + sbb eax, eax + rep stosb + stc +.end: + pop edi ecx eax + ret + +ntfs_find_lfn: +; in: esi->name +; out: CF=1 - file not found +; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory + mov [ntfs_cur_iRecord], 5 ; start parse from root cluster +.doit2: + mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ntfs_cur_offs], 0 + mov eax, [ntfs_data.cur_index_size] + mov [ntfs_cur_size], eax + mov eax, [ntfs_data.cur_index_buf] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + jnc @f +.ret: + ret +@@: + cmp [ntfs_cur_read], 0x20 + jc .ret + pushad + mov esi, [ntfs_data.cur_index_buf] + mov eax, [esi+14h] + add eax, 10h + cmp [ntfs_cur_read], eax + jae .readok1 + add eax, 1FFh + shr eax, 9 + cmp eax, [ntfs_data.cur_index_size] + ja @f +.stc_ret: + popad + stc + ret +@@: +; reallocate + push eax + push [ntfs_data.cur_index_buf] + call kernel_free + pop eax + mov [ntfs_data.cur_index_size], eax + push eax + call kernel_alloc + test eax, eax + jnz @f + and [ntfs_data.cur_index_size], 0 + and [ntfs_data.cur_index_buf], 0 + jmp .stc_ret +@@: + mov [ntfs_data.cur_index_buf], eax + popad + jmp .doit2 +.readok1: + mov ebp, [esi+8] ; subnode_size + shr ebp, 9 + cmp ebp, [ntfs_data.cur_index_size] + jbe .ok2 + push esi ebp + push ebp + call kernel_alloc + pop ebp esi + test eax, eax + jz .stc_ret + mov edi, eax + mov ecx, [ntfs_data.cur_index_size] + shl ecx, 9-2 + rep movsd + mov esi, eax + mov [ntfs_data.cur_index_size], ebp + push esi ebp + push [ntfs_data.cur_index_buf] + call kernel_free + pop ebp esi + mov [ntfs_data.cur_index_buf], esi +.ok2: + add esi, 10h + mov edi, [esp+4] +; edi -> name, esi -> current index data, ebp = subnode size +.scanloop: + add esi, [esi] +.scanloopint: + test byte [esi+0Ch], 2 + jnz .subnode + push esi + add esi, 0x52 + movzx ecx, byte [esi-2] + push edi +@@: + lodsw + call uni2ansi_char + call char_toupper + push eax + mov al, [edi] + inc edi + call char_toupper + cmp al, [esp] + pop eax + loopz @b + jz .found + pop edi + pop esi + jb .subnode +.scanloopcont: + movzx eax, word [esi+8] + add esi, eax + jmp .scanloopint +.subnode: + test byte [esi+0Ch], 1 + jz .notfound + movzx eax, word [esi+8] + mov eax, [esi+eax-8] + mul [ntfs_data.sectors_per_cluster] + mov [ntfs_cur_offs], eax + mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION + mov [ntfs_cur_size], ebp + mov eax, [ntfs_data.cur_index_buf] + mov esi, eax + mov [ntfs_cur_buf], eax + call ntfs_read_attr + mov eax, ebp + shl eax, 9 + cmp [ntfs_cur_read], eax + jnz .notfound + cmp dword [esi], 'INDX' + jnz .notfound + mov ebx, esi + call ntfs_restore_usa + jc .notfound + add esi, 0x18 + jmp .scanloop +.notfound: + popad + stc + ret +.found: + cmp byte [edi], 0 + jz .done + cmp byte [edi], '/' + jz .next + pop edi + pop esi + jmp .scanloopcont +.done: +.next: + pop esi + pop esi + mov eax, [esi] + mov [ntfs_cur_iRecord], eax + mov [esp+1Ch], esi + mov [esp+4], edi + popad + inc esi + cmp byte [esi-1], 0 + jnz .doit2 + ret + +;---------------------------------------------------------------- +; +; ntfs_HdRead - read NTFS 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 +; +;-------------------------------------------------------------- +ntfs_HdRead: + cmp byte [esi], 0 + jnz @f + or ebx, -1 + push ERROR_ACCESS_DENIED + pop eax + ret +@@: + call ntfs_find_lfn + jnc .found + or ebx, -1 + push ERROR_FILE_NOT_FOUND + pop eax + ret +.found: + mov [ntfs_cur_attr], 0x80 ; $DATA + and [ntfs_cur_offs], 0 + and [ntfs_cur_size], 0 + call ntfs_read_attr + jnc @f + or ebx, -1 + push ERROR_ACCESS_DENIED + pop eax + ret +@@: + pushad + and dword [esp+10h], 0 + xor eax, eax + test ebx, ebx + jz .zero1 + cmp dword [ebx+4], 0x200 + jb @f +.eof0: + popad + xor ebx, ebx +.eof: + push ERROR_END_OF_FILE + pop eax + ret +@@: + mov eax, [ebx] + test eax, 0x1FF + jz .alignedstart + push edx + mov edx, [ebx+4] + shrd eax, edx, 9 + pop edx + mov [ntfs_cur_offs], eax + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr.continue + mov eax, [ebx] + and eax, 0x1FF + lea esi, [ntfs_bitmap_buf+eax] + sub eax, [ntfs_cur_read] + jae .eof0 + neg eax + push ecx + cmp ecx, eax + jb @f + mov ecx, eax +@@: + mov [esp+10h+4], ecx + mov edi, edx + rep movsb + mov edx, edi + pop ecx + sub ecx, [esp+10h] + jnz @f +.retok: + popad + xor eax, eax + ret +@@: + cmp [ntfs_cur_read], 0x200 + jz .alignedstart +.eof_ebx: + popad + jmp .eof +.alignedstart: + mov eax, [ebx] + push edx + mov edx, [ebx+4] + add eax, 511 + adc edx, 0 + shrd eax, edx, 9 + pop edx +.zero1: + mov [ntfs_cur_offs], eax + mov [ntfs_cur_buf], edx + mov eax, ecx + shr eax, 9 + mov [ntfs_cur_size], eax + add eax, [ntfs_cur_offs] + push eax + call ntfs_read_attr.continue + pop [ntfs_cur_offs] + mov eax, [ntfs_cur_read] + add [esp+10h], eax + mov eax, ecx + and eax, not 0x1FF + cmp [ntfs_cur_read], eax + jnz .eof_ebx + and ecx, 0x1FF + jz .retok + add edx, [ntfs_cur_read] + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr.continue + cmp [ntfs_cur_read], ecx + jb @f + mov [ntfs_cur_read], ecx +@@: + xchg ecx, [ntfs_cur_read] + push ecx + mov edi, edx + mov esi, ntfs_bitmap_buf + add [esp+10h+4], ecx + rep movsb + pop ecx + xor eax, eax + cmp ecx, [ntfs_cur_read] + jz @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+1Ch], eax + popad + ret + +;---------------------------------------------------------------- +; +; ntfs_HdReadFolder - read NTFS 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 +; +;-------------------------------------------------------------- +ntfs_HdReadFolder: + mov eax, 5 ; root cluster + cmp byte [esi], 0 + jz .doit + call ntfs_find_lfn + jnc .doit2 +.notfound: + or ebx, -1 + push ERROR_FILE_NOT_FOUND +.pop_ret: + pop eax + ret +.doit: + mov [ntfs_cur_iRecord], eax +.doit2: + mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 1 + mov [ntfs_cur_buf], ntfs_bitmap_buf + call ntfs_read_attr + jc .notfound + mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT + and [ntfs_cur_offs], 0 + mov eax, [ntfs_data.cur_index_size] + mov [ntfs_cur_size], eax + mov eax, [ntfs_data.cur_index_buf] + mov [ntfs_cur_buf], eax + call ntfs_read_attr + jnc .ok + cmp [hd_error], 0 + jz .notfound + or ebx, -1 + push 11 + jmp .pop_ret +.ok: + cmp [ntfs_cur_read], 0x20 + jae @f + or ebx, -1 +.fserr: + push ERROR_FAT_TABLE + jmp .pop_ret +@@: + pushad + mov esi, [ntfs_data.cur_index_buf] + mov eax, [esi+14h] + add eax, 10h + cmp [ntfs_cur_read], eax + jae .readok1 + add eax, 1FFh + shr eax, 9 + cmp eax, [ntfs_data.cur_index_size] + ja @f + popad + jmp .fserr +@@: +; reallocate + push eax + push [ntfs_data.cur_index_buf] + call kernel_free + pop eax + mov [ntfs_data.cur_index_size], eax + push eax + call kernel_alloc + test eax, eax + jnz @f + and [ntfs_data.cur_index_size], 0 + and [ntfs_data.cur_index_buf], 0 +.nomem: + popad + or ebx, -1 + push 12 + pop eax + ret +@@: + mov [ntfs_data.cur_index_buf], eax + popad + jmp .doit2 +.readok1: + mov ebp, [esi+8] ; subnode_size + shr ebp, 9 + cmp ebp, [ntfs_data.cur_index_size] + jbe .ok2 + push esi ebp + push ebp + call kernel_alloc + pop ebp esi + test eax, eax + jz .nomem + mov edi, eax + mov ecx, [ntfs_data.cur_index_size] + shl ecx, 9-2 + rep movsd + mov esi, eax + mov [ntfs_data.cur_index_size], ebp + push esi ebp + push [ntfs_data.cur_index_buf] + call kernel_free + pop ebp esi + mov [ntfs_data.cur_index_buf], esi +.ok2: + add esi, 10h + mov ebx, [esp+10h] + mov edx, [esp+14h] + push dword [ebx+4] ; read ANSI/UNICODE name + mov ebx, [ebx] +; init header + mov edi, edx + mov ecx, 32/4 + xor eax, eax + rep stosd + mov byte [edx], 1 ; version + mov ecx, [esp+4+18h] + push edx + mov edx, esp +; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, +; ecx = number of blocks to read +; edx -> parameters block: dd , dd + cmp [ntfs_cur_iRecord], 5 + jz .skip_specials +; dot and dotdot entries + push esi + xor esi, esi + call .add_special_entry + inc esi + call .add_special_entry + pop esi +.skip_specials: +; at first, dump index root + add esi, [esi] +.dump_root: + test byte [esi+0Ch], 2 + jnz .dump_root_done + call .add_entry + movzx eax, word [esi+8] + add esi, eax + jmp .dump_root +.dump_root_done: +; now dump all subnodes + push ecx edi + mov edi, ntfs_bitmap_buf + mov [ntfs_cur_buf], edi + mov ecx, 0x400/4 + xor eax, eax + rep stosd + mov [ntfs_cur_attr], 0xB0 ; $BITMAP + and [ntfs_cur_offs], 0 + mov [ntfs_cur_size], 2 + call ntfs_read_attr + pop edi ecx + push 0 ; save offset in $BITMAP attribute + and [ntfs_cur_offs], 0 +.dumploop: + mov [ntfs_cur_attr], 0xA0 + mov [ntfs_cur_size], ebp + mov eax, [ntfs_data.cur_index_buf] + mov esi, eax + mov [ntfs_cur_buf], eax + push [ntfs_cur_offs] + mov eax, [ntfs_cur_offs] + imul eax, ebp + mov [ntfs_cur_offs], eax + call ntfs_read_attr + pop [ntfs_cur_offs] + mov eax, ebp + shl eax, 9 + cmp [ntfs_cur_read], eax + jnz .done + push eax + mov eax, [ntfs_cur_offs] + and eax, 0x400*8-1 + bt dword [ntfs_bitmap_buf], eax + pop eax + jnc .dump_subnode_done + cmp dword [esi], 'INDX' + jnz .dump_subnode_done + push ebx + mov ebx, esi + call ntfs_restore_usa + pop ebx + jc .dump_subnode_done + add esi, 0x18 + add esi, [esi] +.dump_subnode: + test byte [esi+0Ch], 2 + jnz .dump_subnode_done + call .add_entry + movzx eax, word [esi+8] + add esi, eax + jmp .dump_subnode +.dump_subnode_done: + inc [ntfs_cur_offs] + test [ntfs_cur_offs], 0x400*8-1 + jnz .dumploop + mov [ntfs_cur_attr], 0xB0 + push ecx edi + mov edi, ntfs_bitmap_buf + mov [ntfs_cur_buf], edi + mov ecx, 0x400/4 + xor eax, eax + rep stosd + pop edi ecx + pop eax + push [ntfs_cur_offs] + inc eax + mov [ntfs_cur_offs], eax + mov [ntfs_cur_size], 2 + push eax + call ntfs_read_attr + pop eax + pop [ntfs_cur_offs] + push eax + jmp .dumploop +.done: + pop eax + pop edx + mov ebx, [edx+4] + pop edx + xor eax, eax + dec ecx + js @f + mov al, ERROR_END_OF_FILE +@@: + mov [esp+1Ch], eax + mov [esp+10h], ebx + popad + ret + +.add_special_entry: + mov eax, [edx] + inc dword [eax+8] ; new file found + dec ebx + jns .ret + dec ecx + js .ret + inc dword [eax+4] ; new file block copied + mov eax, [edx+4] + mov [edi+4], eax +; mov eax, dword [ntfs_bitmap_buf+0x20] +; or al, 0x10 + mov eax, 0x10 + stosd + scasd + push edx + mov eax, dword [ntfs_bitmap_buf] + mov edx, dword [ntfs_bitmap_buf+4] + call ntfs_datetime_to_bdfe + mov eax, dword [ntfs_bitmap_buf+0x18] + mov edx, dword [ntfs_bitmap_buf+0x1C] + call ntfs_datetime_to_bdfe + mov eax, dword [ntfs_bitmap_buf+8] + mov edx, dword [ntfs_bitmap_buf+0xC] + call ntfs_datetime_to_bdfe + pop edx + xor eax, eax + stosd + stosd + mov al, '.' + push edi ecx + lea ecx, [esi+1] + test byte [edi-0x24], 1 + jz @f + rep stosw + pop ecx + xor eax, eax + stosw + pop edi + add edi, 520 + ret +@@: + rep stosb + pop ecx + xor eax, eax + stosb + pop edi + add edi, 264 +.ret: + ret + +.add_entry: +; do not return DOS 8.3 names + cmp byte [esi+0x51], 2 + jz .ret +; do not return system files +; ... note that there will be no bad effects if system files also were reported ... + cmp dword [esi], 0x10 + jb .ret + mov eax, [edx] + inc dword [eax+8] ; new file found + dec ebx + jns .ret + dec ecx + js .ret + inc dword [eax+4] ; new file block copied + mov eax, [edx+4] ; flags + call ntfs_direntry_to_bdfe + push ecx esi edi + movzx ecx, byte [esi+0x50] + add esi, 0x52 + test byte [edi-0x24], 1 + jz .ansi + shr ecx, 1 + rep movsd + adc ecx, ecx + rep movsw + and word [edi], 0 + pop edi + add edi, 520 + pop esi ecx + ret +.ansi: + jecxz .skip +@@: + lodsw + call uni2ansi_char + stosb + loop @b +.skip: + xor al, al + stosb + pop edi + add edi, 264 + pop esi ecx + ret + +ntfs_direntry_to_bdfe: + mov [edi+4], eax ; ANSI/UNICODE name + mov eax, [esi+48h] + test eax, 0x10000000 + jz @f + and eax, not 0x10000000 + or al, 0x10 +@@: + stosd + scasd + push edx + mov eax, [esi+0x18] + mov edx, [esi+0x1C] + call ntfs_datetime_to_bdfe + mov eax, [esi+0x30] + mov edx, [esi+0x34] + call ntfs_datetime_to_bdfe + mov eax, [esi+0x20] + mov edx, [esi+0x24] + call ntfs_datetime_to_bdfe + pop edx + mov eax, [esi+0x40] + stosd + mov eax, [esi+0x44] + stosd + ret + +iglobal +_24 dd 24 +_60 dd 60 +_10000000 dd 10000000 +days400year dd 365*400+100-4+1 +days100year dd 365*100+25-1 +days4year dd 365*4+1 +days1year dd 365 +months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +_400 dd 400 +_100 dd 100 +endg + +ntfs_datetime_to_bdfe: +; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC + push eax + mov eax, edx + xor edx, edx + div [_10000000] + xchg eax, [esp] + div [_10000000] + pop edx +; edx:eax = number of seconds since January 1, 1601 + push eax + mov eax, edx + xor edx, edx + div [_60] + xchg eax, [esp] + div [_60] + mov [edi], dl + pop edx +; edx:eax = number of minutes + div [_60] + mov [edi+1], dl +; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32) + xor edx, edx + div [_24] + mov [edi+2], dl + mov [edi+3], byte 0 +; eax = number of days since January 1, 1601 + xor edx, edx + div [days400year] + imul eax, 400 + add eax, 1601 + mov [edi+6], ax + mov eax, edx + xor edx, edx + div [days100year] + cmp al, 4 + jnz @f + dec eax + add edx, [days100year] +@@: + imul eax, 100 + add [edi+6], ax + mov eax, edx + xor edx, edx + div [days4year] + shl eax, 2 + add [edi+6], ax + mov eax, edx + xor edx, edx + div [days1year] + cmp al, 4 + jnz @f + dec eax + add edx, [days1year] +@@: + add [edi+6], ax + push esi edx + mov esi, months + movzx eax, word [edi+6] + test al, 3 + jnz .noleap + xor edx, edx + push eax + div [_400] + pop eax + test edx, edx + jz .leap + xor edx, edx + div [_100] + test edx, edx + jz .noleap +.leap: + mov esi, months2 +.noleap: + pop edx + xor eax, eax + inc eax +@@: + sub edx, [esi] + jb @f + add esi, 4 + inc eax + jmp @b +@@: + add edx, [esi] + pop esi + inc edx + mov [edi+4], dl + mov [edi+5], al + add edi, 8 + ret + +;---------------------------------------------------------------- +; +; ntfs_HdRewrite - write to NTFS 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 +; +;-------------------------------------------------------------- +ntfs_HdRewrite: + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + +;---------------------------------------------------------------- +; +; ntfs_HdWrite - write to NTFS 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 write, 0+ +; edx mem location to data +; +; ret ebx = bytes written (maybe 0) +; eax = 0 ok write or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdWrite: + xor ebx, ebx + mov eax, ERROR_UNSUPPORTED_FS + ret + +;---------------------------------------------------------------- +; +; ntfs_HdSetFileEnd - set end of file on NTFS 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 +; +;-------------------------------------------------------------- +ntfs_HdSetFileEnd: +ntfs_HdSetFileInfo: +;---------------------------------------------------------------- +; +; ntfs_HdDelete - delete file or empty folder from NTFS hard disk +; +; esi points to filename +; +; ret eax = 0 ok or other = errormsg +; +;-------------------------------------------------------------- +ntfs_HdDelete: + mov eax, ERROR_UNSUPPORTED_FS + ret + +ntfs_HdGetFileInfo: + cmp byte [esi], 0 + jnz @f + push 2 + pop eax + ret +@@: + call ntfs_find_lfn + jnc .doit + push ERROR_FILE_NOT_FOUND + pop eax + cmp [hd_error], 0 + jz @f + mov al, 11 +@@: + ret +.doit: + push esi edi + mov esi, eax + mov edi, edx + xor eax, eax + call ntfs_direntry_to_bdfe + pop edi esi + xor eax, eax + ret diff --git a/kernel/branches/gfx_kernel/fs/part_set.inc b/kernel/branches/gfx_kernel/fs/part_set.inc index aa9fea013..fba973569 100644 --- a/kernel/branches/gfx_kernel/fs/part_set.inc +++ b/kernel/branches/gfx_kernel/fs/part_set.inc @@ -5,7 +5,9 @@ ;* to MBR - Mario79 * ;************************************************************* +uglobal align 4 + ;****************************************************** ; Please do not change this place - variables in text ; Mario79 @@ -13,6 +15,12 @@ align 4 ;****************************************************** PARTITION_START dd 0x3f PARTITION_END dd 0 +fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 +align 4 + +fs_dependent_data_start: +; FATxx data + SECTORS_PER_FAT dd 0x1f3a NUMBER_OF_FATS dd 0x2 SECTORS_PER_CLUSTER dd 0x8 @@ -30,13 +38,40 @@ fatBAD dd 0x0FFFFFF7 fatEND dd 0x0FFFFFF8 fatMASK dd 0x0FFFFFFF -fat_type db 0 ; 0=none, 16=fat16, 32=fat32 +fs_dependent_data_end: +file_system_data_size = $ - PARTITION_START +if file_system_data_size > 96 +ERROR: sizeof(file system data) too big! +end if + +virtual at fs_dependent_data_start +; NTFS data +ntfs_data: +.sectors_per_cluster dd ? +.mft_cluster dd ? +.mftmirr_cluster dd ? +.frs_size dd ? ; FRS size in bytes +.iab_size dd ? ; IndexAllocationBuffer size in bytes +.frs_buffer dd ? +.iab_buffer dd ? +.mft_retrieval dd ? +.mft_retrieval_size dd ? +.mft_retrieval_alloc dd ? +.mft_retrieval_end dd ? +.cur_index_size dd ? +.cur_index_buf dd ? +if $ > fs_dependent_data_end +ERROR: increase sizeof(fs_dependent_data)! +end if +end virtual + ;*************************************************************************** ; End place ; Mario79 ;*************************************************************************** - +endg iglobal + partition_types: ; list of fat16/32 partitions db 0x04 ; DOS: fat16 <32M db 0x06 ; DOS: fat16 >32M @@ -55,6 +90,7 @@ iglobal db 0xce ; DRDOS/secured: fat16, LBA-mapped db 0xd4 ; Old Multiuser DOS secured: fat16 <32M db 0xd6 ; Old Multiuser DOS secured: fat16 >32M + db 0x07 ; NTFS partition_types_end: @@ -79,10 +115,9 @@ endg ; - 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 + call reserve_hd_channel cmp dword [hdpos],0 je problem_hd @@ -120,9 +155,17 @@ extended_already_set: 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 - + mov edx, eax ; start sector + add edx, [ebx+0x1be+8] ; add relative start + push edx + add edx, [ebx+0x1be+12] ; add length + dec edx ; PARTITION_END is inclusive + mov [PARTITION_END], edx ; note that this can be changed + ; when file system data will be available + mov dl, [ebx+0x1be+4] + mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) + pop edx + next_primary_partition: push eax mov al,[ebx+0x1be+4+16] ; get primary partition type @@ -134,8 +177,15 @@ next_primary_partition: 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 + mov edx, eax + add edx, [ebx+0x1be+8+16] + push edx + add edx, [ebx+0x1be+12+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16] + mov [fs_type], dl + pop edx next_primary_partition_1: push eax @@ -148,8 +198,15 @@ next_primary_partition_1: 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 + mov edx, eax + add edx, [ebx+0x1be+8+16+16] + push edx + add edx, [ebx+0x1be+12+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16] + mov [fs_type], dl + pop edx next_primary_partition_2: push eax @@ -162,8 +219,15 @@ next_primary_partition_2: 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 + mov edx, eax + add edx, [ebx+0x1be+8+16+16+16] + push edx + add edx, [ebx+0x1be+12+16+16+16] + dec edx + mov [PARTITION_END], edx + mov dl, [ebx+0x1be+4+16+16+16] + mov [fs_type], dl + pop edx next_partition: push eax @@ -241,7 +305,8 @@ problem_partition_or_fat: popad problem_hd: - mov [fat_type],0 + mov [fs_type],0 + call free_hd_channel mov [hd1_status],0 ; free mov [problem_partition],1 ret @@ -249,14 +314,40 @@ problem_hd: hd_and_partition_ok: mov eax,edx mov [PARTITION_START],eax + mov edx, [PARTITION_END] + sub edx, eax + inc edx ; edx = length of partition - mov [hd_setup],1 +; 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 [hd_error], 0 + jz boot_read_ok + cmp [fs_type], 7 + jnz problem_fat_dec_count +; NTFS duplicates bootsector: +; NT4/2k/XP+ saves bootsector copy in the end of disk +; NT 3.51 saves bootsector copy in the middle of disk + and [hd_error], 0 + mov eax, [PARTITION_END] + call hd_read + cmp [hd_error], 0 + jnz @f + call ntfs_test_bootsec + jnc boot_read_ok +@@: + and [hd_error], 0 + mov eax, edx + shr eax, 1 + add eax, [PARTITION_START] + call hd_read + cmp [hd_error], 0 + jnz problem_fat_dec_count ; ­Ґ бг¤мЎ ... +boot_read_ok: +; mov [hd_setup], 0 +; if we are running on NTFS, check bootsector + cmp [fs_type], 7 + jz ntfs_setup cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector? jnz problem_fat_dec_count @@ -332,7 +423,8 @@ fat32_partition: mov [fatBAD],0x0FFFFFF7 mov [fatEND],0x0FFFFFF8 mov [fatMASK],0x0FFFFFFF - mov [fat_type],32 ; Fat32 + mov [fs_type],32 ; Fat32 + call free_hd_channel mov [hd1_status],0 ; free ret @@ -346,6 +438,7 @@ fat16_partition: mov [fatBAD],0x0000FFF7 mov [fatEND],0x0000FFF8 mov [fatMASK],0x0000FFFF - mov [fat_type],16 ; Fat16 + mov [fs_type],16 ; Fat16 + call free_hd_channel mov [hd1_status],0 ; free ret diff --git a/kernel/branches/gfx_kernel/gui/button.inc b/kernel/branches/gfx_kernel/gui/button.inc index baff920c0..64e056215 100644 --- a/kernel/branches/gfx_kernel/gui/button.inc +++ b/kernel/branches/gfx_kernel/gui/button.inc @@ -18,39 +18,39 @@ dececx: 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 @@ -68,7 +68,7 @@ drawbuttonframes: shr eax,16 shr ebx,16 - mov edx,[0x3010] + mov edx,[TASK_BASE] add eax,[edx-twdw + WDATA.box.left] add ebx,[edx-twdw + WDATA.box.top] @@ -164,13 +164,13 @@ button_dececx: sys_button: push edi - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,8 rol eax,16 - add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] + add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] rol eax,16 rol ebx,16 - add bx,word[edi+0x80000+APPDATA.wnd_clientbox.top] + add bx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] rol ebx,16 pop edi .forced: @@ -197,9 +197,9 @@ sys_button: push ebx sar eax,16 sar ebx,16 - mov edx,[0x3010] - mov esi,[edx-twdw + WDATA.box.left] - mov edi,[edx-twdw + WDATA.box.top] + mov edx,[TASK_BASE] + mov esi,[edx-twdw + WDATA.box.left] + mov edi,[edx-twdw + WDATA.box.top] add eax,esi add ebx,edi mov cx,ax @@ -238,7 +238,7 @@ sys_button: and ecx,0xffff - mov edi,[0xfe88] + mov edi,[BTN_ADDR] movzx eax,word [edi] cmp eax,max_buttons jge noaddbutt @@ -248,7 +248,7 @@ sys_button: shl eax,4 add eax,edi - mov bx,[0x3000] + mov bx,[CURRENT_TASK] mov [eax],bx add eax,2 ; save button id number @@ -287,7 +287,7 @@ remove_button: rnewba2: - mov edi,[0xfe88] + mov edi,[BTN_ADDR] mov eax,edi movzx ebx,word [edi] inc bx @@ -299,7 +299,7 @@ remove_button: add eax,0x10 - mov dx,[0x3000] + mov dx,[CURRENT_TASK] cmp dx,[eax] jnz rnewba @@ -330,11 +330,11 @@ find_pressed_button_frames: shl ebx,5 add ebx,window_data mov ecx, [ebx+ WDATA.box.left] ; window x start - movsx edx,word [eax+4] ; button x start + movsx edx,word [eax+4] ; button x start add ecx,edx push ecx - movzx edx,word[eax+6] ; button x size + movzx edx,word[eax+6] ; button x size add ecx,edx mov esi,ecx inc esi @@ -457,7 +457,7 @@ negativebutton: checkbuttons: - cmp [0xfb40],byte 0 ; mouse buttons pressed + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed jnz @f ret @@: @@ -465,7 +465,7 @@ checkbuttons: pushad xor esi, esi - mov edi, [0xfe88] + mov edi, [BTN_ADDR] movzx edx, word [edi] test edx, edx jne @f @@ -504,8 +504,8 @@ checkbuttons: ; check that button is at top of windowing stack movzx ebx,word [eax] - movzx ecx,word [0xC000 + ebx * 2] - cmp ecx,[0x3004] + movzx ecx,word [WIN_STACK + ebx * 2] + cmp ecx,[TASK_COUNT] jne buttonnewcheck ; check that button start is inside window x/y end @@ -570,7 +570,7 @@ checkbuttons: mov bx,[eax+2] ; button id : bits 00-16 push ebx - mov [0xfb44],byte 1 ; no mouse down checks + mov [MOUSE_DOWN],byte 1 ; no mouse down checks call find_pressed_button_frames call negativebutton @@ -585,13 +585,13 @@ checkbuttons: call stack_handler popad - cmp [0xfb40],byte 0 ; mouse buttons pressed ? + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? jnz cbwaitmouseup popad call negativebutton - mov [0xfff4],byte 0 ; no mouse background - mov [0xfff5],byte 0 ; draw mouse + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse ;..................................... start 2/2 : modified by vhanla ............................. ; check coordinates jmp afterbuttonid @@ -631,16 +631,16 @@ checkbuttons: cmp ecx,edx jg no_on_button popa - mov [0xf500],byte 1 ; no of buttons in buffer + mov [BTN_COUNT],byte 1 ; no of buttons in buffer pop ebx - mov [0xf501],ebx ; lets put the button id in buffer + mov [BTN_BUFF],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 + mov [BTN_COUNT],byte 0 ; no of buttons in buffer yes_on_button: - mov [0xfb44],byte 0 ; mouse down -> do not draw + mov [MOUSE_DOWN],byte 0 ; mouse down -> do not draw popa pop ebx popa diff --git a/kernel/branches/gfx_kernel/gui/event.inc b/kernel/branches/gfx_kernel/gui/event.inc index ebd800087..f3a1e6e02 100644 --- a/kernel/branches/gfx_kernel/gui/event.inc +++ b/kernel/branches/gfx_kernel/gui/event.inc @@ -1,3 +1,465 @@ + +align 4 +init_events: + stdcall kernel_alloc, 512*EVENT_SIZE + mov [events], eax + xor eax, eax + mov [event_uid], eax + not eax + mov edi, event_map + mov [event_start], edi + mov ecx, 64/4 + cld + rep stosd + mov [event_end], edi + ret + +align 4 +proc alloc_event + + pushfd + cli + mov ebx, [event_start] + mov ecx, [event_end] +.l1: + bsf eax,[ebx] + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + mov [event_start],ebx + inc [event_uid] + + sub ebx, event_map + lea eax,[eax+ebx*8] + + lea ebx, [eax+eax*4] + shl eax,5 + lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE) + add eax, [events] + mov ebx, [event_uid] + popfd + ret +endp + +align 4 +free_event: + sub eax, [events] + mov ecx, EVENT_SIZE + mov ebx, event_map + cdq + div ecx + + pushfd + cli + bts [ebx], eax + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [event_start], eax + ja @f + popfd + ret +@@: + mov [event_start], eax + popfd + ret + +EVENT_WATCHED equ 0x10000000 +EVENT_SIGNALED equ 0x20000000 +MANUAL_RESET equ 0x40000000 +MANUAL_DESTROY equ 0x80000000 + + +; param +; eax= event data +; ebx= flags +; +; retval +; eax= event +; edx= id + +create_event: + .flags equ esp+4 + .data equ esp + + push ebx + push eax + + call alloc_event + test eax, eax + jz .fail + + mov [eax+APPOBJ.magic], 'EVNT' + mov [eax+APPOBJ.destroy], destroy_event.internal + mov [eax+EVENT.id], ebx + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov ebx, [CURRENT_TASK+ebx+4] + mov [eax+APPOBJ.pid], ebx + mov edx, [.flags] + mov [eax+EVENT.state], edx + + mov esi, [.data] + test esi, esi + jz @F + lea edi, [eax+EVENT.code] + mov ecx, 6 + cld + rep movsd +@@: + mov ecx, [CURRENT_TASK] + shl ecx,8 + add ecx, SLOT_BASE+APP_OBJ_OFFSET + + pushfd + cli + mov edx, [ecx+APPOBJ.fd] + mov [eax+APPOBJ.fd], edx + mov [eax+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + popfd + mov edx, [eax+EVENT.id] +.fail: + add esp, 8 + ret + +restore .flags +restore .data + +; param +; eax= event +; ebx= id + +destroy_event: + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail +.internal: + mov ebx, [eax+APPOBJ.fd] + mov ecx, [eax+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx +.force: + xor edx, edx ;clear common header + mov [eax], edx + mov [eax+4], edx + mov [eax+8], edx + mov [eax+12], edx + mov [eax+16], edx + + call free_event ;release object memory +.fail: + ret + +align 4 +proc send_event stdcall pid:dword, event:dword + locals + slot dd ? + endl + + mov eax, [pid] + call pid_to_slot + test eax, eax + jz .fail + + shl eax, 8 + cmp [SLOT_BASE+eax+APPDATA.ev_count], 32 + ja .fail + + mov [slot], eax + + call alloc_event + test eax, eax + jz .fail + + lea edi, [eax+EVENT.code] + mov ecx, 6 + mov esi, [event] + cld + rep movsd + + mov ecx, [slot] + add ecx, SLOT_BASE+APP_EV_OFFSET + + mov [eax+APPOBJ.magic], 'EVNT' + mov [eax+APPOBJ.destroy], destroy_event + mov ebx, [pid] + mov [eax+APPOBJ.pid], ebx + mov [eax+EVENT.state], EVENT_SIGNALED + + pushfd + cli ;insert event into + mov edx, [ecx+APPOBJ.fd] ;events list + mov [eax+APPOBJ.fd], edx ;and set events flag + mov [eax+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], eax + mov [edx+APPOBJ.bk], eax + inc [ecx+APPDATA.ev_count-APP_EV_OFFSET] + or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED + popfd +.fail: + ret +endp + +; timeout ignored + +align 4 +proc get_event_ex stdcall, p_ev:dword, timeout:dword + +.wait: + mov edx,[CURRENT_TASK] + shl edx,8 +; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0 +; je .switch + + add edx, SLOT_BASE+APP_EV_OFFSET + + mov eax, [edx+APPOBJ.fd] + cmp eax, edx + je .switch + + lea esi, [eax+EVENT.code] + mov edi, [p_ev] ;copy event data + mov ecx, 6 + cld + rep movsd + + and dword [edi-24], 0xFF00FFFF ;clear priority field + ; + test [eax+EVENT.state], MANUAL_RESET + jnz .done + + pushfd + cli ;remove event from events + mov ebx, [eax+APPOBJ.fd] ;list (reset event) + mov ecx, [eax+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + + and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + + dec [edx+APPDATA.ev_count-APP_EV_OFFSET] + jnz @F + and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED +@@: + popfd + + test [eax+EVENT.state], MANUAL_DESTROY + jz .destroy + + add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET) + + pushfd + cli + mov ebx, [edx+APPOBJ.fd] ;insert event into + mov [eax+APPOBJ.fd], ebx ;objects list + mov [eax+APPOBJ.bk], edx + mov [edx+APPOBJ.fd], eax + mov [ebx+APPOBJ.bk], eax + popfd +.done: + ret + +.destroy: + call destroy_event.force + ret +.switch: + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + jmp .wait +endp + +; param +; eax= event +; ebx= id + +align 4 +wait_event: + .event equ esp + push eax +.wait: + cmp [eax+APPOBJ.magic], 'EVNT' + jne .done + cmp [eax+EVENT.id], ebx + jne .done + + test [eax+EVENT.state], EVENT_SIGNALED + jz .switch + + test [eax+EVENT.state], MANUAL_RESET + jnz .done + + mov edx,[CURRENT_TASK] + shl edx,8 + add edx, SLOT_BASE + + pushfd + cli ;remove event from events + mov ebx, [eax+APPOBJ.fd] ;list (reset event) + mov ecx, [eax+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + dec [edx+APPDATA.ev_count] + jnz @F + and [edx+APPDATA.event_mask], not EVENT_EXTENDED +@@: + and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + popfd + + test [eax+EVENT.state], MANUAL_DESTROY + jz .destroy + + add edx, APP_OBJ_OFFSET + + pushfd + cli + mov ecx, [edx+APPOBJ.fd] ;insert event into + mov [eax+APPOBJ.fd], ecx ;objects list + mov [eax+APPOBJ.bk], edx + mov [edx+APPOBJ.fd], eax + mov [ecx+APPOBJ.bk], eax + popfd +.done: + add esp, 4 + ret +.destroy: + call destroy_event.force + add esp, 4 + ret +.switch: + or [eax+EVENT.state], EVENT_WATCHED + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], byte 5 + call change_task + mov eax, [.event] + jmp .wait +restore .event + +; param +; eax= event +; ebx= id +; ecx= flags +; edx= event data + +raise_event: + .event equ esp + push eax + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail + + mov eax, [eax+APPOBJ.pid] + call pid_to_slot + test eax, eax + jz .fail + + mov esi, edx + test esi, esi + mov edx, [.event] + jz @F + + push ecx + lea edi, [edx+EVENT.code] + mov ecx, 6 + cld + rep movsd + pop ecx +@@: + test [edx+EVENT.state], EVENT_SIGNALED + jnz .done + + test ecx, EVENT_WATCHED + jz @F + test [edx+EVENT.state], EVENT_WATCHED + jz .done +@@: + shl eax, 8 + add eax, SLOT_BASE+APP_EV_OFFSET + + pushfd + cli + mov ebx, [edx+APPOBJ.fd] + mov ecx, [edx+APPOBJ.bk] + mov [ebx+APPOBJ.bk], ecx + mov [ecx+APPOBJ.fd], ebx + + mov ecx, [eax+APPOBJ.fd] + mov [edx+APPOBJ.fd], ecx + mov [edx+APPOBJ.bk], eax + mov [eax+APPOBJ.fd], edx + mov [ecx+APPOBJ.bk], edx + or [edx+EVENT.state], EVENT_SIGNALED + + inc [eax+APPDATA.ev_count-APP_EV_OFFSET] + or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED + popfd +.fail: +.done: + add esp, 4 + ret +restore .event + +; param +; eax= event +; ebx= id +align 4 +clear_event: + .event equ esp + push eax + + cmp [eax+APPOBJ.magic], 'EVNT' + jne .fail + cmp [eax+EVENT.id], ebx + jne .fail + + mov eax, [eax+APPOBJ.pid] + call pid_to_slot + test eax, eax + jz .fail + + shl eax, 8 + add eax, SLOT_BASE+APP_EV_OFFSET + mov edx, [.event] + pushfd + cli ;remove event from events + mov ebx, [edx+APPOBJ.fd] ;list (reset event) + mov ecx, [edx+APPOBJ.bk] ;and clear events flag + mov [ebx+APPOBJ.bk], ecx ;if no active events + mov [ecx+APPOBJ.fd], ebx + + and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) + + dec [eax+APPDATA.ev_count-APP_EV_OFFSET] + jnz @F + and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED +@@: + add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET) + + mov ecx, [eax+APPOBJ.fd] ;insert event into + mov [edx+APPOBJ.fd], ecx ;objects list + mov [edx+APPOBJ.bk], eax + mov [eax+APPOBJ.fd], edx + mov [ecx+APPOBJ.bk], edx + popfd +.fail: +.done: + add esp, 4 + ret +restore .event + sys_getevent: call get_event_for_app @@ -6,23 +468,22 @@ sys_getevent: align 4 - sys_wait_event_timeout: mov ebx,[timer_ticks] add ebx,eax cmp ebx,[timer_ticks] jna .swfet2 - .swfet1: +.swfet1: call get_event_for_app test eax,eax jne .eventoccur_time call change_task cmp ebx,[timer_ticks] jg .swfet1 - .swfet2: +.swfet2: xor eax,eax - .eventoccur_time: +.eventoccur_time: mov [esp+36],eax ret @@ -36,7 +497,7 @@ sys_waitforevent: jne eventoccur newwait: - mov eax, [0x3010] + mov eax, [TASK_BASE] mov [eax+TASKDATA.state], byte 5 call change_task @@ -46,15 +507,14 @@ sys_waitforevent: mov [esp+36],eax ret - get_event_for_app: pushad - mov edi,[0x3010] ; WINDOW REDRAW + mov edi,[TASK_BASE] ; WINDOW REDRAW test [edi+TASKDATA.event_mask],dword 1 jz no_eventoccur1 - ;mov edi,[0x3010] + ;mov edi,[TASK_BASE] cmp [edi-twdw+WDATA.fl_redraw],byte 0 je no_eventoccur1 popad @@ -62,15 +522,15 @@ get_event_for_app: ret no_eventoccur1: - ;mov edi,[0x3010] ; KEY IN BUFFER + ;mov edi,[TASK_BASE] ; 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] + mov ecx, [CURRENT_TASK] + movzx edx,word [WIN_STACK+ecx*2] + mov eax, [TASK_COUNT] cmp eax,edx jne no_eventoccur2x - cmp [0xf400],byte 0 + cmp [KEY_COUNT],byte 0 je no_eventoccur2x eventoccur2: popad @@ -86,18 +546,18 @@ get_event_for_app: jb @b no_eventoccur2: - ;mov edi,[0x3010] ; BUTTON IN BUFFER + ;mov edi,[TASK_BASE] ; BUTTON IN BUFFER test [edi+TASKDATA.event_mask],dword 4 jz no_eventoccur3 - cmp [0xf500],byte 0 + cmp [BTN_COUNT],byte 0 je no_eventoccur3 - mov ecx, [0x3000] - movzx edx, word [0xC000+ecx*2] - mov eax, [0x3004] + mov ecx, [CURRENT_TASK] + movzx edx, word [WIN_STACK+ecx*2] + mov eax, [TASK_COUNT] cmp eax,edx jnz no_eventoccur3 popad - mov eax,[0xf501] + mov eax,[BTN_BUFF] cmp eax,65535 je no_event_1 mov eax,3 @@ -105,91 +565,100 @@ get_event_for_app: no_event_1: mov [window_minimize],1 - mov [0xf500],byte 0 + mov [BTN_COUNT],byte 0 xor eax, eax ret no_eventoccur3: - - - ;mov edi,[0x3010] ; mouse event + + + ;mov edi,[TASK_BASE] ; mouse event test [edi+TASKDATA.event_mask],dword 00100000b jz no_mouse_event - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,8 - test [eax+0x80000+APPDATA.event_mask],dword 00100000b + test [eax+SLOT_BASE+APPDATA.event_mask],dword 00100000b jz no_mouse_event - and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-00100000b + and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-00100000b popad mov eax,6 ret no_mouse_event: - - ;mov edi,[0x3010] ; DESKTOP BACKGROUND REDRAW + + ;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW test [edi+TASKDATA.event_mask],dword 16 jz no_eventoccur5 - cmp [0xfff0],byte 2 + cmp [REDRAW_BACKGROUND],byte 2 jnz no_eventoccur5 popad mov eax,5 ret no_eventoccur5: - ;mov edi,[0x3010] ; IPC + ;mov edi,[TASK_BASE] ; IPC test [edi+TASKDATA.event_mask],dword 01000000b jz no_ipc - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,8 - test [eax+0x80000+APPDATA.event_mask],dword 01000000b + test [eax+SLOT_BASE+APPDATA.event_mask],dword 01000000b jz no_ipc - and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-01000000b + and [eax+SLOT_BASE+APPDATA.event_mask],dword 0xffffffff-01000000b popad mov eax,7 ret no_ipc: - ;mov edi,[0x3010] ; STACK + ;mov edi,[TASK_BASE] ; STACK test [edi+TASKDATA.event_mask],dword 10000000b jz no_stack_event - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,8 - test [eax+0x80000+APPDATA.event_mask],dword 10000000b + test [eax+SLOT_BASE+APPDATA.event_mask],dword 10000000b jz no_stack_event - and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-10000000b + and [eax+SLOT_BASE+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] + jz .test_IRQ + mov eax, [CURRENT_TASK] 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 + test byte [eax+SLOT_BASE+APPDATA.event_mask+1], byte 1 + jz .test_IRQ + and byte [eax+SLOT_BASE+APPDATA.event_mask+1], not 1 popad mov eax, 9 ret - no_debug_event: +;.test_ext: +; mov eax, [CURRENT_TASK] +; shl eax, 8 +; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED +; jz .test_IRQ +; popad +; mov eax, 10 +; ret + +.test_IRQ: cmp dword [edi+TASKDATA.event_mask], 0xFFFF jbe no_events - mov esi,0x2e0000 ; IRQ'S AND DATA + mov esi,IRQ_SAVE ; IRQ'S AND DATA mov ebx,0x00010000 xor ecx, ecx irq_event_test: - mov edi,[0x3010] + mov edi,[TASK_BASE] 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,[TASK_BASE] mov eax,[eax+TASKDATA.pid] cmp edx,eax jne no_irq_event @@ -213,3 +682,4 @@ get_event_for_app: ret + diff --git a/kernel/branches/gfx_kernel/gui/font.inc b/kernel/branches/gfx_kernel/gui/font.inc index cd62e2dac..8b2a94931 100644 --- a/kernel/branches/gfx_kernel/gui/font.inc +++ b/kernel/branches/gfx_kernel/gui/font.inc @@ -36,7 +36,7 @@ dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) jnz .font2 pushad mov esi, 9 - lea ebp, [0x3F600+8*edx+edx] + lea ebp, [FONT_I+8*edx+edx] .symloop1: mov dl, byte [ebp] or dl, 1 shl 6 @@ -69,7 +69,7 @@ dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org]) .font2: pushad add edx, edx - lea ebp, [0x3EC00+4*edx+edx+1] + lea ebp, [FONT_II+4*edx+edx+1] push 9 movzx esi, byte [ebp-1] .symloop2: diff --git a/kernel/branches/gfx_kernel/gui/skincode.inc b/kernel/branches/gfx_kernel/gui/skincode.inc index 0f1d5df7f..b56d63a7c 100644 --- a/kernel/branches/gfx_kernel/gui/skincode.inc +++ b/kernel/branches/gfx_kernel/gui/skincode.inc @@ -1,6 +1,6 @@ include "skindata.inc" -skin_data = 0x00778000 +;skin_data = 0x00778000 load_skin_file: ; eax = filename @@ -270,7 +270,7 @@ drawwindow_IV: push edx - mov edi,[esp] ; RECTANGLE + mov edi,edx mov ebp,skin_active cmp byte [esp+32+4+4],0 @@ -290,6 +290,7 @@ drawwindow_IV: ; shr esi,1 ; and esi,0x007f7f7f mov esi,[ebp+SKIN_DATA.colors.outer] + or [edi+WDATA.fl_wdrawn], 4 call draw_rectangle mov ecx,3 _dw3l: @@ -345,6 +346,8 @@ drawwindow_IV: sub ecx,4 sub edx,4 mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz _noinside2 call [drawbar] _noinside2: @@ -352,7 +355,7 @@ drawwindow_IV: jne no_skin_add_button ;* close button - mov edi,[0xfe88] + mov edi,[BTN_ADDR] movzx eax,word [edi] cmp eax,1000 jge no_skin_add_button @@ -362,7 +365,7 @@ drawwindow_IV: shl eax,4 add eax,edi - mov bx,[0x3000] + mov bx,[CURRENT_TASK] mov [eax],bx add eax,2 ; save button id number @@ -391,7 +394,7 @@ drawwindow_IV: mov [eax],bx ;* minimize button - mov edi,[0xfe88] + mov edi,[BTN_ADDR] movzx eax,word [edi] cmp eax,1000 jge no_skin_add_button @@ -401,7 +404,7 @@ drawwindow_IV: shl eax,4 add eax,edi - mov bx,[0x3000] + mov bx,[CURRENT_TASK] mov [eax],bx add eax,2 ; save button id number @@ -430,8 +433,13 @@ drawwindow_IV: mov [eax],bx no_skin_add_button: + pop edi + and [edi+WDATA.fl_wdrawn], not 4 + test [edi+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes +@@: - add esp,4 popa ret 4 diff --git a/kernel/branches/gfx_kernel/gui/window.inc b/kernel/branches/gfx_kernel/gui/window.inc index 23618e021..8b4eb6aa1 100644 --- a/kernel/branches/gfx_kernel/gui/window.inc +++ b/kernel/branches/gfx_kernel/gui/window.inc @@ -30,13 +30,13 @@ setwindowdefaults: pushad xor eax,eax - mov ecx,0xc000 + mov ecx,WIN_STACK @@: 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 + cmp ecx,WIN_POS-2 ; the more high, the more surface jnz @b popad @@ -66,15 +66,15 @@ __sys_calculatescreen: mov edx, [0xFE04] call [setscreen] - mov ebp, [0x3004] ; number of processes + mov ebp, [TASK_COUNT] ; number of processes cmp ebp, 1 jbe .finish align 4 .new_wnd: - movzx edi, word [0xC400 + esi * 2] + movzx edi, word [WIN_POS + esi * 2] shl edi, 5 - cmp [0x3000+edi+TASKDATA.state], byte 9 + cmp [CURRENT_TASK+edi+TASKDATA.state], byte 9 je .not_wnd add edi, window_data @@ -114,7 +114,7 @@ __sys_calculatescreen: @@: push esi - movzx esi, word [0xC400 + esi * 2] + movzx esi, word [WIN_POS + esi * 2] call [setscreen] pop esi @@ -191,9 +191,9 @@ display_settings: redraw_screen_direct: mov [dlx],dword 0 mov [dly],dword 0 - mov eax,[0xfe00] + mov eax,[ScreenWidth] mov [dlxe],eax - mov eax,[0xfe04] + mov eax,[ScreenHeight] mov [dlye],eax mov eax,window_data call redrawscreen @@ -217,7 +217,7 @@ display_settings: cmp eax,2 ; set common window colours jne no_com_colours mov [windowtypechanged],dword 1 - mov esi,[0x3010] + mov esi,[TASK_BASE] add esi,TASKDATA.mem_start add ebx,[esi] mov esi,ebx @@ -231,7 +231,7 @@ display_settings: cmp eax,3 ; get common window colours jne no_get_com - mov esi,[0x3010] + mov esi,[TASK_BASE] add esi,TASKDATA.mem_start add ebx,[esi] mov edi,ebx @@ -269,10 +269,10 @@ display_settings: movsx ebx,word[esp+16] cmp eax,ebx jge .lp1 - or eax,eax;[0xFE00] + or eax,eax;[ScreenWidth] jl @f mov [screen_workarea.left],eax - @@: cmp ebx,[0xFE00] + @@: cmp ebx,[ScreenWidth] jg .lp1 mov [screen_workarea.right],ebx .lp1: movsx eax,word[esp+24+2] @@ -282,14 +282,14 @@ display_settings: or eax,eax;[0xFE04] jl @f mov [screen_workarea.top],eax - @@: cmp ebx,[0xFE04] + @@: cmp ebx,[ScreenHeight] jg .lp2 mov [screen_workarea.bottom],ebx .lp2: call repos_windows mov eax, 0 mov ebx, 0 - mov ecx, [0xfe00] - mov edx, [0xfe04] + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] call [calculatescreen] ; jmp redraw_screen_direct .exit: @@ -310,7 +310,7 @@ display_settings: cmp eax,8 ; set window skin jne no_set_skin mov eax,ebx - mov edi,[0x3010] + mov edi,[TASK_BASE] 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 @@ -340,8 +340,8 @@ display_settings: pushad mov eax, 0 mov ebx, 0 - mov ecx, [0xfe00] - mov edx, [0xfe04] + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] call [calculatescreen] popad mov dword[esp+32+36],0 @@ -357,57 +357,57 @@ display_settings: repos_windows: - mov ecx,[0x3004] - mov esi,0x20*2 - mov byte[0x0000fff0],1 + mov ecx,[TASK_COUNT] + mov edi,0x20*2 + mov byte[REDRAW_BACKGROUND],1 dec ecx jge @f ret - @@: mov [esi+WDATA.fl_redraw],1 - test [esi+WDATA.fl_wstate],WSTATE_MAXIMIZED + @@: mov [edi+WDATA.fl_redraw],1 + test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED jz .lp2 mov eax,[screen_workarea.left] - mov [esi+WDATA.box.left],eax + mov [edi+WDATA.box.left],eax sub eax,[screen_workarea.right] neg eax - mov [esi+WDATA.box.width],eax + mov [edi+WDATA.box.width],eax mov eax,[screen_workarea.top] - mov [esi+WDATA.box.top],eax - test [esi+WDATA.fl_wstate],WSTATE_ROLLEDUP + mov [edi+WDATA.box.top],eax + test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP jnz .lp1 sub eax,[screen_workarea.bottom] neg eax - mov [esi+WDATA.box.height],eax - .lp1: add esi,0x20 + mov [edi+WDATA.box.height],eax + .lp1: + call set_window_clientbox + add edi,0x20 loop @b ret - .lp2: mov eax,[esi+WDATA.box.left] - add eax,[esi+WDATA.box.width] - mov ebx,[0x0000fe00] + .lp2: mov eax,[edi+WDATA.box.left] + add eax,[edi+WDATA.box.width] + mov ebx,[ScreenWidth] ; inc ebx cmp eax,ebx jle .lp4 - mov eax,[esi+WDATA.box.width] + mov eax,[edi+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] + mov [edi+WDATA.box.width],ebx + .lp3: sub ebx,[edi+WDATA.box.width] + mov [edi+WDATA.box.left],ebx + .lp4: mov eax,[edi+WDATA.box.top] + add eax,[edi+WDATA.box.height] + mov ebx,[ScreenHeight] ; inc ebx cmp eax,ebx jle .lp6 - mov eax,[esi+WDATA.box.height] + mov eax,[edi+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 + mov [edi+WDATA.box.height],ebx + .lp5: sub ebx,[edi+WDATA.box.height] + mov [edi+WDATA.box.top],ebx + .lp6: jmp .lp1 uglobal common_colours: @@ -434,8 +434,8 @@ sys_window_mouse: cmp [new_window_starting],eax jb swml1 - mov [0xfff4],byte 0 ; no mouse background - mov [0xfff5],byte 0 ; draw mouse + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse mov [new_window_starting],eax @@ -474,14 +474,22 @@ drawwindow_I_caption: 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] - test ecx,0x80000000 - jz .nofa sub ecx,0x00040404 mov [esi+WDATA.cl_titlebar],ecx - .nofa: - .faj: 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 @@ -497,6 +505,7 @@ drawwindow_I_caption: drawwindow_I: pushad + or [edx+WDATA.fl_wdrawn], 4 mov esi,[edx+WDATA.cl_frames] ; rectangle mov eax,[edx+WDATA.box.left] @@ -509,6 +518,12 @@ drawwindow_I: add ebx,[edx+WDATA.box.height] call draw_rectangle + and [edx+WDATA.fl_wdrawn], not 4 + test [edx+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes +@@: + call drawwindow_I_caption mov edx,[esi+WDATA.box.top] ; inside work area @@ -522,6 +537,8 @@ drawwindow_I: mov ecx,[esi+WDATA.box.width] mov edx,[esi+WDATA.box.height] mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz noinside call [drawbar] noinside: @@ -638,7 +655,13 @@ drawwindow_III: shr esi,1 and esi,0x007f7f7f push esi + or [edi+WDATA.fl_wdrawn], 4 call draw_rectangle + and [edi+WDATA.fl_wdrawn], not 4 + test [edi+WDATA.fl_wdrawn], 2 + jz @f + call drawwindowframes +@@: mov ecx,3 dw3l: add eax,1*65536-1 @@ -667,6 +690,8 @@ drawwindow_III: sub ecx,4 sub edx,4 mov edi,[esi+WDATA.cl_workarea] + test edi,0x40000000 + jnz noinside2 call [drawbar] noinside2: @@ -686,8 +711,8 @@ windowactivate: ; if type of current active window is 3, ; it must be redrawn - mov eax, [0x3004] - movzx eax, word [0xC400 + eax*2] + mov eax, [TASK_COUNT] + movzx eax, word [WIN_POS + eax*2] shl eax, 5 add eax, window_data mov ebx, [eax + WDATA.cl_workarea] @@ -699,14 +724,14 @@ windowactivate: push esi movzx eax, word [esi] ; ax <- process no - movzx eax, word [0xC000+eax*2] ; ax <- position in window stack + movzx eax, word [WIN_STACK+eax*2] ; ax <- position in window stack xor esi, esi ; drop others waloop: - cmp esi, dword [0x3004] + cmp esi, dword [TASK_COUNT] jae wacont inc esi - lea edi, [0xC000 + esi*2] + lea edi, [WIN_STACK + esi*2] mov bx, [edi] ; position of the current process cmp bx, ax jbe @f @@ -719,21 +744,22 @@ windowactivate: 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) + mov bx, [TASK_COUNT] ; number of processes + mov [WIN_STACK+eax*2], bx ; this is the last (and the upper) ; update on screen -window stack xor esi, esi waloop2: - cmp esi,[0x3004] + mov edi, [TASK_COUNT] + cmp esi, edi jae wacont2 inc esi - movzx ebx, word [esi*2 + 0xC000] - mov [ebx*2 + 0xC400], si + movzx ebx, word [esi*2 + WIN_STACK] + mov [ebx*2 + WIN_POS], si jmp waloop2 wacont2: - mov [0xf400], byte 0 ; empty keyboard buffer - mov [0xf500], byte 0 ; empty button buffer + mov [KEY_COUNT], byte 0 ; empty keyboard buffer + mov [BTN_COUNT], byte 0 ; empty button buffer popad ret @@ -755,8 +781,8 @@ checkwindowdraw: ; 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 + movzx eax, word [WIN_STACK + esi * 2] ; get value of the curr process + lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 push esi @@ -766,15 +792,15 @@ checkwindowdraw: add esi, 2 push esi - mov eax, [0x3004] - lea eax, word [0xC400 + eax * 2] ; number of the upper window + mov eax, [TASK_COUNT] + lea eax, word [WIN_POS + 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 + cmp [CURRENT_TASK + eax + TASKDATA.state], byte 9 je .new_check ; skip dead windows lea esi, [eax+window_data] @@ -784,7 +810,7 @@ checkwindowdraw: add edx, ebx ; y0e mov ecx, [esi+WDATA.box.top] ; y ; y check - cmp ecx, edx + cmp ecx, edx jae .new_check ; y < y0e mov eax, [esi+WDATA.box.height] add ecx, eax ; ye @@ -827,14 +853,14 @@ waredraw: ; if redraw necessary at activate jz .do_not_draw popad - mov [0xfb44], byte 1 ; do draw mouse + mov [MOUSE_DOWN], byte 1 ; do draw mouse call windowactivate ; update screen info call [calc_clipping_rects] pushad - mov edi, [0x3004] ; the last process (number) - movzx esi, word [0xC400 + edi * 2] + mov edi, [TASK_COUNT] ; the last process (number) + movzx esi, word [WIN_POS + edi * 2] shl esi, 5 add esi, window_data @@ -847,13 +873,13 @@ waredraw: ; if redraw necessary at activate add ecx, eax ; ecx = x_end add edx, ebx ; edx = y_end - mov edi, [0x3004] - movzx esi, word [0xC400 + edi * 2] + mov edi, [TASK_COUNT] + movzx esi, word [WIN_POS + edi * 2] call [setscreen] popad mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app - mov [0xfb44],byte 0 ; mouse down checks + mov [MOUSE_DOWN],byte 0 ; mouse down checks ret @@ -862,16 +888,16 @@ waredraw: ; if redraw necessary at activate popad call windowactivate - mov [0xfb44],byte 0 ; mouse down checks - mov [0xfff4],byte 0 ; no mouse background - mov [0xfff5],byte 0 ; draw mouse + mov [MOUSE_DOWN],byte 0 ; mouse down checks + mov [MOUSE_BACKGROUND],byte 0 ; no mouse background + mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse ret ; eax = window number on screen ; corrupts registers and [dl*] minimize_window: - movzx eax, word [0xC400+eax*2] + movzx eax, word [WIN_POS+eax*2] shl eax, 5 add eax, window_data test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED @@ -904,7 +930,7 @@ minimize_window: restore_minimized_window: pushfd cli - movzx esi, word [0xC400+eax*2] + movzx esi, word [WIN_POS+eax*2] mov edi, esi shl edi, 5 add edi, window_data @@ -912,7 +938,7 @@ restore_minimized_window: jz .skip_redrawings mov [edi+WDATA.fl_redraw], 1 and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED - cmp eax, [0x3004] ; the uppermost window + cmp eax, [TASK_COUNT] ; the uppermost window jnz .no_uppermost mov eax, [edi+WDATA.box.left] mov ebx, [edi+WDATA.box.top] @@ -931,7 +957,7 @@ restore_minimized_window: add edx, [edi+WDATA.box.height] call [calculatescreen] .done: - mov [0xfff4],byte 0 ; no mouse under + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under .skip_redrawings: popfd ret @@ -949,7 +975,7 @@ checkwindows: cmp [window_minimize], 0 je .no_minimizing - mov eax, [0x3004] ; the uppermost window + mov eax, [TASK_COUNT] ; the uppermost window mov bl, 0 xchg [window_minimize], bl cmp bl, 1 @@ -961,13 +987,13 @@ checkwindows: .continue: .no_minimizing: - cmp [0xfb40],byte 0 ; mouse buttons pressed ? + cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? jne .mouse_buttons_pressed popad ret .mouse_buttons_pressed: - mov esi,[0x3004] + mov esi,[TASK_COUNT] inc esi cwloop: @@ -975,7 +1001,7 @@ checkwindows: jb .exit dec esi - movzx edi, word [0xC400 + esi * 2] ; ebx + movzx edi, word [WIN_POS + esi * 2] ; ebx shl edi, 5 add edi, window_data ; mov edi, ebx @@ -987,9 +1013,9 @@ checkwindows: test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED jnz cwloop - movzx eax, word [0xfb0a] - movzx ebx, word [0xfb0c] - + movzx eax, word [MOUSE_X] + movzx ebx, word [MOUSE_Y] + cmp eax,ecx jl cwloop cmp ebx,edx @@ -1003,13 +1029,13 @@ checkwindows: pushad mov eax, esi - mov ebx, [0x3004] + mov ebx, [TASK_COUNT] cmp eax, ebx ; is this window active? jz .move_resize_window ; eax = position in windowing stack ; redraw must ? - lea esi, [0xC400 + esi * 2] + lea esi, [WIN_POS + esi * 2] call waredraw add esp, 32 @@ -1018,7 +1044,6 @@ checkwindows: ret .move_resize_window: ; MOVE OR RESIZE WINDOW - popad ; Check for user enabled fixed window @@ -1068,7 +1093,7 @@ checkwindows: mov [latest_window_touch], ecx mov [latest_window_touch_delta], edx - mov cl, [0xfb40] ; save for shade check + mov cl, [BTN_DOWN] ; save for shade check mov [do_resize], cl no_emulation_righ_button: mov ecx, [edi + WDATA.box.left] @@ -1086,8 +1111,8 @@ checkwindows: sub eax, ecx sub ebx, edx - mov esi, [0xfb0a] - mov [0xf300], esi + mov esi, [MOUSE_X] + mov [WIN_TEMP_XY], esi push eax;ad ; wait for putimages to finish ; mov eax,5 @@ -1116,19 +1141,19 @@ checkwindows: @@: mov [reposition],0 - mov [0xfb44],byte 1 ; no reaction to mouse up/down + mov [MOUSE_DOWN],byte 1 ; no reaction to mouse up/down ; move window newchm: - mov [0xfff5],byte 1 + mov [DONT_DRAW_MOUSE],byte 1 call checkidle call checkVga_N13 - mov [0xfff4],byte 0 + mov [MOUSE_BACKGROUND],byte 0 call [draw_pointer] @@ -1136,12 +1161,12 @@ checkwindows: call stack_handler popad - mov esi,[0xf300] - cmp esi,[0xfb0a] + mov esi,[WIN_TEMP_XY] + cmp esi,[MOUSE_X] je cwb - movzx ecx,word[0xfb0a] - movzx edx,word[0xfb0c] + movzx ecx,word[MOUSE_X] + movzx edx,word[MOUSE_Y] sub ecx,eax sub edx,ebx push eax @@ -1151,8 +1176,8 @@ checkwindows: call drawwindowframes @@: - mov ax,[0xfe00] - mov bx,[0xfe04] + movzx eax,word[ScreenWidth] + movzx ebx,word[ScreenHeight] cmp [do_resize_from_corner],1 je no_new_position @@ -1178,9 +1203,9 @@ checkwindows: ;shr edx,5 ;shl edx,8 ;add edx,0x80000 ; process base at 0x80000+ - lea edx, [0x80000 + edx*8] + lea edx, [SLOT_BASE + edx*8] - movzx eax,word [0xfb0a] + movzx eax,word [MOUSE_X] cmp eax,[edi + WDATA.box.left] jl nnepx sub eax,[edi + WDATA.box.left] @@ -1193,7 +1218,7 @@ checkwindows: call get_rolledup_height mov ebx,eax - movzx eax,word [0xfb0c] + movzx eax,word [MOUSE_Y] cmp eax,[edi + WDATA.box.top] jl nnepy sub eax,[edi + WDATA.box.top] @@ -1216,14 +1241,14 @@ checkwindows: call drawwindowframes @@: - mov esi,[0xfb0a] - mov [0xf300],esi + mov esi,[MOUSE_X] + mov [WIN_TEMP_XY],esi cwb: - cmp [0xfb40],byte 0 - jne newchm + cmp [BTN_DOWN],byte 0 + jne newchm ; new position done - mov [0xfff5],byte 1 + mov [DONT_DRAW_MOUSE],byte 1 mov cl,0 test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED jnz @f @@ -1238,6 +1263,7 @@ checkwindows: mov [edi + WDATA.box.width],eax mov eax,[npye] mov [edi + WDATA.box.height],eax + call set_window_clientbox @@: mov [reposition],cl @@ -1252,7 +1278,7 @@ checkwindows: @@: sub edi,window_data shr edi,5 shl edi,8 - add edi,0x80000+APPDATA.saved_box + add edi,SLOT_BASE+APPDATA.saved_box cld rep movsd pop ecx edi esi @@ -1266,7 +1292,7 @@ checkwindows: sub edx,window_data shr edx,5 shl edx,8 - add edx,0x80000 ; process base at 0x80000+ + add edx,SLOT_BASE ; process base at 0x80000+ cmp [do_resize],2 ; window shade ? jne no_window_shade @@ -1286,6 +1312,7 @@ checkwindows: mov eax,[screen_workarea.bottom] sub eax,[screen_workarea.top] @@: mov [edi+WDATA.box.height],eax + call set_window_clientbox no_window_shade: @@ -1310,7 +1337,7 @@ checkwindows: neg eax mov [edi+WDATA.box.height],eax @@: - jmp no_fullscreen_restore + jmp restore_from_fullscreen.clientbox restore_from_fullscreen: and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED push [edi+WDATA.box.height] @@ -1325,6 +1352,8 @@ checkwindows: jz @f mov [edi+WDATA.box.height],eax @@: + .clientbox: + call set_window_clientbox no_fullscreen_restore: @@ -1335,7 +1364,7 @@ checkwindows: cmp [reposition],0 je retwm - mov [0xfff5],byte 1 ; no mouse + mov [DONT_DRAW_MOUSE],byte 1 ; no mouse call [calc_clipping_rects] mov eax,edi @@ -1346,7 +1375,7 @@ checkwindows: mov ecx,100 ; wait to avoid mouse residuals waitre2: - mov [0xfff5],byte 1 + mov [DONT_DRAW_MOUSE],byte 1 call checkidle cmp [edi+WDATA.fl_redraw],0 jz retwm @@ -1354,9 +1383,9 @@ checkwindows: retwm: - mov [0xfff5],byte 0 ; mouse pointer - mov [0xfff4],byte 0 ; no mouse under - mov [0xfb44],byte 0 ; react to mouse up/down + mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under + mov [MOUSE_DOWN],byte 0 ; react to mouse up/down mov esi,window_moved call sys_msg_board_str @@ -1393,10 +1422,12 @@ endg ; draw negative window frames - drawwindowframes: - pushad + cli + + mov ecx,0x01000000 + mov edi,1 mov eax,[npx] shl eax,16 @@ -1406,11 +1437,7 @@ drawwindowframes: 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 @@ -1422,11 +1449,7 @@ drawwindowframes: 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 @@ -1435,11 +1458,7 @@ drawwindowframes: 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] @@ -1450,18 +1469,11 @@ drawwindowframes: 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 +.ret: + sti popad - ret @@ -1476,17 +1488,17 @@ random_shaped_window: test eax, eax jne rsw_no_address - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,8 - mov [eax+0x80000+APPDATA.wnd_shape],ebx + mov [eax+SLOT_BASE+APPDATA.wnd_shape],ebx rsw_no_address: cmp eax,1 jne rsw_no_scale - mov eax,[0x3000] + mov eax,[CURRENT_TASK] shl eax,8 - mov byte [eax+0x80000+APPDATA.wnd_shape_scale], bl + mov byte [eax+SLOT_BASE+APPDATA.wnd_shape_scale], bl rsw_no_scale: ret diff --git a/kernel/branches/gfx_kernel/hid/keyboard.inc b/kernel/branches/gfx_kernel/hid/keyboard.inc index 8b293843c..d384047fd 100644 --- a/kernel/branches/gfx_kernel/hid/keyboard.inc +++ b/kernel/branches/gfx_kernel/hid/keyboard.inc @@ -86,15 +86,15 @@ hotkey_do_test: align 4 irq1: - save_ring3_context - mov ax, os_data - mov ds, ax - mov es, ax +; 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] + movzx eax,word[TASK_COUNT] ; top window process + movzx eax,word[WIN_POS+eax*2] shl eax,8 - mov al,[0x80000+eax+APPDATA.keyboard_mode] + mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode] mov [keyboard_mode],al in al,0x60 @@ -267,21 +267,22 @@ irq1: .scancode: mov bl, ch .dowrite: - movzx eax,byte[0xF400] + movzx eax,byte[KEY_COUNT] cmp al,120 jae .exit.irq1 inc eax - mov [0xF400],al - mov [0xF400+eax],bl + mov [KEY_COUNT],al + mov [KEY_COUNT+eax],bl .exit.irq1: mov [check_idle_semaphore],5 - mov al,0x20 ; ready for next irq - out 0x20,al +; mov al,0x20 ; ready for next irq +; out 0x20,al - restore_ring3_context - iret +; restore_ring3_context +; iret + ret set_lights: mov al,0xED diff --git a/kernel/branches/gfx_kernel/hid/m_com1.inc b/kernel/branches/gfx_kernel/hid/m_com1.inc index 237ba70d2..f1b63f6d0 100644 --- a/kernel/branches/gfx_kernel/hid/m_com1.inc +++ b/kernel/branches/gfx_kernel/hid/m_com1.inc @@ -61,7 +61,7 @@ check_mouse_data_com1: shr ah,5 and ah,1 add al,ah - mov [0xfb40],al + mov [BTN_DOWN],al mov [mouse_active],1 ; Прибавить перемещение по X к координате X mov AL,[FirstByte] @@ -69,21 +69,21 @@ check_mouse_data_com1: or AL,[SecondByte] cbw call mouse_acceleration_com1 - add AX,[0xFB0A] ;[XCoordinate] + add AX,[MOUSE_X] ;[XCoordinate] ; Курсор не должен выходить за левую или ; правую границу экрана js @@X1 - cmp AX,[0xFE00] ;ScreenLength + cmp AX,[ScreenWidth] ;ScreenLength jb @@X2 ; Установить координату X по правой границе - mov AX,[0xFE00] ;ScreenLength-1 + mov AX,[ScreenWidth] ;ScreenLength-1 dec ax jmp @@X2 @@X1: ; Установить координату X по левой границе xor AX,AX @@X2: - mov [0xFB0A],AX ;[XCoordinate] + mov [MOUSE_X],AX ;[XCoordinate] ; Прибавить перемещение по Y к координате Y mov AL,[FirstByte] and AL,00001100b @@ -91,21 +91,21 @@ check_mouse_data_com1: or AL,[ThirdByte] cbw call mouse_acceleration_com1 - add AX,[0xFB0C] ;[YCoordinate] + add AX,[MOUSE_Y] ;[YCoordinate] ; Курсор не должен выходить за верхнюю или ; нижнюю границу экрана js @@Y1 - cmp AX,[0xFE04] ;ScreenHeigth + cmp AX,[ScreenHeight] ;ScreenHeigth jb @@Y2 ; Установить координату X по нижней границе - mov AX,[0xFE04] ;ScreenHeigth-1 + mov AX,[ScreenHeight] ;ScreenHeigth-1 dec ax jmp @@Y2 @@Y1: ; Установить координату X по верхней границе xor AX,AX @@Y2: - mov [0xFB0C],AX ;[YCoordinate] + mov [MOUSE_Y],AX ;[YCoordinate] mov eax,[timer_ticks] mov [timer_ticks_com],eax jmp @@EndMouseInterrupt @@ -125,6 +125,6 @@ mouse_acceleration_com1: cmp eax,[mouse_delay] pop eax ja @f - shl ax,1 + imul ax,[mouse_speed_factor] @@: ret diff --git a/kernel/branches/gfx_kernel/hid/m_com2.inc b/kernel/branches/gfx_kernel/hid/m_com2.inc index 2f364cc15..6c33f1b90 100644 --- a/kernel/branches/gfx_kernel/hid/m_com2.inc +++ b/kernel/branches/gfx_kernel/hid/m_com2.inc @@ -61,7 +61,7 @@ check_mouse_data_com2: shr ah,5 and ah,1 add al,ah - mov [0xfb40],al + mov [BTN_DOWN],al mov [mouse_active],1 ; Прибавить перемещение по X к координате X mov AL,[FirstByte_1] @@ -69,21 +69,21 @@ check_mouse_data_com2: or AL,[SecondByte_1] cbw call mouse_acceleration_com2 - add AX,[0xFB0A] ;[XCoordinate] + add AX,[MOUSE_X] ;[XCoordinate] ; Курсор не должен выходить за левую или ; правую границу экрана js @@X1_1 - cmp AX,[0xFE00] ;ScreenLength + cmp AX,[ScreenWidth] ;ScreenLength jb @@X2_1 ; Установить координату X по правой границе - mov AX,[0xFE00] ;ScreenLength-1 + mov AX,[ScreenWidth] ;ScreenLength-1 dec ax jmp @@X2_1 @@X1_1: ; Установить координату X по левой границе xor AX,AX @@X2_1: - mov [0xFB0A],AX ;[XCoordinate] + mov [MOUSE_X],AX ;[XCoordinate] ; Прибавить перемещение по Y к координате Y mov AL,[FirstByte_1] and AL,00001100b @@ -91,21 +91,21 @@ check_mouse_data_com2: or AL,[ThirdByte_1] cbw call mouse_acceleration_com2 - add AX,[0xFB0C] ;[YCoordinate] + add AX,[MOUSE_Y] ;[YCoordinate] ; Курсор не должен выходить за верхнюю или ; нижнюю границу экрана js @@Y1_1 - cmp AX,[0xFE04] ;ScreenHeigth + cmp AX,[ScreenHeight] ;ScreenHeigth jb @@Y2_1 ; Установить координату X по нижней границе - mov AX,[0xFE04] ;ScreenHeigth-1 + mov AX,[ScreenHeight] ;ScreenHeigth-1 dec ax jmp @@Y2_1 @@Y1_1: ; Установить координату X по верхней границе xor AX,AX @@Y2_1: - mov [0xFB0C],AX ;[YCoordinate] + mov [MOUSE_Y],AX ;[YCoordinate] mov eax,[timer_ticks] mov [timer_ticks_com_1],eax jmp @@EndMouseInterrupt_1 @@ -125,6 +125,6 @@ mouse_acceleration_com2: cmp eax,[mouse_delay] pop eax ja @f - shl ax,1 + imul ax,[mouse_speed_factor] @@: ret diff --git a/kernel/branches/gfx_kernel/hid/m_ps2.inc b/kernel/branches/gfx_kernel/hid/m_ps2.inc index 460d27385..09d50779c 100644 --- a/kernel/branches/gfx_kernel/hid/m_ps2.inc +++ b/kernel/branches/gfx_kernel/hid/m_ps2.inc @@ -42,13 +42,13 @@ check_mouse_data_ps2: ; Записать новое значение байта состояния кнопок mov al,[FirstByte_2] ;[0xfb01] and eax,3 - mov [0xfb40],al + mov [BTN_DOWN],al mov [mouse_active],1 ; Вычислить новую X-координату курсора ; Занести в AX перемещение по X mov AH,0 ;дублируем знак во все разряды AH mov AL,[FirstByte_2] - test AL,10000b + test AL,10000b jz @@M0 mov AH,0FFh ; Занести в AL младший байт @@ -57,18 +57,18 @@ check_mouse_data_ps2: call mouse_acceleration_ps2 ; Вычислить новое значение координаты ; курсора по X - add AX,[0xFB0A] ;[XCoordinate] + add AX,[MOUSE_X] ;[XCoordinate] cmp AX,0 jge @@M1 mov AX,0 jmp @@M2 @@M1: - cmp AX,[0xFE00] ;ScreenLength + cmp AX,[ScreenWidth] ;ScreenLength jl @@M2 - mov AX,[0xFE00] ;ScreenLength-1 + mov AX,[ScreenWidth] ;ScreenLength-1 dec ax @@M2: - mov [0xFB0A],AX ;[XCoordinate] + mov [MOUSE_X],AX ;[XCoordinate] ; Вычисляем новую Y-координату курсора ; Занести в AX перемещение по Y @@ -84,19 +84,19 @@ check_mouse_data_ps2: ; Вычислить новое значение координаты курсора ; по Y (Y-координата мыши PS/2 направлена ; противоположно экранной) - neg AX - add AX,[0xFB0C] ;[YCoordinate] + neg AX + add AX,[MOUSE_Y] ;[YCoordinate] cmp AX,0 jge @@M4 mov AX,0 jmp @@M5 @@M4: - cmp AX,[0xFE04] ;ScreenHeigth + cmp AX,[ScreenHeight] ;ScreenHeigth jl @@M5 - mov AX,[0xFE04] ;ScreenHeigth-1 + mov AX,[ScreenHeight] ;ScreenHeigth-1 dec ax @@M5: - mov [0xFB0C],AX ;[YCoordinate] + mov [MOUSE_Y],AX ;[YCoordinate] ; Показать курсор в новой позиции mov eax,[timer_ticks] @@ -106,7 +106,7 @@ check_mouse_data_ps2: ; Обнаружен сбой в порядке передачи информации от мыши @@Error_2: mov [MouseByteNumber_2],0 -; Нормальное завершение прерывания +; Нормальное завершение прерывани @@EndMouseInterrupt_2: call ready_for_next_irq_1 ret @@ -129,7 +129,7 @@ mouse_acceleration_ps2: ;*********************************************** Wait8042BufferEmpty: ; push CX -; mov CX,0FFFFh ;задать число циклов ожидания +; mov CX,0FFFFh ;задать число циклов ожидани ;@@kb: ; in AL,64h ;получить статус ; test AL,10b ;буфер i8042 свободен? @@ -138,7 +138,7 @@ Wait8042BufferEmpty: push ecx xor ecx,ecx @@: - in al,64h + in al,64h test al,00000010b loopnz @b pop ecx @@ -150,8 +150,8 @@ Wait8042BufferEmpty: ;* ОЖИДАНИЕ ПОСТУПЛЕНИЯ ДАННЫХ ОТ МЫШИ * ;*************************************** WaitMouseData: -; push CX -; mov CX,0FFFFh ;задать число циклов ожидания +; push CX +; mov CX,0FFFFh ;задать число циклов ожидани ;@@mouse: ; in AL,64h ;опросить регистр статуса ; test AL,100000b ;данные поступили? @@ -160,11 +160,11 @@ WaitMouseData: push ecx mov ECX,0FFFFh @@: - in al,64h + in al,64h test al,100000b loopz @b pop ecx ;Если при выходе из подпрограммы установлен ;флаг ZF - ошибка - ret + ret diff --git a/kernel/branches/gfx_kernel/hid/mousedrv.inc b/kernel/branches/gfx_kernel/hid/mousedrv.inc index b25b7101c..749ec204e 100644 --- a/kernel/branches/gfx_kernel/hid/mousedrv.inc +++ b/kernel/branches/gfx_kernel/hid/mousedrv.inc @@ -40,124 +40,152 @@ include 'm_com2.inc' __sys_draw_mouse_under: ; return old picture + cmp [set_hw_cursor], 0 + jz @F + pushad + movzx eax,word [X_UNDER] + movzx ebx,word [Y_UNDER] + stdcall [hw_restore], eax, ebx + popad + ret +@@: pushad - xor ecx,ecx xor edx,edx - mov esi,mouseunder-4 - align 4 - mres: - - add esi,4 - - movsx eax,word[0xfb4a] +mres: + movzx eax,word [X_UNDER] + movzx ebx,word [Y_UNDER] add eax,ecx - js .skip - movsx ebx,word[0xfb4c] add ebx,edx - js .skip - push ecx push edx - mov ecx,[esi] - - mov edi,1 ;force - push esi + 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 esi - pop edx pop ecx - .skip: inc ecx - cmp ecx,32 - + cmp ecx, 16 jnz mres xor ecx, ecx inc edx - cmp edx,32 + cmp edx, 24 jnz mres - popad ret - save_draw_mouse: + + cmp [set_hw_cursor], 0 + jz @F + pushad + + mov [X_UNDER],ax + mov [Y_UNDER],bx + movzx eax,word [MOUSE_Y] + movzx ebx,word [MOUSE_X] + push eax + push ebx + + mov ecx, [ScreenWidth] + inc ecx + mul ecx + movzx edx, byte [display_data+ebx+eax] + shl edx, 8 + mov ecx, [edx+SLOT_BASE+APPDATA.cursor] + + cmp [ecx+CURSOR.magic], 'CURS' + jne .fail +; cmp [ecx+CURSOR.size], CURSOR_SIZE +; jne .fail + push ecx + call [set_hw_cursor] + popad + ret +.fail: + mov ecx, [def_cursor] + mov [edx+SLOT_BASE+APPDATA.cursor], ecx + push ecx + call [set_hw_cursor] + popad + ret + +@@: pushad ; save & draw - mov [0xfb4a],ax - mov [0xfb4c],bx + mov [X_UNDER],ax + mov [Y_UNDER],bx push eax push ebx - xor ecx,ecx - mov edx,ecx - mov esi,mouseunder-4;3 - mov edi,mousepointer+62-4 - - mov dword[0x6900],mouseunder+mousecomb - - drm: - - add esi,4;3 - add edi,4 - - push eax ebx ecx edx - - push eax 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 - js @f add ebx,edx - js @f - push esi edi - call [getpixel] - pop edi esi - mov [esi],ecx - pop ebx eax - - push esi edi + push ecx + call getpixel + mov [COLOR_TEMP],ecx + pop ecx + mov eax,edx + shl eax,6 + shl ecx,2 + add eax,ecx + add eax,mouseunder + mov ebx,[COLOR_TEMP] + 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,[MOUSE_PICTURE] ; we have our str address + mov esi, edi + add esi, 16*24*3 + push ecx + mov ecx, [COLOR_TEMP] call combine_colors - pop edi esi - mov [0xfb10],ecx - - pop edx ecx ebx eax - - xchg esi,[0x6900] - push dword[0xFB10] - pop dword[esi] - add esi,3 - xchg esi,[0x6900] - - jc mnext - - add eax,ecx ; we have x coord+cycle - js mnext - add ebx,edx ; and y coord+cycle - js mnext - - push ecx edi esi - mov ecx, [0xfb10] - mov edi, 1 - call [putpixel] - pop esi edi ecx - jmp mnext - @@: add esp,8 - pop edx ecx ebx eax - mnext: - - mov ebx,[esp+0] ; pure y coord again - mov eax,[esp+4] ; and x - - inc ecx ; +1 cycle - cmp ecx,32 - jnz drm - xor ecx,ecx - inc edx - cmp edx,32 - jnz drm + mov [MOUSE_COLOR_MEM], 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, [MOUSE_COLOR_MEM] + 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 @@ -170,141 +198,132 @@ combine_colors: ; ; out ; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) - ; colors: - ; [esp] = background: - ; [edi] = cursor - ; = combined - - cmp byte[edi+3],0 - jne @f - stc - ret - @@: - cmp byte[edi+3],255 - jne @f - mov ecx,[edi] - and ecx,0x00FFFFFF - clc - ret - @@: + push eax + push ebx + push edx push ecx - - xor ecx,ecx - - movzx eax,byte[edi+2] - movzx ebx,byte[esp+2] - sub eax,ebx - movzx ebx,byte[edi+3] - imul ebx - xor edx,edx - mov ebx,255 - div ebx - add al,[esp+2] - mov cl,al - shl ecx,8 - - movzx eax,byte[edi+1] - movzx ebx,byte[esp+1] - sub eax,ebx - movzx ebx,byte[edi+3] - imul ebx - xor edx,edx - mov ebx,255 - div ebx - add al,[esp+1] - mov cl,al - shl ecx,8 - - movzx eax,byte[edi+0] - movzx ebx,byte[esp+0] - sub eax,ebx - movzx ebx,byte[edi+3] - imul ebx - xor edx,edx - mov ebx,255 - div ebx - add al,[esp+0] - mov cl,al - - add esp,4 - - clc + 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 + cmp dword [MOUSE_VISIBLE],dword 0 je @f ret -@@: +@@: pushad - cmp [0x3000],dword 1 + cmp [CURRENT_TASK],dword 1 je disable_m - mov edx,[0x3000] + mov edx,[CURRENT_TASK] shl edx,5 add edx,window_data - movzx eax,word[0xfb0a] - movzx ecx,word[mousepointer+10] - sub eax,ecx - movzx ebx,word[0xfb0c] - movzx ecx,word[mousepointer+12] - sub ebx,ecx - mov ecx,[0xfe00] + movzx eax, word [MOUSE_X] + movzx ebx, word [MOUSE_Y] + mov ecx,[ScreenWidth] + inc ecx imul ecx,ebx add ecx,eax add ecx, display_data -; mov eax, [0x3000] - movzx eax, byte [edx+twdw+0xe] + mov eax, [CURRENT_TASK] movzx ebx, byte [ecx] cmp eax,ebx je yes_mouse_disable - movzx ebx, byte [ecx+32] + movzx ebx, byte [ecx+16] cmp eax,ebx je yes_mouse_disable - mov ebx,[0xfe00] + mov ebx,[ScreenWidth] inc ebx - imul ebx,32 + imul ebx,10 add ecx,ebx movzx ebx, byte [ecx] cmp eax,ebx je yes_mouse_disable - movzx ebx, byte [ecx+32] + movzx ebx, byte [ecx+16] cmp eax,ebx je yes_mouse_disable jmp no_mouse_disable yes_mouse_disable: - mov edx,[0x3000] + mov edx,[CURRENT_TASK] shl edx,5 add edx,window_data - movzx eax, word [0xfb0a] - movzx ebx, word [0xfb0c] - movzx ecx,word[mousepointer+10] - sub eax,ecx - movzx ecx,word[mousepointer+12] - sub ebx,ecx + movzx eax, word [MOUSE_X] + movzx ebx, word [MOUSE_Y] mov ecx,[edx+0] ; mouse inside the area ? - add eax,32 + add eax,14 cmp eax,ecx - jl no_mouse_disable - sub eax,32 + jb no_mouse_disable + sub eax,14 add ecx,[edx+8] cmp eax,ecx jg no_mouse_disable mov ecx,[edx+4] - add ebx,32 + add ebx,20 cmp ebx,ecx - jl no_mouse_disable - sub ebx,32 + 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 + cmp dword [MOUSE_VISIBLE],dword 0 jne no_mouse_disable cli - call [draw_mouse_under] + call [draw_mouse_under] sti - mov [0xf204],dword 1 + mov [MOUSE_VISIBLE],dword 1 no_mouse_disable: popad ret @@ -326,15 +345,11 @@ __sys_draw_pointer: mov [MouseTickCounter],eax pop eax pushad - cmp dword [0xf204],dword 0 ; mouse visible ? + cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ? je chms00 - mov [0xf204], dword 0 - movzx ebx,word [0xfb0c] - movzx eax,word [0xfb0a] - movzx esi,word[mousepointer+10] - sub eax,esi - movzx esi,word[mousepointer+12] - sub ebx,esi + mov [MOUSE_VISIBLE], dword 0 + movzx ebx,word [MOUSE_Y] + movzx eax,word [MOUSE_X] cli call save_draw_mouse sti @@ -342,14 +357,10 @@ nodmu2: popad ret chms00: - movsx ecx,word[0xfb4a] - movsx edx,word[0xfb4c] - movzx ebx,word [0xfb0c] - movzx eax,word [0xfb0a] - movzx esi,word[mousepointer+10] - sub eax,esi - movzx esi,word[mousepointer+12] - sub ebx,esi + movzx ecx,word [X_UNDER] + movzx edx,word [Y_UNDER] + movzx ebx,word [MOUSE_Y] + movzx eax,word [MOUSE_X] cmp eax,ecx jne redrawmouse cmp ebx,edx diff --git a/kernel/branches/gfx_kernel/kernel.asm b/kernel/branches/gfx_kernel/kernel.asm index 7575b6edd..c98a87416 100644 --- a/kernel/branches/gfx_kernel/kernel.asm +++ b/kernel/branches/gfx_kernel/kernel.asm @@ -10,23 +10,24 @@ ;; Compile with last version FASM ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +include "proc32.inc" include "kglobals.inc" include "lang.inc" -WinMapAddress equ 0x460000 -display_data = 0x460000 +include "const.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 +;window_data equ 0x0000 +;tss_data equ 0xD20000 tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 -draw_data equ 0xC00000 -sysint_stack_data equ 0xC03000 +;draw_data equ 0xC00000 +;sysint_stack_data equ 0xC03000 - -twdw equ (0x3000-window_data) +;twdw equ (0x3000-window_data) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -61,13 +62,14 @@ twdw equ (0x3000-window_data) 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 +draw_line dd __sys_draw_line +disable_mouse dd __sys_disable_mouse +draw_pointer dd __sys_draw_pointer draw_mouse_under dd __sys_draw_mouse_under drawbar dd __sys_drawbar.forced putpixel dd __sys_putpixel @@ -78,7 +80,7 @@ calculatescreen dd __sys_calculatescreen setscreen dd __sys_setscreen ; } mike.dld -version db 'Kolibri OS version 0.5.8.1 ',13,10,13,10,0 +version db 'Kolibri OS version 0.6.5.0 ',13,10,13,10,0 ;dd endofcode-0x10000 ;db 'Boot02' @@ -118,17 +120,7 @@ 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: + mov ecx, CR0_PE ; Enabling 32 bit protected mode @@ -149,13 +141,18 @@ app_data equ 3+app_data_l-gdts jnz l.6 mov al, 0xDF out 0x60, al + l.7: in al, 0x64 + test al, 2 + jnz l.7 + mov al, 0xFF + out 0x64, 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 +org $+0x10000 mov ax,os_data ; Selector for os mov ds,ax mov es,ax @@ -165,8 +162,18 @@ org $+0x10000 mov esp,0x3ec00 ; Set stack jmp pword os_code:B32 ; jmp to enable 32 bit mode +if gdte >= $ +error 'GDT overlaps with used code!' +end if + use32 +include 'unpacker.inc' + +__DEBUG__ fix 1 +__DEBUG_LEVEL__ fix 1 +include 'fdo.inc' + iglobal boot_memdetect db 'Determining amount of memory',0 boot_fonts db 'Fonts loaded',0 @@ -225,21 +232,14 @@ boot_log: 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 ' + char db 'FONTS/CHAR.MT',0 + char2 db 'FONTS/CHAR2.MT',0 bootpath db '/KOLIBRI ' bootpath2 db 0 - vmode db 'VMODE MDR' - cur_file db 'ARROW CUR' + vmode db 'drivers/VMODE.MDR',0 + cur_file db 'ARROW.CUR',0 vrr_m db '/rd/1/VRR_M',0 endg @@ -262,6 +262,7 @@ B32: rep stosd ; CLEAR 0x80000-0x90000 ; xor eax,eax + mov edi,0x80000 mov ecx,(0x90000-0x80000)/4 ; cld @@ -286,6 +287,8 @@ B32: rep stosd ; SAVE REAL MODE VARIABLES + mov ax, [0x2f0000 + 0x9031] + mov [IDEContrRegsBaseAddr], ax ; --------------- APM --------------------- mov eax, [0x2f0000 + 0x9040] ; entry point mov dword[apm_entry], eax @@ -296,31 +299,33 @@ B32: ; ----------------------------------------- ; movzx eax,byte [0x2f0000+0x9010] ; mouse port ; mov [0xF604],byte 1 ;al + mov al, [0x2F0000+0x901F] ; DMA writing + mov [allow_dma_write], al mov al,[0x2f0000+0x9000] ; bpp - mov [0xFBF1],al + mov [ScreenBPP],al movzx eax,word [0x2f0000+0x900A] ; X max ; dec eax - mov [0xfe00],eax + mov [ScreenWidth],eax mov [screen_workarea.right],eax movzx eax,word [0x2f0000+0x900C] ; Y max ; dec eax - mov [0xfe04],eax + mov [ScreenHeight],eax mov [screen_workarea.bottom],eax movzx eax,word [0x2f0000+0x9008] ; screen mode - mov [0xFE0C],eax + mov [SCR_MODE],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 + mov [BANK_SWITCH],eax + mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine + cmp [SCR_MODE],word 0x13 ; 320x200 je @f - cmp [0xFE0C],word 0x12 ; VGA 640x480 + cmp [SCR_MODE],word 0x12 ; VGA 640x480 je @f mov ax,[0x2f0000+0x9001] ; for other modes - mov [0xfe08],ax + mov [BytesPerScanLine],ax mov al,[0x2F0000+0x9034] ; vesa major version number (ascii) - mov [0xE034],al + mov [VESA_VER_MAJOR],al mov al,[0x2F0000+0x9035] ; card vendor (intel=1, s3=2, other=3) - mov [0xE035],al + mov [GFX_CARD_VENDOR],al @@: ; GRAPHICS ADDRESSES @@ -335,126 +340,161 @@ B32: mov byte [0x2f0000+0x901e],0x0 mov eax,[0x2f0000+0x9018] ;no_d_lfb: - mov [0xfe80],eax + mov [LFBAddress],eax - cmp [0xfe0c],word 0100000000000000b + cmp [SCR_MODE],word 0100000000000000b jge setvesa20 - cmp [0xfe0c],word 0x13 + cmp [SCR_MODE],word 0x13 je v20ga32 - mov [0xe020],dword Vesa12_putpixel24 ; Vesa 1.2 + mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 mov [0xe024],dword Vesa12_getpixel24 - cmp [0xfbf1],byte 24 + cmp [ScreenBPP],byte 24 jz ga24 - mov [0xe020],dword Vesa12_putpixel32 + mov [PUTPIXEL],dword Vesa12_putpixel32 mov [0xe024],dword Vesa12_getpixel32 ga24: jmp v20ga24 setvesa20: - mov [0xe020],dword Vesa20_putpixel24 ; Vesa 2.0 + mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 mov [0xe024],dword Vesa20_getpixel24 - cmp [0xfbf1],byte 24 + cmp [ScreenBPP],byte 24 jz v20ga24 v20ga32: - mov [0xe020],dword Vesa20_putpixel32 + mov [PUTPIXEL],dword Vesa20_putpixel32 mov [0xe024],dword Vesa20_getpixel32 v20ga24: - cmp [0xfe0c],word 0x12 ; 16 C VGA 640x480 + cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 jne no_mode_0x12 - mov [0xe020],dword VGA_putpixel + mov [PUTPIXEL],dword VGA_putpixel mov [0xe024],dword Vesa20_getpixel32 no_mode_0x12: + call test_cpu +; btr [cpu_caps], CAPS_SSE ;test: dont't use sse code +; btr [cpu_caps], CAPS_SSE2 ;test: don't use sse2 + +; btr [cpu_caps], CAPS_FXSR ;test: disable sse support + ;all sse commands rise #UD exption +; btr [cpu_caps], CAPS_PSE ;test: don't use large pages +; btr [cpu_caps], CAPS_PGE ;test: don't use global pages +; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR + bts [cpu_caps], CAPS_TSC ;force use rdtsc + +; -------- Fast System Call init ---------- +; Intel SYSENTER/SYSEXIT (AMD CPU support it too) + bt [cpu_caps], CAPS_SEP + jnc .SEnP ; SysEnter not Present + xor edx, edx + mov ecx, MSR_SYSENTER_CS + mov eax, os_code + wrmsr + mov ecx, MSR_SYSENTER_ESP + mov eax, sysenter_stack ; Check it + wrmsr + mov ecx, MSR_SYSENTER_EIP + mov eax, sysenter_entry + wrmsr +.SEnP: +; AMD SYSCALL/SYSRET + cmp byte[cpu_vendor], 'A' + jne .noSYSCALL + mov eax, 0x80000001 + cpuid + test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support + jz .noSYSCALL + mov ecx, MSR_AMD_EFER + rdmsr + or eax, 1 ; bit_0 - System Call Extension (SCE) + wrmsr + + ; !!!! It`s dirty hack, fix it !!! + ; Bits of EDX : + ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + + ; mov edx, (os_code + 16) * 65536 + os_code + mov edx, 0x1B0013 + + mov eax, syscall_entry + mov ecx, MSR_AMD_STAR + wrmsr +.noSYSCALL: +; ----------------------------------------- + + + ; MEMORY MODEL + call mem_test + call init_mtrr + call init_mem + call init_page_map -; 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 + mov eax, sys_pgdir + mov cr3, eax - 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 + mov eax,cr0 + or eax,CR0_PG + mov cr0,eax + + call init_kernel_heap + stdcall kernel_alloc, 0x2000 + mov [os_stack], eax + + call init_LFB + call init_fpu + + call init_malloc + + stdcall alloc_kernel_space, 0x4F000 + mov [ipc_tmp], eax + mov ebx, 0x1000 + + add eax, 0x40000 + mov [proc_mem_map], eax + + add eax, 0x8000 + mov [proc_mem_pdir], eax + + add eax, ebx + mov [proc_mem_tab], eax + + add eax, ebx + mov [tmp_task_pdir], eax + + add eax, ebx + mov [tmp_task_ptab], eax + + add eax, ebx + mov [ipc_pdir], eax + + add eax, ebx + mov [ipc_ptab], eax + + call init_events + + mov eax, srv.fd-SRV_FD_OFFSET + mov [srv.fd], eax + mov [srv.bk], eax + + mov edi, irq_tab + xor eax, eax + mov ecx, 16 + rep stosd ;Set base of graphic segment to linear address of LFB - mov eax,[0xfe80] ; set for gs + mov eax,[LFBAddress] ; set for gs mov [graph_data_l+2],ax shr eax,16 mov [graph_data_l+4],al mov [graph_data_l+7],ah +;!!!!!!!!!!!!!!!!!!!!!!!!!! +include 'detect/disks.inc' +;!!!!!!!!!!!!!!!!!!!!!!!!!! + ; READ RAMDISK IMAGE FROM HD ;!!!!!!!!!!!!!!!!!!!!!!! @@ -477,23 +517,21 @@ include 'vmodeld.inc' ; LOAD FONTS I and II - mov [0x3000],dword 1 - mov [0x3004],dword 1 - mov [0x3010],dword 0x3020 + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],dword 1 + mov [TASK_BASE],dword TASK_DATA - mov eax,char - mov esi,12 + mov esi,char xor ebx,ebx mov ecx,2560;26000 - mov edx,0x3F600;0x37000 - call fileread + mov edx,FONT_I + call fs_RamdiskRead - mov eax,char2 - mov esi,12 + mov esi,char2 xor ebx,ebx mov ecx,2560;26000 - mov edx,0x3EC00;0x30000 - call fileread + mov edx,FONT_II + call fs_RamdiskRead mov esi,boot_fonts call boot_log @@ -506,22 +544,11 @@ include 'vmodeld.inc' or ecx, (10+29*6) shl 16 ; "Determining amount of memory" sub ecx, 10 mov edx, 0xFFFFFF - mov ebx, [0xFE8C] + mov ebx, [MEM_AMOUNT] 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: - - + call display_number_force ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f @@ -538,67 +565,7 @@ include 'vmodeld.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 + cli mov esi,boot_devices call boot_log @@ -617,12 +584,11 @@ finit ;reset the registers, contents which are still equal RM ; SET MOUSE - mov eax,cur_file - mov esi,12 - mov ebx,0 + mov esi,cur_file + xor ebx,ebx mov ecx,26000 mov edx,mousepointer - call fileread + call fs_RamdiskRead mov esi,mousepointer+62+32*31*4 mov edi,mousepointer+62 @@ -642,6 +608,8 @@ finit ;reset the registers, contents which are still equal RM call boot_log call setmouse + mov [pci_access_enabled],1 + ; SET PRELIMINARY WINDOW STACK AND POSITIONS mov esi,boot_windefs @@ -670,51 +638,83 @@ finit ;reset the registers, contents which are still equal RM 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 -;---------------------- -mov eax,[0xfe00] -mov ebx,[0xfe04] -xor ecx,ecx -mov [0],ecx -mov [4],ecx -mov [8],eax -mov [12],ebx -mov [256+0],ecx -mov [256+4],ecx -mov [256+8],eax -mov [256+12],ebx -;---------------------- - ; 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 + mov eax, fpu_data + mov dword [SLOT_BASE+APPDATA.fpu_state], eax + mov dword [SLOT_BASE+APPDATA.fpu_handler], 0 + mov dword [SLOT_BASE+APPDATA.sse_handler], 0 + + ; name for OS/IDLE process + + mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' + mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' + mov edi, [os_stack] + mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi + add edi, 0x2000-512 + mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi + +;---------------------- +mov eax,[ScreenWidth] +mov ebx,[ScreenHeight] +xor ecx,ecx +mov [0],ecx +mov [4],ecx +mov [8],eax +mov [12],ebx +mov [256+0],ecx +mov [256+4],ecx +mov [256+8],eax +mov [256+12],ebx +;---------------------- + + + mov esi, fpu_data + mov ecx, 512/4 cld - rep movsd + rep movsd + + mov dword [SLOT_BASE+256+APPDATA.fpu_handler], 0 + mov dword [SLOT_BASE+256+APPDATA.sse_handler], 0 + + mov ebx, [def_cursor] + mov dword [SLOT_BASE+256+APPDATA.cursor], ebx + + mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET + mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx + mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx + + ; task list + mov [TASK_DATA+TASKDATA.wnd_number], 1 ; on screen number + mov [TASK_DATA+TASKDATA.pid], 1 ; process id number + mov [TASK_DATA+TASKDATA.mem_start], 0 ; process base address + + mov edi,tss_data+tss_step + mov ecx, (tss_step)/4 + xor eax, eax + cld + rep stosd + + mov edi,tss_data+tss_step + mov [edi+TSS._ss0], os_data + mov eax,cr3 + mov [edi+TSS._cr3],eax + mov [edi+TSS._eip],osloop + mov [edi+TSS._eflags],dword 0x11202 ; sti and resume + mov eax, [os_stack] + add eax, 0x2000-512 + mov [edi+TSS._esp], eax + mov [edi+TSS._cs],os_code + mov [edi+TSS._ss],os_data + mov [edi+TSS._ds],os_data + mov [edi+TSS._es],os_data + mov [edi+TSS._fs],os_data + mov [edi+TSS._gs],os_data mov ax,tss0 ltr ax + call init_cursors + ; READ TSC / SECOND @@ -727,7 +727,10 @@ mov [256+12],ebx call _rdtsc sub eax,ecx shl eax,2 - mov [0xf600],eax ; save tsc / sec + mov [CPU_FREQ],eax ; save tsc / sec + mov ebx, 1000000 + div ebx + mov [stall_mcs], eax ; SET VARIABLES @@ -740,14 +743,14 @@ mov [256+12],ebx ; PALETTE FOR 320x200 and 640x480 16 col - cmp [0xfe0c],word 0x12 + cmp [SCR_MODE],word 0x12 jne no_pal_vga mov esi,boot_pal_vga call boot_log call paletteVGA no_pal_vga: - cmp [0xfe0c],word 0x13 + cmp [SCR_MODE],word 0x13 jne no_pal_ega mov esi,boot_pal_ega call boot_log @@ -763,41 +766,34 @@ mov [256+12],ebx movsd call load_skin -; MTRR'S - - call enable_mtrr - - ; LOAD FIRST APPLICATION - mov [0x3000],dword 1 - mov [0x3004],dword 1 + mov [CURRENT_TASK],dword 1 + mov [TASK_COUNT],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 + + mov ebp, vrr_m + xor ebx, ebx + xor edx, edx + call fs_execute 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 - +no_load_vrr_m: + mov ebp, firstapp + xor ebx, ebx + xor edx, edx + call fs_execute cmp eax,2 ; continue if a process has been loaded je first_app_found mov eax, 0xDEADBEEF ; otherwise halt hlt - first_app_found: +first_app_found: cli - ;mov [0x3004],dword 2 - mov [0x3000],dword 1 ; set OS task fisrt + ;mov [TASK_COUNT],dword 2 + mov [CURRENT_TASK],dword 1 ; set OS task fisrt ; SET KEYBOARD PARAMETERS @@ -805,12 +801,11 @@ mov [256+12],ebx call kb_write ; wait until 8042 is ready -; xor ecx,ecx -; @@: -; in al,64h -; and al,00000010b -; loopnz @b - call Wait8042BufferEmpty + xor ecx,ecx + @@: + in al,64h + and al,00000010b + loopnz @b ; mov al, 0xED ; svetodiody - only for testing! ; call kb_write @@ -821,10 +816,10 @@ mov [256+12],ebx mov al, 0xF3 ; set repeat rate & delay call kb_write - call kb_read +; call kb_read mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 call kb_write - call kb_read +; call kb_read ;// mike.dld [ call set_lights ;// mike.dld ] @@ -834,7 +829,7 @@ mov [256+12],ebx mov esi,boot_tasking call boot_log - mov [0xe000],byte 1 ; multitasking enabled + ; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled ; UNMASK ALL IRQ'S @@ -856,7 +851,11 @@ mov [256+12],ebx loop ready_for_irqs ; flush the queue + stdcall attach_int_handler, dword 1, irq1 + ; mov [dma_hdd],1 + cmp [IDEContrRegsBaseAddr], 0 + setnz [dma_hdd] sti jmp $ ; wait here for timer to take control @@ -870,7 +869,6 @@ mov [256+12],ebx ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; align 32 osloop: - call [draw_pointer] call checkbuttons call checkwindows @@ -963,57 +961,6 @@ include "kernel32.inc" ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -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 @@ -1034,12 +981,35 @@ reserve_irqs_ports: ; RESERVE PORTS - mov edi,1 ; 0x00-0xff - mov [0x2d0000],edi + mov edi,1 ; 0x00-0x2d + mov [RESERVED_PORTS],edi shl edi,4 - mov [0x2d0000+edi+0],dword 1 - mov [0x2d0000+edi+4],dword 0x0 - mov [0x2d0000+edi+8],dword 0xff + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x0 + mov [RESERVED_PORTS+edi+8],dword 0x2d + + inc dword [RESERVED_PORTS] ; 0x30-0x4d + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x30 + mov [RESERVED_PORTS+edi+8],dword 0x4d + + inc dword [RESERVED_PORTS] ; 0x50-0xdf + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0x50 + mov [RESERVED_PORTS+edi+8],dword 0xdf + + inc dword [RESERVED_PORTS] ; 0xe5-0xff + mov edi,[RESERVED_PORTS] + shl edi,4 + mov [RESERVED_PORTS+edi+0],dword 1 + mov [RESERVED_PORTS+edi+4],dword 0xe5 + mov [RESERVED_PORTS+edi+8],dword 0xff + + ; cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff ; jne ripl1 ; inc dword [0x2d0000] @@ -1088,10 +1058,10 @@ 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 + mov [MOUSE_BUFF_COUNT],byte 0 ; mouse buffer + mov [KEY_COUNT],byte 0 ; keyboard buffer + mov [BTN_COUNT],byte 0 ; button buffer +; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y push eax mov ax,[0x2f0000+0x900c] @@ -1099,12 +1069,12 @@ set_variables: shl eax,16 mov ax,[0x2f0000+0x900A] shr ax,1 - mov [0xfb0a],eax + mov [MOUSE_X],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 + mov [BTN_ADDR],dword BUTTON_INFO ; address of button list ;!! IP 04.02.2005: mov [next_usage_update], 100 @@ -1115,12 +1085,12 @@ set_variables: ;* mouse centered - start code- Mario79 mouse_centered: push eax - mov eax,[0xFE00] + mov eax,[ScreenWidth] shr eax,1 - mov [0xFB0A],ax - mov eax,[0xFE04] + mov [MOUSE_X],ax + mov eax,[ScreenHeight] shr eax,1 - mov [0xFB0C],ax + mov [MOUSE_Y],ax pop eax ret ;* mouse centered - end code- Mario79 @@ -1132,14 +1102,14 @@ sys_outport: mov edi,ebx ; separate flag for read / write and ebx,65535 - mov ecx,[0x2d0000] + mov ecx,[RESERVED_PORTS] test ecx,ecx jne sopl8 mov [esp+36],dword 1 ret sopl8: - mov edx,[0x3010] + mov edx,[TASK_BASE] mov edx,[edx+0x4] and ebx,65535 cld @@ -1147,7 +1117,7 @@ sys_outport: mov esi,ecx shl esi,4 - add esi,0x2d0000 + add esi,RESERVED_PORTS cmp edx,[esi+0] jne sopl2 cmp ebx,[esi+4] @@ -1282,50 +1252,6 @@ sys_sb16II: 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 @@ -1339,6 +1265,8 @@ display_number: ; ebx = number or pointer ; ecx = x shl 16 + y ; edx = color + xor edi, edi +display_number_force: cmp eax,0xffff ; length > 0 ? jge cont_displ @@ -1364,7 +1292,7 @@ display_number: and eax,0x3f push eax mov edi,esp - add edi,4+64 + add edi,4+64-1 mov ecx,eax mov eax,ebx mov ebx,10 @@ -1388,7 +1316,7 @@ display_number: and eax,0x3f push eax mov edi,esp - add edi,4+64 + add edi,4+64-1 mov ecx,eax mov eax,ebx mov ebx,16 @@ -1413,7 +1341,7 @@ display_number: and eax,0x3f push eax mov edi,esp - add edi,4+64 + add edi,4+64-1 mov ecx,eax mov eax,ebx mov ebx,2 @@ -1446,23 +1374,31 @@ draw_num_text: ; edx length ; edi 1 force +; mov edi,[CURRENT_TASK] +; shl edi,8 +; add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] +; rol eax,16 +; add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] +; rol eax,16 + mov edx,eax - mov ecx,65 + mov ecx,64+4 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 edx,[TASK_BASE] mov ebx,[edx-twdw+WDATA.box.left] + add ebx, [(edx-CURRENT_TASK)*8+SLOT_BASE+APPDATA.wnd_clientbox.left] shl ebx,16 add ebx,[edx-twdw+WDATA.box.top] + add ebx, [(edx-CURRENT_TASK)*8+SLOT_BASE+APPDATA.wnd_clientbox.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 + mov edi, [esp+64+4] jmp dtext read_string: @@ -1485,7 +1421,6 @@ sys_setup: ; 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 @@ -1508,7 +1443,9 @@ sys_setup: mov word [midisp],bx ret +iglobal midi_base dw 0 +endg nsyse1: @@ -1516,7 +1453,7 @@ midi_base dw 0 jnz nsyse2 cmp ebx,1 jnz kbnobase - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov eax,ecx mov ebx,keymap @@ -1526,7 +1463,7 @@ midi_base dw 0 kbnobase: cmp ebx,2 jnz kbnoshift - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov eax,ecx mov ebx,keymap_shift @@ -1536,7 +1473,7 @@ midi_base dw 0 kbnoshift: cmp ebx,3 jne kbnoalt - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov eax,ecx mov ebx,keymap_alt @@ -1602,17 +1539,6 @@ cd_base db 0 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 @@ -1648,14 +1574,16 @@ wss_temp dd 0 mov [hdpos],4 ; call set_FAT32_variables noseslhd: - mov [0xfe10],dword 0 call reserve_hd1 - call clear_hd_cache + call reserve_hd_channel + call free_hd_channel mov [hd1_status],0 ; free nosethd: ret +iglobal hd_base db 0 +endg nsyse7: @@ -1664,7 +1592,8 @@ hd_base db 0 mov [fat32part],ebx ; call set_FAT32_variables call reserve_hd1 - call clear_hd_cache + call reserve_hd_channel + call free_hd_channel pusha call choice_necessity_partition_1 popa @@ -1712,7 +1641,6 @@ sys_getsetup: ; 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 @@ -1728,7 +1656,7 @@ sys_getsetup: jne ngsyse2 cmp ebx,1 jnz kbnobaseret - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov ebx,ecx mov eax,keymap @@ -1738,7 +1666,7 @@ sys_getsetup: kbnobaseret: cmp ebx,2 jnz kbnoshiftret - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov ebx,ecx mov eax,keymap_shift @@ -1748,7 +1676,7 @@ sys_getsetup: kbnoshiftret: cmp ebx,3 jne kbnoaltret - mov edi,[0x3010] + mov edi,[TASK_BASE] add ecx,[edi+TASKDATA.mem_start] mov ebx,ecx mov eax,keymap_alt @@ -1783,12 +1711,6 @@ sys_getsetup: 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] @@ -1828,45 +1750,75 @@ sys_getsetup: mov [esp+36],dword 1 ret - +iglobal align 4 +mousefn dd msscreen, mswin, msbutton, msset + dd app_load_cursor + dd app_set_cursor + dd app_delete_cursor +endg readmousepos: ; eax=0 screen relative ; eax=1 window relative ; eax=2 buttons pressed +; eax=3 set mouse pos ; reserved +; eax=4 load cursor +; eax=5 set cursor +; eax=6 delete cursor ; reserved - test eax,eax - jnz nosr - mov eax,[0xfb0a] - shl eax,16 - mov ax,[0xfb0c] - mov [esp+36],eax - ret - nosr: + cmp eax, 6 + ja msset + jmp [mousefn+eax*4] +msscreen: + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov [esp+36],eax + ret +mswin: + mov eax,[MOUSE_X] + shl eax,16 + mov ax,[MOUSE_Y] + mov esi,[TASK_BASE] + mov bx, word [esi-twdw+WDATA.box.left] + shl ebx,16 + mov bx, word [esi-twdw+WDATA.box.top] + sub eax,ebx - 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 [esp+36],eax - ret - nowr: + mov edi,[CURRENT_TASK] + shl edi,8 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol eax,16 + sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol eax,16 + mov [esp+36],eax + ret +msbutton: + movzx eax,byte [BTN_DOWN] + mov [esp+36],eax + ret +msset: + ret - cmp eax,2 - jnz nomb - movzx eax,byte [0xfb40] - nomb: - mov [esp+36],eax +app_load_cursor: + add ebx, new_app_base + cmp ebx, new_app_base + jb msset + stdcall load_cursor, ebx, ecx + mov [esp+36], eax + ret - ret +app_set_cursor: + stdcall set_cursor, ebx + mov [esp+36], eax + ret + +app_delete_cursor: + stdcall delete_cursor, ebx + mov [esp+36], eax + ret is_input: @@ -1877,7 +1829,6 @@ is_input: pop edx ret - is_output: push edx @@ -1981,7 +1932,7 @@ include 'detect/ps2mouse.inc' sys_end: - mov eax,[0x3010] + mov eax,[TASK_BASE] mov [eax+TASKDATA.state], 3 ; terminate this program waitterm: ; wait here for termination @@ -1990,6 +1941,7 @@ sys_end: jmp waitterm iglobal +align 4 sys_system_table: dd sysfn_shutdown ; 1 = system shutdown dd sysfn_terminate ; 2 = terminate thread @@ -2008,9 +1960,10 @@ sys_system_table: 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 + dd sysfn_terminate2 ; 18 = terminate thread using PID ; instead of slot dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration + dd sysfn_meminfo ; 20 = get extended memory info sysfn_num = ($ - sys_system_table)/4 endg @@ -2025,10 +1978,11 @@ sys_system: sysfn_shutdown: ; 18.1 = BOOT mov [0x2f0000+0x9030],byte 0 for_shutdown_parameter: - mov eax,[0x3004] + + mov eax,[TASK_COUNT] add eax,2 mov [shutdown_processes],eax - mov [0xFF00],al + mov [SYS_SHUTDOWN],al and dword [esp+36], 0 ret uglobal @@ -2038,13 +1992,13 @@ sysfn_shutdown: ; 18.1 = BOOT sysfn_terminate: ; 18.2 = TERMINATE cmp ebx,2 jb noprocessterminate - mov edx,[0x3004] + mov edx,[TASK_COUNT] cmp ebx,edx ja noprocessterminate - mov eax,[0x3004] + mov eax,[TASK_COUNT] shl ebx,5 - mov edx,[ebx+0x3000+TASKDATA.pid] - add ebx,0x3000+TASKDATA.state + mov edx,[ebx+CURRENT_TASK+TASKDATA.pid] + add ebx,CURRENT_TASK+TASKDATA.state cmp byte [ebx], 9 jz noprocessterminate @@ -2061,7 +2015,7 @@ sysfn_terminate: ; 18.2 = TERMINATE sysfn_terminate2: ;lock application_table_status mutex -.table_status: +.table_status: cli cmp [application_table_status],0 je .stf @@ -2089,20 +2043,20 @@ sysfn_terminate2: sysfn_activate: ; 18.3 = ACTIVATE WINDOW cmp ebx,2 jb .nowindowactivate - cmp ebx,[0x3004] + cmp ebx,[TASK_COUNT] ja .nowindowactivate mov [window_minimize], 2 ; restore window if minimized - movzx esi, word [0xC000 + ebx*2] - cmp esi, [0x3004] + movzx esi, word [WIN_STACK + ebx*2] + cmp esi, [TASK_COUNT] 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] + movzx esi, word [WIN_STACK + ebx * 2] + lea esi, [WIN_POS + esi * 2] call waredraw .nowindowactivate: ret @@ -2113,7 +2067,7 @@ sysfn_getidletime: ; 18.4 = GET IDLETIME ret sysfn_getcpuclock: ; 18.5 = GET TSC/SEC - mov eax,[0xf600] + mov eax,[CPU_FREQ] mov [esp+36], eax ret @@ -2123,8 +2077,8 @@ sysfn_getcpuclock: ; 18.5 = GET TSC/SEC ;!!!!!!!!!!!!!!!!!!!!!!!! sysfn_getactive: ; 18.7 = get active window - mov eax, [0x3004] - movzx eax, word [0xC400 + eax*2] + mov eax, [TASK_COUNT] + movzx eax, word [WIN_POS + eax*2] mov [esp+36],eax ret @@ -2164,10 +2118,10 @@ sysfn_getdiskinfo: ; 18.11 = get disk info table rep movsb ret for_all_tables: - mov edi,[0x3010] + mov edi,[TASK_BASE] mov edi,[edi+TASKDATA.mem_start] add edi,ecx - mov esi,0x40000 + mov esi,DRIVE_DATA ret full_table: cmp ebx,2 @@ -2183,7 +2137,7 @@ sysfn_lastkey: ; 18.12 = return 0 (backward compatibility) ret sysfn_getversion: ; 18.13 = get kernel ID and version - mov edi,[0x3010] + mov edi,[TASK_BASE] mov edi,[edi+TASKDATA.mem_start] add edi,ebx mov esi,version_inf @@ -2211,7 +2165,7 @@ sysfn_centermouse: ; 18.15 = mouse centered sysfn_mouse_acceleration: ; 18.19 = set/get mouse features cmp ebx,0 ; get mouse speed factor jnz .set_mouse_acceleration - xor eax,eax + xor eax,eax mov ax,[mouse_speed_factor] mov [esp+36],eax ret @@ -2234,24 +2188,22 @@ sysfn_mouse_acceleration: ; 18.19 = set/get mouse features .set_pointer_position: cmp ebx,4 ; set mouse pointer position jnz .end - mov [0xFB0C],cx ;y + mov [MOUSE_Y],cx ;y ror ecx,16 - mov [0xFB0A],cx ;x + mov [MOUSE_X],cx ;x rol ecx,16 .end: ret sysfn_getfreemem: - mov eax,[MEM_FreeSpace] - shl eax,2 - mov [esp+36],eax + mov eax, [pg_data.pages_free] + shl eax, 2 + mov [esp+36],eax ret sysfn_getallmem: - mov eax,[0xFE8C] - shr eax,10 -; mov eax,[MEM_AllSpace] -; shl eax,2 + mov eax,[MEM_AMOUNT] + shr eax, 10 mov [esp+36],eax ret @@ -2265,7 +2217,7 @@ endg iglobal version_inf: - db 0,5,8,1 ; version 0.5.8.1 + db 0,6,5,0 ; version 0.6.5.0 db UID_KOLIBRI db 'Kolibri',0 version_end: @@ -2350,7 +2302,7 @@ sys_background: and edx,0xFF000000 ;255*256*256*256 and ecx,0x00FFFFFF ;255*256*256+255*256+255 add edx,ecx - mov [ebx+0x300000],edx + mov [ebx+IMG_BACKGROUND],edx ; mov [bgrchanged],1 ret nosb2: @@ -2362,7 +2314,7 @@ draw_background_temp: ; je nosb31 ;draw_background_temp: ; mov [bgrchanged],1 ;0 - mov [0xfff0],byte 1 + mov [REDRAW_BACKGROUND],byte 1 mov [background_defined], 1 nosb31: ret @@ -2381,7 +2333,7 @@ draw_background_temp: cmp eax,5 ; BLOCK MOVE TO BGR jnz nosb5 ; bughere - mov edi, [0x3010] + mov edi, [TASK_BASE] add ebx, [edi+TASKDATA.mem_start] ; mov esi, ebx ; mov edi, ecx @@ -2391,7 +2343,7 @@ draw_background_temp: cmp ecx, 0x160000-16 ja .fin ; add edi, 0x300000 - add ebx, 0x300000 + add ebx, IMG_BACKGROUND mov ecx, edx cmp ecx, 0x160000-16 ja .fin @@ -2424,7 +2376,7 @@ sys_getbackground: mov edx,0x160000-16 cmp edx,ebx jbe nogb2 - mov eax, [ebx+0x300000] + mov eax, [ebx+IMG_BACKGROUND] and eax, 0xFFFFFF mov [esp+36],eax ret @@ -2443,26 +2395,26 @@ 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] + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK + movzx ecx,word [WIN_STACK + ebx * 2] + mov edx,[TASK_COUNT] cmp ecx,edx jne .finish - cmp [0xf400],byte 0 + cmp [KEY_COUNT],byte 0 je .finish - movzx eax,byte [0xf401] + movzx eax,byte [KEY_BUFF] shl eax,8 push eax - dec byte [0xf400] - and byte [0xf400],127 - movzx ecx,byte [0xf400] + dec byte [KEY_COUNT] + and byte [KEY_COUNT],127 + movzx ecx,byte [KEY_COUNT] add ecx,2 ; mov esi,0xf402 ; mov edi,0xf401 ; cld ; rep movsb - mov eax, 0xF402 - mov ebx, 0xF401 + mov eax, KEY_BUFF+1 + mov ebx, KEY_BUFF call memmove pop eax .ret_eax: @@ -2491,18 +2443,18 @@ align 4 sys_getbutton: - mov ebx, [0x3000] ; TOP OF WINDOW STACK + mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK mov [esp+36],dword 1 - movzx ecx, word [0xC000 + ebx * 2] - mov edx, [0x3004] ; less than 256 processes + movzx ecx, word [WIN_STACK + ebx * 2] + mov edx, [TASK_COUNT] ; less than 256 processes cmp ecx,edx jne .exit - movzx eax,byte [0xf500] + movzx eax,byte [BTN_COUNT] test eax,eax jz .exit - mov eax,[0xf501] + mov eax,[BTN_BUFF] shl eax,8 - mov [0xf500],byte 0 + mov [BTN_COUNT],byte 0 mov [esp+36],eax .exit: ret @@ -2523,12 +2475,12 @@ sys_cpuusage: ; +30 dword PID , process idenfification number ; - mov edi,[0x3010] ; eax = return area + mov edi,[TASK_BASE] ; eax = return area add eax,[edi + TASKDATA.mem_start] cmp ebx,-1 ; who am I ? jne no_who_am_i - mov ebx,[0x3000] + mov ebx,[CURRENT_TASK] no_who_am_i: push eax ; return area @@ -2543,20 +2495,20 @@ sys_cpuusage: xor edx,edx mov eax,0x20 mul ebx - add eax,0x3000+TASKDATA.cpu_usage + add eax,CURRENT_TASK+TASKDATA.cpu_usage mov ebx,eax pop eax mov ecx,[ebx] mov [eax],ecx pop ebx - mov cx, [0xC000 + ebx * 2] + mov cx, [WIN_STACK + ebx * 2] mov [eax+4],cx - mov cx, [0xC400 + ebx * 2] + mov cx, [WIN_POS + ebx * 2] mov [eax+6],cx push eax mov eax,ebx shl eax,8 - add eax,0x80000+APPDATA.app_name + add eax,SLOT_BASE+APPDATA.app_name pop ebx add ebx,10 mov ecx,11 @@ -2570,7 +2522,7 @@ sys_cpuusage: cmp ecx,1 je os_mem shl ecx,8 - mov edx,[0x80000+ecx+APPDATA.mem_size] ;0x8c + mov edx,[SLOT_BASE+ecx+APPDATA.mem_size] ;0x8c mov eax,std_application_base_address ; eax run base -> edx used memory os_mem: @@ -2582,7 +2534,7 @@ sys_cpuusage: mov eax,[esp] shl eax,5 - add eax,0x3000+TASKDATA.pid + add eax,CURRENT_TASK+TASKDATA.pid mov eax,[eax] mov [ebx+20],eax @@ -2601,17 +2553,33 @@ sys_cpuusage: mov eax,[esp] shl eax,5 - add eax,0x3000+TASKDATA.state + add eax,CURRENT_TASK+TASKDATA.state mov eax,[eax] mov [ebx+40],ax + ; Window client area box + + mov esi,[esp] + shl esi,8 + add esi,SLOT_BASE+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 eax,[TASK_COUNT] mov [esp+36],eax ret @@ -2698,11 +2666,11 @@ sys_redrawstat: ; buttons away - mov ecx,[0x3000] + mov ecx,[CURRENT_TASK] sys_newba2: - mov edi,[0xfe88] + mov edi,[BTN_ADDR] cmp [edi],dword 0 ; empty button list ? je end_of_buttons_away @@ -2741,17 +2709,17 @@ sys_redrawstat: cmp eax,2 jnz srl1 - mov edx,[0x3010] ; return whole screen draw area for this app - add edx,draw_data-0x3000 + mov edx,[TASK_BASE] ; return whole screen draw area for this app + add edx,draw_data-CURRENT_TASK mov [edx+RECT.left], 0 mov [edx+RECT.top], 0 - mov eax,[0xfe00] + mov eax,[ScreenWidth] mov [edx+RECT.right],eax - mov eax,[0xfe04] + mov eax,[ScreenHeight] mov [edx+RECT.bottom],eax - mov edi,[0x3010] - mov [edi-twdw+WDATA.fl_wdrawn], 1 ; no new position & buttons from app + mov edi,[TASK_BASE] + or [edi-twdw+WDATA.fl_wdrawn], 1 ; no new position & buttons from app call sys_window_mouse @@ -2811,9 +2779,9 @@ sys_drawwindow: ; parameter for drawwindow_IV push 0 - mov edi, [0x3004] - movzx edi, word [0xC400 + edi*2] - cmp edi, [0x3000] + mov edi, [TASK_COUNT] + movzx edi, word [WIN_POS + edi*2] + cmp edi, [CURRENT_TASK] jne @f inc dword [esp] @@: @@ -2837,12 +2805,12 @@ draw_window_caption: call [disable_mouse] xor eax,eax - mov edx,[0x3004] - movzx edx,word[0xC400+edx*2] - cmp edx,[0x3000] + mov edx,[TASK_COUNT] + movzx edx,word[WIN_POS+edx*2] + cmp edx,[CURRENT_TASK] jne @f inc eax - @@: mov edx,[0x3000] + @@: mov edx,[CURRENT_TASK] shl edx,5 add edx,window_data movzx ebx,[edx+WDATA.fl_wstyle] @@ -2870,11 +2838,11 @@ draw_window_caption: ;-------------------------------------------------------------- .2: ;jmp @f - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,5 test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION jz @f - mov ecx,[edi*8+0x80000+APPDATA.wnd_caption] + mov ecx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] or ecx,ecx jz @f add ecx,[edi+twdw+TASKDATA.mem_start] @@ -2960,40 +2928,40 @@ set_window_clientbox: movzx eax,[ecx+WDATA.fl_wstyle] and eax,0x0F mov eax,[eax*8+window_topleft+0] - mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax shl eax,1 neg eax add eax,[ecx+WDATA.box.width] - mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax + mov [edi+SLOT_BASE+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 + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax neg eax sub eax,[esp] add eax,[ecx+WDATA.box.height] - mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax + mov [edi+SLOT_BASE+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 [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax mov eax,[ecx+WDATA.box.width] - mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax mov eax,[ecx+WDATA.box.height] - mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax + mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax pop edi ecx eax ret sys_set_window: - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,5 add edi,window_data @@ -3002,11 +2970,9 @@ sys_set_window: mov [edi+WDATA.cl_titlebar],edx mov [edi+WDATA.cl_frames],esi - call set_window_clientbox - ; check flag (?) - cmp [edi+WDATA.fl_wdrawn],1 - jz newd + test [edi+WDATA.fl_wdrawn],1 + jnz newd push eax mov eax,[timer_ticks] ;[0xfdf0] @@ -3021,9 +2987,9 @@ sys_set_window: mov word[edi+WDATA.box.left],ax mov word[edi+WDATA.box.top],bx - call check_window_position + call set_window_clientbox push ecx esi edi ; save for window fullscreen/resize ;mov esi,edi @@ -3032,7 +2998,7 @@ sys_set_window: sub edi,window_data shl edi,3 - add edi,0x80000 + add edi,SLOT_BASE and cl,0x0F mov [edi+APPDATA.wnd_caption],0 @@ -3042,9 +3008,10 @@ sys_set_window: @@: mov esi,[esp+0] add edi, APPDATA.saved_box - mov ecx,4 - cld - rep movsd + movsd + movsd + movsd + movsd pop edi esi ecx push eax ebx ecx edx @@ -3059,8 +3026,8 @@ sys_set_window: call [calc_clipping_rects] pop edx ecx ebx eax - mov [0xf400],byte 0 ; empty keyboard buffer - mov [0xf500],byte 0 ; empty button buffer + mov [KEY_COUNT],byte 0 ; empty keyboard buffer + mov [BTN_COUNT],byte 0 ; empty button buffer newd: mov [edi+WDATA.fl_redraw],byte 0 ; no redraw @@ -3077,18 +3044,20 @@ syscall_windowsettings: ; NOTE: only window owner thread can set its caption, ; so there's no parameter for PID/TID - mov edi,[0x3000] + mov edi,[CURRENT_TASK] 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 +; diamond, 31.10.2006: check removed because with new memory manager +; there can be valid data after APPDATA.mem_size bound +; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size] +; add ecx,255 ; max caption length +; cmp ebx,ecx +; ja .exit_fail - mov [edi*8+0x80000+APPDATA.wnd_caption],ebx + mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ebx or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION call draw_window_caption @@ -3110,7 +3079,7 @@ syscall_windowsettings: sys_window_move: - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,5 add edi,window_data @@ -3144,13 +3113,14 @@ sys_window_move: .no_y_resizing: call check_window_position + call set_window_clientbox 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 + add edi, SLOT_BASE + APPDATA.saved_box mov ecx,4 cld rep movsd @@ -3161,8 +3131,9 @@ sys_window_move: mov ebx, [edi + WDATA.box.top] mov ecx, [edi + WDATA.box.width] mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx + add ecx,eax + add edx,ebx + call [calculatescreen] popad @@ -3184,9 +3155,9 @@ sys_window_move: 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 [DONT_DRAW_MOUSE],byte 0 ; mouse pointer + mov [MOUSE_BACKGROUND],byte 0 ; no mouse under + mov [MOUSE_DOWN],byte 0 ; react to mouse up/down mov ecx,10 ; wait 1/10 second .wmrl3: @@ -3208,13 +3179,13 @@ sys_window_move: ; call change_task ; mov [draw_data+32+0],dword 0 ; mov [draw_data+32+4],dword 0 -; mov eax,[0xfe00] +; mov eax,[ScreenWidth ; 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 +; mov [MOUSE_BACKGROUND],byte 0 ;temp_nobackgr: ; ret @@ -3334,13 +3305,13 @@ ret checkpixel: push eax edx - mov edx,[0xfe00] ; screen x size + mov edx,[ScreenWidth] ; screen x size inc edx imul edx, ebx mov dl, [eax+edx+display_data] ; lea eax, [...] xor ecx, ecx - mov eax, [0x3000] + mov eax, [CURRENT_TASK] cmp al, dl setne cl @@ -3376,46 +3347,46 @@ checkmisc: jne mouse_not_active mov [mouse_active], 0 xor edi, edi - mov ecx, [0x3004] + mov ecx, [TASK_COUNT] set_mouse_event: add edi, 256 - or [edi+0x80000+APPDATA.event_mask], dword 00100000b + or [edi+SLOT_BASE+APPDATA.event_mask], dword 00100000b loop set_mouse_event mouse_not_active: - cmp [0xfff0],byte 0 ; background update ? + cmp [REDRAW_BACKGROUND],byte 0 ; background update ? jz nobackgr cmp [background_defined], 0 jz nobackgr - mov [0xfff0],byte 2 + mov [REDRAW_BACKGROUND],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 + mov [draw_data+32 + RECT.left],dword 0 + mov [draw_data+32 + RECT.top],dword 0 + mov eax,[ScreenWidth] + mov ebx,[ScreenHeight] + mov [draw_data+32 + RECT.right],eax + mov [draw_data+32 + RECT.bottom],ebx call [drawbackground] - mov [0xfff0],byte 0 - mov [0xfff4],byte 0 + mov [REDRAW_BACKGROUND],byte 0 + mov [MOUSE_BACKGROUND],byte 0 nobackgr: ; system shutdown request - cmp [0xFF00],byte 0 + cmp [SYS_SHUTDOWN],byte 0 je noshutdown mov edx,[shutdown_processes] sub dl,2 - cmp [0xff00],dl + cmp [SYS_SHUTDOWN],dl jne no_mark_system_shutdown mov edx,0x3040 - movzx ecx,byte [0xff00] + movzx ecx,byte [SYS_SHUTDOWN] add ecx,5 markz: mov [edx+TASKDATA.state],byte 3 @@ -3426,16 +3397,16 @@ checkmisc: call [disable_mouse] - dec byte [0xff00] + dec byte [SYS_SHUTDOWN] - cmp [0xff00],byte 0 + cmp [SYS_SHUTDOWN],byte 0 je system_shutdown noshutdown: - mov eax,[0x3004] ; termination - mov ebx,0x3020+TASKDATA.state + mov eax,[TASK_COUNT] ; termination + mov ebx,TASK_DATA+TASKDATA.state mov esi,1 newct: @@ -3490,8 +3461,8 @@ redrawscreen: mov ebx, [edi + WDATA.box.top] mov ecx, [edi + WDATA.box.width] mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx + add ecx,eax + add edx,ebx mov ecx,[dlye] ; ecx = area y end ebx = window y start cmp ecx,ebx @@ -3507,7 +3478,7 @@ redrawscreen: 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 jl ricino @@ -3552,7 +3523,7 @@ redrawscreen: pop ecx - cmp ecx,[0x3004] + cmp ecx,[TASK_COUNT] jle newdw2 pop eax @@ -3567,7 +3538,7 @@ calculatebackground: ; background mov [display_data-8],dword 4 ; size x mov [display_data-4],dword 2 ; size y - mov edi, 0x300000 ; set background to black + mov edi, IMG_BACKGROUND ; set background to black xor eax, eax mov ecx, 0x0fff00 / 4 cld @@ -3575,10 +3546,10 @@ calculatebackground: ; background mov edi,display_data ; set os to use all pixels mov eax,0x01010101 - mov ecx,0x1fff00 / 4 + mov ecx,0x15ff00 / 4 rep stosd - mov byte [0xFFF0], 0 ; do not draw background! + mov byte [REDRAW_BACKGROUND], 0 ; do not draw background! ret @@ -3622,7 +3593,7 @@ delay_ms: ; delay in 1/1000 sec set_app_param: push edi - mov edi,[0x3010] + mov edi,[TASK_BASE] mov [edi+TASKDATA.event_mask],eax pop edi @@ -3711,7 +3682,7 @@ memmove: ; memory move in bytes ;; 5 file not found ;; ebx = size of file ; -; mov edi,[0x3010] +; mov edi,[TASK_BASE] ; add edi,0x10 ; add esi,[edi] ; add eax,[edi] @@ -3739,12 +3710,12 @@ align 4 sys_programirq: - mov edi,[0x3010] + mov edi,[TASK_BASE] add eax,[edi+TASKDATA.mem_start] cmp ebx,16 jae .not_owner - mov edi,[0x3010] + mov edi,[TASK_BASE] mov edi,[edi+TASKDATA.pid] cmp edi,[irq_owner+ebx*4] je spril1 @@ -3773,7 +3744,7 @@ get_irq_data: shl edx,2 add edx,irq_owner mov edx,[edx] - mov edi,[0x3010] + mov edi,[TASK_BASE] mov edi,[edi+TASKDATA.pid] cmp edx,edi je gidril1 @@ -3785,7 +3756,7 @@ get_irq_data: mov ebx,eax shl ebx,12 - add ebx,0x2e0000 + add ebx,IRQ_SAVE mov eax,[ebx] mov ecx,1 test eax,eax @@ -3813,7 +3784,7 @@ set_io_access_rights: pushad - mov edi,[0x3000] + mov edi,[CURRENT_TASK] imul edi,tss_step add edi,tss_data+128 ; add edi,128 @@ -3845,10 +3816,6 @@ set_io_access_rights: ret - - - - r_f_port_area: test eax, eax @@ -3864,7 +3831,7 @@ r_f_port_area: ja rpal1 cmp ecx,65536 jae rpal1 - mov esi,[0x2d0000] + mov esi,[RESERVED_PORTS] test esi,esi ; no reserved areas ? je rpal2 cmp esi,255 ; max reserved @@ -3872,7 +3839,7 @@ r_f_port_area: rpal3: mov edi,esi shl edi,4 - add edi,0x2d0000 + add edi,RESERVED_PORTS cmp ebx,[edi+8] ja rpal4 cmp ecx,[edi+4] @@ -3920,12 +3887,12 @@ r_f_port_area: popad ; end enable io map sti - mov edi,[0x2d0000] + mov edi,[RESERVED_PORTS] add edi,1 - mov [0x2d0000],edi + mov [RESERVED_PORTS],edi shl edi,4 - add edi,0x2d0000 - mov esi,[0x3010] + add edi,RESERVED_PORTS + mov esi,[TASK_BASE] mov esi,[esi+TASKDATA.pid] mov [edi],esi mov [edi+4],ebx @@ -3934,22 +3901,19 @@ r_f_port_area: xor eax, eax ret - - - free_port_area: pushad - mov esi,[0x2d0000] ; no reserved areas ? + mov esi,[RESERVED_PORTS] ; no reserved areas ? test esi,esi je frpal2 - mov edx,[0x3010] + mov edx,[TASK_BASE] mov edx,[edx+TASKDATA.pid] frpal3: mov edi,esi shl edi,4 - add edi,0x2d0000 + add edi,RESERVED_PORTS cmp edx,[edi] jne frpal4 cmp ebx,[edi+4] @@ -3973,7 +3937,7 @@ free_port_area: cld rep movsb - dec dword [0x2d0000] + dec dword [RESERVED_PORTS] popad @@ -4018,7 +3982,7 @@ reserve_free_irq: lea edi,[irq_owner+ebx*4] mov edx,[edi] - mov eax,[0x3010] + mov eax,[TASK_BASE] cmp edx,[eax+TASKDATA.pid] jne fril1 dec ecx @@ -4033,7 +3997,7 @@ reserve_free_irq: cmp dword [edi], 0 jnz ril1 - mov edx,[0x3010] + mov edx,[TASK_BASE] mov edx,[edx+TASKDATA.pid] mov [edi],edx dec ecx @@ -4041,16 +4005,14 @@ reserve_free_irq: mov [esp+36],ecx ; return in eax ret - - __sys_drawbackground: inc [mouse_pause] - cmp [0xfe0c],word 0x12 + cmp [SCR_MODE],word 0x12 je dbrv20 dbrv12: - cmp [0xfe0c],word 0100000000000000b + cmp [SCR_MODE],word 0100000000000000b jge dbrv20 - cmp [0xfe0c],word 0x13 + cmp [SCR_MODE],word 0x13 je dbrv20 call vesa12_drawbackground dec [mouse_pause] @@ -4089,20 +4051,25 @@ __sys_putimage: .exit: ret @@: - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,8 - add dx,word[edi+0x80000+APPDATA.wnd_clientbox.top] + add dx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] rol edx,16 - add dx,word[edi+0x80000+APPDATA.wnd_clientbox.left] + add dx,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] rol edx,16 .forced: + push ebp esi 0 + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp +sys_putimage_bpp: +; call [disable_mouse] ; this will be done in xxx_putimage ; mov eax, vga_putimage - cmp [0xfe0c], word 0x12 + cmp [SCR_MODE], word 0x12 jz @f ;.doit mov eax, vesa12_putimage - cmp [0xfe0c], word 0100000000000000b + cmp [SCR_MODE], word 0100000000000000b jae @f - cmp [0xfe0c], word 0x13 + cmp [SCR_MODE], word 0x13 jnz .doit @@: mov eax, vesa20_putimage @@ -4110,29 +4077,98 @@ __sys_putimage: inc [mouse_pause] call eax dec [mouse_pause] + pop ebp esi ebp jmp [draw_pointer] +syscall_putimage_palette: + lea edi, [esi+std_application_base_address] + mov esi, edx + mov edx, ecx + mov ecx, ebx + lea ebx, [eax+std_application_base_address] +sys_putimage_palette: +; ebx = pointer to image +; ecx = [xsize]*65536 + [ysize] +; edx = [xstart]*65536 + [ystart] +; esi = number of bits per pixel, must be 8, 24 or 32 +; edi = pointer to palette +; ebp = row delta + mov eax, [CURRENT_TASK] + shl eax, 8 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] + rol edx, 16 + add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] + rol edx, 16 +.forced: + push ebp esi ebp + cmp esi, 8 + jnz @f + mov ebp, putimage_get8bpp + mov esi, putimage_init8bpp + jmp sys_putimage_bpp +@@: + cmp esi, 24 + jnz @f + mov ebp, putimage_get24bpp + mov esi, putimage_init24bpp + jmp sys_putimage_bpp +@@: + cmp esi, 32 + jnz @f + mov ebp, putimage_get32bpp + mov esi, putimage_init32bpp + jmp sys_putimage_bpp +@@: + pop ebp esi + ret + +putimage_init24bpp: + lea eax, [eax*3] +putimage_init8bpp: + ret + +putimage_get24bpp: + mov eax, [esi] + add esi, 3 + ret 4 +putimage_get8bpp: + movzx eax, byte [esi] + push edx + mov edx, [esp+8] + mov eax, [edx+eax*4] + pop edx + inc esi + ret 4 + +putimage_init32bpp: + shl eax, 2 + ret +putimage_get32bpp: + lodsd + ret 4 + ; eax x beginning ; ebx y beginning ; ecx x end -; edx y end + ; edx y end ; edi color __sys_drawbar: - mov esi,[0x3000] + mov esi,[CURRENT_TASK] 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] + add eax,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ecx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] + add edx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] .forced: inc [mouse_pause] - cmp [0xfe0c],word 0x12 +; call [disable_mouse] + cmp [SCR_MODE],word 0x12 je dbv20 sdbv20: - cmp [0xfe0c],word 0100000000000000b + cmp [SCR_MODE],word 0100000000000000b jge dbv20 - cmp [0xfe0c],word 0x13 + cmp [SCR_MODE],word 0x13 je dbv20 call vesa12_drawbar dec [mouse_pause] @@ -4150,7 +4186,7 @@ kb_read: push ecx edx - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kr_loop: in al,0x64 test al,1 @@ -4178,15 +4214,15 @@ 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: +; 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: @@ -4257,7 +4293,7 @@ kb_cmd: setmouse: ; set mousepicture -pointer ; ps2 mouse enable - mov [0xf200],dword mousepointer+62+32*31*4 + mov [MOUSE_PICTURE],dword mousepointer+62+32*31*4 cli ; mov bl,0xa8 ; enable mouse cmd @@ -4351,10 +4387,8 @@ setmouse: ; set mousepicture -pointer _rdtsc: - - mov edx,[cpuid_1+3*4] - test edx,00010000b - jz ret_rdtsc + bt [cpu_caps], CAPS_TSC + jnc ret_rdtsc rdtsc ret ret_rdtsc: @@ -4362,8 +4396,6 @@ _rdtsc: mov eax,0xffffffff ret - - rerouteirqs: cli @@ -4438,7 +4470,7 @@ sys_msg_board_str: ret uglobal - msg_board_data: times 512 db 0 + msg_board_data: times 4096 db 0 msg_board_count dd 0x0 endg @@ -4454,7 +4486,7 @@ sys_msg_board: mov [msg_board_data+ecx],bl inc ecx - and ecx, 511 + and ecx, 4095 mov [msg_board_count], ecx mov [check_idle_semaphore], 5 ret @@ -4491,36 +4523,14 @@ sys_msg_board: -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] + mov edi, [CURRENT_TASK] dec eax ; 1 = set keyboard mode jne no_set_keyboard_setup shl edi,8 - mov [edi+0x80000 + APPDATA.keyboard_mode],bl + mov [edi+SLOT_BASE + APPDATA.keyboard_mode],bl ret @@ -4530,7 +4540,7 @@ sys_process_def: jne no_get_keyboard_setup shl edi,8 - movzx eax, byte [0x80000+edi + APPDATA.keyboard_mode] + movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode] mov [esp+36],eax @@ -4629,137 +4639,15 @@ 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] + mov eax,[ScreenWidth] shl eax,16 - mov ax,[0xfe04] + mov ax,[ScreenHeight] add eax,0x00010001 mov [esp+36],eax ret @@ -4767,14 +4655,14 @@ sys_gs: ; direct screen access cmp eax,2 ; bits per pixel jne no_gs2 - movzx eax,byte [0xfbf1] + movzx eax,byte [ScreenBPP] mov [esp+36],eax ret no_gs2: cmp eax,3 ; bytes per scanline jne no_gs3 - mov eax,[0xfe08] + mov eax,[BytesPerScanLine] mov [esp+36],eax ret no_gs3: @@ -4797,13 +4685,13 @@ align 4 ; system functions syscall_setpixel: ; SetPixel - mov edx,[0x3010] + mov edx,[TASK_BASE] add eax,[edx-twdw+WDATA.box.left] add ebx,[edx-twdw+WDATA.box.top] - mov edi,[0x3000] + mov edi,[CURRENT_TASK] shl edi,8 - add eax,[edi+0x80000+APPDATA.wnd_clientbox.left] - add ebx,[edi+0x80000+APPDATA.wnd_clientbox.top] + add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] xor edi,edi ; no force ; mov edi,1 call [disable_mouse] @@ -4813,15 +4701,15 @@ align 4 syscall_writetext: ; WriteText - mov edi,[0x3010] + mov edi,[TASK_BASE] mov ebp,[edi-twdw+WDATA.box.left] push esi - mov esi,[0x3000] + mov esi,[CURRENT_TASK] shl esi,8 - add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left] + add ebp,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] shl ebp,16 add ebp,[edi-twdw+WDATA.box.top] - add bp,word[esi+0x80000+APPDATA.wnd_clientbox.top] + add bp,word[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] pop esi add ecx,[edi+TASKDATA.mem_start] add eax,ebp @@ -4833,8 +4721,8 @@ align 4 syscall_openramdiskfile: ; OpenRamdiskFile - mov edi,[0x3010] - add edi, TASKDATA.mem_start + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start add eax,[edi] add edx,[edi] mov esi,12 @@ -4856,10 +4744,10 @@ syscall_drawrect: ; DrawRect sar eax,16 movzx edx,bx sar ebx,16 - mov esi,[0x3000] + mov esi,[CURRENT_TASK] shl esi,8 - add eax,[esi+0x80000+APPDATA.wnd_clientbox.left] - add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top] + add eax,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] + add ebx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] add ecx,eax add edx,ebx jmp [drawbar] @@ -4870,71 +4758,26 @@ align 4 syscall_getscreensize: ; GetScreenSize - movzx eax,word[0xfe00] + movzx eax,word[ScreenWidth] shl eax,16 - mov ax,[0xfe04] + mov ax,[ScreenHeight] mov [esp+36],eax ret align 4 -syscall_startapp: ; StartApp - mov edi,[0x3010] - add edi, TASKDATA.mem_start - add eax,[edi] - test ebx,ebx - jz noapppar - add ebx,[edi] - noapppar: -; call start_application_fl - xor edx,edx ; compatibility - flags=0 - call new_start_application_fl - mov [esp+36],eax - ret - - -align 4 - syscall_cdaudio: ; CD call sys_cd_audio mov [esp+36],eax ret -; ReadHd and StartHdApp functions are obsolete. Use 58 or 70 functions instead. -;align 4 -; -;syscall_readhd: ; ReadHd -; -; mov edi,[0x3010] -; add edi,0x10 -; add esi,[edi] -; add eax,[edi] -; call read_hd_file -; mov [esp+36],eax -; mov [esp+24],ebx -; ret - -;align 4 -; -;syscall_starthdapp: ; StartHdApp -; -; mov edi,[0x3010] -; add edi,0x10 -; add eax,[edi] -; add ecx,[edi] -; xor ebp,ebp -; xor edx,edx ; compatibility - flags=0 -; call start_application_hd -; mov [esp+36],eax -; ret - align 4 syscall_delramdiskfile: ; DelRamdiskFile - mov edi,[0x3010] - add edi, TASKDATA.mem_start + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start add eax,[edi] call filedelete mov [esp+36],eax @@ -4944,8 +4787,8 @@ align 4 syscall_writeramdiskfile: ; WriteRamdiskFile - mov edi,[0x3010] - add edi, TASKDATA.mem_start + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start add eax,[edi] add ebx,[edi] call filesave @@ -4955,7 +4798,7 @@ syscall_writeramdiskfile: ; WriteRamdiskFile align 4 syscall_getpixel: ; GetPixel - mov ecx,[0xfe00] + mov ecx,[ScreenWidth] inc ecx xor edx,edx div ecx @@ -4969,8 +4812,8 @@ align 4 syscall_readstring: ; ReadString - mov edi,[0x3010] - add edi, TASKDATA.mem_start + mov edi,[TASK_BASE] + add edi,TASKDATA.mem_start add eax,[edi] call read_string mov [esp+36],eax @@ -4980,17 +4823,17 @@ align 4 syscall_drawline: ; DrawLine - mov edi,[0x3010] + mov edi,[TASK_BASE] mov edx, [edi-twdw+WDATA.box.left] - mov esi,[0x3000] + mov esi,[CURRENT_TASK] shl esi,8 - add edx, [esi+0x80000+APPDATA.wnd_clientbox.left] + add edx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.left] add ax,dx rol eax,16 add ax,dx rol eax,16 mov edx, [edi-twdw+WDATA.box.top] - add edx, [esi+0x80000+APPDATA.wnd_clientbox.top] + add edx,[esi+SLOT_BASE+APPDATA.wnd_clientbox.top] add bx,dx rol ebx,16 add bx,dx @@ -5065,7 +4908,7 @@ align 4 read_from_hd: ; Read from hd - fn not in use - mov edi,[0x3010] + mov edi,[TASK_BASE] add edi,TASKDATA.mem_start add eax,[edi] add ecx,[edi] @@ -5077,31 +4920,9 @@ read_from_hd: ; Read from hd - fn not in use 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 -; +paleholder: + ret ; --------------- APM --------------------- apm_entry dp 0 @@ -5113,10 +4934,10 @@ sys_apm: 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 @@ -5151,7 +4972,7 @@ undefined_syscall: ; Undefined system call ; push edi -; mov edi,[0x3000] ; restore processes tss pointer in gdt, busyfl? +; mov edi,[CURRENT_TASK] ; restore processes tss pointer in gdt, busyfl? ; imul edi,8 ; mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b @@ -5160,8 +4981,6 @@ undefined_syscall: ; Undefined system call ; ret - - keymap: db '6',27 @@ -5281,10 +5100,14 @@ wraw_bacground_select db 0 pci_access_enabled dd 0x0 ; 0 = disabled , 1 = enabled sb16 dd 0x0 - wss dd 0x0 buttontype dd 0x0 windowtypechanged dd 0x0 + +align 4 + cpu_caps dd 4 dup(0) + pg_data PG_DATA + heap_test dd ? endg iglobal @@ -5293,6 +5116,10 @@ iglobal syslang dd 0x1 endg +if __DEBUG__ eq 1 + include_debug_strings +end if + IncludeIGlobals endofcode: IncludeUGlobals diff --git a/kernel/branches/gfx_kernel/kernel16.inc b/kernel/branches/gfx_kernel/kernel16.inc index d6a2c77fa..e69bd79df 100644 --- a/kernel/branches/gfx_kernel/kernel16.inc +++ b/kernel/branches/gfx_kernel/kernel16.inc @@ -18,11 +18,19 @@ ;!!! if lang eq en include "boot/booteng.inc" ; english system boot messages -else +else if lang eq ru include "boot/bootru.inc" ; russian system boot messages +else if lang eq et +include "boot/bootet.inc" ; estonian system boot messages +else +include "boot/bootge.inc" ; german system boot messages ;!!! end if +if lang eq et +include "boot/et.inc" ; Estonian font +else include "boot/ru.inc" ; Russian font +end if org $-0x10000 include "boot/bootcode.inc" ; 16 bit system boot code diff --git a/kernel/branches/gfx_kernel/kernel32.inc b/kernel/branches/gfx_kernel/kernel32.inc index 1a1bef638..6759bd15b 100644 --- a/kernel/branches/gfx_kernel/kernel32.inc +++ b/kernel/branches/gfx_kernel/kernel32.inc @@ -50,6 +50,31 @@ macro diff16 title,l1,l2 display 13,10 } +; \begin{diamond}[29.09.2006] +; may be useful for kernel debugging +; example 1: +; dbgstr 'Hello, World!' +; example 2: +; dbgstr 'Hello, World!', save_flags +macro dbgstr string*, f +{ +local a +iglobal_nested +a db 'K : ',string,13,10,0 +endg_nested +if ~ f eq + pushfd +end if + push esi + mov esi, a + call sys_msg_board_str + pop esi +if ~ f eq + popfd +end if +} +; \end{diamond}[29.09.2006] + ;struc db [a] { common . db a ; if ~used . ; display 'not used db: ',`.,13,10 @@ -96,7 +121,7 @@ virtual at 0 end virtual ; constants definition -WSTATE_NORMAL = 00000000b +WSTATE_NORMAL = 00000000b WSTATE_MAXIMIZED = 00000001b WSTATE_MINIMIZED = 00000010b WSTATE_ROLLEDUP = 00000100b @@ -146,13 +171,26 @@ 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 ? + + .fpu_state dd ? ;+16 + .ev_count dd ? ;+20 + .fpu_handler dd ? ;+24 + .sse_handler dd ? ;+28 + .pl0_stack dd ? ;unused ;+32 + .heap_base dd ? ;+36 + .heap_top dd ? ;+40 + .cursor dd ? ;+44 + .fd_ev dd ? ;+48 + .bk_ev dd ? ;+52 + .fd_obj dd ? ;+56 + .bk_obj dd ? ;+60 + + db 64 dup(?) ;+64 + + .wnd_shape dd ? ;+128 + .wnd_shape_scale dd ? ;+132 + dd ? ;+136 + .mem_size dd ? ;+140 .saved_box BOX .ipc_start dd ? .ipc_size dd ? @@ -184,9 +222,13 @@ 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 +include "core/fpu.inc" ; all fpu/sse support +include "core/memory.inc" +include "core/heap.inc" ; kernel and app heap +include "core/malloc.inc" ; small kernel heap +include "core/taskman.inc" +include "core/dll.inc" +include "core/exports.inc" ; GUI stuff include "gui/window.inc" @@ -202,6 +244,7 @@ include "boot/shutdown.inc" ; shutdown or restart include "fs/fs.inc" ; syscall include "fs/fat32.inc" ; read / write for fat32 filesystem +include "fs/ntfs.inc" ; read / write for ntfs 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 @@ -217,6 +260,7 @@ include "sound/playnote.inc" ; player Note for Speaker PC include "video/vesa12.inc" ; Vesa 1.2 functions include "video/vesa20.inc" ; Vesa 2.0 functions include "video/vga.inc" ; VGA 16 color functions +include "video/cursors.inc" ; cursors functions ; Network Interface & TCPIP Stack @@ -239,6 +283,9 @@ include "bus/pci/pci32.inc" include "blkdev/fdc.inc" include "blkdev/flp_drv.inc" +; HD drive controller +include "blkdev/hd_drv.inc" + ; CD drive controller include "blkdev/cdrom.inc" diff --git a/kernel/branches/gfx_kernel/kglobals.inc b/kernel/branches/gfx_kernel/kglobals.inc index 75688d765..68276a10c 100644 --- a/kernel/branches/gfx_kernel/kglobals.inc +++ b/kernel/branches/gfx_kernel/kglobals.inc @@ -5,6 +5,10 @@ macro iglobal { IGlobals equ IGlobals, macro __IGlobalBlock { } +macro iglobal_nested { + IGlobals equ IGlobals, + macro __IGlobalBlock \{ } + ;------------------------------------------------------------- ; use 'uglobal' for inserting uninitialized global definitions. ; even when you define some data values, these variables @@ -14,7 +18,12 @@ macro uglobal { UGlobals equ UGlobals, macro __UGlobalBlock { } +macro uglobal_nested { + UGlobals equ UGlobals, + macro __UGlobalBlock \{ } + endg fix } ; Use endg for ending iglobal and uglobal blocks. +endg_nested fix \} macro IncludeIGlobals{ macro IGlobals dummy,[n] \{ __IGlobalBlock diff --git a/kernel/branches/gfx_kernel/lang.inc b/kernel/branches/gfx_kernel/lang.inc deleted file mode 100644 index 7a62d6c0b..000000000 --- a/kernel/branches/gfx_kernel/lang.inc +++ /dev/null @@ -1 +0,0 @@ -lang fix en diff --git a/kernel/branches/gfx_kernel/memmap.inc b/kernel/branches/gfx_kernel/memmap.inc index 374de645f..9b2bbe6dc 100644 --- a/kernel/branches/gfx_kernel/memmap.inc +++ b/kernel/branches/gfx_kernel/memmap.inc @@ -14,11 +14,10 @@ ; 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:901F byte DMA write : 1=yes, 2=no ; 0:9020 8bytes pci data ; 0:9030 byte VRR start enabled 1, 2-no ; 0:9031 word IDEContrRegsBaseAddr -; 0:9034 byte vesa major version number (ascii) -; 0:9035 byte card vendor (intel=1, s3=2, other=3) ; 0x9040 - dword - entry point of APM BIOS ; 0x9044 - word - version (BCD) ; 0x9046 - word - flags @@ -56,8 +55,7 @@ ; 3c dword cpu usage in cpu timer tics ; ; -; 5000 -> 5FFF save_syscall_data - syscall trace -; 6000 -> 68FF free +; 5000 -> 68FF free ; 6900 -> 6EFF saved picture under mouse pointer ; ; 6F00 -> 6FFF free @@ -81,8 +79,6 @@ ; E020 dword putpixel address ; E024 dword getpixel address ; E030 dword Vesa 1.2 pm bank switch address -; E034 byte vesa major version number (ascii) -; E035 byte card vendor (intel=1, s3=2, other=3) ; F200 dword mousepicture -pointer ; F204 dword mouse appearance counter ; F300 dword x & y temp for windowmove @@ -110,7 +106,6 @@ ; 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 @@ -130,9 +125,10 @@ ; 3F600 -> 3FFFF basic text font I ; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79) -; 50000 -> 5FFFF free (64 Kb) +; 50000 -> 50FFF main page directory +; 50200 -> 5FFFF pages bitmap -; 60000 -> 7FFFF reserved to physical memory manager +; 60000 -> 7FFFF free (128 Kb) ; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries ; ; 00 11db name of app running @@ -203,35 +199,26 @@ ; 760000 -> 76ffff !vrr driver ; 770000 -> 777fff tcp memory ( 32 kb) ; -; 778000 -> 77ffff window skinning ( 32 kb) -; 780000 -> 7fffff reserved to physical memory manager +; 780000 -> 987FFF TSS and IO map for (8192*8)=65536 ports +; (128+8192)*256 = 2129920 = 0x208000 ; -; 800000 -> BFFFFF mapped to LFB -; -; -; C00000 -> C01FFF draw_data - 256 entries +; 988000 -> 98AFFF 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 +; 0x0098B000 -> kernel heap ; - - +; 0x01FFFFFF heap min limit +; 0x7DBFFFFF heap max limit +; 0x7DC00000 -> 0x7FBFFFFF LFB 32Mb +; 0x7DC00000 -> 0x7E3FFFFF application available LFB 8Mb +; 0x7E400000 -> 0x7FBFFFFF kernel LFB part 24 Mb +; 0x7FC00000 -> 0x7FFFFFFF page tables 4Mb +; 0x80000000 -> 0xFFFFFFFF application 2Gb diff --git a/kernel/branches/gfx_kernel/network/eth_drv/arp.inc b/kernel/branches/gfx_kernel/network/eth_drv/arp.inc new file mode 100644 index 000000000..94ac376b6 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/eth_drv/arp.inc @@ -0,0 +1,546 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; ARP.INC +;; +;; Address Resolution Protocol +;; +;; Last revision: 10.11.2006 +;; +;; This file contains the following: +;; arp_table_manager - Manages an ARPTable +;; arp_request - Sends an ARP request on the ethernet +;; arp_handler - Called when an ARP packet is received +;; +;; Changes history: +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net +;; 11.11.2006 - [Johnny_B] and [smb] +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +ARP_NO_ENTRY equ 0 +ARP_VALID_MAPPING equ 1 +ARP_AWAITING_RESPONSE equ 2 +ARP_RESPONSE_TIMEOUT equ 3 + +struc ARP_ENTRY ;=14 bytes +{ .IP dd ? ;+00 + .MAC dp ? ;+04 + .Status dw ? ;+10 + .TTL dw ? ;+12 : ( in seconds ) +} + +virtual at 0 + ARP_ENTRY ARP_ENTRY +end virtual + +; 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 static 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 + + +; The follow is the ARP Table. +; This table must be manually updated and the kernel recompilied if +; changes are made to it. +; Empty entries are filled with zeros + +ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry +ARP_TABLE_SIZE equ 20 ; Size of table +ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table + +;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!! +;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!! +uglobal + ARPTable: +;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF + times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 +endg + +iglobal + NumARP: dd ARP_TABLE_ENTRIES + ARPTable_ptr dd ARPTable ;pointer to ARPTable +endg + +ARP_REQ_OPCODE equ 0x0100 ;request +ARP_REP_OPCODE equ 0x0200 ;reply + +struc ARP_PACKET +{ .HardwareType dw ? ;+00 + .ProtocolType dw ? ;+02 + .HardwareSize db ? ;+04 + .ProtocolSize db ? ;+05 + .Opcode dw ? ;+06 + .SenderMAC dp ? ;+08 + .SenderIP dd ? ;+14 + .TargetMAC dp ? ;+18 + .TargetIP dd ? ;+24 +} + +virtual at 0 + ARP_PACKET ARP_PACKET +end virtual + + + +;*************************************************************************** +; Function +; arp_table_manager [by Johnny_B] +; +; Description +; Does a most required operations with ARP-table +; IN: +; Operation: see Opcode's constants below +; Index: Index of entry in the ARP-table +; Extra: Extra parameter for some Opcodes +; OUT: +; EAX = Returned value depends on opcodes, more detailed see below +; +;*************************************************************************** +;Opcode's constants +ARP_TABLE_ADD equ 1 +ARP_TABLE_DEL equ 2 +ARP_TABLE_GET equ 3 +ARP_TABLE_GET_ENTRIES_NUMBER equ 4 +ARP_TABLE_IP_TO_MAC equ 5 +ARP_TABLE_TIMER equ 6 + +;Index's constants +EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET +EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY + +align 4 +proc arp_table_manager stdcall uses ebx esi edi ecx edx,\ + Opcode:DWORD,Index:DWORD,Extra:DWORD + + mov ebx, dword[ARPTable_ptr] ;ARPTable base + mov ecx, dword[NumARP] ;ARP-entries counter + + mov eax, dword[Opcode] + cmp eax, ARP_TABLE_TIMER + je .timer + cmp eax, ARP_TABLE_ADD + je .add + cmp eax, ARP_TABLE_DEL + je .del + cmp eax, ARP_TABLE_GET + je .get + cmp eax, ARP_TABLE_IP_TO_MAC + je .ip_to_mac + cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER + je .get_entries_number + jmp .exit ;if unknown opcode + + +;;BEGIN TIMER +;;Description: it must be callback every second. It is responsible for removing expired routes. +;;IN: Operation: ARP_TABLE_TIMER +;; Index: must be zero +;; Extra: must be zero +;;OUT: +;; EAX=not defined +;; +.timer: + test ecx, ecx + jz .exit ;if NumARP=0 nothing to do + sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number + jz .exit ;if NumARP=number of static entries then exit + + add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base + + .timer_loop: + movsx esi, word [ebx + ARP_ENTRY.TTL] + cmp esi, 0xFFFFFFFF + je .timer_loop_end ;if TTL==0xFFFF then it's static entry + + test esi, esi + jnz .timer_loop_end_with_dec ;if TTL!=0 + + ; Ok, TTL is 0 + ;if Status==AWAITING_RESPONSE and TTL==0 + ;then we have to change it to ARP_RESPONSE_TIMEOUT + cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE + jne @f + + mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT + mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec + jmp .timer_loop_end + + @@: + ;if TTL==0 and Status==VALID_MAPPING, we have to delete it + ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too + mov esi, dword[NumARP] + sub esi, ecx ;esi=index of entry, will be deleted + stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra + jmp .timer_loop_end + + + .timer_loop_end_with_dec: + dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL + .timer_loop_end: + add ebx, ARP_ENTRY_SIZE + loop .timer_loop + + jmp .exit +;;END TIMER + +;;BEGIN ADD +;;Description: it adds an entry in the table. If ARP-table already +;; contains same IP, it will be updated. +;;IN: Operation: ARP_TABLE_ADD +;; Index: specifies what contains Extra-parameter +;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR, +;; then Extra contains pointer to ARP_PACKET, +;; otherwise Extra contains pointer to ARP_ENTRY +;;OUT: +;; EAX=index of entry, that has been added +;; +.add: + + sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack + + mov esi, [Extra] ;pointer + mov edi, [Index] ;opcode + + cmp edi, EXTRA_IS_ARP_PACKET_PTR + je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry + ;else it contain ptr to arp-entry + + cld + ; esi already has been loaded + mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) + mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! + rep movsw ;copy + jmp .search + + .arp_packet_to_entry: + mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET + mov [esp + ARP_ENTRY.IP], edx + + cld + lea esi, [esi + ARP_PACKET.SenderMAC] + lea edi, [esp + ARP_ENTRY.MAC] + movsd + movsw + mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry + mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour + + .search: + mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search + mov ecx, dword[NumARP] ;ecx=ARP-entries counter + jecxz .add_to_end ;if ARP-entries number == 0 + imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes) + @@: + sub eax, ARP_ENTRY_SIZE + cmp dword[ebx + eax + ARP_ENTRY.IP], edx + loopnz @b + jz .replace ; found, replace existing entry, ptr to it is in eax + + .add_to_end: + ;else add to end + or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible + mov ecx, dword[NumARP] + cmp ecx, ARP_TABLE_SIZE + je .add_exit ;if arp-entries number is equal to arp-table maxsize + + imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable + inc dword [NumARP] ;increase ARP-entries counter + + .replace: + cld + mov esi, esp ;esp=base of ARP-entry, that will be added + lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) + mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! + rep movsw + + mov ecx, ARP_ENTRY_SIZE + xor edx, edx ;"div" takes operand from EDX:EAX + div ecx ;eax=index of entry, which has been added + +.add_exit: + add esp, ARP_ENTRY_SIZE ;free stack + jmp .exit +;;END ADD + +;;BEGIN DEL +;;Description: it deletes an entry in the table. +;;IN: Operation: ARP_TABLE_DEL +;; Index: index of entry, that should be deleted +;; Extra: must be zero +;;OUT: +;; EAX=not defined +;; +.del: + mov esi, [Index] + imul esi, ARP_ENTRY_SIZE + + mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE + sub ecx, esi + + lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted + lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry + + shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! + cld + rep movsw + + dec dword[NumARP] ;decrease arp-entries counter + jmp .exit +;;END DEL + +;;BEGIN GET +;;Description: it reads an entry of table into buffer. +;;IN: Operation: ARP_TABLE_GET +;; Index: index of entry, that should be read +;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) +;;OUT: +;; EAX=not defined +;; +.get: + mov esi, [Index] + imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY + mov edi, [Extra] ;edi=buffer for reading + mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!! + cld + rep movsw + jmp .exit +;;END GET + +;;BEGIN IP_TO_MAC +;;Description: it gets an IP from Index, scans each entry in the table and writes +;; MAC, that relates to specified IP, into buffer specified in Extra. +;; And if it cannot find an IP-address in the table, it does an ARP-request of that. +;;IN: Operation: ARP_TABLE_IP_TO_MAC +;; Index: IP that should be transformed into MAC +;; Extra: pointer to buffer where will be written the MAC-address. +;;OUT: +;; EAX=ARP table entry status code. +;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. +;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. +;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. +;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. +;; +;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet +;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this +;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. +;; +.ip_to_mac: + + xor eax, eax + mov edi, dword[Extra] + cld + stosd + stosw + + cmp dword[NumARP], 0 + je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. + ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY + + ; first, check destination IP to see if it is on 'this' network. + ; The test is: + ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) + ; destination is local + ; else + ; destination is remote, so pass to gateway + + mov eax, [Index] ;eax=required IP + mov esi, eax + and esi, [subnet_mask] + mov ecx, [stack_ip] + and ecx, [subnet_mask] + cmp esi, ecx + je @f ;if we and target IP are located in the same network + mov eax, [gateway_ip] + @@: + + mov ecx, dword[NumARP] + imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size + + @@: + sub esi, ARP_ENTRY_SIZE + cmp [ebx + esi], eax ; ebx=ARPTable base + loopnz @b ; Return back if non match + jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table + + ; Return the entry status in eax + movzx eax, word[ebx + esi + ARP_ENTRY.Status] + + ; esi holds index + cld + lea esi, [ebx + esi + ARP_ENTRY.MAC] + mov edi, [Extra] ;edi=ptr to buffer for write MAC + movsd + movsw + jmp .exit + + .ip_to_mac_send_request: + stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr + mov eax, ARP_NO_ENTRY + jmp .exit + +;;END IP_TO_MAC + +;;BEGIN GET_ENTRIES_NUMBER +;;Description: returns an ARP-entries number in the ARPTable +;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER +;; Index: must be zero +;; Extra: must be zero +;;OUT: +;; EAX=ARP-entries number in the ARPTable + .get_entries_number: + mov eax, dword[NumARP] + jmp .exit +;;END GET_ENTRIES_NUMBER + +.exit: + ret +endp + + +;*************************************************************************** +; 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 + + stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET + + inc dword[arp_rx_count] ;increase ARP-packets counter + + cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet? + jne .exit ; No - so exit + + mov eax, [stack_ip] + cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address? + jne .exit ; No - so quit now + + ; OK, it is a request for my MAC address. Build the frame and send it + ; We can reuse the packet. + + mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE + + cld + mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC + movsd + movsw + + mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP + movsd + + mov esi, node_addr + mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC + movsd + movsw + + mov esi, stack_ip + mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP + movsd + + ; Now, send it! + mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address + mov bx, ETHER_ARP ;type of protocol + mov ecx, 28 ;data size + mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data + call dword [drvr_transmit] ;transmit packet + + .exit: + ret + + +;*************************************************************************** +; Function +; arp_request [by Johnny_B] +; +; Description +; Sends an ARP request on the ethernet +; IN: +; TargetIP : requested IP address +; SenderIP_ptr : POINTER to sender's IP address(our system's address) +; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) +; OUT: +; EAX=0 (if all is ok), otherwise EAX is not defined +; +; EBX,ESI,EDI will be saved +; +;*************************************************************************** +proc arp_request stdcall uses ebx esi edi,\ + TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD + + inc dword[arp_tx_count] ; increase counter + + sub esp, 28 ; allocate memory for ARP_PACKET + + mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet + mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP + mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length + mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length + mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request + + cld + mov esi,[SenderMAC_ptr] + lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr + movsd + movsw + + mov esi,[SenderIP_ptr] + lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr + movsd + + xor eax, eax + lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed) + stosd + stosw + + mov esi, dword[TargetIP] + mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter) + + ; Now, send it! + mov edi, broadcast_add ; Pointer to 48 bit destination address + mov bx, ETHER_ARP ; Type of packet + mov ecx, 28 ; size of packet + lea esi, [esp + ARP_PACKET]; pointer to packet data + call dword [drvr_transmit] ; Call the drivers transmit function + + add esp, 28 ; free memory, allocated before for ARP_PACKET + + ; Add an entry in the ARP table, awaiting response + sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry + + mov esi, dword[TargetIP] + mov dword[esp + ARP_ENTRY.IP],esi + + lea edi, [esp + ARP_ENTRY.MAC] + xor eax, eax + stosd + stosw + + mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE + mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds + + stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp + add esp, ARP_ENTRY_SIZE ; free memory + +.exit: + ret +endp diff --git a/kernel/branches/gfx_kernel/network/eth_drv/3c59x.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/3c59x.inc similarity index 100% rename from kernel/branches/gfx_kernel/network/eth_drv/3c59x.inc rename to kernel/branches/gfx_kernel/network/eth_drv/drivers/3c59x.inc diff --git a/kernel/branches/gfx_kernel/network/eth_drv/i8255x.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/i8255x.inc similarity index 100% rename from kernel/branches/gfx_kernel/network/eth_drv/i8255x.inc rename to kernel/branches/gfx_kernel/network/eth_drv/drivers/i8255x.inc diff --git a/kernel/branches/gfx_kernel/network/eth_drv/pcnet32.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/pcnet32.inc similarity index 100% rename from kernel/branches/gfx_kernel/network/eth_drv/pcnet32.inc rename to kernel/branches/gfx_kernel/network/eth_drv/drivers/pcnet32.inc diff --git a/kernel/branches/gfx_kernel/network/eth_drv/rtl8029.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8029.inc similarity index 100% rename from kernel/branches/gfx_kernel/network/eth_drv/rtl8029.inc rename to kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8029.inc diff --git a/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8139.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8139.inc new file mode 100644 index 000000000..cb938da18 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8139.inc @@ -0,0 +1,612 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; 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 ;; +;; ;; +;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + 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 + test ax, 0x1fff ; or no size given + jz .send_packet + 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 +; 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 + +rtl8139_cable: + pusha + mov edx, [io_addr] + add edx, 0x58 + in al,dx + test al,1 SHL 2 + jnz .notconnected + popa + xor al,al + inc al + ret + .notconnected: + popa + xor al,al + ret diff --git a/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8169.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8169.inc new file mode 100644 index 000000000..999f870f0 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/eth_drv/drivers/rtl8169.inc @@ -0,0 +1,1204 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; RTL8169.INC ;; +;; ;; +;; Ethernet driver for Menuet OS ;; +;; ;; +;; Version 0.1 11 February 2007 ;; +;; ;; +;; Driver for chips of RealTek 8169 family ;; +;; References: ;; +;; r8169.c - linux driver (etherboot project) ;; +;; ethernet driver template by Mike Hibbett ;; +;; ;; +;; The copyright statement is ;; +;; ;; +;; GNU GENERAL PUBLIC LICENSE ;; +;; Version 2, June 1991 ;; +;; ;; +;; Copyright 2007 mike.dld, ;; +;; mike.dld@gmail.com ;; +;; ;; +;; 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 + + RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address + RTL8169_REG_MAR0 equ 0x8 ; Multicast filter + RTL8169_REG_TxDescStartAddr equ 0x20 + RTL8169_REG_TxHDescStartAddr equ 0x28 + RTL8169_REG_FLASH equ 0x30 + RTL8169_REG_ERSR equ 0x36 + RTL8169_REG_ChipCmd equ 0x37 + RTL8169_REG_TxPoll equ 0x38 + RTL8169_REG_IntrMask equ 0x3C + RTL8169_REG_IntrStatus equ 0x3E + RTL8169_REG_TxConfig equ 0x40 + RTL8169_REG_RxConfig equ 0x44 + RTL8169_REG_RxMissed equ 0x4C + RTL8169_REG_Cfg9346 equ 0x50 + RTL8169_REG_Config0 equ 0x51 + RTL8169_REG_Config1 equ 0x52 + RTL8169_REG_Config2 equ 0x53 + RTL8169_REG_Config3 equ 0x54 + RTL8169_REG_Config4 equ 0x55 + RTL8169_REG_Config5 equ 0x56 + RTL8169_REG_MultiIntr equ 0x5C + RTL8169_REG_PHYAR equ 0x60 + RTL8169_REG_TBICSR equ 0x64 + RTL8169_REG_TBI_ANAR equ 0x68 + RTL8169_REG_TBI_LPAR equ 0x6A + RTL8169_REG_PHYstatus equ 0x6C + RTL8169_REG_RxMaxSize equ 0xDA + RTL8169_REG_CPlusCmd equ 0xE0 + RTL8169_REG_RxDescStartAddr equ 0xE4 + RTL8169_REG_ETThReg equ 0xEC + RTL8169_REG_FuncEvent equ 0xF0 + RTL8169_REG_FuncEventMask equ 0xF4 + RTL8169_REG_FuncPresetState equ 0xF8 + RTL8169_REG_FuncForceEvent equ 0xFC + + ; InterruptStatusBits + RTL8169_ISB_SYSErr equ 0x8000 + RTL8169_ISB_PCSTimeout equ 0x4000 + RTL8169_ISB_SWInt equ 0x0100 + RTL8169_ISB_TxDescUnavail equ 0x80 + RTL8169_ISB_RxFIFOOver equ 0x40 + RTL8169_ISB_LinkChg equ 0x20 + RTL8169_ISB_RxOverflow equ 0x10 + RTL8169_ISB_TxErr equ 0x08 + RTL8169_ISB_TxOK equ 0x04 + RTL8169_ISB_RxErr equ 0x02 + RTL8169_ISB_RxOK equ 0x01 + + ; RxStatusDesc + RTL8169_SD_RxRES equ 0x00200000 + RTL8169_SD_RxCRC equ 0x00080000 + RTL8169_SD_RxRUNT equ 0x00100000 + RTL8169_SD_RxRWT equ 0x00400000 + + ; ChipCmdBits + RTL8169_CMD_Reset equ 0x10 + RTL8169_CMD_RxEnb equ 0x08 + RTL8169_CMD_TxEnb equ 0x04 + RTL8169_CMD_RxBufEmpty equ 0x01 + + ; Cfg9346Bits + RTL8169_CFG_9346_Lock equ 0x00 + RTL8169_CFG_9346_Unlock equ 0xC0 + + ; rx_mode_bits + RTL8169_RXM_AcceptErr equ 0x20 + RTL8169_RXM_AcceptRunt equ 0x10 + RTL8169_RXM_AcceptBroadcast equ 0x08 + RTL8169_RXM_AcceptMulticast equ 0x04 + RTL8169_RXM_AcceptMyPhys equ 0x02 + RTL8169_RXM_AcceptAllPhys equ 0x01 + + ; RxConfigBits + RTL8169_RXC_FIFOShift equ 13 + RTL8169_RXC_DMAShift equ 8 + + ; TxConfigBits + RTL8169_TXC_InterFrameGapShift equ 24 + RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits + + ; rtl8169_PHYstatus + RTL8169_PHYS_TBI_Enable equ 0x80 + RTL8169_PHYS_TxFlowCtrl equ 0x40 + RTL8169_PHYS_RxFlowCtrl equ 0x20 + RTL8169_PHYS_1000bpsF equ 0x10 + RTL8169_PHYS_100bps equ 0x08 + RTL8169_PHYS_10bps equ 0x04 + RTL8169_PHYS_LinkStatus equ 0x02 + RTL8169_PHYS_FullDup equ 0x01 + + ; GIGABIT_PHY_registers + RTL8169_PHY_CTRL_REG equ 0 + RTL8169_PHY_STAT_REG equ 1 + RTL8169_PHY_AUTO_NEGO_REG equ 4 + RTL8169_PHY_1000_CTRL_REG equ 9 + + ; GIGABIT_PHY_REG_BIT + RTL8169_PHY_Restart_Auto_Nego equ 0x0200 + RTL8169_PHY_Enable_Auto_Nego equ 0x1000 + + ; PHY_STAT_REG = 1; + RTL8169_PHY_Auto_Neco_Comp equ 0x0020 + + ; PHY_AUTO_NEGO_REG = 4; + RTL8169_PHY_Cap_10_Half equ 0x0020 + RTL8169_PHY_Cap_10_Full equ 0x0040 + RTL8169_PHY_Cap_100_Half equ 0x0080 + RTL8169_PHY_Cap_100_Full equ 0x0100 + + ; PHY_1000_CTRL_REG = 9; + RTL8169_PHY_Cap_1000_Full equ 0x0200 + RTL8169_PHY_Cap_1000_Half equ 0x0100 + + RTL8169_PHY_Cap_PAUSE equ 0x0400 + RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800 + + RTL8169_PHY_Cap_Null equ 0x0 + + ; _MediaType + RTL8169_MT_10_Half equ 0x01 + RTL8169_MT_10_Full equ 0x02 + RTL8169_MT_100_Half equ 0x04 + RTL8169_MT_100_Full equ 0x08 + RTL8169_MT_1000_Full equ 0x10 + + ; _TBICSRBit + RTL8169_TBI_LinkOK equ 0x02000000 + + ; _DescStatusBit + RTL8169_DSB_OWNbit equ 0x80000000 + RTL8169_DSB_EORbit equ 0x40000000 + RTL8169_DSB_FSbit equ 0x20000000 + RTL8169_DSB_LSbit equ 0x10000000 + +; MAC address length +MAC_ADDR_LEN equ 6 + +; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) +MAX_ETH_FRAME_SIZE equ 1536 + +TX_FIFO_THRESH equ 256 ; In bytes + +RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer +RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 +ETTh equ 0x3F ; 0x3F means NO threshold + +EarlyTxThld equ 0x3F ; 0x3F means NO early transmit +RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1 +InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one + +NUM_TX_DESC equ 1 ; Number of Tx descriptor registers +NUM_RX_DESC equ 4 ; Number of Rx descriptor registers +RX_BUF_SIZE equ 1536 ; Rx Buffer size + +HZ equ 1000 + +RTL_MIN_IO_SIZE equ 0x80 +TX_TIMEOUT equ (6*HZ) + +RTL8169_TIMER_EXPIRE_TIME equ 100 + +ETH_HDR_LEN equ 14 +DEFAULT_MTU equ 1500 +DEFAULT_RX_BUF_LEN equ 1536 + + +;#ifdef RTL8169_JUMBO_FRAME_SUPPORT +;#define MAX_JUMBO_FRAME_MTU ( 10000 ) +;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) +;#else +MAX_RX_SKBDATA_SIZE equ 1600 +;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT + +;#ifdef RTL8169_USE_IO +;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) +macro RTL_W8 reg,val8 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val8 eq al + mov al,val8 + end if + out dx,al +} +;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) +macro RTL_W16 reg,val16 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val16 eq ax + mov ax,val16 + end if + out dx,ax +} +;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) +macro RTL_W32 reg,val32 { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + if ~val32 eq eax + mov eax,val32 + end if + out dx,eax +} +;!!!#define RTL_R8(reg) inb (ioaddr + (reg)) +macro RTL_R8 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in al,dx +} +;!!!#define RTL_R16(reg) inw (ioaddr + (reg)) +macro RTL_R16 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in ax,dx +} +;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) +macro RTL_R32 reg { + if ~reg eq dx + mov dx,word[rtl8169_tpc.mmio_addr] + add dx,reg + end if + in eax,dx +} +;#else +; write/read MMIO register +;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) +;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) +;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) +;#define RTL_R8(reg) readb (ioaddr + (reg)) +;#define RTL_R16(reg) readw (ioaddr + (reg)) +;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) +;#endif + +MCFG_METHOD_01 equ 0x01 +MCFG_METHOD_02 equ 0x02 +MCFG_METHOD_03 equ 0x03 +MCFG_METHOD_04 equ 0x04 +MCFG_METHOD_05 equ 0x05 +MCFG_METHOD_11 equ 0x0b +MCFG_METHOD_12 equ 0x0c +MCFG_METHOD_13 equ 0x0d +MCFG_METHOD_14 equ 0x0e +MCFG_METHOD_15 equ 0x0f + +PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000 +PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001 +PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002 + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +struc rtl8169_TxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_TxDesc rtl8169_TxDesc + sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc +end virtual + +struc rtl8169_RxDesc { + .status dd ? + .vlan_tag dd ? + .buf_addr dd ? + .buf_Haddr dd ? +} +virtual at 0 + rtl8169_RxDesc rtl8169_RxDesc + sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc +end virtual + +virtual at eth_data_start + +; Define the TX Descriptor +align 256 +rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; TX Descriptor. All descriptors point to a +; part of this buffer +align 256 +rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE + +; Define the RX Descriptor +align 256 +rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc + +; Create a static buffer of size RX_BUF_SZ for each +; RX Descriptor All descriptors point to a +; part of this buffer +align 256 +rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE + +rtl8169_tpc: + .mmio_addr dd ? ; memory map physical address + .chipset dd ? + .pcfg dd ? + .mcfg dd ? + .cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt + .cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt + .TxDescArrays dd ? ; Index of Tx Descriptor buffer + .RxDescArrays dd ? ; Index of Rx Descriptor buffer + .TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer + .RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer + .RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array + .Tx_skbuff rd NUM_TX_DESC + +end virtual + +rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK +rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E + +iglobal + +;static struct { +; const char *name; +; u8 mcfg; /* depend on RTL8169 docs */ +; u32 RxConfigMask; /* should clear the bits supported by this chip */ +;} +rtl_chip_info dd \ + MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169 + MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s + MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb + MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc + MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E + MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139 + MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139 + MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139 + +mac_info dd \ + 0x38800000, MCFG_METHOD_15, \ + 0x38000000, MCFG_METHOD_12, \ + 0x34000000, MCFG_METHOD_13, \ + 0x30800000, MCFG_METHOD_14, \ + 0x30000000, MCFG_METHOD_11, \ + 0x18000000, MCFG_METHOD_05, \ + 0x10000000, MCFG_METHOD_04, \ + 0x04000000, MCFG_METHOD_03, \ + 0x00800000, MCFG_METHOD_02, \ + 0x00000000, MCFG_METHOD_01 ; catch-all + +endg + +PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space +PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space +PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering +PCI_LATENCY_TIMER equ 0x0d ; 8 bits +PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles +PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate +PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping +PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking +PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping +PCI_COMMAND_SERR equ 0x100 ; Enable SERR +PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes + +PCI_VENDOR_ID equ 0x00 ; 16 bits +PCI_DEVICE_ID equ 0x02 ; 16 bits +PCI_COMMAND equ 0x04 ; 16 bits + +PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits +PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits +PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits +PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits +PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits +PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits + +PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 +PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address +PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] +PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address + +PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) +PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) +PCI_BASE_ADDRESS_SPACE_IO equ 0x01 +PCI_ROM_ADDRESS equ 0x30 ; 32 bits + +proc CONFIG_CMD,where:byte + movzx eax,byte[pci_bus] + shl eax,8 + mov al,[pci_dev] + shl eax,8 + mov al,[where] + and al,not 3 + or eax,0x80000000 + ret +endp + +proc pci_read_config_byte,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + in al,dx + pop edx + ret +endp + +proc pci_read_config_word,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + in ax,dx + pop edx + ret +endp + +proc pci_read_config_dword,where:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + in eax,dx + pop edx + ret +endp + +proc pci_write_config_byte,where:dword,value:byte + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,3 + add edx,0xCFC + mov al,[value] + out dx,al + pop edx + ret +endp + +proc pci_write_config_word,where:dword,value:word + push edx + stdcall CONFIG_CMD,[where] + mov dx,0xCF8 + out dx,eax + mov edx,[where] + and edx,2 + add edx,0xCFC + mov ax,[value] + out dx,ax + pop edx + ret +endp + +proc pci_write_config_dword,where:dword,value:dword + push edx + stdcall CONFIG_CMD,[where] + mov edx,0xCF8 + out dx,eax + mov edx,0xCFC + mov eax,[value] + out dx,eax + pop edx + ret +endp + +; Set device to be a busmaster in case BIOS neglected to do so. +; Also adjust PCI latency timer to a reasonable value, 32. +proc adjust_pci_device + + DEBUGF 1,"K : adjust_pci_device\n" + + stdcall pci_read_config_word,PCI_COMMAND + mov bx,ax + or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO + cmp ax,bx + je @f + DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2 + stdcall pci_write_config_word,PCI_COMMAND,ebx + @@: + stdcall pci_read_config_byte,PCI_LATENCY_TIMER + cmp al,32 + jae @f + DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al + stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32 + @@: + ret +endp + +; Find the start of a pci resource +proc pci_bar_start,index:dword + stdcall pci_read_config_dword,[index] + test eax,PCI_BASE_ADDRESS_SPACE_IO + jz @f + and eax,PCI_BASE_ADDRESS_IO_MASK + jmp .exit + @@: push eax + and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK + cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64 + jne .not64 + mov eax,[index] + add eax,4 + stdcall pci_read_config_dword,eax + or eax,eax + jz .not64 + DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n" + add esp,4 + or eax,-1 + ret + .not64: + pop eax + and eax,PCI_BASE_ADDRESS_MEM_MASK + .exit: + ret +endp + +proc rtl8169_init_board + + DEBUGF 1,"K : rtl8169_init_board\n" + + call adjust_pci_device + + stdcall pci_bar_start,PCI_BASE_ADDRESS_0 + mov [rtl8169_tpc.mmio_addr],eax + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + test al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + ; identify config method + RTL_R32 RTL8169_REG_TxConfig + and eax,0x7c800000 + DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax + mov esi,mac_info-8 + @@: add esi,8 + mov ecx,eax + and ecx,[esi] + cmp ecx,[esi] + jne @b + mov eax,[esi+4] + mov [rtl8169_tpc.mcfg],eax + + mov [rtl8169_tpc.pcfg],PCFG_METHOD_3 + stdcall RTL8169_READ_GMII_REG,3 + and al,0x0f + or al,al + jnz @f + mov [rtl8169_tpc.pcfg],PCFG_METHOD_1 + jmp .pconf + @@: dec al + jnz .pconf + mov [rtl8169_tpc.pcfg],PCFG_METHOD_2 + .pconf: + + ; identify chip attached to board + mov ecx,10 + mov eax,[rtl8169_tpc.mcfg] + @@: dec ecx + js @f + cmp eax,[rtl_chip_info+ecx*8] + jne @b + mov [rtl8169_tpc.chipset],ecx + jmp .match + @@: + ; if unknown chip, assume array element #0, original RTL-8169 in this case + DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n" + RTL_R32 RTL8169_REG_TxConfig + DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax + + mov [rtl8169_tpc.chipset],0 + + xor eax,eax + inc eax + ret + + .match: + xor eax,eax + ret +endp + +proc rtl8169_hw_PHY_config + + DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg] + +; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg); + + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04 + jne .not_4 +; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 +; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e +; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb +; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + jmp .exit + .not_4: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + je @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne .not_2_or_3 + @@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 + stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1 + stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 + stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 + stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 + stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 + stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800 + stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 + stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 + stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000 + jmp .exit + .not_2_or_3: +; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg); + DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg] + .exit: + ret +endp + +;proc pci_write_config_byte +; ret +;endp + +proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword + + DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value] + + movzx eax,[RegAddr] + shl eax,16 + or eax,[value] + or eax,0x80000000 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed writing to the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jz .exit + stdcall udelay,100 + loop @b + .exit: + ret +endp + +proc RTL8169_READ_GMII_REG,RegAddr:byte + + DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2 + + push ecx + movzx eax,[RegAddr] + shl eax,16 +; or eax,0x0 + RTL_W32 RTL8169_REG_PHYAR,eax + stdcall udelay,1000 + + mov ecx,2000 + ; Check if the RTL8169 has completed retrieving data from the specified MII register + @@: RTL_R32 RTL8169_REG_PHYAR + test eax,0x80000000 + jnz .exit + stdcall udelay,100 + loop @b + + or eax,-1 + pop ecx + ret + .exit: + RTL_R32 RTL8169_REG_PHYAR + and eax,0xFFFF + pop ecx + ret +endp + +proc rtl8169_set_rx_mode + + DEBUGF 1,"K : rtl8169_set_rx_mode\n" + + ; IFF_ALLMULTI + ; Too many to filter perfectly -- accept all multicasts + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys) + RTL_W32 RTL8169_REG_RxConfig,eax + + ; Multicast hash filter + RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff + RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff + ret +endp + +proc rtl8169_init_ring + + DEBUGF 1,"K : rtl8169_init_ring\n" + + xor eax,eax + mov [rtl8169_tpc.cur_rx],eax + mov [rtl8169_tpc.cur_tx],eax + + mov edi,[rtl8169_tpc.TxDescArray] + mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4 + cld + rep stosd + mov edi,[rtl8169_tpc.RxDescArray] + mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4 + rep stosd + + mov edi,rtl8169_tpc.Tx_skbuff + mov eax,rtl8169_txb + mov ecx,NUM_TX_DESC + @@: stosd + inc eax ; add eax,RX_BUF_SIZE ??? + loop @b + +;!!! for (i = 0; i < NUM_RX_DESC; i++) { +;!!! if (i == (NUM_RX_DESC - 1)) +;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE; +;!!! else +;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE; +;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; +;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]); +;!!! } + mov esi,rtl8169_tpc.RxBufferRing + mov edi,[rtl8169_tpc.RxDescArray] + mov eax,rtl8169_rxb + mov ecx,NUM_RX_DESC + @@: mov [esi],eax + mov [edi+rtl8169_RxDesc.buf_addr],eax + mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE + add esi,4 + add edi,sizeof.rtl8169_RxDesc + add eax,RX_BUF_SIZE + loop @b + + or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit + + ret +endp + +proc rtl8169_hw_start + + DEBUGF 1,"K : rtl8169_hw_start\n" + + ; Soft reset the chip + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset + ; Check that the chip has finished the reset + mov ecx,1000 + @@: RTL_R8 RTL8169_REG_ChipCmd + and al,RTL8169_CMD_Reset + jz @f + stdcall udelay,10 + loop @b + @@: + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock + RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb + RTL_W8 RTL8169_REG_ETThReg,ETTh + ; For gigabit rtl8169 + RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize + ; Set Rx Config register + RTL_R32 RTL8169_REG_RxConfig + mov ecx,[rtl8169_tpc.chipset] + and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask + or eax,rtl8169_rx_config + RTL_W32 RTL8169_REG_RxConfig,eax + ; Set DMA burst size and Interframe Gap Time + RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift) + RTL_R16 RTL8169_REG_CPlusCmd + RTL_W16 RTL8169_REG_CPlusCmd,ax + + RTL_R16 RTL8169_REG_CPlusCmd + or ax,1 shl 3 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jne @f + or ax,1 shl 14 +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n" + jmp .set + @@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n" + .set: RTL_W16 RTL8169_REG_CPlusCmd,ax + +; RTL_W16 0xE2,0x1517 +; RTL_W16 0xE2,0x152a +; RTL_W16 0xE2,0x282a + RTL_W16 0xE2,0x0000 + + MOV [rtl8169_tpc.cur_rx],0 + RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray] + RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray] + RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock + stdcall udelay,10 + RTL_W32 RTL8169_REG_RxMissed,0 + call rtl8169_set_rx_mode + ; no early-rx interrupts + RTL_R16 RTL8169_REG_MultiIntr + and ax,0xF000 + RTL_W16 RTL8169_REG_MultiIntr,ax + RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask + ret +endp + +proc udelay,msec:dword + push esi + mov esi,[msec] + call delay_ms + pop esi + ret +endp + +;*************************************************************************** +; Function +; rtl8169_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 +; +;*************************************************************************** +proc rtl8169_probe + + DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + call rtl8169_init_board + + mov ecx,MAC_ADDR_LEN + mov edx,[rtl8169_tpc.mmio_addr] + add edx,RTL8169_REG_MAC0 + xor ebx,ebx + ; Get MAC address. FIXME: read EEPROM + @@: RTL_R8 dx + mov [node_addr+ebx],al + inc edx + inc ebx + loop @b + + DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2 + + ; Config PHY + stdcall rtl8169_hw_PHY_config +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 + jae @f +; DEBUGF 1,"K : Set PCI Latency=0x40\n" +; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40 + @@: + cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 + jne @f +; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" + RTL_W8 0x82,0x01 +; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n" + stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0 + @@: + ; if TBI is not enabled + RTL_R8 RTL8169_REG_PHYstatus + test al,RTL8169_PHYS_TBI_Enable + jz .tbi_dis + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG + ; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged + and eax,0x0C1F + or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax + ; enable 1000 Full Mode + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168 + ; Enable auto-negotiation and restart auto-nigotiation + stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego + stdcall udelay,100 + mov ecx,10000 + ; wait for auto-negotiation process + @@: dec ecx + jz @f + stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG + stdcall udelay,100 + test eax,RTL8169_PHY_Auto_Neco_Comp + jz @b + RTL_R8 RTL8169_REG_PHYstatus + jmp @f + .tbi_dis: + stdcall udelay,100 + @@: + call rtl8169_reset + ret +endp + +;*************************************************************************** +; Function +; rt8169_reset +; Description +; Place the chip (ie, the ethernet card) into a virgin state +; Destroyed registers +; eax, ebx, ecx, edx +; +;*************************************************************************** +proc rtl8169_reset + + DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 + + mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring + ; Tx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring + + mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring + ; Rx Desscriptor needs 256 bytes alignment + mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring + + call rtl8169_init_ring + call rtl8169_hw_start + ; Construct a perfect filter frame with the mac address as first match + ; and broadcast for all others + mov edi,rtl8169_txb + or al,-1 + mov ecx,192 + cld + rep stosb + + mov esi,node_addr + mov edi,rtl8169_txb + movsd + movsw + + mov eax,[pci_data] + mov [eth_status],eax + ret +endp + +;*************************************************************************** +; Function +; rtl8169_transmit +; Description +; Transmits a packet of data via the ethernet card +; d - edi - Pointer to 48 bit destination address +; t - bx - Type of packet +; s - ecx - size of packet +; p - esi - pointer to packet data +; Destroyed registers +; eax, edx, esi, edi +; +;*************************************************************************** +proc rtl8169_transmit + + DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi + + push ecx edx esi + mov eax,MAX_ETH_FRAME_SIZE + mul [rtl8169_tpc.cur_tx] + mov esi,edi + ; point to the current txb incase multiple tx_rings are used + mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4] + 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 + +;!!! s += ETH_HLEN; +;!!! s &= 0x0FFF; +;!!! while (s < ETH_ZLEN) +;!!! ptxb[s++] = '\0'; + mov edi,eax + pop ecx + push eax + add ecx,ETH_HLEN + and ecx,0x0FFF + xor al,al + add edi,ecx + @@: cmp ecx,ETH_ZLEN + jae @f + stosb + inc ecx + jmp @b + @@: pop eax + + mov ebx,eax + mov eax,sizeof.rtl8169_TxDesc + mul [rtl8169_tpc.cur_tx] + add eax,[rtl8169_tpc.TxDescArray] + xchg eax,ebx + mov [ebx + rtl8169_TxDesc.buf_addr],eax + + mov eax,ecx + cmp eax,ETH_ZLEN + jae @f + mov eax,ETH_ZLEN + @@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit + cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_TxDesc.status],eax + + RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit + + inc [rtl8169_tpc.cur_tx] + and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 + +;!!! to = currticks() + TX_TIMEOUT; +;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ + mov ecx,TX_TIMEOUT / 10 + @@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit + jnz @f + stdcall udelay,10 + loop @b + DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n" + @@: + + ret +endp + +;*************************************************************************** +; Function +; rtl8169_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 +; +;*************************************************************************** +proc rtl8169_poll + +; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8 + + mov word[eth_rx_data_len],0 + + mov eax,sizeof.rtl8169_RxDesc + mul [rtl8169_tpc.cur_rx] + add eax,[rtl8169_tpc.RxDescArray] + mov ebx,eax + +; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status] + + test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600 + jnz .exit + +; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx] + + ; h/w no longer present (hotplug?) or major error, bail + RTL_R16 RTL8169_REG_IntrStatus + +; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax + + cmp ax,0xFFFF + je .exit + + push eax + and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK) + RTL_W16 RTL8169_REG_IntrStatus,ax + + mov eax,[ebx + rtl8169_RxDesc.status] + +; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax + + test eax,RTL8169_SD_RxRES + jnz .else + and eax,0x00001FFF +; jz .exit.pop + add eax,-4 + mov [eth_rx_data_len],ax + + DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax + + push eax + mov ecx,eax + shr ecx,2 + mov eax,[rtl8169_tpc.cur_rx] + mov edx,[rtl8169_tpc.RxBufferRing + eax * 4] + mov esi,edx + mov edi,Ether_buffer + cld + rep movsd + pop ecx + and ecx,3 + rep movsb + + mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE + cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + jne @f + or eax,RTL8169_DSB_EORbit + @@: mov [ebx + rtl8169_RxDesc.status],eax + + mov [ebx + rtl8169_RxDesc.buf_addr],edx + jmp @f + .else: + DEBUGF 1,"K : rtl8169_poll: Rx Error\n" + ; FIXME: shouldn't I reset the status on an error + @@: + inc [rtl8169_tpc.cur_rx] + and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 + .exit.pop: + pop eax + and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK + RTL_W16 RTL8169_REG_IntrStatus,ax + .exit: + ret +endp + +proc rtl8169_cable + ret +endp diff --git a/kernel/branches/gfx_kernel/network/eth_drv/sis900.inc b/kernel/branches/gfx_kernel/network/eth_drv/drivers/sis900.inc similarity index 100% rename from kernel/branches/gfx_kernel/network/eth_drv/sis900.inc rename to kernel/branches/gfx_kernel/network/eth_drv/drivers/sis900.inc diff --git a/kernel/branches/gfx_kernel/network/eth_drv/pci.inc b/kernel/branches/gfx_kernel/network/eth_drv/pci.inc new file mode 100644 index 000000000..21b0212b5 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/eth_drv/pci.inc @@ -0,0 +1,341 @@ +;*************************************************************************** +; +; PCI CODE FOLLOWS +; +; the following functions provide access to the PCI interface. +; These functions are used by scan_bus, and also some ethernet drivers +; +;*************************************************************************** + +; 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 + +;*************************************************************************** +; 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 + mov eax, [esi+20] + mov [drvr_cable], 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 \ No newline at end of file diff --git a/kernel/branches/gfx_kernel/network/eth_drv/rtl8139.inc b/kernel/branches/gfx_kernel/network/eth_drv/rtl8139.inc deleted file mode 100644 index d4e50b422..000000000 --- a/kernel/branches/gfx_kernel/network/eth_drv/rtl8139.inc +++ /dev/null @@ -1,595 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; 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/branches/gfx_kernel/network/icmp.inc b/kernel/branches/gfx_kernel/network/icmp.inc new file mode 100644 index 000000000..cc4ad81f1 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/icmp.inc @@ -0,0 +1,188 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; ICMP.INC +;; +;; Internet Control Message Protocol ( RFC 792 ) +;; +;; Last revision: 11.11.2006 +;; +;; This file contains the following: +;; icmp_rx - processes ICMP-packets received by the IP layer +;; +;; Changes history: +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net +;; 11.11.2006 - [Johnny_B] and [smb] +;; +;; Current status: +;; This implemetation of ICMP proto supports message of ECHO type. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +struc ICMP_PACKET +{ .Type db ? ;+00 + .Code db ? ;+01 + .Checksum dw ? ;+02 + .Identifier dw ? ;+04 + .SequenceNumber dw ? ;+06 + .Data db ? ;+08 +} + +virtual at 0 + ICMP_PACKET ICMP_PACKET +end virtual + + +; Example: +; ECHO message format +; +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Type | Code | Checksum | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Identifier | Sequence Number | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; | Data ... +; +-+-+-+-+- +; + +; +; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources +; + +ICMP_ECHOREPLY equ 0 ; echo reply message + +ICMP_UNREACH equ 3 + ICMP_UNREACH_NET equ 0 ; bad net + ICMP_UNREACH_HOST equ 1 ; bad host + ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol + ICMP_UNREACH_PORT equ 3 ; bad port + ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop + ICMP_UNREACH_SRCFAIL equ 5 ; src route failed + ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net + ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host + ICMP_UNREACH_ISOLATED equ 8 ; src host isolated + ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access + ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto + ICMP_UNREACH_TOSNET equ 11 ; bad tos for net + ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host + ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib + ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. + ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff + +ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down + +ICMP_REDIRECT equ 5 ; shorter route, codes: + ICMP_REDIRECT_NET equ 0 ; for network + ICMP_REDIRECT_HOST equ 1 ; for host + ICMP_REDIRECT_TOSNET equ 2 ; for tos and net + ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host + +ICMP_ALTHOSTADDR equ 6 ; alternate host address +ICMP_ECHO equ 8 ; echo service +ICMP_ROUTERADVERT equ 9 ; router advertisement + ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement + ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing + +ICMP_ROUTERSOLICIT equ 10 ; router solicitation +ICMP_TIMXCEED equ 11 ; time exceeded, code: + ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit + ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass + +ICMP_PARAMPROB equ 12 ; ip header bad + ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr + ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent + ICMP_PARAMPROB_LENGTH equ 2 ; bad length + +ICMP_TSTAMP equ 13 ; timestamp request +ICMP_TSTAMPREPLY equ 14 ; timestamp reply +ICMP_IREQ equ 15 ; information request +ICMP_IREQREPLY equ 16 ; information reply +ICMP_MASKREQ equ 17 ; address mask request +ICMP_MASKREPLY equ 18 ; address mask reply +ICMP_TRACEROUTE equ 30 ; traceroute +ICMP_DATACONVERR equ 31 ; data conversion error +ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect +ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you + ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here +ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req +ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply +ICMP_SKIP equ 39 ; SKIP + +ICMP_PHOTURIS equ 40 ; Photuris + ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index + ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed + ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed + + +;*************************************************************************** +; Function +; icmp_rx [by Johnny_B] +; +; Description +; ICMP protocol handler +; This is a kernel function, called by ip_rx +; +; IN: +; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards +; IPPacketBase - IP_PACKET base address +; IPHeaderLength - Header length of IP_PACKET +; +; OUT: +; EAX=not defined +; +; All used registers will be saved +; +;*************************************************************************** +proc icmp_rx stdcall uses ebx esi edi,\ + buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD + + mov esi,[IPPacketBase] ;esi=IP_PACKET base address + mov edi, esi + add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address + + cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not + jz .icmp_echo + + mov eax, [buffer_number] + call freeBuff + jmp .exit + + .icmp_echo: + + ; swap the source and destination addresses + mov ecx, [esi + IP_PACKET.DestinationAddress] + mov ebx, [esi + IP_PACKET.SourceAddress] + mov [esi + IP_PACKET.DestinationAddress], ebx + mov [esi + IP_PACKET.SourceAddress], ecx + + ; recalculate the IP header checksum + mov eax,[IPHeaderLength] + stdcall checksum_jb,esi,eax ;buf_ptr,buf_size + + mov byte[esi + IP_PACKET.HeaderChecksum], ah + mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order? + + mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response + mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc + + ; Calculate the length of the ICMP data ( IP payload) + xor eax, eax + mov ah, byte[esi + IP_PACKET.TotalLength] + mov al, byte[esi + IP_PACKET.TotalLength + 1] + sub ax, word[IPHeaderLength] ;ax=ICMP-packet length + + stdcall checksum_jb,edi,eax ;buf_ptr,buf_size + + mov byte[edi + ICMP_PACKET.Checksum], ah + mov byte[edi + ICMP_PACKET.Checksum + 1], al + + ; Queue packet for transmission + mov ebx, [buffer_number] + mov eax, NET1OUT_QUEUE + call queue + + .exit: + ret +endp \ No newline at end of file diff --git a/kernel/branches/gfx_kernel/network/ip.inc b/kernel/branches/gfx_kernel/network/ip.inc index 36d46cff7..6e8d3b27d 100644 --- a/kernel/branches/gfx_kernel/network/ip.inc +++ b/kernel/branches/gfx_kernel/network/ip.inc @@ -12,6 +12,29 @@ ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; IP underlying protocols numbers +PROTOCOL_ICMP equ 1 +PROTOCOL_TCP equ 6 +PROTOCOL_UDP equ 17 + +struc IP_PACKET +{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits] + .TypeOfService db ? ;+01 + .TotalLength dw ? ;+02 + .Identification dw ? ;+04 + .FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15] + .TimeToLive db ? ;+08 + .Protocol db ? ;+09 + .HeaderChecksum dw ? ;+10 + .SourceAddress dd ? ;+12 + .DestinationAddress dd ? ;+16 + .DataOrOptional dd ? ;+20 +} + +virtual at 0 + IP_PACKET IP_PACKET +end virtual + ;******************************************************************* ; Interface @@ -24,179 +47,151 @@ ;******************************************************************* +; +; IP Packet after reception - Normal IP packet format +; +; 0 1 2 3 +; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;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 | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +;20 | Data | +; +-+-+-.......... -+ +; +; +; [smb] attention! according to RFC 791 IP packet may have 'options' sections, +; so we can't simply think, that data have offset 20. We must calculate offset from +; IHL field +; +macro GET_IHL reg, header_addr +{ + movzx reg, byte [header_addr] + + ; we need 4-7 bits, so.... + and reg, 0x0000000F + + ; IHL keeps number of octets, so we need to << 2 'reg' + shl reg, 2 +} + + ;*************************************************************************** ; Function ; ip_rx ; ; Description -; Handles received IP packets ; This is a kernel function, called by stack_handler +; Processes all IP-packets received by the network layer +; It calls the appropriate protocol handler ; ;*************************************************************************** -ip_rx: +proc ip_rx stdcall +local buffer_number dd ? + ; Look for a buffer to tx mov eax, IPIN_QUEUE call dequeue cmp ax, NO_BUFFER - je ipr_exit ; Exit if no buffer available + je .exit ; Exit if no buffer available - push eax + mov [buffer_number], eax ;save buffer number ; convert buffer pointer eax to the absolute address - mov ecx, IPBUFFSIZE - mul ecx + imul eax, IPBUFFSIZE add eax, IPbuffs - mov edx, eax ; Save the address in edx for use by future processes + mov ebx, eax ; ebx=pointer to IP_PACKET ; 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 - + mov dx, word[ebx + IP_PACKET.HeaderChecksum] + xchg dh,dl ; Get the checksum in intel format + + mov [ebx + IP_PACKET.HeaderChecksum], 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 + GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx + stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size + cmp dx, ax + + mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!! + jnz .dump ;if CHECKSUM isn't valid then dump packet + + ; Validate the IP address, if it isn't broadcast + mov eax, [stack_ip] + cmp dword[ebx + IP_PACKET.DestinationAddress], eax + je @f ; 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 + cmp dword[ebx + IP_PACKET.DestinationAddress], 0xffffffff + jne .dump - ; Validate the IP address, if it isn't broadcast - cmp eax, [stack_ip] - jnz ipr_dump + @@: + mov al, [ebx + IP_PACKET.VersionAndIHL] + and al, 0x0f ;get IHL(header length) + cmp al, 0x05 ;if IHL!= 5*4(20 bytes) + jnz .dump ;then dump it -ipr_p0: - mov al, [edx] - and al, 0x0f - cmp al, 0x05 - jnz ipr_dump + cmp byte[ebx + IP_PACKET.TimeToLive], byte 0 + je .dump ;if TTL==0 then dump it - cmp [edx+8], byte 0 - jz ipr_dump - - mov ax, [edx + 6] - and ax, 0xFFBF - cmp ax, 0 - jnz ipr_dump + mov ax, word[ebx + IP_PACKET.FlagsAndFragmentOffset] + and ax, 0xFFBF ;get flags + cmp ax, 0 ;if some flags was set then we dump this packet + jnz .dump ;the flags should be used for fragmented packets ; 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: + mov al, [ebx + IP_PACKET.Protocol] + cmp al , PROTOCOL_TCP - jnz ipr_p2 - pop eax + jne .not_tcp + DEBUGF 1,"K : ip_rx - TCP packet\n" + mov eax, dword[buffer_number] call tcp_rx - jmp ipr_exit + jmp .exit -ipr_p2: - cmp al , PROTOCOL_UDP - jnz ipr_dump - pop eax + .not_tcp: + cmp al, PROTOCOL_UDP + jne .not_udp + DEBUGF 1,"K : ip_rx - UDP packet\n" + mov eax, dword[buffer_number] call udp_rx - jmp ipr_exit + jmp .exit -ipr_dump: + .not_udp: + cmp al , PROTOCOL_ICMP + jne .dump ;protocol ain't supported + + DEBUGF 1,"K : ip_rx - ICMP packet\n" + ;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx + mov eax, dword[buffer_number] + stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength + jmp .exit + + +.dump: ; No protocol handler available, so ; silently dump the packet, freeing up the queue buffer -; inc dword [dumped_rx_count] + inc dword [dumped_rx_count] - pop eax + mov eax, dword[buffer_number] call freeBuff -ipr_exit: + .exit: ret +endp - - -;*************************************************************************** -; 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/branches/gfx_kernel/network/socket.inc b/kernel/branches/gfx_kernel/network/socket.inc new file mode 100644 index 000000000..e991d4cd9 --- /dev/null +++ b/kernel/branches/gfx_kernel/network/socket.inc @@ -0,0 +1,926 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; SOCKET.INC +;; +;; Sockets constants, structures and functions +;; +;; Last revision: 11.11.2006 +;; +;; This file contains the following: +;; is_localport_unused +;; get_free_socket +;; socket_open +;; socket_open_tcp +;; socket_close +;; socket_close_tcp +;; socket_poll +;; socket_status +;; socket_read +;; socket_write +;; socket_write_tcp +;; +;; +;; Changes history: +;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net +;; 11.11.2006 - [Johnny_B] and [smb] +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; +; 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 +; +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 0| Status ( of this buffer ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 4| Application Process ID | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 8| Local IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 12| Local IP Port | Unused ( set to 0 ) | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 16| Remote IP Address | +; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +; 20| 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 offset from +; 76| RX Data | +; +-+-+-.......... -+ + + +; so, define struct +struc SOCKET +{ .Status dd ? ;+00 - Status ( of this buffer ) + .PID dd ? ;+04 - Application Process ID + .LocalIP dd ? ;+08 - Local IP Address + .LocalPort dw ? ;+12 - Local Port + .UnusedL dw ? ;+14 - may be removed in future + .RemoteIP dd ? ;+16 - Remote IP Address + .RemotePort dw ? ;+20 - Remote Port + .UnusedR dw ? ;+22 - may be removed in future + .rxDataCount dd ? ;+24 - Rx Data Count + .TCBState dd ? ;+28 - TCB STATE + .TCBTimer dd ? ;+32 - TCB Timer (seconds) + .ISS dd ? ;+36 - Initial Send Sequence + .IRS dd ? ;+40 - Initial Receive Sequence + .SND_UNA dd ? ;+44 - Sequence number of unack'ed sent packets + .SND_NXT dd ? ;+48 - Next send sequence number to use + .SND_WND dd ? ;+52 - Send window + .RCV_NXT dd ? ;+56 - Next receive sequence number to use + .RCV_WND dd ? ;+60 - Receive window + .SEG_LEN dd ? ;+64 - Segment length + .SEG_WND dd ? ;+68 - Segment window + .wndsizeTimer dd ? ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER + .rxData dd ? ;+76 - receive data buffer here +} + +virtual at 0 + SOCKET SOCKET +end virtual + +; simple macro calcing real memory address of SOCKET struct by socket's +macro Index2RealAddr reg +{ + shl reg, 12 + add reg, sockets +} + +;Constants +; current socket statuses +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 + +;*************************************************************************** +; 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 + SOCKET.LocalPort], 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 + SOCKET.Status], 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 +; 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 + Index2RealAddr eax + + mov [eax + SOCKET.Status], dword SOCK_OPEN + + xchg bh, bl + mov [eax + SOCKET.LocalPort], bx + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx + + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count + + mov esi, [TASK_BASE] + mov ebx, [esi+TASKDATA.pid] + mov [eax + SOCKET.PID], 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 + Index2RealAddr eax + + mov [sktAddr], eax + mov [eax], dword SOCK_OPEN + + ; TODO - check this works! + mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer. + + xchg bh, bl + mov [eax + SOCKET.LocalPort], bx +; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) +; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) + + xchg ch, cl + mov [eax + SOCKET.RemotePort], cx +; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) +; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) + + mov ebx, [stack_ip] + mov [eax + SOCKET.LocalIP], ebx + mov [eax + SOCKET.RemoteIP], edx + mov [eax + SOCKET.rxDataCount], dword 0 + + ; 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 + SOCKET.TCBState], ebx ; Indicate the state of the TCB + + mov esi, [TASK_BASE] + mov ecx, [esi+TASKDATA.pid] + mov [eax + SOCKET.PID], 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: + Index2RealAddr ebx + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp [ebx + SOCKET.Status], 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: + + mov [esi], byte 0xFF + jmp sct001 + +sct003: + popa + + Index2RealAddr ebx + mov [sktAddr], ebx + mov eax, 0xFFFFFFFF ; assume this operation will fail.. + cmp [ebx + SOCKET.Status], 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 + SOCKET.TCBState] + 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 + SOCKET.TCBState], eax + xor eax, eax + jmp sct_send + +sct_finwait1: + ; Send a fin, then enter finwait2 state + mov eax, TCB_FIN_WAIT_1 + mov [ebx + SOCKET.TCBState], 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: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.rxDataCount] + + ret + + + +;*************************************************************************** +; Function +; socket_status +; +; Description +; socket # in ebx +; returns TCB state in eax. +; +;*************************************************************************** +socket_status: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.TCBState] + + ret + + + +;*************************************************************************** +; Function +; socket_read +; +; Description +; socket # in ebx +; returns # of bytes remaining in eax, data in bl +; +;*************************************************************************** +socket_read: + Index2RealAddr ebx + mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes + mov ecx, 1 + test eax, eax + jz sr2 + + dec eax + mov esi, ebx ; esi is address of socket + mov [ebx + SOCKET.rxDataCount], eax ; store new count + ;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte + 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_read_packet +; +; Description +; socket # in ebx +; datapointer # in ecx +; buffer size in edx +; returns # of bytes copied in eax +; +;*************************************************************************** +socket_read_packet: + Index2RealAddr ebx ; get real socket address + mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes + test eax, eax ; if count of bytes is zero.. + jz .exit ; exit function (eax will be zero) + + test edx, edx ; if buffer size is zero, copy all data + jz .copyallbytes + cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data + jge .copyallbytes + + sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy) + mov [ebx + SOCKET.rxDataCount], eax ; + push eax + mov eax, edx ; number of bytes we want to copy must be in eax + call .startcopy ; copy to the application + + mov esi, ebx ; now we're going to copy the remaining bytes to the beginning + add esi, SOCKETHEADERSIZE ; we dont need to copy the header + mov edi, esi ; edi is where we're going to copy to + add esi, edx ; esi is from where we copy + pop ecx ; count of bytes we have left + push ecx ; push it again so we can re-use it later + shr ecx, 2 ; divide eax by 4 + cld + rep movsd ; copy all full dwords + pop ecx + and ecx, 3 + rep movsb ; copy remaining bytes + + ret ; at last, exit + +.copyallbytes: + xor esi, esi + mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) + +.startcopy: + mov edi, ecx ; + add edi, std_application_base_address ; get data pointer to buffer in application + + mov esi, ebx ; + add esi, SOCKETHEADERSIZE ; we dont need to copy the header + mov ecx, eax ; eax is count of bytes + push ecx + shr ecx, 2 ; divide eax by 4 + cld ; copy all full dwords + rep movsd ; + pop ecx + and ecx, 3 + rep movsb ; copy the rest bytes + +.exit: + ret ; exit, or go back to shift remaining bytes if any + + + + +;*************************************************************************** +; 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: + Index2RealAddr ebx + + 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, [TASK_BASE] + 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 + GET_IHL ecx,edx ; get IP-Header length + stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size + + 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: + Index2RealAddr ebx + + 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 + SOCKET.wndsizeTimer], 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, [TASK_BASE] + 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 + +swt001: + xor eax, eax + +swt_exit: + ret + diff --git a/kernel/branches/gfx_kernel/network/stack.inc b/kernel/branches/gfx_kernel/network/stack.inc index 2d0427d1f..0b43fadd2 100644 --- a/kernel/branches/gfx_kernel/network/stack.inc +++ b/kernel/branches/gfx_kernel/network/stack.inc @@ -13,9 +13,13 @@ ;; Version 0.7 ;; ;; Added a timer per socket to allow delays when rx window ;; ;; gets below 1KB ;; +;; ;; +;; 10.01.2007 Bugfix for checksum function from Paolo Franchetti ;; +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;******************************************************************* ; Interface ; The interfaces defined in ETHERNET.INC plus: @@ -27,172 +31,39 @@ ; ;******************************************************************* - - -; -; 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 +uglobal +StackCounters: + dumped_rx_count: dd 0 + arp_tx_count: dd 0 + arp_rx_count: dd 0 + ip_rx_count: dd 0 + ip_tx_count: dd 0 +endg ; socket buffers -SOCKETBUFFSIZE equ 4096 ; state + config + buffer. -SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data +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 +NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 +; IPBUFF status values +BUFF_EMPTY equ 0 +BUFF_RX_FULL equ 1 +BUFF_ALLOCATED equ 2 +BUFF_TX_FULL equ 3 -NUMQUEUES equ 4 -EMPTY_QUEUE equ 0 -IPIN_QUEUE equ 1 -IPOUT_QUEUE equ 2 -NET1OUT_QUEUE equ 3 +NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX -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 +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 ; These are the 0x40 function codes for application access to the stack STACK_DRIVER_STATUS equ 52 @@ -202,60 +73,49 @@ 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 +eth_data_start equ 0x700000 +stack_data equ 0x704000 +stack_data_end equ 0x71ffff ; 32 bit word -stack_config equ stack_data +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 +stack_ip equ stack_data + 4 + ; 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 + + +; TODO :: empty memory area + ; Address of selected socket -sktAddr equ stack_data + 32 +sktAddr equ stack_data + 32 ; Parameter to checksum routine - data ptr -checkAdd1 equ stack_data + 36 +checkAdd1 equ stack_data + 36 ; Parameter to checksum routine - 2nd data ptr -checkAdd2 equ stack_data + 40 +checkAdd2 equ stack_data + 40 ; Parameter to checksum routine - data size -checkSize1 equ stack_data + 44 +checkSize1 equ stack_data + 44 ; Parameter to checksum routine - 2nd data size -checkSize2 equ stack_data + 46 +checkSize2 equ stack_data + 46 ; result of checksum routine -checkResult equ stack_data + 48 +checkResult equ stack_data + 48 ; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| -pseudoHeader equ stack_data + 50 +pseudoHeader equ stack_data + 50 ; receive and transmit IP buffer allocation -sockets equ stack_data + 62 -Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) +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 ) +Ether_buffer equ Next_free2 +Next_free3 equ Ether_buffer + 1518 +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 @@ -263,10 +123,35 @@ last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) -resendQ equ 0x770000 -resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP +resendQ equ 0x770000 +resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP +; simple macro for memory set operation +macro _memset_dw adr,value,amount +{ + mov edi, adr + mov ecx, amount + if value = 0 + xor eax, eax + else + mov eax, value + end if + cld + rep stosd +} + + +; Below, the main network layer source code is included +; +include "queue.inc" +include "eth_drv/ethernet.inc" +include "ip.inc" +include "icmp.inc" +include "tcp.inc" +include "udp.inc" +include "socket.inc" + ;*************************************************************************** ; Function ; stack_init @@ -278,41 +163,21 @@ resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP ; 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 + ; Init two address spaces with default values + _memset_dw stack_data_start, 0, 0x20000/4 + _memset_dw resendQ, 0xFFFFFFFF, NUMRESENDENTRIES - ; Initialise TCP resend queue data structures - mov eax, 0xFFFFFFFF - mov edi, resendQ - mov ecx, NUMRESENDENTRIES ; 1 dword per entry - cld - rep stosd + ; Queries initialization + call queueInit - - 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 + ; The following block sets up the 1s timer + mov al, 0x0 + out 0x70, al + in al, 0x71 + mov [last_1sTick], al +ret @@ -334,7 +199,7 @@ stack_handler: ; Test for 10ms tick, call tcp timer mov eax, [timer_ticks] ;[0xfdf0] cmp eax, [last_1hsTick] - je sh_001 + je sh_001 mov [last_1hsTick], eax call tcp_tx_handler @@ -342,82 +207,55 @@ stack_handler: sh_001: ; Test for 1 second event, call 1s timer functions - mov al,0x0 ;second - out 0x70,al - in al,0x71 + mov al, 0x0 ;second + out 0x70, al + in al, 0x71 cmp al, [last_1sTick] - je sh_exit + je sh_exit mov [last_1sTick], al - call arp_timer + stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0 call tcp_tcb_handler sh_exit: ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Checksum [by Johnny_B] +;; IN: +;; buf_ptr=POINTER to buffer +;; buf_size=SIZE of buffer +;; OUT: +;; AX=16-bit checksum +;; Saves all used registers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +proc checksum_jb stdcall uses ebx esi ecx,\ + buf_ptr:DWORD, buf_size:DWORD + xor eax, eax + xor ebx, ebx ;accumulator + mov esi, dword[buf_ptr] + mov ecx, dword[buf_size] + shr ecx, 1 ; ecx=ecx/2 + jnc @f ; if CF==0 then size is even number + mov bh, byte[esi + ecx*2] + @@: + cld + .loop: + lodsw ;eax=word[esi],esi=esi+2 + xchg ah,al ;cause must be a net byte-order + add ebx, eax + loop .loop -;*************************************************************************** -; 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 eax, ebx + shr eax, 16 + add ax, bx + not 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 - - +endp ;*************************************************************************** ; Function @@ -430,16 +268,16 @@ gfs_exit: ; Internetworking with TCP/IP Volume II by D.E. Comer ; ;*************************************************************************** + + checksum: pusha - - xor edx, edx ; edx is the accumulative checksum + mov eax, [checkAdd1] + xor edx, edx ; edx is the accumulative checksum xor ebx, ebx mov cx, [checkSize1] shr cx, 1 - jz cs1_1 - - mov eax, [checkAdd1] + jz cs1_1 cs1: mov bh, [eax] @@ -452,7 +290,7 @@ cs1: cs1_1: and word [checkSize1], 0x01 - jz cs_test2 + jz cs_test2 mov bh, [eax] xor bl, bl @@ -462,13 +300,13 @@ cs1_1: cs_test2: mov cx, [checkSize2] cmp cx, 0 - jz cs_exit ; Finished if no 2nd buffer - - shr cx, 1 - jz cs2_1 + jz cs_exit ; Finished if no 2nd buffer mov eax, [checkAdd2] + shr cx, 1 + jz cs2_1 + cs2: mov bh, [eax] mov bl, [eax + 1] @@ -480,7 +318,7 @@ cs2: cs2_1: and word [checkSize2], 0x01 - jz cs_exit + jz cs_exit mov bh, [eax] xor bl, bl @@ -510,14 +348,14 @@ cs_exit: ; app_stack_handler ; ; Description -; This is an application service, called by int 0x40 fn 52 +; This is an application service, called by int 0x40, function 52 ; It provides application access to the network interface layer ; ;*************************************************************************** app_stack_handler: cmp eax, 0 jnz not0 - ; Read the configuartion word + ; Read the configuration word mov eax, [stack_config] ret @@ -547,7 +385,7 @@ not1: and bl, 0x7f cmp bl, 3 - je ash_eth_enable + je ash_eth_enable ; Ethernet isn't enabled, so make sure that the card is disabled mov [ethernet_active], byte 0 @@ -558,7 +396,7 @@ ash_eth_enable: ; if found call eth_probe cmp eax, 0 - je ash_eth_done ; Abort if no hardware found + je ash_eth_done ; Abort if no hardware found mov [ethernet_active], byte 1 @@ -572,20 +410,9 @@ not2: mov [stack_ip], ebx ret +;old functions was deleted + 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 @@ -653,15 +480,101 @@ not12: not13: cmp eax, 14 - jnz stack_driver_end + jnz not14 ; write the dns IP Address mov [dns_ip], ebx ret -stack_driver_end: +; +not14: + cmp eax, 15 + jnz not15 + + ; in ebx we need 4 to read the last 2 bytes + cmp ebx, dword 4 + je read + + ; or we need 0 to read the first 4 bytes + cmp ebx, dword 0 + jnz param_error + + ; read MAC, returned (in mirrored byte order) in eax +read: + mov eax, [node_addr + ebx] + jmp @f + +param_error: + mov eax, -1 ; params not accepted +@@: + ret + + +; 0 -> arp_probe +; 1 -> arp_announce +; 2 -> arp_responce (not supported yet) + +not15: ; ARP stuff + cmp eax, 16 + jnz not16 + + cmp ebx, 0 + je a_probe + + cmp ebx, 1 + je a_ann ; arp announce + +; cmp ebx,2 +; jne a_resp ; arp response + + jmp param15_error + + +; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed +; ecx: pointer to target MAC, MAC should set to 0 by application +; edx: target IP +a_probe: + push dword [stack_ip] + + mov edx, [stack_ip] + mov [stack_ip], dword 0 + mov esi, ecx ; pointer to target MAC address + call arp_request + + pop dword [stack_ip] + jmp @f + +; arp announce, sender IP must be set to target IP +; ecx: pointer to target MAC +a_ann: + mov edx, [stack_ip] + mov esi, ecx ; pointer to target MAC address + call arp_request + jmp @f + +param15_error: + mov eax, -1 + +@@: + ret +; +; modified by [smb] + +; +; ARPTable manager interface +not16: + cmp eax, 17 + jnz stack_driver_end + + ;see "proc arp_table_manager" for more details + stdcall arp_table_manager,ebx,ecx,edx ;Opcode,Index,Extra + ret +; + +stack_driver_end: + ret @@ -670,7 +583,7 @@ stack_driver_end: ; app_socket_handler ; ; Description -; This is an application service, called by int 0x40 +; This is an application service, called by int 0x40, function 53 ; It provides application access to stack socket services ; such as opening sockets ; @@ -746,6 +659,28 @@ nots8: ret nots9: + cmp eax, 10 + jnz nots10 + + mov eax,dword[drvr_cable] + test eax,eax + jnz @f ; if function is not implented, return -1 + mov al,-1 + ret + + @@: + call dword[drvr_cable] + ret + + +nots10: + cmp eax, 11 + jnz nots11 + + call socket_read_packet + ret + +nots11: cmp eax, 254 jnz notdump @@ -980,9 +915,9 @@ stack_get_packet: mov eax, NET1OUT_QUEUE call dequeue cmp ax, NO_BUFFER - je sgp_non_exit ; Exit if no buffer available + je sgp_non_exit ; Exit if no buffer available - push eax ; Save buffer number for freeing at end + push eax ; Save buffer number for freeing at end push edx ; convert buffer pointer eax to the absolute address @@ -991,20 +926,20 @@ stack_get_packet: add eax, IPbuffs pop edx - push eax ; save address of IP data + push eax ; save address of IP data ; Get the address of the callers data - mov edi,[0x3010] + mov edi,[TASK_BASE] 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 ecx, 1500 ; should get the actual number of bytes to write mov esi, eax cld - rep movsb ; copy the data across + rep movsb ; copy the data across ; And finally, return the buffer to the free queue pop eax @@ -1035,7 +970,7 @@ stack_insert_packet: mov eax, EMPTY_QUEUE call dequeue cmp ax, NO_BUFFER - je sip_err_exit + je sip_err_exit push eax @@ -1052,19 +987,19 @@ stack_insert_packet: ; 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 + 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] + mov edi,[TASK_BASE] add edi,TASKDATA.mem_start add eax,[edi] mov esi, eax mov edi, edx cld - rep movsb ; copy the data across + rep movsb ; copy the data across pop ebx @@ -1080,705 +1015,3 @@ 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/branches/gfx_kernel/network/tcp.inc b/kernel/branches/gfx_kernel/network/tcp.inc index 179f42535..aae99c63a 100644 --- a/kernel/branches/gfx_kernel/network/tcp.inc +++ b/kernel/branches/gfx_kernel/network/tcp.inc @@ -14,6 +14,23 @@ ;; gets below 1KB ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; 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 + +TCP_RETRIES equ 5 ; Number of times to resend a packet +TCP_TIMEOUT equ 10 ; resend if not replied to in x hs ;******************************************************************* ; Interface @@ -27,6 +44,48 @@ ;******************************************************************* +; 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 + + +struc TCP_PACKET +{ .SourcePort dw ? ;+00 + .DestinationPort dw ? ;+02 + .SequenceNumber dd ? ;+04 + .AckNumber dd ? ;+08 + .DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7] + .Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN + .Window dw ? ;+14 + .Checksum dw ? ;+16 + .UrgentPointer dw ? ;+18 + .Options rb 3 ;+20 + .Padding db ? ;+23 + .Data db ? ;+24 +} + +virtual at 0 + TCP_PACKET TCP_PACKET +end virtual + + ;*************************************************************************** ; Function @@ -116,7 +175,7 @@ tth001: cmp ecx, NUMRESENDENTRIES je tth003 ; None left cmp [esi], byte 0xFF - jne tth002 ; found one + jne tth002 ; found one inc ecx add esi, 4 jmp tth001 @@ -126,7 +185,7 @@ tth002: dec word [esi+2] mov ax, [esi+2] cmp ax, 0 - je tth002a + je tth002a inc ecx add esi, 4 jmp tth001 ; Timer not zero, so move on @@ -494,15 +553,9 @@ btp_001: 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 + GET_IHL eax,edx ; get IP-Header length + stdcall checksum_jb,edx,eax ; buf_ptr, buf_size - call checksum - - mov ax, [checkResult] mov [edx + 10], ah mov [edx + 11], al @@ -1004,19 +1057,19 @@ ste_data: ; flag an event to the application pop eax mov ecx,1 - mov esi,0x3020+TASKDATA.pid + mov esi,TASK_DATA+TASKDATA.pid news: cmp [esi],eax je foundPID1 inc ecx add esi,0x20 - cmp ecx,[0x3004] + cmp ecx,[TASK_COUNT] jbe news foundPID1: shl ecx,8 - or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event + or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event pop ecx diff --git a/kernel/branches/gfx_kernel/network/udp.inc b/kernel/branches/gfx_kernel/network/udp.inc index ff36d37ab..b4b7bda25 100644 --- a/kernel/branches/gfx_kernel/network/udp.inc +++ b/kernel/branches/gfx_kernel/network/udp.inc @@ -11,53 +11,80 @@ ;; See file COPYING for details ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - + + ;******************************************************************* ; Interface ; ; udp_rx Handles received IP packets with the UDP protocol -; +; ;******************************************************************* - - - - + + +; +; 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 | +; +-+-+-.......... -+ +; + +struc UDP_PACKET +{ .SourcePort dw ? ;+00 + .DestinationPort dw ? ;+02 + .Length dw ? ;+04 - Length of (UDP Header + Data) + .Checksum dw ? ;+06 + .Data db ? ;+08 +} + +virtual at 0 + UDP_PACKET UDP_PACKET +end virtual + + ;*************************************************************************** ; Function -; udp_rx +; udp_rx [by Johnny_B] ; ; Description ; UDP 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 ; ;*************************************************************************** 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 @@ -65,13 +92,13 @@ fs_done: ; 255.255.255.255 mov ebx, [eax + sockets + 16] cmp ebx, 0xffffffff - je udprx_002 - + 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: +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 @@ -79,59 +106,58 @@ udprx_002: 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 + 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 - + mov esi,TASK_DATA+TASKDATA.pid + newsearch: cmp [esi],eax je foundPID inc ecx add esi,0x20 - cmp ecx,[0x3004] + cmp ecx,[TASK_COUNT] jbe newsearch - -foundPID: - shl ecx,8 - or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event - mov [check_idle_semaphore],200 +foundPID: + shl ecx,8 + or dword [ecx+SLOT_BASE+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 + ret diff --git a/kernel/branches/gfx_kernel/proc32.inc b/kernel/branches/gfx_kernel/proc32.inc new file mode 100644 index 000000000..98a1bd334 --- /dev/null +++ b/kernel/branches/gfx_kernel/proc32.inc @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/kernel/branches/gfx_kernel/sound/sb16.inc b/kernel/branches/gfx_kernel/sound/sb16.inc index 6d7ec5e97..9153bceba 100644 --- a/kernel/branches/gfx_kernel/sound/sb16.inc +++ b/kernel/branches/gfx_kernel/sound/sb16.inc @@ -30,7 +30,7 @@ sound_interface: cmp eax,0 ; Load data jne no_SB16_load_music - mov edi,[0x3010] + mov edi,[TASK_BASE] add edi,TASKDATA.mem_start add ebx,[edi] call code_SB16_load_music @@ -67,17 +67,17 @@ sound_interface: ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cmp eax, edi ; this is subfunction #55 ? jne retFunc55 ; if no then return. - cmp byte [sound_flag],0 + 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, [TASK_BASE] ; 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,[TASK_BASE] mov eax,[eax+TASKDATA.pid] mov [pidProcessNote],eax xor eax, eax ; Ok! EAX = 0 diff --git a/kernel/branches/gfx_kernel/unpacker.inc b/kernel/branches/gfx_kernel/unpacker.inc new file mode 100644 index 000000000..044ad697c --- /dev/null +++ b/kernel/branches/gfx_kernel/unpacker.inc @@ -0,0 +1,504 @@ +; void __stdcall unpack(void* packed_data, void* unpacked_data); +unpack: + pushad + mov esi, [esp+32+4] + mov edi, [esp+32+8] + mov eax, [esi+8] + and al, 0xC0 + cmp al, 0xC0 + jz .failed + mov eax, [esi+8] + push eax + add esi, 12 + and al, not 0xC0 + dec eax + jz .lzma +.failed: + pop eax + popad + ret 8 +.lzma: + call .lzma_unpack +.common: + pop eax + test al, 0x80 + jnz .ctr1 + test al, 0x40 + jz .ok + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c1: + lodsb + sub al, 0E8h + cmp al, 1 + ja .c1 + cmp byte [esi], dl + jnz .c1 + lodsd +; "bswap eax" is not supported on i386 + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c1 +.ok: + popad + ret 8 +.ctr1: + lodsd + mov ecx, eax + jecxz .ok + mov dl, [esi] + mov esi, [esp+32+8] +.c2: + lodsb +@@: + cmp al, 0xF + jnz .f + lodsb + cmp al, 80h + jb @b + cmp al, 90h + jb @f +.f: + sub al, 0E8h + cmp al, 1 + ja .c2 +@@: + cmp byte [esi], dl + jnz .c2 + lodsd + shr ax, 8 + ror eax, 16 + xchg al, ah + sub eax, esi + add eax, [esp+32+8] + mov [esi-4], eax + loop .c2 + jmp .ok + +.lzma_unpack: + +.pb = 2 ; pos state bits +.lp = 0 ; literal pos state bits +.lc = 3 ; literal context bits +.posStateMask = ((1 shl .pb)-1) +.literalPosMask = ((1 shl .lp)-1) + +.kNumPosBitsMax = 4 +.kNumPosStatesMax = (1 shl .kNumPosBitsMax) + +.kLenNumLowBits = 3 +.kLenNumLowSymbols = (1 shl .kLenNumLowBits) +.kLenNumMidBits = 3 +.kLenNumMidSymbols = (1 shl .kLenNumMidBits) +.kLenNumHighBits = 8 +.kLenNumHighSymbols = (1 shl .kLenNumHighBits) + +.LenChoice = 0 +.LenChoice2 = 1 +.LenLow = 2 +.LenMid = (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits)) +.LenHigh = (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits)) +.kNumLenProbs = (.LenHigh + .kLenNumHighSymbols) + +.kNumStates = 12 +.kNumLitStates = 7 +.kStartPosModelIndex = 4 +.kEndPosModelIndex = 14 +.kNumFullDistances = (1 shl (.kEndPosModelIndex/2)) +.kNumPosSlotBits = 6 +.kNumLenToPosStates = 4 +.kNumAlignBits = 4 +.kAlignTableSize = (1 shl .kNumAlignBits) +.kMatchMinLen = 2 + +.IsMatch = 0 +.IsRep = (.IsMatch + (.kNumStates shl .kNumPosBitsMax)) +.IsRepG0 = (.IsRep + .kNumStates) +.IsRepG1 = (.IsRepG0 + .kNumStates) +.IsRepG2 = (.IsRepG1 + .kNumStates) +.IsRep0Long = (.IsRepG2 + .kNumStates) +.PosSlot = (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax)) +.SpecPos = (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits)) +.Align_ = (.SpecPos + .kNumFullDistances - .kEndPosModelIndex) +.Lencoder = (.Align_ + .kAlignTableSize) +.RepLencoder = (.Lencoder + .kNumLenProbs) +.Literal = (.RepLencoder + .kNumLenProbs) + +.LZMA_BASE_SIZE = 1846 ; must be ==Literal +.LZMA_LIT_SIZE = 768 + +.kNumTopBits = 24 +.kTopValue = (1 shl .kNumTopBits) + +.kNumBitModelTotalBits = 11 +.kBitModelTotal = (1 shl .kNumBitModelTotalBits) +.kNumMoveBits = 5 + + push edi +; int state=0; + xor ebx, ebx + mov [.previousByte], bl +; unsigned rep0=1,rep1=1,rep2=1,rep3=1; + mov eax, 1 + mov edi, .rep0 + stosd + stosd + stosd + stosd +; int len=0; +; result=0; + mov ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp)) + mov eax, .kBitModelTotal/2 + mov edi, .p + rep stosd +; RangeDecoderInit +; rd->ExtraBytes = 0 +; rd->Buffer = stream +; rd->BufferLim = stream+bufferSize +; rd->Range = 0xFFFFFFFF + pop edi + mov ebp, [esi-8] ; dest_length + add ebp, edi ; ebp = destination limit + lodsd +; rd->code_ = eax + mov [.code_], eax + or [.range], -1 +.main_loop: + cmp edi, ebp + jae .main_loop_done + mov edx, edi + and edx, .posStateMask + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.p + .IsMatch*4 + eax + edx*4] + call .RangeDecoderBitDecode + jc .1 + movzx eax, [.previousByte] +if .literalPosMask + mov ah, dl + and ah, .literalPosMask +end if + shr eax, 8-.lc + imul eax, .LZMA_LIT_SIZE*4 + add eax, .p+.Literal*4 + cmp ebx, .kNumLitStates + jb .literal + xor edx, edx + sub edx, [.rep0] + mov dl, [edi + edx] + call .LzmaLiteralDecodeMatch + jmp @f +.literal: + call .LzmaLiteralDecode +@@: + mov [.previousByte], al + stosb + mov al, bl + cmp bl, 4 + jb @f + mov al, 3 + cmp bl, 10 + jb @f + mov al, 6 +@@: sub bl, al + jmp .main_loop +.1: + lea eax, [.p + .IsRep*4 + ebx*4] + call .RangeDecoderBitDecode + jnc .10 + lea eax, [.p + .IsRepG0*4 + ebx*4] + call .RangeDecoderBitDecode + jc .111 + mov eax, ebx + shl eax, .kNumPosBitsMax+2 + lea eax, [.p + .IsRep0Long*4 + eax + edx*4] + call .RangeDecoderBitDecode + jc .1101 + cmp bl, 7 + setae bl + lea ebx, [9 + ebx + ebx] + xor edx, edx + sub edx, [.rep0] + mov al, [edi + edx] + stosb + mov [.previousByte], al + jmp .main_loop +.111: + lea eax, [.p + .IsRepG1*4 + ebx*4] + call .RangeDecoderBitDecode + mov eax, [.rep1] + jnc .l3 +.l1: + lea eax, [.p + .IsRepG2*4 + ebx*4] + call .RangeDecoderBitDecode + mov eax, [.rep2] + jnc .l2 + xchg [.rep3], eax +.l2: + push [.rep1] + pop [.rep2] +.l3: + xchg eax, [.rep0] + mov [.rep1], eax +.1101: + mov eax, .p + .RepLencoder*4 + call .LzmaLenDecode + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 8 + jmp .repmovsb +.10: + mov eax, [.rep0] + xchg eax, [.rep1] + xchg eax, [.rep2] + xchg eax, [.rep3] + cmp bl, 7 + setc bl + adc bl, bl + xor bl, 3 + add bl, 7 + mov eax, .p + .Lencoder*4 + call .LzmaLenDecode + mov eax, .kNumLenToPosStates-1 + cmp eax, ecx + jb @f + mov eax, ecx +@@: + push ecx + mov ecx, .kNumPosSlotBits + shl eax, cl + shl eax, 2 + add eax, .p+.PosSlot*4 + call .RangeDecoderBitTreeDecode + mov [.rep0], ecx + cmp ecx, .kStartPosModelIndex + jb .l6 + push ecx + mov eax, ecx + and eax, 1 + shr ecx, 1 + or eax, 2 + dec ecx + shl eax, cl + mov [.rep0], eax + pop edx + cmp edx, .kEndPosModelIndex + jae .l5 + sub eax, edx + shl eax, 2 + add eax, .p + (.SpecPos - 1)*4 + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx + jmp .l6 +.l5: + sub ecx, .kNumAlignBits + call .RangeDecoderDecodeDirectBits + mov ecx, .kNumAlignBits + shl eax, cl + add [.rep0], eax + mov eax, .p+.Align_*4 + call .RangeDecoderReverseBitTreeDecode + add [.rep0], ecx +.l6: + pop ecx + inc [.rep0] + jz .main_loop_done +.repmovsb: + add ecx, .kMatchMinLen + push esi + mov esi, edi + sub esi, [.rep0] + rep movsb + pop esi + mov al, [edi-1] + mov [.previousByte], al + jmp .main_loop +.main_loop_done: + ret + +.RangeDecoderBitDecode: +; in: eax->prob +; out: CF=bit; destroys eax + push edx + mov edx, [.range] + shr edx, .kNumBitModelTotalBits + imul edx, [eax] + cmp [.code_], edx + jae .ae + mov [.range], edx + mov edx, .kBitModelTotal + sub edx, [eax] + shr edx, .kNumMoveBits + add [eax], edx + clc +.n: + lahf + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + lodsb + mov byte [.code_], al +@@: + sahf + pop edx + ret +.ae: + sub [.range], edx + sub [.code_], edx + mov edx, [eax] + shr edx, .kNumMoveBits + sub [eax], edx + stc + jmp .n + +.RangeDecoderDecodeDirectBits: +; in: ecx=numTotalBits +; out: eax=result; destroys edx + xor eax, eax +.l: + shr [.range], 1 + shl eax, 1 + mov edx, [.code_] + sub edx, [.range] + jb @f + mov [.code_], edx + or eax, 1 +@@: + cmp [.range], .kTopValue + jae @f + shl [.range], 8 + shl [.code_], 8 + push eax + lodsb + mov byte [.code_], al + pop eax +@@: + loop .l + ret + +.LzmaLiteralDecode: +; in: eax->probs +; out: al=byte; destroys edx + push ecx + mov ecx, 1 +@@: + push eax + lea eax, [eax+ecx*4] + call .RangeDecoderBitDecode + pop eax + adc cl, cl + jnc @b +.LzmaLiteralDecode.ret: + mov al, cl + pop ecx + ret +.LzmaLiteralDecodeMatch: +; in: eax->probs, dl=matchByte +; out: al=byte; destroys edx + push ecx + mov ecx, 1 +.LzmaLiteralDecodeMatch.1: + add dl, dl + setc ch + push eax + lea eax, [eax+ecx*4+0x100*4] + call .RangeDecoderBitDecode + pop eax + adc cl, cl + jc .LzmaLiteralDecode.ret + xor ch, cl + test ch, 1 + mov ch, 0 + jnz @b + jmp .LzmaLiteralDecodeMatch.1 + +.LzmaLenDecode: +; in: eax->prob, edx=posState +; out: ecx=len + push eax + add eax, .LenChoice*4 + call .RangeDecoderBitDecode + pop eax + jnc .0 + push eax + add eax, .LenChoice2*4 + call .RangeDecoderBitDecode + pop eax + jc @f + mov ecx, .kLenNumMidBits + shl edx, cl + lea eax, [eax + .LenMid*4 + edx*4] + call .RangeDecoderBitTreeDecode + add ecx, .kLenNumLowSymbols + ret +@@: + add eax, .LenHigh*4 + mov ecx, .kLenNumHighBits + call .RangeDecoderBitTreeDecode + add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols + ret +.0: + mov ecx, .kLenNumLowBits + shl edx, cl + lea eax, [eax + .LenLow*4 + edx*4] +.RangeDecoderBitTreeDecode: +; in: eax->probs,ecx=numLevels +; out: ecx=length; destroys edx + push ebx + mov edx, 1 + mov ebx, edx +@@: + push eax + lea eax, [eax+edx*4] + call .RangeDecoderBitDecode + pop eax + adc dl, dl + add bl, bl + loop @b + sub dl, bl + pop ebx + mov ecx, edx + ret +.RangeDecoderReverseBitTreeDecode: +; in: eax->probs,ecx=numLevels +; out: ecx=length; destroys edx + push ebx ecx + mov edx, 1 + xor ebx, ebx +@@: + push eax + lea eax, [eax+edx*4] + call .RangeDecoderBitDecode + lahf + adc edx, edx + sahf + rcr ebx, 1 + pop eax + loop @b + pop ecx + rol ebx, cl + mov ecx, ebx + pop ebx + ret + +uglobal +align 4 +unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) +unpack.code_ dd ? +unpack.range dd ? +unpack.rep0 dd ? +unpack.rep1 dd ? +unpack.rep2 dd ? +unpack.rep3 dd ? +unpack.previousByte db ? +endg diff --git a/kernel/branches/gfx_kernel/video/arrow.cur b/kernel/branches/gfx_kernel/video/arrow.cur new file mode 100644 index 000000000..5e0790095 Binary files /dev/null and b/kernel/branches/gfx_kernel/video/arrow.cur differ diff --git a/kernel/branches/gfx_kernel/video/cursors.inc b/kernel/branches/gfx_kernel/video/cursors.inc new file mode 100644 index 000000000..78826037f --- /dev/null +++ b/kernel/branches/gfx_kernel/video/cursors.inc @@ -0,0 +1,746 @@ + +LOAD_FROM_FILE equ 0 +LOAD_FROM_MEM equ 1 +LOAD_INDIRECT equ 2 +LOAD_SYSTEM equ 3 +VIDEO_FREE equ 2 + +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 +} + +virtual at 0 + BI BITMAPINFOHEADER +end virtual + +align 4 +proc vesa_init_cursor stdcall, dst:dword, src:dword + locals + rBase dd ? + pQuad dd ? + pBits dd ? + pAnd dd ? + width dd ? + height dd ? + counter dd ? + endl + + mov esi, [src] + add esi,[esi+18] + mov eax,esi + + cmp [esi+BI.biBitCount], 24 + je .img_24 + cmp [esi+BI.biBitCount], 8 + je .img_8 + cmp [esi+BI.biBitCount], 4 + je .img_4 + +.img_2: + add eax, [esi] + mov [pQuad],eax + add eax,8 + mov [pBits],eax + add eax, 128 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, [dst] + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] +.l21: + mov ebx, [pBits] + mov ebx, [ebx] + bswap ebx + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + xor ecx, ecx + shl ebx,1 + setc cl + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + add edi, 4 + dec [counter] + jnz @B + + add [pBits], 4 + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l21 + ret + +.img_4: + add eax, [esi] + mov [pQuad],eax + add eax,64 + mov [pBits],eax + add eax, 0x200 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, [dst] + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] + mov ebx, [pBits] +.l4: + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 16 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + and cl, 0xF0 + shr ecx, 2 + mov ecx, [esi+ecx] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + and cl, 0x0F + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi+4], edx + + inc ebx + add edi, 8 + dec [counter] + jnz @B + + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l4 + ret +.img_8: + add eax, [esi] + mov [pQuad],eax + add eax,1024 + mov [pBits],eax + add eax, 1024 + mov [pAnd],eax + mov eax,[esi+4] + mov [width],eax + mov ebx,[esi+8] + shr ebx,1 + mov [height],ebx + + mov edi, [dst] + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pQuad] + mov ebx, [pBits] +.l81: + mov eax, [pAnd] + mov eax, [eax] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + movzx ecx, byte [ebx] + mov ecx, [esi+ecx*4] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + inc ebx + add edi, 4 + dec [counter] + jnz @B + + add [pAnd], 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l81 + ret +.img_24: + add eax, [esi] + mov [pQuad],eax + add eax, 0xC00 + mov [pAnd],eax + mov eax,[esi+BI.biWidth] + mov [width],eax + mov ebx,[esi+BI.biHeight] + shr ebx,1 + mov [height],ebx + + mov edi, [dst] + add edi, 32*31*4 + mov [rBase],edi + + mov esi,[pAnd] + mov ebx, [pQuad] +.row_24: + mov eax, [esi] + bswap eax + mov [counter], 32 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + mov ecx, [ebx] + and ecx, 0x00FFFFFF + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + add ebx, 3 + add edi, 4 + dec [counter] + jnz @B + + add esi, 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .row_24 + ret +endp + +align 4 +proc set_cursor stdcall, hcursor:dword + mov eax, [hcursor] + cmp [eax+CURSOR.magic], 'CURS' + jne .fail +; cmp [eax+CURSOR.size], CURSOR_SIZE +; jne .fail + mov ebx, [CURRENT_TASK] + shl ebx, 8 + xchg eax, [ebx+SLOT_BASE+APPDATA.cursor] + ret +.fail: + mov eax, [def_cursor] + mov ebx, [CURRENT_TASK] + shl ebx, 8 + xchg eax, [ebx+SLOT_BASE+APPDATA.cursor] + ret +endp + +; param +; eax= pid +; ebx= src +; ecx= flags + +vesa_cursor: +.src equ esp +.flags equ esp+4 +.hcursor equ esp+8 + + sub esp, 4 ;space for .hcursor + push ecx + push ebx + + mov ebx, eax + mov eax, CURSOR_SIZE + call create_kernel_object + test eax, eax + jz .fail + + mov [.hcursor],eax + + xor ebx, ebx + mov [eax+CURSOR.magic], 'CURS' + mov [eax+CURSOR.destroy], destroy_cursor + mov [eax+CURSOR.hot_x], ebx + mov [eax+CURSOR.hot_y], ebx + + stdcall kernel_alloc, 0x1000 + test eax, eax + jz .fail + + mov edi, [.hcursor] + mov [edi+CURSOR.base], eax + + mov esi, [.src] + mov ebx, [.flags] + cmp bx, LOAD_INDIRECT + je .indirect + + movzx ecx, word [esi+10] + movzx edx, word [esi+12] + mov [edi+CURSOR.hot_x], ecx + mov [edi+CURSOR.hot_y], edx + + stdcall vesa_init_cursor, eax, esi + mov eax, [.hcursor] +.fail: + add esp, 12 + ret +.indirect: + shr ebx, 16 + movzx ecx, bh + movzx edx, bl + mov [eax+CURSOR.hot_x], ecx + mov [eax+CURSOR.hot_y], edx + + xchg edi, eax + mov ecx, 1024 + cld + rep movsd + add esp, 12 + ret + +align 4 +proc load_cursor stdcall, src:dword, flags:dword + locals + handle dd ? + endl + + xor eax, eax + mov [handle], eax + cmp word [flags], LOAD_FROM_FILE + jne @F + + stdcall load_file, [src] + test eax, eax + jz .exit + mov [src], eax +@@: + mov eax, [CURRENT_TASK] + shl eax, 5 + mov eax, [CURRENT_TASK+eax+4] + mov ebx, [src] + mov ecx, [flags] + call [create_cursor] ;eax, ebx, ecx + mov [handle], eax +.fail: + cmp word [flags], LOAD_FROM_FILE + jne .exit + stdcall kernel_free, [src] +.exit: + mov eax, [handle] + ret +endp + +align 4 +proc delete_cursor stdcall, hcursor:dword + locals + hsrv dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + endl + + mov esi, [hcursor] + cmp [esi+CURSOR.magic], 'CURS' + jne .fail +; cmp [esi+CURSOR.size], CURSOR_SIZE +; jne .fail + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov ebx, [CURRENT_TASK+ebx+4] + cmp ebx, [esi+CURSOR.pid] + jne .fail + + mov ebx, [CURRENT_TASK] + shl ebx, 8 + cmp esi, [ebx+SLOT_BASE+APPDATA.cursor] + jne @F + mov eax, [def_cursor] + mov [ebx+SLOT_BASE+APPDATA.cursor], eax +@@: + mov eax, [hcursor] + call [eax+APPOBJ.destroy] +.fail: + ret +endp + +; param +; eax= cursor + +align 4 +destroy_cursor: + + push eax + stdcall kernel_free, [eax+CURSOR.base] + pop eax + + call destroy_kernel_object + ret + +align 4 +proc init_cursors + cmp [SCR_MODE],word 0x13 + jbe .fail + + movzx eax, byte [ScreenBPP] + mov ebx, [BytesPerScanLine] + cmp eax, 32 + jne @F + sub ebx, 128 + jmp .init +@@: + cmp eax, 24 + jne .fail + sub ebx, 96 +.init: + mov [cur_def_interl], ebx + + stdcall load_driver, szHwMouse + mov [hw_cursor], eax + test eax, eax + jz .sw_mouse + + stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM + mov [def_cursor], eax + ret +.sw_mouse: + mov [create_cursor], vesa_cursor + + stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM + mov [def_cursor], eax + + mov ecx, [ScreenWidth] + mov edx, [ScreenHeight] + inc ecx + inc edx + mov [scr_width], ecx + mov [scr_height], edx + + movzx ebx, byte [ScreenBPP] + cmp ebx, 32 + jne @F + + mov dword [set_hw_cursor], cursor_32 + mov dword [hw_restore], restore_32 + ret +@@: + mov dword [set_hw_cursor], cursor_24 + mov dword [hw_restore], restore_24 + ret +.fail: + xor eax, eax + mov dword [set_hw_cursor], eax + mov dword [hw_restore], eax + ret +endp + +align 4 +proc restore_24 stdcall, x:dword, y:dword + locals + w dd ? + endl + + mov edi, [cur_saved_base] + mov edx, [cur_saved_h] + mov ebx, [cur_saved_interl] + + mov esi, cur_saved_data +@@: + mov ecx, [cur_saved_w] + lea ecx, [ecx+ecx*2] + rep movsb + add edi, ebx + dec edx + jnz @B + ret +endp + +align 4 +proc restore_32 stdcall, x:dword, y:dword + locals + w dd ? + endl + + mov edi, [cur_saved_base] + mov edx, [cur_saved_h] + mov ebx, [cur_saved_interl] + + mov esi, cur_saved_data +@@: + mov ecx, [cur_saved_w] + rep movsd + add edi, ebx + dec edx + jnz @B + ret +endp + +align 4 +proc cursor_24 stdcall, hcursor:dword, x:dword, y:dword + locals + w dd ? + h dd ? + st dd ? + _dx dd ? + _dy dd ? + endl + + mov esi, [hcursor] + mov ecx, [x] + mov eax, [y] + mov ebx, [BytesPerScanLine] + + xor edx, edx + sub ecx, [esi+CURSOR.hot_x] + mov [x], ecx + sets dl + dec edx + and ecx, edx ;clip x to 0<=x + mov edi, ecx + sub edi, [x] + mov [_dx], edi + + xor edx, edx + sub eax, [esi+CURSOR.hot_y] + mov [y], eax + sets dl + dec edx + and eax, edx ;clip y to 0<=y + mov edi, eax + sub edi, [y] + mov [_dy], edi + + mul ebx + lea esi, [ecx+ecx*2] + add esi, [LFBAddress] + add esi, eax + mov [cur_saved_base],esi + + mov edi, [scr_width] + mov edx, [scr_height] + mov eax, 32 + + sub edi, ecx + cmp edi, eax + jng @F + mov edi, eax +@@: + sub edi, [_dx] + + sub edx, [y] + cmp edx, eax + jng @F + mov edx, eax +@@: + sub edx, [_dy] + + mov [w], edi + mov [h], edx + mov [cur_saved_w], edi + mov [cur_saved_h], edx + + sub eax, edi + shl eax, 2 ;lea eax, [eax+eax*2] + lea edi, [edi+edi*2] + sub ebx, edi + mov [cur_saved_interl], ebx + + mov edi, cur_saved_data +@@: + mov ecx, [w] + lea ecx, [ecx+ecx*2] + rep movsb + add esi, ebx + dec edx + jnz @B + +;draw cursor + mov edx, eax + mov edi, [cur_saved_base] + mov eax, [_dy] + shl eax, 5 + add eax, [_dx] + shl eax, 2 + + mov esi, [hcursor] + mov esi, [esi+CURSOR.base] + add esi, eax +.row: + mov ecx, [w] +.pix: + lodsd + test eax, 0xFF000000 + jz @F + + mov word [edi], ax + shr eax, 16 + mov [edi+2],al +@@: + add edi, 3 + dec ecx + jnz .pix + + add esi, edx + add edi, ebx + dec [h] + jnz .row + ret +endp + +align 4 +proc cursor_32 stdcall, hcursor:dword, x:dword, y:dword + locals + w dd ? + h dd ? + st dd ? + _dx dd ? + _dy dd ? + endl + + mov esi, [hcursor] + mov ecx, [x] + mov eax, [y] + mov ebx, [BytesPerScanLine] + + xor edx, edx + sub ecx, [esi+CURSOR.hot_x] + mov [x], ecx + sets dl + dec edx + and ecx, edx ;clip x to 0<=x + mov edi, ecx + sub edi, [x] + mov [_dx], edi + + xor edx, edx + sub eax, [esi+CURSOR.hot_y] + mov [y], eax + sets dl + dec edx + and eax, edx ;clip y to 0<=y + mov edi, eax + sub edi, [y] + mov [_dy], edi + + mul ebx + lea esi, [eax+ecx*4] + add esi, [LFBAddress] + mov [cur_saved_base],esi + + mov edi, [scr_width] + mov edx, [scr_height] + mov eax, 32 + + sub edi, ecx + cmp edi, eax + jng @F + mov edi, eax +@@: + sub edi, [_dx] + + sub edx, [y] + cmp edx, eax + jng @F + mov edx, eax +@@: + sub edx, [_dy] + + mov [w], edi + mov [h], edx + mov [cur_saved_w], edi + mov [cur_saved_h], edx + + sub eax, edi + shl eax, 2 + shl edi, 2 + sub ebx, edi + mov [cur_saved_interl], ebx + + mov edi, cur_saved_data +@@: + mov ecx, [w] + rep movsd + add esi, ebx + dec edx + jnz @B + +;draw cursor + mov edx, eax + mov edi, [cur_saved_base] + mov eax, [_dy] + shl eax, 5 + add eax, [_dx] + shl eax, 2 + + mov esi, [hcursor] + mov esi, [esi+CURSOR.base] + add esi, eax +.row: + mov ecx, [w] +.pix: + lodsd + test eax, 0xFF000000 + jz @F + mov [edi], eax +@@: + add edi, 4 + dec ecx + jnz .pix + add esi, edx + add edi, ebx + dec [h] + jnz .row + ret +endp + +align 4 +def_arrow: + file 'arrow.cur' + diff --git a/kernel/branches/gfx_kernel/video/vesa12.inc b/kernel/branches/gfx_kernel/video/vesa12.inc index fd8aeef34..9dfdbd359 100644 --- a/kernel/branches/gfx_kernel/video/vesa12.inc +++ b/kernel/branches/gfx_kernel/video/vesa12.inc @@ -32,9 +32,9 @@ ; modified by Mario79 ;set_bank: ;cli -;cmp al,[0xfff2] +;cmp al,[BANK_RW] ;je retsb -;mov [0xfff2],al +;mov [BANK_RW],al ;push dx ;mov dx,3D8h ;out dx,al @@ -46,82 +46,82 @@ ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ; set_bank for S3 videocards, work on S3 ViRGE PCI (325) -; modified by kmeaw -set_bank: +; 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 +cli +cmp al,[BANK_RW] +je retsb +mov [BANK_RW],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 +inc dx +mov al, 0x48 out dx, al ;3d5 -? -dec dx -mov al, 0x31 +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 +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 +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: +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 @@ -132,9 +132,9 @@ ret ; ;set_bank: ;cli -;cmp al,[0xfff2] +;cmp al,[BANK_RW] ;je retsb -;mov [0xfff2],al +;mov [BANK_RW],al ;push ax ;push dx ;mov dx,3CEh @@ -160,9 +160,9 @@ ret ;set_bank: ; cli -; cmp al,[0xfff2] +; cmp al,[BANK_RW] ; je retsb -; mov [0xfff2],al +; mov [BANK_RW],al ; push ax ; push dx ; mov ah,al @@ -216,7 +216,7 @@ vesa12_drawbackground: push eax push ebx - mov esi,0x300000 + mov esi,IMG_BACKGROUND cmp [WinMapAddress-12],dword 1 ; tiled background jne no_vesa12_tiled_bgr @@ -247,7 +247,7 @@ vesa12_drawbackground: imul eax,dword [WinMapAddress-8] xor edx,edx - mov ecx,[0xfe00] + mov ecx,[ScreenWidth] inc ecx div ecx @@ -255,7 +255,7 @@ vesa12_drawbackground: mov eax,ebx imul eax,dword [WinMapAddress-4] xor edx,edx - mov ecx,[0xfe04] + mov ecx,[ScreenHeight] inc ecx div ecx mov ebx,eax @@ -278,7 +278,7 @@ vesa12_drawbackground: add esi,eax add esi,eax add esi,eax - add esi,0x300000 + add esi,IMG_BACKGROUND pop ebx pop eax @@ -288,20 +288,20 @@ vesa12_drawbackground: pusha mov esi,eax mov edi,ebx - mov eax,[0xfe00] + mov eax,[ScreenWidth] add eax,1 mul ebx add eax,esi add eax,WinMapAddress cmp [eax],byte 1 jnz v12nbgp - mov eax,[0xfe08] + mov eax,[BytesPerScanLine] mov ebx,edi mul ebx add eax,esi add eax,esi add eax,esi - cmp [0xFBF1],byte 24 + cmp [ScreenBPP],byte 24 jz v12bgl3 add eax,esi @@ -310,13 +310,13 @@ vesa12_drawbackground: push ebx push eax - sub eax,[0xfe80] + sub eax,[LFBAddress] shr eax,16 call set_bank pop eax and eax,65535 - add eax,0xa0000 + add eax,VGABasePtr pop ebx mov [eax],cx @@ -364,24 +364,24 @@ vesa12_drawbar: push ebx push ecx push edx - mov ecx,[0x3010] + mov ecx,[TASK_BASE] add eax,[ecx-twdw+WDATA.box.left] add ebx,[ecx-twdw+WDATA.box.top] push eax mov eax,ebx ; y - mov ebx,[0xfe08] + mov ebx,[BytesPerScanLine] mul ebx pop ecx add eax,ecx ; x add eax,ecx add eax,ecx - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start jz dbpi2412 add eax,ecx dbpi2412: - add eax,[0xfe80] + add eax,[LFBAddress] mov edi,eax ; x size @@ -390,7 +390,7 @@ vesa12_drawbar: mov ecx,eax add ecx,eax add ecx,eax - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size jz dbpi24312 add ecx,eax @@ -402,18 +402,18 @@ vesa12_drawbar: push eax push ecx - mov eax,[0x3010] - mov ecx,[eax+draw_data-0x3000+RECT.left] + mov eax,[TASK_BASE] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.left] cmp ecx,0 jnz dbcblimitlset12 - mov ecx,[eax+draw_data-0x3000+RECT.top] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.top] cmp ecx,0 jnz dbcblimitlset12 - mov ecx,[eax+draw_data-0x3000+RECT.right] - cmp ecx,[0xfe00] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] + cmp ecx,[ScreenWidth] jnz dbcblimitlset12 - mov ecx,[eax+draw_data-0x3000+RECT.bottom] - cmp ecx,[0xfe04] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] + cmp ecx,[ScreenHeight] jnz dbcblimitlset12 pop ecx pop eax @@ -428,7 +428,7 @@ vesa12_drawbar: dbcblimitlno12: - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? jz dbpi24bit12 jmp dbpi32bit12 @@ -458,11 +458,11 @@ dbpi24bit12: xor edx,edx mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] mov ebx,3 div ebx add eax,WinMapAddress - mov ebx,[0x3000] + mov ebx,[CURRENT_TASK] cld dbnp2412: @@ -481,11 +481,11 @@ dbpi24bit12: push edi mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] shr eax,16 call set_bank and edi,0xffff - add edi,0xa0000 + add edi,VGABasePtr mov eax,[esp+8+3*4+16+4+4] stosw shr eax,16 @@ -523,7 +523,7 @@ dbpi24bit12: pop ecx pop edi pop ebx - add edi,[0xfe08] + add edi,[BytesPerScanLine] dec ebx jz dbnonewpi12 jmp dbnewpi12 @@ -550,10 +550,10 @@ dbpi24bit12: push ecx mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] shr eax,2 add eax,WinMapAddress - mov ebx,[0x3000] + mov ebx,[CURRENT_TASK] cld dbnp3212: @@ -572,11 +572,11 @@ dbpi24bit12: push edi mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] shr eax,16 call set_bank and edi,0xffff - add edi,0xa0000 + add edi,VGABasePtr mov eax,[esp+8+3*4+16+4+4] stosw shr eax,16 @@ -615,7 +615,7 @@ dbpi24bit12: pop ecx pop edi pop ebx - add edi,[0xfe08] + add edi,[BytesPerScanLine] dec ebx jz nodbnewpi3212 jmp dbnewpi3212 @@ -631,14 +631,14 @@ Vesa12_putpixel24: mov edi,eax ; x mov eax,ebx ; y lea edi,[edi+edi*2] - mov ebx,[0xfe08] + mov ebx,[BytesPerScanLine] mul ebx add edi,eax mov eax,edi shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov eax,[esp+28] stosw shr eax,16 @@ -653,14 +653,14 @@ Vesa12_putpixel32: mov edi,eax ; x mov eax,ebx ; y shl edi,2 - mov ebx,[0xfe08] + mov ebx,[BytesPerScanLine] mul ebx add edi,eax mov eax,edi shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov ecx,[esp+28] mov [edi],ecx sti @@ -672,14 +672,14 @@ Vesa12_getpixel24: mov edi,eax ; x mov eax,ebx ; y lea edi,[edi+edi*2] - mov ebx,[0xfe08] + mov ebx,[BytesPerScanLine] mul ebx add edi,eax mov eax,edi shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov ecx,[edi] and ecx,255*256*256+255*256+255 sti @@ -691,7 +691,7 @@ Vesa12_getpixel32: mov edi,eax ; x mov eax,ebx ; y shl edi,2 - mov ebx,[0xfe08] + mov ebx,[BytesPerScanLine] xor edx,edx mul ebx add edi,eax @@ -699,7 +699,7 @@ Vesa12_getpixel32: shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov ecx,[edi] and ecx,255*256*256+255*256+255 sti @@ -709,6 +709,12 @@ Vesa12_getpixel32: vesa12_putimage: +; ebx = pointer to image +; ecx = size [x|y] +; edx = coordinates [x|y] +; ebp = pointer to 'get' function +; esi = pointer to 'init' function +; edi = parameter for 'get' function ; mov ebx,image ; mov ecx,320*65536+240 @@ -725,137 +731,108 @@ vesa12_putimage: push edx movzx eax,word [esp+2] movzx ebx,word [esp+0] - mov ecx,[0x3010] + mov ecx,[TASK_BASE] 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 + mul dword [BytesPerScanLine] pop ecx add eax,ecx ; x add eax,ecx add eax,ecx - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start jz pi2412 add eax,ecx pi2412: - add eax,[0xfe80] + add eax,[LFBAddress] 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: + movzx ecx,word [esp+6] 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 + mov eax,[TASK_BASE] + cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0 jnz dbcblimitlset212 - mov ecx,[eax+draw_data-0x3000+RECT.top] - cmp ecx,0 + cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0 jnz dbcblimitlset212 - mov ecx,[eax+draw_data-0x3000+RECT.right] - cmp ecx,[0xfe00] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] + cmp ecx,[ScreenWidth] jnz dbcblimitlset212 - mov ecx,[eax+draw_data-0x3000+RECT.bottom] - cmp ecx,[0xfe04] + mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] + cmp ecx,[ScreenHeight] jnz dbcblimitlset212 pop ecx - pop eax - push dword 0 + push 0 jmp dbcblimitlno212 dbcblimitlset212: pop ecx - pop eax - push dword 1 + push 1 dbcblimitlno212: - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - jz pi24bit12 - jmp pi32bit12 + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? + jnz 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 edx,edi + sub edx,[LFBAddress] mov ebx,3 div ebx - add eax,WinMapAddress - mov ebx,[0x3000] - mov bh,[esp+4*4] + add edx,WinMapAddress + mov ebx,[CURRENT_TASK] + mov bh,[esp+4*3] np2412: - cmp bl,[eax] + cmp bl,[edx] jnz imp24no12 - mov edx,[esi] - cmp bh,0 - jz imp24yes12 +; mov eax,[esi] + push dword [esp+4*3+20] + call ebp +; cmp bh,0 +; jz imp24yes12 ; call dbcplimit ; jnz imp24no12 imp24yes12: - push eax push edi + push eax mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] 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 + and edi,0xffff + add edi,VGABasePtr + mov [edi],ax + shr eax,16 + mov [edi+2],al + pop edi imp24no12: - inc eax - add esi,3 + inc edx +; add esi,3 add edi,3 dec ecx jnz np2412 @@ -864,73 +841,64 @@ vesa12_putimage: 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 + add edi,[BytesPerScanLine] + add esi,[esp+32] dec ebx - jz nonewpi12 - jmp newpi12 + jnz newpi12 nonewpi12: - add esp,7*4 - mov eax,0 - ret + pop eax edx ecx ebx eax edi esi + xor eax, eax + 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] + mov edx,edi + sub edx,[LFBAddress] + shr edx,2 + add edx,WinMapAddress + mov ebx,[CURRENT_TASK] + mov bh,[esp+4*3] np3212: - cmp bl,[eax] + cmp bl,[edx] jnz imp32no12 - mov edx,[esi] - cmp bh,0 - jz imp32yes12 +; mov eax,[esi] + push dword [esp+4*3+20] + call ebp +; cmp bh,0 +; jz imp32yes12 ; call dbcplimit ; jnz imp32no12 imp32yes12: - push eax push edi + push eax mov eax,edi - sub eax,[0xfe80] + sub eax,[LFBAddress] shr eax,16 call set_bank - and edi,0xffff - add edi,0xa0000 - mov [edi],edx - sti - pop edi pop eax + and edi,0xffff + mov [edi+VGABasePtr],eax + pop edi imp32no12: - inc eax - add esi,3 + inc edx +; add esi,3 add edi,4 dec ecx jnz np3212 @@ -939,28 +907,23 @@ vesa12_putimage: 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 + add edi,[BytesPerScanLine] dec ebx - jz nonewpi3212 - jmp newpi3212 + jnz newpi3212 nonewpi3212: - add esp,7*4 - mov eax,0 - ret + pop eax edx ecx ebx eax edi esi + xor eax, eax + ret vesa12_read_screen_pixel: and eax,0x3FFFFF - cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? + cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? jz v12rsp24 mov edi,eax shl edi,2 @@ -968,7 +931,7 @@ vesa12_read_screen_pixel: shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov eax,[edi] and eax,0x00ffffff ret @@ -979,7 +942,7 @@ vesa12_read_screen_pixel: shr eax,16 call set_bank and edi,65535 - add edi,0xa0000 + add edi,VGABasePtr mov eax,[edi] and eax,0x00ffffff ret diff --git a/kernel/branches/gfx_kernel/video/vesa20.inc b/kernel/branches/gfx_kernel/video/vesa20.inc index df83a5ffd..a4796af55 100644 --- a/kernel/branches/gfx_kernel/video/vesa20.inc +++ b/kernel/branches/gfx_kernel/video/vesa20.inc @@ -17,12 +17,12 @@ ; 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 +;ScreenWidth equ 0xfe00 +;ScreenHeight equ 0xfe04 +;BytesPerScanLine equ 0xfe08 +;LFBAddress equ 0xfe80 +;ScreenBPP equ 0xfbf1 +;WinMapAddress equ 0x460000 @@ -76,29 +76,34 @@ virtual at esp .abs_cx dd ? .abs_cy dd ? .line_increment dd ? - .source_bpp dd ? .winmap_newline dd ? .screen_newline dd ? - .stack_data = 4*13 + .stack_data = 4*12 + .edi dd ? + .esi dd ? + .ebp dd ? + .esp dd ? + .ebx dd ? + .edx dd ? + .ecx dd ? + .eax dd ? + .ret_addr dd ? + .arg_0 dd ? end virtual -align 4 +align 16 ; ebx = pointer ; ecx = size [x|y] ; edx = coordinates [x|y] +; ebp = pointer to 'get' function +; esi = pointer to 'init' function +; edi = parameter for 'get' function 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 @@ -117,7 +122,7 @@ vesa20_putimage: mov [putimg.image_cy], edx ; calculate absolute (i.e. screen) coordinates - mov eax, [0x3010] + mov eax, [TASK_BASE] mov ebx, [eax-twdw + WDATA.box.left] add ebx, [putimg.image_cx] mov [putimg.abs_cx], ebx @@ -164,7 +169,9 @@ vesa20_putimage: mov eax, [putimg.image_sx] sub eax, [putimg.real_sx] ;; imul eax, [putimg.source_bpp] - lea eax, [eax + eax * 2] +; lea eax, [eax + eax * 2] + call esi + add eax, [putimg.arg_0] mov [putimg.line_increment], eax ; winmap new line increment @@ -183,7 +190,7 @@ vesa20_putimage: mov [putimg.screen_newline], eax ; pointer to image - mov ecx, [putimg.pti] + mov esi, [putimg.pti] ; pointer to screen mov edx, [putimg.abs_cy] @@ -204,7 +211,7 @@ vesa20_putimage: xchg eax, ebp ; get process number - mov ebx, [0x3000] + mov ebx, [CURRENT_TASK] cmp byte [ScreenBPP], 32 je put_image_end_32 @@ -213,29 +220,32 @@ vesa20_putimage: mov edi, [putimg.real_sy] align 4 .new_line: - mov esi, [putimg.real_sx] + mov ecx, [putimg.real_sx] ; push ebp edx align 4 .new_x: + push [putimg.edi] + mov eax, [putimg.ebp+4] + call eax cmp [ebp], bl jne .skip - mov eax, [ecx] ; ecx = RRBBGGRR +; mov eax, [esi] ; eax = RRBBGGRR mov [edx], ax shr eax, 16 mov [edx+2], al .skip: - add ecx, 3 ;[putimg.source_bpp] +; add esi, 3 ;[putimg.source_bpp] add edx, 3 inc ebp - dec esi + dec ecx jnz .new_x ; pop edx ebp - add ecx, [putimg.line_increment] + add esi, [putimg.line_increment] add edx, [putimg.screen_newline] ;[BytesPerScanLine] add ebp, [putimg.winmap_newline] ;[ScreenWidth] ;inc ebp @@ -251,27 +261,30 @@ put_image_end_32: mov edi, [putimg.real_sy] align 4 .new_line: - mov esi, [putimg.real_sx] + mov ecx, [putimg.real_sx] ; push ebp edx align 4 .new_x: + push [putimg.edi] + mov eax, [putimg.ebp+4] + call eax cmp [ebp], bl jne .skip - mov eax, [ecx] ; ecx = RRBBGGRR +; mov eax, [esi] ; ecx = RRBBGGRR mov [edx], eax .skip: - add ecx, [putimg.source_bpp] +; add esi, [putimg.source_bpp] add edx, 4 inc ebp - dec esi + dec ecx jnz .new_x ; pop edx ebp - add ecx, [putimg.line_increment] + add esi, [putimg.line_increment] add edx, [putimg.screen_newline] ;[BytesPerScanLine] add ebp, [putimg.winmap_newline] ;[ScreenWidth] ;inc ebp @@ -281,7 +294,7 @@ put_image_end_32: .finish: add esp, putimg.stack_data popad - call VGA__putimage + call VGA__putimage mov [EGA_counter],1 ret @@ -315,12 +328,12 @@ __sys_putpixel: ; check if negation test ecx,0x01000000 jz .noneg - call __sys_getpixel + call getpixel not ecx mov [esp+32-8],ecx .noneg: ; OK to set pixel - call dword [0xe020] ; call the real put_pixel function + call dword [PUTPIXEL] ; call the real put_pixel function .exit: popad @@ -588,7 +601,7 @@ align 4 ; edx ye ; edi color vesa20_drawbar: - + pushad call [disable_mouse] @@ -606,7 +619,7 @@ vesa20_drawbar: mov [drbar.bar_cx], eax mov [drbar.bar_cy], ebx - mov edi, [0x3010] + mov edi, [TASK_BASE] add eax, [edi-twdw + WDATA.box.left] ; win_cx add ebx, [edi-twdw + WDATA.box.top] ; win_cy mov [drbar.abs_cx], eax @@ -625,7 +638,7 @@ vesa20_drawbar: popad xor eax, eax inc eax - + ret @@: cmp ebx, [drbar.bar_sx] @@ -645,7 +658,7 @@ vesa20_drawbar: popad xor eax, eax inc eax - + ret @@: cmp ebx, [drbar.bar_sy] @@ -688,7 +701,7 @@ vesa20_drawbar: xchg eax, ebp ; get process number - mov ebx, [0x3000] + mov ebx, [CURRENT_TASK] cmp byte [ScreenBPP], 24 jne draw_bar_end_32 @@ -917,7 +930,7 @@ vesa20_drawbackground_tiled: mov ebx,[esp+8] ; ebx:=B*3 mul ebx ; add esi,eax ; - mov eax,[esi+0x300000] + mov eax,[esi+IMG_BACKGROUND] and eax,0xffffff xchg edi, ebp @@ -1032,45 +1045,110 @@ vesa20_drawbackground_stretch: call calculate_edi - sdp3: ; MAIN LOOP +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 +mov cx,dx +lea esi,[eax+eax*2] +mov eax,dword [WinMapAddress-4] +imul eax, [esp+0] ;0 +xor edx,edx +mov ebx,[ScreenHeight] +div ebx +shl ecx,16 +mov cx,dx +imul eax, [esp+8] ;8 +add esi,eax +mov eax,[esi+IMG_BACKGROUND] +push eax +ror ecx,16 +xor eax,eax +mov ax,cx +shl eax,1 ; умножение на 2 +lea eax,[eax+eax*4] ; умножение на 5 +xor edx,edx +mov ebx,[ScreenWidth] +div ebx +cmp eax,5 +pop eax +jb @f +mov ebx,[esi+IMG_BACKGROUND+3] +call overlapping_of_points +@@: +push eax +ror ecx,16 +xor eax,eax +mov ax,cx +shl eax,1 ; умножение на 2 +lea eax,[eax+eax*4] ; умножение на +xor edx,edx +mov ebx,[ScreenHeight] +div ebx +cmp eax,5 +pop eax +jb @f +mov ebx,[display_data-8] +shl ebx,1 +add ebx,[display_data-8] +add ebx,IMG_BACKGROUND +add ebx,esi +mov ebx,[ebx] +call overlapping_of_points +@@: +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 - 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 +overlapping_of_points: +push ecx edi +mov ecx,eax +mov edx,ebx +xor eax,eax +mov al,cl +xor ebx,ebx +mov bl,dl +add eax,ebx +rcr eax,1 +xor edi,edi +mov di,ax +xor eax,eax +mov al,ch +xor ebx,ebx +mov bl,dh +add eax,ebx +rcr eax,1 +ror edi,8 +add edi,eax +ror ecx,8 +ror edx,8 +xor eax,eax +mov al,ch +xor ebx,ebx +mov bl,dh +add eax,ebx +rcr eax,1 +ror edi,8 +add eax,edi +ror eax,16 +pop edi ecx +ret snbgp: add ebp,3 ; +3 diff --git a/kernel/branches/gfx_kernel/video/vga.inc b/kernel/branches/gfx_kernel/video/vga.inc index 3de0d0efb..9fe840db9 100644 --- a/kernel/branches/gfx_kernel/video/vga.inc +++ b/kernel/branches/gfx_kernel/video/vga.inc @@ -53,8 +53,8 @@ paletteVGA: add ah,1 loop palvganew ; mov dx, 3ceh -; mov ax, 0005h -; out dx, ax +; mov ax, 0005h +; out dx, ax ret palette320x200: @@ -114,7 +114,7 @@ uglobal novesachecksum dd 0x0 EGA_counter db 0 VGA_drawing_screen db 0 - VGA_8_pixels: + VGA_8_pixels: rb 16 temp: .cx dd 0 @@ -122,14 +122,14 @@ endg checkVga_N13: - cmp [0xfe0c],dword 0x13 + cmp [SCR_MODE],dword 0x13 jne @f ; cnvl: pushad cmp [EGA_counter],1 je novesal - mov ecx,[0xfb0a] + mov ecx,[MOUSE_X] cmp ecx,[novesachecksum] jne novesal popad @@ -151,7 +151,7 @@ checkVga_N13: sub eax,100 imul eax,640*4 add ecx,eax - movzx eax,word [0xfb0a] + movzx eax,word [MOUSE_X] cmp eax,160 jge m13l1 mov eax,160 @@ -163,9 +163,9 @@ checkVga_N13: sub eax,160 shl eax,2 add ecx,eax - mov esi,[0xfe80] + mov esi,[LFBAddress] add esi,ecx - mov edi,0xa0000 + mov edi,VGABasePtr mov edx,200 mov ecx,320 cld @@ -196,17 +196,17 @@ checkVga_N13: ret VGA_drawbackground: -; draw all - cmp [0xfe0c],dword 0x12 +; draw all + cmp [SCR_MODE],dword 0x12 jne .end pushad - mov esi,[0xfe80] - mov edi,0xa0000 + mov esi,[LFBAddress] + mov edi,VGABasePtr mov ebx,640/32 ; 640*480/(8*4) mov edx,480 @@: push ebx edx esi edi - shl edx,9 + shl edx,9 lea edx,[edx+edx*4] add esi,edx shr edx,5 @@ -224,7 +224,7 @@ VGA_draw_long_line: mov dx,3ceh mov ax,0ff08h cli - out dx, ax + out dx, ax mov ax,0005h out dx, ax m12pix: @@ -318,15 +318,15 @@ VGA_putpixel: ; ebx = y mov ecx,eax mov eax, [esp+32-8+4] ; color - shl ebx,9 + 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 + add edi, [LFBAddress] ; + 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 + add edi, VGABasePtr ; address of pixel in VGA area and ecx,0x07 ; bit no. (modulo 8) pushfd ; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) @@ -346,7 +346,7 @@ VGA_putpixel: cmp ah,170 jbe .p13red or dl,0x08 -.p13red: +.p13red: shr eax,8 cmp ah,85 jbe .p13cont @@ -369,11 +369,11 @@ VGA_putpixel: popfd ;.end: ret - + VGA__putimage: ; ecx = size [x|y] ; edx = coordinates [x|y] - cmp [0xfe0c],dword 0x12 + cmp [SCR_MODE],dword 0x12 jne @f pushad rol edx,16 @@ -393,7 +393,7 @@ VGA_draw_bar: ; ebx cy ; ecx xe ; edx ye - cmp [0xfe0c],dword 0x12 + cmp [SCR_MODE],dword 0x12 jne @f pushad sub ecx,eax @@ -409,19 +409,19 @@ VGA_draw_bar: VGA_draw_bar_1: mov [temp.cx],eax - mov eax, [0x3010] + mov eax, [TASK_BASE] add ebx, [eax-twdw + 4] mov eax, [eax-twdw + 0] add eax, [temp.cx] and eax,0xfff8 - shl ebx,9 + 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 + add esi, [LFBAddress] ; + LFB address shr ebx,5 ; change BytesPerPixel to 1/8 mov edi,ebx - add edi, 0x0a0000 ; address of pixel in VGA area + add edi, VGABasePtr ; address of pixel in VGA area mov ebx,ecx shr ebx,5 inc ebx @@ -434,7 +434,7 @@ VGA_draw_bar_1: VGA_draw_long_line_1: push ebx edx esi edi - shl edx,9 + shl edx,9 lea edx,[edx+edx*4] add esi,edx shr edx,5 diff --git a/kernel/branches/gfx_kernel/vmode/clipping.asm b/kernel/branches/gfx_kernel/vmode/clipping.asm index c184abddd..c78adb36a 100755 --- a/kernel/branches/gfx_kernel/vmode/clipping.asm +++ b/kernel/branches/gfx_kernel/vmode/clipping.asm @@ -44,7 +44,7 @@ EQUAL_TOP = 00001000b func calc_clipping_rects begin mov [cnt],0 - movzx ebp,word[0x3000] + movzx ebp,word[CURRENT_TASK] shl ebp,5 cmp ebp,0x20 @@ -96,7 +96,7 @@ comment ^ inc eax add [rct.bottom],eax ^ - movzx ecx,word[0x00003004] ; number of processes + movzx ecx,word[TASK_COUNT] ; number of processes jif ecx,be,1,.exit ; calculate clipping rectangles @@ -104,10 +104,10 @@ comment ^ mov esi,1 ; go forward through all windows .next_window: - movzx edi,word[0x00003000] ; calling process number + movzx edi,word[CURRENT_TASK] ; calling process number - mov ax,[0x0000C000+esi*2] - jif ax,be,[0x0000C000+edi*2],.end_window.2 + mov ax,[WIN_STACK+esi*2] + jif ax,be,[WIN_STACK+edi*2],.end_window.2 mov ebp,[cnt] shl ebp,4 ; ebp *= SR @@ -266,7 +266,7 @@ rc_left equ edx pop esi; ecx .end_window.2: inc esi - jif esi,be,[0x00003004],.next_window + jif esi,be,[TASK_COUNT],.next_window ; dec ecx ; jnz .next_window diff --git a/kernel/branches/gfx_kernel/vmode/norm_04.inc b/kernel/branches/gfx_kernel/vmode/norm_04.inc index 5305913ff..5da1c3922 100755 --- a/kernel/branches/gfx_kernel/vmode/norm_04.inc +++ b/kernel/branches/gfx_kernel/vmode/norm_04.inc @@ -2,7 +2,7 @@ func color_24_to_4_bits begin push edx mov dl,0 - cmp al,85 ; blue + cmp al,85 ; blue jbe .p13green or dl,0x01 cmp al,170 @@ -10,14 +10,14 @@ begin or dl,0x08 .p13green: shr eax,8 - cmp al,85 ; green + cmp al,85 ; green jbe .p13red or dl,0x02 cmp al,170 jbe .p13red or dl,0x08 .p13red: - cmp ah,85 ; red + cmp ah,85 ; red jbe .p13cont or dl,0x04 cmp ah,170 @@ -56,19 +56,19 @@ begin mov edi,eax pop eax - mov ebp,[0x3010] - movsx esi,word[ebp-0x3000+0] + mov ebp,[TASK_BASE] + movsx esi,word[ebp-CURRENT_TASK+0] add eax,esi add ecx,esi - movsx esi,word[ebp-0x3000+4] + movsx esi,word[ebp-CURRENT_TASK+4] add ebx,esi add edx,esi -; add eax,[ebp-0x3000+0] -; add ebx,[ebp-0x3000+4] -; add ecx,[ebp-0x3000+0] -; add edx,[ebp-0x3000+4] +; add eax,[ebp-CURRENT_TASK+0] +; add ebx,[ebp-CURRENT_TASK+4] +; add ecx,[ebp-CURRENT_TASK+0] +; add edx,[ebp-CURRENT_TASK+4] - mov esi,[0x00003000] + mov esi,[CURRENT_TASK] mov esi,[CLIP_RECTS+esi*4] mov ebp,[esi] or ebp,ebp @@ -89,10 +89,10 @@ begin mov edx,[rr.bottom] @@: call is_intersect_rc jc .put - cmp [mouse_invisible],0 - jne .put + cmp byte[MOUSE_VISIBLE],0 + je .put call [SF.draw_mouse_under] - mov [mouse_invisible],1 + mov byte[MOUSE_VISIBLE],0 .put: sub edx,ebx push edx edi ebx eax mov edi,ebx @@ -101,7 +101,7 @@ begin add edi,ebx shr eax,3 add edi,eax - add edi,0x000A0000 + add edi,VGABasePtr pop eax ebx mov ebx,eax @@ -114,102 +114,102 @@ begin ;ebx = x ; dx = Graphix Controller - mov cl,bl ; Get StartBit - and ecx,07h + mov cl,bl ; Get StartBit + and ecx,07h - mov eax,esi - add eax,ecx - cmp eax,8 ; Is x+Length