Updated gfx_kernel to revision #383

git-svn-id: svn://kolibrios.org@384 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Mihail Semenyako (mike.dld) 2007-03-03 17:43:42 +00:00
parent c47aceb21f
commit 8a1c0404e2
112 changed files with 29643 additions and 10227 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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}

View File

@ -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

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
; Full ASCII code font
; only õ and ä added
; Kaitz
ET_FNT:
fontfile file "ETFONT.FNT"

View File

@ -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

View File

@ -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:

View File

@ -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 "<EFBFBD>¥§®¯ á­®¥ ¢ëª«î祭¨¥ ª®¬¯ìîâ¥à  ¨«¨ "
db ' '
@ -515,6 +520,14 @@ shutdowntext:
db '2) APM - ¢ëª«î祭¨¥ ¯¨â ­¨ï '
db '3) <20>¥à¥§ £à㧪  á¨á⥬ë '
db '4) <20>¥áâ àâ ï¤à  ¨§ Ž‡“ '
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'

View File

@ -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

View File

@ -1,5 +0,0 @@
@erase lang.inc
@echo lang fix en >lang.inc
@fasm kernel.asm kernel.mnt
@erase lang.inc
@pause

View File

@ -1,5 +0,0 @@
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm kernel.asm kernel.mnt
@erase lang.inc
@pause

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<<I))
bt [mst.treemap], ecx
jc .tree
; ms.treemap |= 1<<I;
bts [mst.treemap], ecx
; *H = X;
mov dword [edx], esi
jmp .done
.tree:
; T = *H;
mov edx, [edx]
; K = S << leftshift_for_tree_index(I);
mov eax, ecx
shr eax, 1
sub ecx, 31
mov edi, 37
sub edi, eax
neg ecx
sbb ecx, ecx
and ecx, edi
mov eax, ebx
shl eax, cl ;eax= K
jmp .loop
.not_eq_size:
; C = &(T->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<<idx) & ms.treemap;
; if (leftbits != 0)
or edx, -1
shl edx, cl
and edx, [mst.treemap]
jz @F
bsf eax, edx
; t = ms.treebins[i];
mov eax, [mst.treebins+eax*4]
@@:
; while (t != 0)
test eax, eax
jz .l5
.l4:
; trem = (t->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

View File

@ -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

View File

@ -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 (0<eax<=4096)
;;Result:
;; eax - linear address
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc
MEM_Alloc:
;find chain
test eax,eax
jng MEM_Alloc_Wrong_Size
cmp eax,4096
jg MEM_Alloc_Wrong_Size
push ebx
push ecx
push edx
push esi
dec eax
shr eax,4
xor edx,edx
MEM_Alloc_Find_Size:
add edx,4
shr eax,1
jnz MEM_Alloc_Find_Size
MEM_Alloc_Size_Found:
mov ecx,edx
shr ecx,2
add ecx,4
mov eax,1
shl eax,cl
mov esi,eax
;esi - block size
;edx - offset
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Find_Heap:
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [eax+edx],0
jnz MEM_Alloc_Use_Existing
sub ecx,16
jns MEM_Alloc_Find_Heap
;create new bucket page
call MEM_Alloc_Page_Linear
call MEM_Get_Heap_Number_Linear
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov [ecx+edx],eax
lea ebx,[eax+4096]
MEM_Alloc_List_loop:
mov [eax],eax
mov [eax+4],eax
add [eax],esi
sub [eax+4],esi
add eax,esi
cmp eax,ebx
jnz MEM_Alloc_List_loop
sub ebx,esi
mov dword [ebx],0
sub eax,4096
mov dword [eax+4],0
mov eax,ecx
MEM_Alloc_Use_Existing:
mov ebx,eax
mov eax,[eax+edx]
mov ecx,[eax]
mov [ebx+edx],ecx
test ecx,ecx
jz MEM_Alloc_Became_Empty
mov dword [ecx+4],0
MEM_Alloc_Became_Empty:
mov ecx,eax
sub ecx,ebx
shr ecx,10
and ecx,0xFFFFFFFC
inc byte [ebx+.range_info+ecx+2]
shr edx,2
add edx,128
dec edx
mov [ebx+.range_info+ecx+3],dl
MEM_Alloc_ret:
call MEM_Heap_UnLock
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Alloc_Wrong_Size:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free
;;Parameters:
;; eax - linear address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free
MEM_Free:
test eax,eax
jz MEM_Free_Zero
push ebx
push ecx
push edx
push esi
push edi
push ebp
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Free_ret
mov edx,eax
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub edx,ecx
shr edx,10
and edx,0xFFFFFFFC
mov ebx,[ecx+.range_info+edx]
mov esi,ebx
shr esi,24
sub esi,128
mov edi,[ecx+4+4*esi]
mov [eax],edi
mov dword [eax+4],0
test edi,edi
jz MEM_Free_Empty_List
mov [edi+4],eax
MEM_Free_Empty_List:
mov [ecx+4+4*esi],eax
sub ebx,0x10000
mov [ecx+.range_info+edx],ebx
test ebx,0xFF0000
jnz MEM_Free_ret
;delete empty blocks on the page
lea edx,[esi+5]
and eax,0xFFFFF000
mov edi,eax
mov eax,1
xchg ecx,edx
shl eax,cl
mov ecx,edx
mov edx,eax
;edx - size of block
;edi - start of page
mov eax,edi
lea ebx,[eax+4096]
MEM_Free_Block_loop:
cmp dword [eax+4],0
jnz MEM_Free_Block_Not_First
mov ebp,dword [eax]
mov [ecx+4+4*esi],ebp
test ebp,ebp
jz MEM_Free_Block_Last
mov dword [ebp+4],0
MEM_Free_Block_Last:
jmp MEM_Free_Block_loop_end
MEM_Free_Block_Not_First:
mov ebp,dword [eax]
push ebp
mov ebp,dword [eax+4]
pop dword [ebp]
mov ebp,dword [eax]
test ebp,ebp
jz MEM_Free_Block_loop_end
push dword [eax+4]
pop dword [ebp+4]
; jmp MEM_Free_Block_loop_end
MEM_Free_Block_loop_end:
add eax,edx
cmp eax,ebx
jnz MEM_Free_Block_loop
mov eax,edi
call MEM_Free_Page_Linear
MEM_Free_ret:
call MEM_Heap_UnLock
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Free_Zero:
inc eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference
;; eax - physical address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference
MEM_Add_Reference:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number
test eax,eax
jz MEM_Add_Reference_ret
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_failed
inc dword [ecx+eax+.range_info]
MEM_Add_Reference_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_failed:
xor eax,eax
jmp MEM_Add_Reference_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference_Linear
;; eax - linear address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference_Linear
MEM_Add_Reference_Linear:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Add_Reference_Linear_ret
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub eax,ecx
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_Linear_failed
inc dword [ecx+eax+.range_info]
mov eax,1
MEM_Add_Reference_Linear_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_Linear_failed:
xor eax,eax
jmp MEM_Add_Reference_Linear_ret
end if
end if ;memmanager.inc

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <diamond>
dd undefined_syscall ; 30-reserved
; dd syscall_starthdapp ; 31-StartHdApp - obsolete <diamond>
dd undefined_syscall ; 31-reserved
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
; dd read_floppy_file ; 34-ReadFloppyDrive - obsolete <diamond>
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 <diamond>
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

File diff suppressed because it is too large Load Diff

View File

@ -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
.............
.............

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 ?
}

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if (flag and 10000b) | (parmbytes=0)
retn
else
retn parmbytes
end if }
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ 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:<regs>
\\\{ 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 }

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <eax,ebx,ecx,edx,edi,ebp,esp>
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 <ebx,ecx,edx,esi,edi,ebp,esp>
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 <eax,ebx,ecx,edx,esi,edi,ebp,esp>
if ~_hex eq eax
mov eax,_hex
end if
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
if ~_hex eq ax
movzx eax,_hex
end if
shl eax,16
if (_num eq)
mov edx,4
end if
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
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
}

View File

@ -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}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
; <ecx> = 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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -1 +0,0 @@
lang fix en

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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
ret

View File

@ -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,<params \} }
prologue@proc equ prologuedef
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
epilogue@proc equ epiloguedef
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if (flag and 10000b) | (parmbytes=0)
retn
else
retn parmbytes
end if }
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ 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:<regs>
\\\{ 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 }

View File

@ -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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -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'

View File

@ -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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More