Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 2381 → Rev 2382

/kernel/branches/net/blkdev/cd_drv.inc
30,57 → 30,57
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
pushad
mov eax,[CDSectorAddress]
mov ebx,[CDDataBuf_pointer]
call cd_calculate_cache
xor edi,edi
add esi,8
inc edi
pushad
mov eax, [CDSectorAddress]
mov ebx, [CDDataBuf_pointer]
call cd_calculate_cache
xor edi, edi
add esi, 8
inc edi
.hdreadcache:
; cmp dword [esi+4],0 ; empty
; je .nohdcache
cmp [esi],eax ; correct sector
je .yeshdcache
cmp [esi], eax ; correct sector
je .yeshdcache
.nohdcache:
add esi,8
inc edi
dec ecx
jnz .hdreadcache
call find_empty_slot_CD_cache ; ret in edi
add esi, 8
inc edi
dec ecx
jnz .hdreadcache
call find_empty_slot_CD_cache ; ret in edi
 
push edi
push eax
call cd_calculate_cache_2
shl edi,11
add edi,eax
mov [CDDataBuf_pointer],edi
pop eax
pop edi
push edi
push eax
call cd_calculate_cache_2
shl edi, 11
add edi, eax
mov [CDDataBuf_pointer], edi
pop eax
pop edi
 
call ReadCDWRetr_1
cmp [DevErrorCode],0
jne .exit
call ReadCDWRetr_1
cmp [DevErrorCode], 0
jne .exit
 
mov [CDDataBuf_pointer],ebx
call cd_calculate_cache_1
lea esi,[edi*8+esi]
mov [esi],eax ; sector number
mov [CDDataBuf_pointer], ebx
call cd_calculate_cache_1
lea esi, [edi*8+esi]
mov [esi], eax ; sector number
; mov dword [esi+4],1 ; hd read - mark as same as in hd
.yeshdcache:
mov esi,edi
shl esi,11 ;9
push eax
call cd_calculate_cache_2
add esi,eax
pop eax
mov edi,ebx ;[CDDataBuf_pointer]
mov ecx,512 ;/4
cld
rep movsd ; move data
mov esi, edi
shl esi, 11;9
push eax
call cd_calculate_cache_2
add esi, eax
pop eax
mov edi, ebx;[CDDataBuf_pointer]
mov ecx, 512;/4
cld
rep movsd ; move data
.exit:
popad
ret
popad
ret
 
ReadCDWRetr_1:
pushad
87,7 → 87,7
 
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
mov ECX,MaxRetr
mov ECX, MaxRetr
@@NextRetr:
; Ïîäàòü êîìàíäó
;*************************************************
102,50 → 102,50
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
;*************************************************
;ReadCD:
push ecx
push ecx
; pusha
; Çàäàòü ðàçìåð ñåêòîðà
; mov [CDBlockSize],2048 ;2352
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
; ñåêòîðà äàííûõ
; Çàäàòü êîä êîìàíäû Read CD
mov [PacketCommand],byte 0x28 ;0xBE
mov [PacketCommand], byte 0x28;0xBE
; Çàäàòü àäðåñ ñåêòîðà
mov AX,word [CDSectorAddress+2]
xchg AL,AH
mov word [PacketCommand+2],AX
mov AX,word [CDSectorAddress]
xchg AL,AH
mov word [PacketCommand+4],AX
mov AX, word [CDSectorAddress+2]
xchg AL, AH
mov word [PacketCommand+2], AX
mov AX, word [CDSectorAddress]
xchg AL, AH
mov word [PacketCommand+4], AX
; mov eax,[CDSectorAddress]
; mov [PacketCommand+2],eax
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ
mov [PacketCommand+8],byte 1
mov [PacketCommand+8], byte 1
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå
; mov [PacketCommand+9],byte 0xF8
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
pop ecx
call SendPacketDatCommand
pop ecx
; ret
 
; cmp [DevErrorCode],0
test eax,eax
jz @@End_4
test eax, eax
jz @@End_4
 
or ecx,ecx ;{SPraid.simba} (for cd load)
jz @@End_4
dec ecx
or ecx, ecx ;{SPraid.simba} (for cd load)
jz @@End_4
dec ecx
 
cmp [timer_ticks_enable],0
jne @f
mov eax,NoTickWaitTime
cmp [timer_ticks_enable], 0
jne @f
mov eax, NoTickWaitTime
.wait:
dec eax
dec eax
; test eax,eax
jz @@NextRetr
jmp .wait
jz @@NextRetr
jmp .wait
@@:
; Çàäåðæêà íà 2,5 ñåêóíäû
; mov EAX,[timer_ticks]
154,9 → 154,9
; call change_task
; cmp EAX,[timer_ticks]
; ja @@Wait
loop @@NextRetr
loop @@NextRetr
@@End_4:
mov dword [DevErrorCode],eax
mov dword [DevErrorCode], eax
popad
ret
 
170,13 → 170,15
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
uglobal
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
PacketCommand: rb 12 ;DB 12 DUP (?)
PacketCommand:
rb 12 ;DB 12 DUP (?)
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà
;CDDataBuf DB 4096 DUP (0)
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ
;CDBlockSize DW ?
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ
CDSectorAddress: DD ?
CDSectorAddress:
DD ?
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì
TickCounter_1 DD 0
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà
197,31 → 199,31
; return eax DevErrorCode
;****************************************************
SendPacketDatCommand:
xor eax,eax
; mov byte [DevErrorCode],al
xor eax, eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
mov byte [ATAAddressMode],al
mov byte [ATAAddressMode], al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov byte [ATAFeatures],al
mov byte [ATASectorCount],al
mov byte [ATASectorNumber],al
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
mov [ATAHead],al
mov [ATAHead], al
; mov AX,[CDBlockSize]
mov [ATACylinder],CDBlockSize
mov [ATACommand],0A0h
mov [ATACylinder], CDBlockSize
mov [ATACommand], 0A0h
call SendCommandToHDD_1
test eax,eax
test eax, eax
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
 
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,NoTickWaitTime
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
mov ecx, NoTickWaitTime
@@WaitDevice0:
cmp [timer_ticks_enable],0
cmp [timer_ticks_enable], 0
jne @f
dec ecx
; test ecx,ecx
230,41 → 232,41
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
.test:
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice0
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice0
; Ïîñëàòü ïàêåòíóþ êîìàíäó
cli
mov DX,[ATABasePortAddr]
mov AX,[PacketCommand]
out DX,AX
mov AX,[PacketCommand+2]
out DX,AX
mov AX,[PacketCommand+4]
out DX,AX
mov AX,[PacketCommand+6]
out DX,AX
mov AX,[PacketCommand+8]
out DX,AX
mov AX,[PacketCommand+10]
out DX,AX
mov DX, [ATABasePortAddr]
mov AX, [PacketCommand]
out DX, AX
mov AX, [PacketCommand+2]
out DX, AX
mov AX, [PacketCommand+4]
out DX, AX
mov AX, [PacketCommand+6]
out DX, AX
mov AX, [PacketCommand+8]
out DX, AX
mov AX, [PacketCommand+10]
out DX, AX
sti
; Îæèäàíèå ãîòîâíîñòè äàííûõ
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,NoTickWaitTime
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
mov ecx, NoTickWaitTime
@@WaitDevice1:
cmp [timer_ticks_enable],0
cmp [timer_ticks_enable], 0
jne @f
dec ecx
; test ecx,ecx
273,53 → 275,53
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
.test_1:
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_temp
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice1
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
mov EDI, [CDDataBuf_pointer];0x7000 ;CDDataBuf
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
mov DX, [ATABasePortAddr];ïîðò 1x0h
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
xor ecx,ecx
mov CX,CDBlockSize
xor ecx, ecx
mov CX, CDBlockSize
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2
shr CX, 1;ðàçäåëèòü ðàçìåð áëîêà íà 2
; Ïðèíÿòü áëîê äàííûõ
cli
cld
rep insw
rep insw
sti
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
@@End_8:
xor eax,eax
xor eax, eax
ret
 
; Çàïèñàòü êîä îøèáêè
@@Err1_1:
xor eax,eax
inc eax
ret
xor eax, eax
inc eax
ret
; mov [DevErrorCode],1
; ret
; ret
@@Err6_temp:
mov eax,7
ret
mov eax, 7
ret
; mov [DevErrorCode],7
; ret
; ret
@@Err6:
mov eax,6
ret
mov eax, 6
ret
; mov [DevErrorCode],6
;@@End_8:
; ret
337,89 → 339,89
;***********************************************
SendPacketNoDatCommand:
pushad
xor eax,eax
xor eax, eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
mov byte [ATAAddressMode],al
mov byte [ATAAddressMode], al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov byte [ATAFeatures],al
mov byte [ATASectorCount],al
mov byte [ATASectorNumber],al
mov word [ATACylinder],ax
mov byte [ATAHead],al
mov [ATACommand],0A0h
mov byte [ATAFeatures], al
mov byte [ATASectorCount], al
mov byte [ATASectorNumber], al
mov word [ATACylinder], ax
mov byte [ATAHead], al
mov [ATACommand], 0A0h
call SendCommandToHDD_1
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
test eax,eax
test eax, eax
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
@@WaitDevice0_1:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, BSYWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice0_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice0_1
; Ïîñëàòü ïàêåòíóþ êîìàíäó
; cli
mov DX,[ATABasePortAddr]
mov AX,word [PacketCommand]
out DX,AX
mov AX,word [PacketCommand+2]
out DX,AX
mov AX,word [PacketCommand+4]
out DX,AX
mov AX,word [PacketCommand+6]
out DX,AX
mov AX,word [PacketCommand+8]
out DX,AX
mov AX,word [PacketCommand+10]
out DX,AX
mov DX, [ATABasePortAddr]
mov AX, word [PacketCommand]
out DX, AX
mov AX, word [PacketCommand+2]
out DX, AX
mov AX, word [PacketCommand+4]
out DX, AX
mov AX, word [PacketCommand+6]
out DX, AX
mov AX, word [PacketCommand+8]
out DX, AX
mov AX, word [PacketCommand+10]
out DX, AX
; sti
cmp [ignore_CD_eject_wait],1
je @@clear_DEC
cmp [ignore_CD_eject_wait], 1
je @@clear_DEC
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
@@WaitDevice1_1:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [TickCounter_1]
cmp EAX, MaxCDWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_1
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY
test AL, 40h ;ñîñòîÿíèå ñèãíàëà DRDY
jz @@WaitDevice1_1
@@clear_DEC:
and [DevErrorCode],0
and [DevErrorCode], 0
popad
ret
; Çàïèñàòü êîä îøèáêè
@@Err1_3:
xor eax,eax
inc eax
jmp @@End_9
xor eax, eax
inc eax
jmp @@End_9
@@Err6_1:
mov eax,6
mov eax, 6
@@End_9:
mov [DevErrorCode],eax
mov [DevErrorCode], eax
popad
ret
 
444,123 → 446,123
;****************************************************
SendCommandToHDD_1:
; pushad
; mov [DevErrorCode],0 not need
; mov [DevErrorCode],0 not need
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
cmp [ATAAddressMode],1
cmp [ATAAddressMode], 1
ja @@Err2_4
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3_4
cmp BX,2
cmp BX, 2
ja @@Err3_4
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
shl BX, 1
movzx ebx, bx
mov AX, [ebx+StandardATABases]
mov [ATABasePortAddr], AX
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
mov DX,[ATABasePortAddr]
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
mov DX, [ATABasePortAddr]
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL, [DiskNumber]
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4_4
shl AL,4
or AL,10100000b
out DX,AL
shl AL, 4
or AL, 10100000b
out DX, AL
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
inc DX
mov eax,[timer_ticks]
mov [TickCounter_1],eax
mov ecx,NoTickWaitTime
mov eax, [timer_ticks]
mov [TickCounter_1], eax
mov ecx, NoTickWaitTime
@@WaitHDReady_2:
cmp [timer_ticks_enable],0
jne @f
dec ecx
cmp [timer_ticks_enable], 0
jne @f
dec ecx
; test ecx,ecx
jz @@Err1_4
jmp .test
jz @@Err1_4
jmp .test
@@:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
mov eax,[timer_ticks]
sub eax,[TickCounter_1]
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê.
mov eax, [timer_ticks]
sub eax, [TickCounter_1]
cmp eax, BSYWaitTime;300 ;îæèäàòü 3 ñåê.
ja @@Err1_4 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
.test:
in AL,DX
in AL, DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
test AL, 80h
jnz @@WaitHDReady_2
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
test AL,08h
test AL, 08h
jnz @@WaitHDReady_2
 
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
cli
mov DX,[ATABasePortAddr]
mov DX, [ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
mov AL,[ATAFeatures]
out DX,AL
mov AL, [ATAFeatures]
out DX, AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
mov AL,[ATASectorCount]
out DX,AL
mov AL, [ATASectorCount]
out DX, AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
mov AL,[ATASectorNumber]
out DX,AL
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
mov AX,[ATACylinder]
out DX,AL
mov AX, [ATACylinder]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
mov AL,AH
out DX,AL
mov AL, AH
out DX, AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè
ja @@Err5_4
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
or AL, [ATAHead]
or AL, 10100000b
mov AH, [ATAAddressMode]
shl AH, 6
or AL, AH
out DX, AL
; Ïîñëàòü êîìàíäó
mov AL,[ATACommand]
mov AL, [ATACommand]
inc DX ;ðåãèñòð êîìàíä
out DX,AL
out DX, AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
; mov [DevErrorCode],0
@@End_10:
xor eax,eax
ret
xor eax, eax
ret
; Çàïèñàòü êîä îøèáêè
@@Err1_4:
xor eax,eax
inc eax
xor eax, eax
inc eax
; mov [DevErrorCode],1
ret
ret
@@Err2_4:
mov eax,2
mov eax, 2
; mov [DevErrorCode],2
ret
ret
@@Err3_4:
mov eax,3
mov eax, 3
; mov [DevErrorCode],3
ret
ret
@@Err4_4:
mov eax,4
mov eax, 4
; mov [DevErrorCode],4
ret
ret
@@Err5_4:
mov eax,5
mov eax, 5
; mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
ret
ret
; sti
; popad
 
574,20 → 576,20
WaitUnitReady:
pusha
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
mov EAX,[timer_ticks]
mov [WURStartTime],EAX
mov EAX, [timer_ticks]
mov [WURStartTime], EAX
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
mov [PacketCommand],word 00h
mov [PacketCommand], word 00h
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
mov ecx,NoTickWaitTime
mov ecx, NoTickWaitTime
@@SendCommand:
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
call SendPacketNoDatCommand
cmp [timer_ticks_enable],0
cmp [timer_ticks_enable], 0
jne @f
cmp [DevErrorCode],0
cmp [DevErrorCode], 0
je @@End_11
dec ecx
; cmp ecx,0
596,16 → 598,16
@@:
call change_task
; Ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode],0
cmp [DevErrorCode], 0
je @@End_11
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè
mov EAX,[timer_ticks]
sub EAX,[WURStartTime]
cmp EAX,MaxCDWaitTime
mov EAX, [timer_ticks]
sub EAX, [WURStartTime]
cmp EAX, MaxCDWaitTime
jb @@SendCommand
.Error:
; Îøèáêà òàéì-àóòà
mov [DevErrorCode],1
mov [DevErrorCode], 1
@@End_11:
popa
ret
620,17 → 622,17
prevent_medium_removal:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 0x1E
mov [PacketCommand], byte 0x1E
; Çàäàòü êîä çàïðåòà
mov [PacketCommand+4],byte 11b
mov [PacketCommand+4], byte 11b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
mov eax,ATAPI_IDE0_lock
add eax,[cdpos]
dec eax
mov [eax],byte 1
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
add eax, [cdpos]
dec eax
mov [eax], byte 1
popa
ret
 
644,17 → 646,17
allow_medium_removal:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 0x1E
mov [PacketCommand], byte 0x1E
; Çàäàòü êîä çàïðåòà
mov [PacketCommand+4],byte 00b
mov [PacketCommand+4], byte 00b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
mov eax,ATAPI_IDE0_lock
add eax,[cdpos]
dec eax
mov [eax],byte 0
call SendPacketNoDatCommand
mov eax, ATAPI_IDE0_lock
add eax, [cdpos]
dec eax
mov [eax], byte 0
popa
ret
 
668,12 → 670,12
LoadMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
mov [PacketCommand], word 1Bh
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ
mov [PacketCommand+4],word 00000011b
mov [PacketCommand+4], word 00000011b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
popa
689,12 → 691,12
EjectMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
mov [PacketCommand], word 1Bh
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
mov [PacketCommand+4],word 00000010b
mov [PacketCommand+4], word 00000010b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
popa
711,136 → 713,136
align 4
check_ATAPI_device_event:
pusha
mov eax,[timer_ticks]
sub eax,[timer_ATAPI_check]
cmp eax,100
jb .end_1
mov al,[DRIVE_DATA+1]
and al,11b
cmp al,10b
jz .ide3
mov eax, [timer_ticks]
sub eax, [timer_ATAPI_check]
cmp eax, 100
jb .end_1
mov al, [DRIVE_DATA+1]
and al, 11b
cmp al, 10b
jz .ide3
.ide2_1:
mov al,[DRIVE_DATA+1]
and al,1100b
cmp al,1000b
jz .ide2
mov al, [DRIVE_DATA+1]
and al, 1100b
cmp al, 1000b
jz .ide2
.ide1_1:
mov al,[DRIVE_DATA+1]
and al,110000b
cmp al,100000b
jz .ide1
mov al, [DRIVE_DATA+1]
and al, 110000b
cmp al, 100000b
jz .ide1
.ide0_1:
mov al,[DRIVE_DATA+1]
and al,11000000b
cmp al,10000000b
jz .ide0
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
jz .ide0
.end:
 
sti
mov eax,[timer_ticks]
mov [timer_ATAPI_check],eax
sti
mov eax, [timer_ticks]
mov [timer_ATAPI_check], eax
.end_1:
popa
ret
 
.ide3:
cli
cmp [ATAPI_IDE3_lock],1
jne .ide2_1
cmp [IDE_Channel_2],0
jne .ide1_1
cmp [cd_status],0
jne .end
mov [IDE_Channel_2],1
call reserve_ok2
mov [ChannelNumber],2
mov [DiskNumber],1
mov [cdpos],4
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide3
call syscall_cdaudio.free
jmp .ide2_1
cli
cmp [ATAPI_IDE3_lock], 1
jne .ide2_1
cmp [IDE_Channel_2], 0
jne .ide1_1
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 1
mov [cdpos], 4
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
je .eject_ide3
call syscall_cdaudio.free
jmp .ide2_1
.eject_ide3:
call .eject
call syscall_cdaudio.free
jmp .ide2_1
call .eject
call syscall_cdaudio.free
jmp .ide2_1
 
.ide2:
cli
cmp [ATAPI_IDE2_lock],1
jne .ide1_1
cmp [IDE_Channel_2],0
jne .ide1_1
cmp [cd_status],0
jne .end
mov [IDE_Channel_2],1
call reserve_ok2
mov [ChannelNumber],2
mov [DiskNumber],0
mov [cdpos],3
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide2
call syscall_cdaudio.free
jmp .ide1_1
cli
cmp [ATAPI_IDE2_lock], 1
jne .ide1_1
cmp [IDE_Channel_2], 0
jne .ide1_1
cmp [cd_status], 0
jne .end
mov [IDE_Channel_2], 1
call reserve_ok2
mov [ChannelNumber], 2
mov [DiskNumber], 0
mov [cdpos], 3
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
je .eject_ide2
call syscall_cdaudio.free
jmp .ide1_1
.eject_ide2:
call .eject
call syscall_cdaudio.free
jmp .ide1_1
call .eject
call syscall_cdaudio.free
jmp .ide1_1
 
.ide1:
cli
cmp [ATAPI_IDE1_lock],1
jne .ide0_1
cmp [IDE_Channel_1],0
jne .end
cmp [cd_status],0
jne .end
mov [IDE_Channel_1],1
call reserve_ok2
mov [ChannelNumber],1
mov [DiskNumber],1
mov [cdpos],2
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide1
call syscall_cdaudio.free
jmp .ide0_1
cli
cmp [ATAPI_IDE1_lock], 1
jne .ide0_1
cmp [IDE_Channel_1], 0
jne .end
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 1
mov [cdpos], 2
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
je .eject_ide1
call syscall_cdaudio.free
jmp .ide0_1
.eject_ide1:
call .eject
call syscall_cdaudio.free
jmp .ide0_1
call .eject
call syscall_cdaudio.free
jmp .ide0_1
 
.ide0:
cli
cmp [ATAPI_IDE0_lock],1
jne .end
cmp [IDE_Channel_1],0
jne .end
cmp [cd_status],0
jne .end
mov [IDE_Channel_1],1
call reserve_ok2
mov [ChannelNumber],1
mov [DiskNumber],0
mov [cdpos],1
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide0
call syscall_cdaudio.free
jmp .end
cli
cmp [ATAPI_IDE0_lock], 1
jne .end
cmp [IDE_Channel_1], 0
jne .end
cmp [cd_status], 0
jne .end
mov [IDE_Channel_1], 1
call reserve_ok2
mov [ChannelNumber], 1
mov [DiskNumber], 0
mov [cdpos], 1
call GetEvent_StatusNotification
cmp [CDDataBuf+4], byte 1
je .eject_ide0
call syscall_cdaudio.free
jmp .end
.eject_ide0:
call .eject
call syscall_cdaudio.free
jmp .end
call .eject
call syscall_cdaudio.free
jmp .end
 
.eject:
call clear_CD_cache
call allow_medium_removal
mov [ignore_CD_eject_wait],1
call EjectMedium
mov [ignore_CD_eject_wait],0
call clear_CD_cache
call allow_medium_removal
mov [ignore_CD_eject_wait], 1
call EjectMedium
mov [ignore_CD_eject_wait], 0
ret
iglobal
timer_ATAPI_check dd 0
860,17 → 862,17
;*************************************************
GetEvent_StatusNotification:
pusha
mov [CDDataBuf_pointer],CDDataBuf
mov [CDDataBuf_pointer], CDDataBuf
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 4Ah
mov [PacketCommand+1],byte 00000001b
mov [PacketCommand], byte 4Ah
mov [PacketCommand+1], byte 00000001b
; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé
mov [PacketCommand+4],byte 00010000b
mov [PacketCommand+4], byte 00010000b
; Ðàçìåð âûäåëåííîé îáëàñòè
mov [PacketCommand+7],byte 8h
mov [PacketCommand+8],byte 0h
mov [PacketCommand+7], byte 8h
mov [PacketCommand+8], byte 0h
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
popa
885,19 → 887,19
;*************************************************
Read_TOC:
pusha
mov [CDDataBuf_pointer],CDDataBuf
mov [CDDataBuf_pointer], CDDataBuf
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
call clear_packet_buffer
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
; ñåêòîðà äàííûõ
mov [PacketCommand],byte 0x43
mov [PacketCommand], byte 0x43
; Çàäàòü ôîðìàò
mov [PacketCommand+2],byte 1
mov [PacketCommand+2], byte 1
; Ðàçìåð âûäåëåííîé îáëàñòè
mov [PacketCommand+7],byte 0xFF
mov [PacketCommand+8],byte 0h
mov [PacketCommand+7], byte 0xFF
mov [PacketCommand+8], byte 0h
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
call SendPacketDatCommand
popa
ret
 
923,7 → 925,7
 
clear_packet_buffer:
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
and [PacketCommand],dword 0
and [PacketCommand+4],dword 0
and [PacketCommand+8],dword 0
and [PacketCommand], dword 0
and [PacketCommand+4], dword 0
and [PacketCommand+8], dword 0
ret
/kernel/branches/net/blkdev/cdrom.inc
10,10 → 10,10
 
sys_cd_audio:
 
cmp word [cdbase],word 0
jnz @f
mov eax,1
ret
cmp word [cdbase], word 0
jnz @f
mov eax, 1
ret
@@:
 
; eax=1 cdplay at ebx 0x00FFSSMM
20,252 → 20,252
; eax=2 get tracklist size of ecx to [ebx]
; eax=3 stop/pause playing
 
cmp eax,1
jnz nocdp
call sys_cdplay
ret
cmp eax, 1
jnz nocdp
call sys_cdplay
ret
nocdp:
 
cmp eax,2
jnz nocdtl
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add ebx,[edi]
call sys_cdtracklist
ret
cmp eax, 2
jnz nocdtl
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add ebx, [edi]
call sys_cdtracklist
ret
nocdtl:
 
cmp eax,3
jnz nocdpause
call sys_cdpause
ret
cmp eax, 3
jnz nocdpause
call sys_cdpause
ret
nocdpause:
 
mov eax,0xffffff01
ret
mov eax, 0xffffff01
ret
 
 
 
sys_cd_atapi_command:
 
pushad
pushad
 
mov dx,word [cdbase]
add dx,6
mov ax,word [cdid]
out dx,al
mov esi,10
call delay_ms
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x80
cmp al,0
jnz res
jmp cdl6
mov dx, word [cdbase]
add dx, 6
mov ax, word [cdid]
out dx, al
mov esi, 10
call delay_ms
mov dx, word [cdbase]
add dx, 7
in al, dx
and al, 0x80
cmp al, 0
jnz res
jmp cdl6
res:
mov dx,word [cdbase]
add dx,7
mov al,0x8
out dx,al
mov dx,word [cdbase]
add dx,0x206
mov al,0xe
out dx,al
mov esi,1
call delay_ms
mov dx,word [cdbase]
add dx,0x206
mov al,0x8
out dx,al
mov esi,30
call delay_ms
xor cx,cx
mov dx, word [cdbase]
add dx, 7
mov al, 0x8
out dx, al
mov dx, word [cdbase]
add dx, 0x206
mov al, 0xe
out dx, al
mov esi, 1
call delay_ms
mov dx, word [cdbase]
add dx, 0x206
mov al, 0x8
out dx, al
mov esi, 30
call delay_ms
xor cx, cx
cdl5:
inc cx
cmp cx,10
jz cdl6
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x88
cmp al,0x00
jz cdl5
mov esi,100
call delay_ms
jmp cdl5
inc cx
cmp cx, 10
jz cdl6
mov dx, word [cdbase]
add dx, 7
in al, dx
and al, 0x88
cmp al, 0x00
jz cdl5
mov esi, 100
call delay_ms
jmp cdl5
cdl6:
mov dx,word [cdbase]
add dx,4
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,5
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,7
mov al,0xec
out dx,al
mov esi,5
call delay_ms
mov dx,word [cdbase]
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,128
out dx,al
add dx,2
mov al,0xa0
out dx,al
xor cx,cx
mov dx,word [cdbase]
add dx,7
mov dx, word [cdbase]
add dx, 4
mov al, 0
out dx, al
mov dx, word [cdbase]
add dx, 5
mov al, 0
out dx, al
mov dx, word [cdbase]
add dx, 7
mov al, 0xec
out dx, al
mov esi, 5
call delay_ms
mov dx, word [cdbase]
add dx, 1
mov al, 0
out dx, al
add dx, 1
mov al, 0
out dx, al
add dx, 1
mov al, 0
out dx, al
add dx, 1
mov al, 0
out dx, al
add dx, 1
mov al, 128
out dx, al
add dx, 2
mov al, 0xa0
out dx, al
xor cx, cx
mov dx, word [cdbase]
add dx, 7
cdl1:
inc cx
cmp cx,100
jz cdl2
in al,dx
and ax,0x88
cmp al,0x8
jz cdl2
mov esi,2
call delay_ms
jmp cdl1
inc cx
cmp cx, 100
jz cdl2
in al, dx
and ax, 0x88
cmp al, 0x8
jz cdl2
mov esi, 2
call delay_ms
jmp cdl1
cdl2:
 
popad
ret
popad
ret
 
 
sys_cdplay:
 
mov ax,5
push ax
push ebx
mov ax, 5
push ax
push ebx
cdplay:
call sys_cd_atapi_command
cli
mov dx,word [cdbase]
mov ax,0x0047
out dx,ax
mov al,1
mov ah,[esp+0] ; min xx
out dx,ax
mov ax,[esp+1] ; fr sec
out dx,ax
mov ax,256+99
out dx,ax
mov ax,0x0001
out dx,ax
mov ax,0x0000
out dx,ax
mov esi,10
call delay_ms
sti
add dx,7
in al,dx
test al,1
jz cdplayok
mov ax,[esp+4]
dec ax
mov [esp+4],ax
cmp ax,0
jz cdplayfail
jmp cdplay
call sys_cd_atapi_command
cli
mov dx, word [cdbase]
mov ax, 0x0047
out dx, ax
mov al, 1
mov ah, [esp+0]; min xx
out dx, ax
mov ax, [esp+1]; fr sec
out dx, ax
mov ax, 256+99
out dx, ax
mov ax, 0x0001
out dx, ax
mov ax, 0x0000
out dx, ax
mov esi, 10
call delay_ms
sti
add dx, 7
in al, dx
test al, 1
jz cdplayok
mov ax, [esp+4]
dec ax
mov [esp+4], ax
cmp ax, 0
jz cdplayfail
jmp cdplay
cdplayfail:
cdplayok:
pop ebx
pop ax
xor eax, eax
ret
pop ebx
pop ax
xor eax, eax
ret
 
 
sys_cdtracklist:
 
push ebx
push ebx
tcdplay:
call sys_cd_atapi_command
mov dx,word [cdbase]
mov ax,0x43+2*256
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,200
out dx,ax
mov ax,0x0
out dx,ax
in al,dx
mov cx,1000
mov dx,word [cdbase]
add dx,7
cld
call sys_cd_atapi_command
mov dx, word [cdbase]
mov ax, 0x43+2*256
out dx, ax
mov ax, 0x0
out dx, ax
mov ax, 0x0
out dx, ax
mov ax, 0x0
out dx, ax
mov ax, 200
out dx, ax
mov ax, 0x0
out dx, ax
in al, dx
mov cx, 1000
mov dx, word [cdbase]
add dx, 7
cld
cdtrnwewait:
mov esi,10
call delay_ms
in al,dx
and al,128
cmp al,0
jz cdtrl1
loop cdtrnwewait
mov esi, 10
call delay_ms
in al, dx
and al, 128
cmp al, 0
jz cdtrl1
loop cdtrnwewait
cdtrl1:
; read the result
mov ecx,[esp+0]
mov dx,word [cdbase]
mov ecx, [esp+0]
mov dx, word [cdbase]
cdtrread:
add dx,7
in al,dx
and al,8
cmp al,8
jnz cdtrdone
sub dx,7
in ax,dx
mov [ecx],ax
add ecx,2
jmp cdtrread
add dx, 7
in al, dx
and al, 8
cmp al, 8
jnz cdtrdone
sub dx, 7
in ax, dx
mov [ecx], ax
add ecx, 2
jmp cdtrread
cdtrdone:
pop ecx
xor eax, eax
ret
pop ecx
xor eax, eax
ret
 
 
sys_cdpause:
 
call sys_cd_atapi_command
call sys_cd_atapi_command
 
mov dx,word [cdbase]
mov ax,0x004B
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov dx, word [cdbase]
mov ax, 0x004B
out dx, ax
mov ax, 0
out dx, ax
mov ax, 0
out dx, ax
mov ax, 0
out dx, ax
mov ax, 0
out dx, ax
mov ax, 0
out dx, ax
 
mov esi,10
call delay_ms
add dx,7
in al,dx
mov esi, 10
call delay_ms
add dx, 7
in al, dx
 
xor eax, eax
ret
xor eax, eax
ret
 
/kernel/branches/net/blkdev/disk.inc
0,0 → 1,1258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
; =============================================================================
; ================================= Constants =================================
; =============================================================================
; Error codes for callback functions.
DISK_STATUS_OK = 0 ; success
DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters
DISK_STATUS_NO_MEDIA = 2 ; no media present
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data
; Driver flags. Represent bits in DISK.DriverFlags.
DISK_NO_INSERT_NOTIFICATION = 1
; Media flags. Represent bits in DISKMEDIAINFO.Flags.
DISK_MEDIA_READONLY = 1
 
; If too many partitions are detected,there is probably an error on the disk.
; 256 partitions should be enough for any reasonable use.
; Also, the same number is limiting the number of MBRs to process; if
; too many MBRs are visible,there probably is a loop in the MBR structure.
MAX_NUM_PARTITIONS = 256
 
; =============================================================================
; ================================ Structures =================================
; =============================================================================
; This structure defines all callback functions for working with the physical
; device. They are implemented by a driver. Objects with this structure reside
; in a driver.
struct DISKFUNC
strucsize dd ?
; Size of the structure. This field is intended for possible extensions of
; this structure. If a new function is added to this structure and a driver
; implements an old version, the caller can detect this by checking .strucsize,
; so the driver remains compatible.
close dd ?
; The pointer to the function which frees all driver-specific resources for
; the disk.
; Optional, may be NULL.
; void close(void* userdata);
closemedia dd ?
; The pointer to the function which informs the driver that the kernel has
; finished all processing with the current media. If media is removed, the
; driver should decline all requests to that media with DISK_STATUS_NO_MEDIA,
; even if new media is inserted, until this function is called. If media is
; removed, a new call to 'disk_media_changed' is not allowed until this
; function is called.
; Optional, may be NULL (if media is not removable).
; void closemedia(void* userdata);
querymedia dd ?
; The pointer to the function which determines capabilities of the media.
; int querymedia(void* userdata, DISKMEDIAINFO* info);
; Return value: one of DISK_STATUS_*
read dd ?
; The pointer to the function which reads data from the device.
; int read(void* userdata, void* buffer, __int64 startsector, int* numsectors);
; input: *numsectors = number of sectors to read
; output: *numsectors = number of sectors which were successfully read
; Return value: one of DISK_STATUS_*
write dd ?
; The pointer to the function which writes data to the device.
; Optional, may be NULL.
; int write(void* userdata, void* buffer, __int64 startsector, int* numsectors);
; input: *numsectors = number of sectors to write
; output: *numsectors = number of sectors which were successfully written
; Return value: one of DISK_STATUS_*
flush dd ?
; The pointer to the function which flushes the internal device cache.
; Optional, may be NULL.
; int flush(void* userdata);
; Return value: one of DISK_STATUS_*
; Note that read/write are called by the cache manager, so a driver should not
; create a software cache. This function is implemented for flushing a hardware
; cache, if it exists.
adjust_cache_size dd ?
; The pointer to the function which returns the cache size for this device.
; Optional, may be NULL.
; unsigned int adjust_cache_size(unsigned int suggested_size);
; Return value: 0 = disable cache, otherwise = used cache size in bytes.
ends
 
; This structure holds information on a medium.
; Objects with this structure are allocated by the kernel as a part of the DISK
; structure and are filled by a driver in the 'querymedia' callback.
struct DISKMEDIAINFO
Flags dd ?
; Combination of DISK_MEDIA_* bits.
SectorSize dd ?
; Size of the sector.
Capacity dq ?
; Size of the media in sectors.
ends
 
; This structure represents the disk cache. To follow the old implementation,
; there are two distinct caches for a disk, one for "system" data,and the other
; for "application" data.
struct DISKCACHE
mutex MUTEX
; Lock to protect the cache.
; The following fields are inherited from data32.inc:cache_ideX.
pointer dd ?
data_size dd ? ; unused
data dd ?
sad_size dd ?
search_start dd ?
ends
 
; This structure represents a disk device and its media for the kernel.
; This structure is allocated by the kernel in the 'disk_add' function,
; freed in the 'disk_dereference' function.
struct DISK
; Fields of disk object
Next dd ?
Prev dd ?
; All disk devices are linked in one list with these two fields.
; Head of the list is the 'disk_list' variable.
Functions dd ?
; Pointer to the 'DISKFUNC' structure with driver functions.
Name dd ?
; Pointer to the string used for accesses through the global filesystem.
UserData dd ?
; This field is passed to all callback functions so a driver can decide which
; physical device is addressed.
DriverFlags dd ?
; Bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit is defined.
; If it is set, the driver will never issue 'disk_media_changed' notification
; with argument set to true, so the kernel must try to detect media during
; requests from the file system.
RefCount dd ?
; Count of active references to this structure. One reference is kept during
; the lifetime of the structure between 'disk_add' and 'disk_del'.
; Another reference is taken during any filesystem operation for this disk.
; One reference is added if media is inserted.
; The structure is destroyed when the reference count decrements to zero:
; this usually occurs in 'disk_del', but can be delayed to the end of last
; filesystem operation, if one is active.
MediaLock MUTEX
; Lock to protect the MEDIA structure. See the description after
; 'disk_list_mutex' for the locking strategy.
; Fields of media object
MediaInserted db ?
; 0 if media is not inserted, nonzero otherwise.
MediaUsed db ?
; 0 if media fields are not used, nonzero otherwise. If .MediaRefCount is
; nonzero, this field is nonzero too; however, when .MediaRefCount goes
; to zero, there is some time interval during which media object is still used.
align 4
; The following fields are not valid unless either .MediaInserted is nonzero
; or they are accessed from a code which has obtained the reference when
; .MediaInserted was nonzero.
MediaRefCount dd ?
; Count of active references to the media object. One reference is kept during
; the lifetime of the media between two calls to 'disk_media_changed'.
; Another reference is taken during any filesystem operation for this media.
; The callback 'closemedia' is called when the reference count decrements to
; zero: this usually occurs in 'disk_media_changed', but can be delayed to the
; end of the last filesystem operation, if one is active.
MediaInfo DISKMEDIAINFO
; This field keeps information on the current media.
NumPartitions dd ?
; Number of partitions on this media.
Partitions dd ?
; Pointer to array of .NumPartitions pointers to PARTITION structures.
cache_size dd ?
; inherited from cache_ideX_size
SysCache DISKCACHE
AppCache DISKCACHE
; Two caches for the disk.
ends
 
; This structure represents one partition for the kernel. This is a base
; template, the actual contents after common fields is determined by the
; file system code for this partition.
struct PARTITION
FirstSector dq ?
; First sector of the partition.
Length dq ?
; Length of the partition in sectors.
Disk dd ?
; Pointer to parent DISK structure.
FSUserFunctions dd ?
; Handlers for the sysfunction 70h. This field is a pointer to the following
; array. The first dword is a number of supported subfunctions, other dwords
; point to handlers of corresponding subfunctions.
; This field is 0 if file system is not recognized.
; ...fs-specific data may follow...
ends
 
; This is an external structure, it represents an entry in the partition table.
struct PARTITION_TABLE_ENTRY
Bootable db ?
; 80h = bootable partition, 0 = non-bootable partition, other values = invalid
FirstHead db ?
FirstSector db ?
FirstTrack db ?
; Coordinates of first sector in CHS.
Type db ?
; Partition type, one of predefined constants. 0 = empty, several types denote
; extended partition (see process_partition_table_entry), we are not interested
; in other values.
LastHead db ?
LastSector db ?
LastTrack db ?
; Coordinates of last sector in CHS.
FirstAbsSector dd ?
; Coordinate of first sector in LBA.
Length dd ?
; Length of the partition in sectors.
ends
 
; =============================================================================
; ================================ Global data ================================
; =============================================================================
iglobal
; The pseudo-item for the list of all DISK structures.
; Initialized to the empty list.
disk_list:
dd disk_list
dd disk_list
endg
uglobal
; This mutex guards all operations with the global list of DISK structures.
disk_list_mutex MUTEX
; * There are two dependent objects, a disk and a media. In the simplest case,
; disk and media are both non-removable. However, in the general case both
; can be removed at any time, simultaneously or only media,and this makes things
; complicated.
; * For efficiency, both disk and media objects are located in the one
; structure named DISK. However, logically they are different.
; * The following operations use data of disk object: adding (disk_add);
; deleting (disk_del); filesystem (fs_lfn which eventually calls
; dyndisk_handler or dyndisk_enum_root).
; * The following operations use data of media object: adding/removing
; (disk_media_changed); filesystem (fs_lfn which eventually calls
; dyndisk_handler; dyndisk_enum_root doesn't work with media).
; * Notifications disk_add, disk_media_changed, disk_del are synchronized
; between themselves, this is a requirement for the driver. However, file
; system operations are asynchronous, can be issued at any time by any
; thread.
; * We must prevent a situation when a filesystem operation thinks that the
; object is still valid but in fact the notification has destroyed the
; object. So we keep a reference counter for both disk and media and destroy
; the object when this counter goes to zero.
; * The driver must know when it is safe to free driver-allocated resources.
; The object can be alive even after death notification has completed.
; We use special callbacks to satisfy both assertions: 'close' for the disk
; and 'closemedia' for the media. The destruction of the object includes
; calling the corresponding callback.
; * Each filesystem operation keeps one reference for the disk and one
; reference for the media. Notification disk_del forces notification on the
; media death, so the reference counter for the disk is always not less than
; the reference counter for the media.
; * Two operations "get the object" and "increment the reference counter" can
; not be done simultaneously. We use a mutex to guard the consistency here.
; It must be a part of the container for the object, so that this mutex can
; be acquired as a part of getting the object from the container. The
; container for disk object is the global list, and this list is guarded by
; 'disk_list_mutex'. The container for media object is the disk object, and
; the corresponding mutex is DISK.MediaLock.
; * Notifications do not change the data of objects, they can only remove
; objects. Thus we don't need another synchronization at this level. If two
; filesystem operations are referencing the same filesystem data, this is
; better resolved at the level of the filesystem.
endg
 
iglobal
; The function 'disk_scan_partitions' needs three 512-byte buffers for
; MBR, bootsector and fs-temporary sector data. It can not use the static
; buffers always, since it can be called for two or more disks in parallel.
; However, this case is not typical. We reserve three static 512-byte buffers
; and a flag that these buffers are currently used. If 'disk_scan_partitions'
; detects that the buffers are currently used, it allocates buffers from the
; heap.
; The flag is implemented as a global dword variable. When the static buffers
; are not used, the value is -1. When the static buffers are used, the value
; is normally 0 and temporarily can become greater. The function increments
; this value. If the resulting value is zero, it uses the buffers and
; decrements the value when the job is done. Otherwise, it immediately
; decrements the value and uses buffers from the heap, allocated in the
; beginning and freed in the end.
partition_buffer_users dd -1
endg
uglobal
; The static buffers for MBR, bootsector and fs-temporary sector data.
align 16
mbr_buffer rb 512
bootsect_buffer rb 512
fs_tmp_buffer rb 512
endg
 
iglobal
; This is the array of default implementations of driver callbacks.
; Same as DRIVERFUNC structure except for the first field; all functions must
; have the default implementations.
align 4
disk_default_callbacks:
dd disk_default_close
dd disk_default_closemedia
dd disk_default_querymedia
dd disk_default_read
dd disk_default_write
dd disk_default_flush
dd disk_default_adjust_cache_size
endg
 
; =============================================================================
; ================================= Functions =================================
; =============================================================================
 
; This function registers a disk device.
; This includes:
; - allocating an internal structure describing this device;
; - registering this structure in the global filesystem.
; The function initializes the disk as if there is no media. If a media is
; present, the function 'disk_media_changed' should be called after this
; function succeeds.
; Parameters:
; [esp+4] = pointer to DISKFUNC structure with the callbacks
; [esp+8] = pointer to name (ASCIIZ string)
; [esp+12] = userdata to be passed to the callbacks as is.
; [esp+16] = flags, bitfield. Currently only DISK_NO_INSERT_NOTIFICATION bit
; is defined.
; Return value:
; NULL = operation has failed
; non-NULL = handle of the disk. This handle can be used
; in the operations with other Disk* functions.
; The handle is the pointer to the internal structure DISK.
disk_add:
push ebx esi ; save used registers to be stdcall
; 1. Allocate the DISK structure.
; 1a. Call the heap manager.
push sizeof.DISK
pop eax
call malloc
; 1b. Check the result. If allocation failed, return (go to 9) with eax = 0.
test eax, eax
jz .nothing
; 2. Copy the disk name to the DISK structure.
; 2a. Get length of the name, including the terminating zero.
mov ebx, [esp+8+8] ; ebx = pointer to name
push eax ; save allocated pointer to DISK
xor eax, eax ; the argument of malloc() is in eax
@@:
inc eax
cmp byte [ebx+eax-1], 0
jnz @b
; 2b. Call the heap manager.
call malloc
; 2c. Check the result. If allocation failed, go to 7.
pop esi ; restore allocated pointer to DISK
test eax, eax
jz .free
; 2d. Store the allocated pointer to the DISK structure.
mov [esi+DISK.Name], eax
; 2e. Copy the name.
@@:
mov dl, [ebx]
mov [eax], dl
inc ebx
inc eax
test dl, dl
jnz @b
; 3. Copy other arguments of the function to the DISK structure.
mov eax, [esp+4+8]
mov [esi+DISK.Functions], eax
mov eax, [esp+12+8]
mov [esi+DISK.UserData], eax
mov eax, [esp+16+8]
mov [esi+DISK.DriverFlags], eax
; 4. Initialize other fields of the DISK structure.
; Media is not inserted, reference counter is 1.
lea ecx, [esi+DISK.MediaLock]
call mutex_init
xor eax, eax
mov dword [esi+DISK.MediaInserted], eax
inc eax
mov [esi+DISK.RefCount], eax
; The DISK structure is initialized.
; 5. Insert the new structure to the global list.
; 5a. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
; 5b. Insert item to the tail of double-linked list.
mov edx, disk_list
list_add_tail esi, edx ;esi= new edx= list head
; 5c. Release the mutex.
call mutex_unlock
; 6. Return with eax = pointer to DISK.
xchg eax, esi
jmp .nothing
.free:
; Memory allocation for DISK structure succeeded, but for disk name failed.
; 7. Free the DISK structure.
xchg eax, esi
call free
; 8. Return with eax = 0.
xor eax, eax
.nothing:
; 9. Return.
pop esi ebx ; restore used registers to be stdcall
ret 16 ; purge 4 dword arguments to be stdcall
 
; This function deletes a disk device from the global filesystem.
; This includes:
; - removing a media including all partitions;
; - deleting this structure from the global filesystem;
; - dereferencing the DISK structure and possibly destroying it.
; Parameters:
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; Return value: none.
disk_del:
push esi ; save used registers to be stdcall
; 1. Force media to be removed. If the media is already removed, the
; call does nothing.
mov esi, [esp+4+8] ; esi = handle of the disk
stdcall disk_media_changed, esi, 0
; 2. Delete the structure from the global list.
; 2a. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
; 2b. Delete item from double-linked list.
mov eax, [esi+DISK.Next]
mov edx, [esi+DISK.Prev]
mov [eax+DISK.Prev], edx
mov [edx+DISK.Next], eax
; 2c. Release the mutex.
call mutex_unlock
; 3. The structure still has one reference created in disk_add. Remove this
; reference. If there are no other references, disk_dereference will free the
; structure.
call disk_dereference
; 4. Return.
pop esi ; restore used registers to be stdcall
ret 4 ; purge 1 dword argument to be stdcall
 
; This is an internal function which removes a previously obtained reference
; to the disk. If this is the last reference, this function lets the driver
; finalize all associated data, and afterwards frees the DISK structure.
; esi = pointer to DISK structure
disk_dereference:
; 1. Decrement reference counter. Use atomic operation to correctly handle
; possible simultaneous calls.
lock dec [esi+DISK.RefCount]
; 2. If the result is nonzero, there are other references, so nothing to do.
; In this case, return (go to 4).
jnz .nothing
; 3. If we are here, we just removed the last reference and must destroy the
; disk object.
; 3a. Call the driver.
mov al, DISKFUNC.close
stdcall disk_call_driver
; 3b. Free the structure.
xchg eax, esi
call free
; 4. Return.
.nothing:
ret
 
; This is an internal function which removes a previously obtained reference
; to the media. If this is the last reference, this function calls 'closemedia'
; callback to signal the driver that the processing has finished and it is safe
; to inform about a new media.
; esi = pointer to DISK structure
disk_media_dereference:
; 1. Decrement reference counter. Use atomic operation to correctly handle
; possible simultaneous calls.
lock dec [esi+DISK.MediaRefCount]
; 2. If the result is nonzero, there are other references, so nothing to do.
; In this case, return (go to 4).
jnz .nothing
; 3. If we are here, we just removed the last reference and must destroy the
; media object.
; Note that the same place inside the DISK structure is reused for all media
; objects, so we must guarantee that reusing does not happen while freeing.
; Reusing is only possible when someone processes a new media. There are two
; mutually exclusive variants:
; * driver issues media insert notifications (DISK_NO_INSERT_NOTIFICATION bit
; in DISK.DriverFlags is not set). In this case, we require from the driver
; that such notification (except for the first one) can occur only after a
; call to 'closemedia' callback.
; * driver does not issue media insert notifications. In this case, the kernel
; itself must sometimes check whether media is inserted. We have the flag
; DISK.MediaUsed, visible to the kernel. This flag signals to the other parts
; of kernel that the way is free.
; In the first case other parts of the kernel do not use DISK.MediaUsed, so it
; does not matter when this flag is cleared. In the second case this flag must
; be cleared after all other actions, including call to 'closemedia'.
; 3a. Free all partitions.
push esi edi
mov edi, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
test edi, edi
jz .nofree
.freeloop:
lodsd
call free
dec edi
jnz .freeloop
.nofree:
pop edi esi
; 3b. Free the cache.
call disk_free_cache
; 3c. Call the driver.
mov al, DISKFUNC.closemedia
stdcall disk_call_driver
; 3d. Clear the flag.
mov [esi+DISK.MediaUsed], 0
.nothing:
ret
 
; This function is called by the driver and informs the kernel that the media
; has changed. If the media is non-removable, it is called exactly once
; immediately after 'disk_add' and once from 'disk_del'.
; Parameters:
; [esp+4] = handle of the disk, i.e. the pointer to the DISK structure.
; [esp+8] = new status of the media: zero = no media, nonzero = media inserted.
disk_media_changed:
push ebx esi edi ; save used registers to be stdcall
; 1. Remove the existing media, if it is present.
mov esi, [esp+4+12] ; esi = pointer to DISK
; 1a. Check whether it is present. Since DISK.MediaInserted is changed only
; in this function and calls to this function are synchronized, no lock is
; required for checking.
cmp [esi+DISK.MediaInserted], 0
jz .noremove
; We really need to remove the media.
; 1b. Acquire mutex.
lea ecx, [esi+DISK.MediaLock]
call mutex_lock
; 1c. Clear the flag.
mov [esi+DISK.MediaInserted], 0
; 1d. Release mutex.
call mutex_unlock
; 1e. Remove the "lifetime" reference and possibly destroy the structure.
call disk_media_dereference
.noremove:
; 2. Test whether there is new media.
cmp dword [esp+8+12], 0
jz .noinsert
; Yep, there is.
; 3. Process the new media. We assume that all media fields are available to
; use, see comments in 'disk_media_dereference' (this covers using by previous
; media referencers) and note that calls to this function are synchronized
; (this covers using by new media referencers).
; 3a. Call the 'querymedia' callback.
; .Flags are set to zero for possible future extensions.
lea edx, [esi+DISK.MediaInfo]
and [edx+DISKMEDIAINFO.Flags], 0
mov al, DISKFUNC.querymedia
stdcall disk_call_driver, edx
; 3b. Check the result of the callback. Abort if it failed.
test eax, eax
jnz .noinsert
; 3c. Allocate the cache unless disabled by the driver. Abort if failed.
call disk_init_cache
test al, al
jz .noinsert
; 3d. Acquire the lifetime reference for the media object.
inc [esi+DISK.MediaRefCount]
; 3e. Scan for partitions. Ignore result; the list of partitions is valid even
; on errors.
call disk_scan_partitions
; 3f. Media is inserted and available for use.
inc [esi+DISK.MediaInserted]
.noinsert:
; 4. Return.
pop edi esi ebx ; restore used registers to be stdcall
ret 8 ; purge 2 dword arguments to be stdcall
 
; This function is a thunk for all functions of a disk driver.
; It checks whether the referenced function is implemented in the driver.
; If so, this function jumps to the function in the driver.
; Otherwise, it jumps to the default implementation.
; al = offset of function in the DISKFUNC structure;
; esi = pointer to the DISK structure;
; stack is the same as for the corresponding function except that the
; first parameter (void* userdata) is prepended automatically.
disk_call_driver:
movzx eax, al ; eax = offset of function in the DISKFUNC structure
; 1. Prepend the first argument to the stack.
pop ecx ; ecx = return address
push [esi+DISK.UserData] ; add argument
push ecx ; save return address
; 2. Check that the required function is inside the table. If not, go to 5.
mov ecx, [esi+DISK.Functions]
cmp eax, [ecx+DISKFUNC.strucsize]
jae .default
; 3. Check that the required function is implemented. If not, go to 5.
mov ecx, [ecx+eax]
test ecx, ecx
jz .default
; 4. Jump to the required function.
jmp ecx
.default:
; 5. Driver does not implement the required function; use default implementation.
jmp dword [disk_default_callbacks+eax-4]
 
; The default implementation of DISKFUNC.querymedia.
disk_default_querymedia:
push DISK_STATUS_INVALID_CALL
pop eax
ret 8
 
; The default implementation of DISKFUNC.read and DISKFUNC.write.
disk_default_read:
disk_default_write:
push DISK_STATUS_INVALID_CALL
pop eax
ret 20
 
; The default implementation of DISKFUNC.close, DISKFUNC.closemedia and
; DISKFUNC.flush.
disk_default_close:
disk_default_closemedia:
disk_default_flush:
xor eax, eax
ret 4
 
; The default implementation of DISKFUNC.adjust_cache_size.
disk_default_adjust_cache_size:
mov eax, [esp+4]
ret 4
 
; This is an internal function called from 'disk_media_changed' when a new media
; is detected. It creates the list of partitions for the media.
; If media is not partitioned, then the list consists of one partition which
; covers all the media.
; esi = pointer to the DISK structure.
disk_scan_partitions:
; 1. Initialize .NumPartitions and .Partitions fields as zeros: empty list.
and [esi+DISK.NumPartitions], 0
and [esi+DISK.Partitions], 0
; 2. Currently we can work only with 512-bytes sectors. Check this restriction.
; The only exception is 2048-bytes CD/DVD, but they are not supported yet by
; this code.
cmp [esi+DISK.MediaInfo.SectorSize], 512
jz .doscan
DEBUGF 1,'K : sector size is %d, only 512 is supported\n',[esi+DISK.MediaInfo.SectorSize]
ret
.doscan:
; 3. Acquire the buffer for MBR and bootsector tests. See the comment before
; the 'partition_buffer_users' variable.
mov ebx, mbr_buffer ; assume the global buffer is free
lock inc [partition_buffer_users]
jz .buffer_acquired ; yes, it is free
lock dec [partition_buffer_users] ; no, we must allocate
stdcall kernel_alloc, 512*3
test eax, eax
jz .nothing
xchg eax, ebx
.buffer_acquired:
; MBR/EBRs are organized in the chain. We use a loop over MBR/EBRs, but no
; more than MAX_NUM_PARTITION times.
; 4. Prepare things for the loop.
; ebp will hold the sector number for current MBR/EBR.
; [esp] will hold the sector number for current extended partition, if there
; is one.
; [esp+4] will hold the counter that prevents long loops.
push ebp ; save ebp
push MAX_NUM_PARTITIONS ; the counter of max MBRs to process
xor ebp, ebp ; start from sector zero
push ebp ; no extended partition yet
.new_mbr:
; 5. Read the current sector.
; Note that 'read' callback operates with 64-bit sector numbers, so we must
; push additional zero as a high dword of sector number.
mov al, DISKFUNC.read
push 1
stdcall disk_call_driver, ebx, ebp, 0, esp
pop ecx
; 6. If the read has failed, abort the loop.
dec ecx
jnz .mbr_failed
; 7. Check the MBR/EBR signature. If it is wrong, abort the loop.
; Soon we will access the partition table which starts at ebx+0x1BE,
; so we can fill its address right now. If we do it now, then the addressing
; [ecx+0x40] is shorter than [ebx+0x1fe]: one-byte offset vs 4-bytes offset.
lea ecx, [ebx+0x1be] ; ecx -> partition table
cmp word [ecx+0x40], 0xaa55
jnz .mbr_failed
; 8. The MBR is treated differently from EBRs. For MBR we additionally need to
; execute step 9 and possibly step 10.
test ebp, ebp
jnz .mbr
; The partition table can be present or not present. In the first case, we just
; read the MBR. In the second case, we just read the bootsector for a
; filesystem.
; The following algorithm is used to distinguish between these cases.
; A. If at least one entry of the partition table is invalid, this is
; a bootsector. See the description of 'is_partition_table_entry' for
; definition of validity.
; B. If all entries are empty (filesystem type field is zero) and the first
; byte is jmp opcode (0EBh or 0E9h), this is a bootsector which happens to
; have zeros in the place of partition table.
; C. Otherwise, this is an MBR.
; 9. Test for MBR vs bootsector.
; 9a. Check entries. If any is invalid, go to 10 (rule A).
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
add ecx, 10h
call is_partition_table_entry
jc .notmbr
; 9b. Check types of the entries. If at least one is nonzero, go to 11 (rule C).
mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type]
or al, [ecx+PARTITION_TABLE_ENTRY.Type]
jnz .mbr
; 9c. Empty partition table or bootsector with many zeroes? (rule B)
cmp byte [ebx], 0EBh
jz .notmbr
cmp byte [ebx], 0E9h
jnz .mbr
.notmbr:
; 10. This is not an MBR. The media is not partitioned. Create one partition
; which covers all the media and abort the loop.
stdcall disk_add_partition, 0, 0, \
dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4]
jmp .done
.mbr:
; 11. Process all entries of the new MBR/EBR
lea ecx, [ebx+0x1be] ; ecx -> partition table
push 0 ; assume no extended partition
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
add ecx, 10h
call process_partition_table_entry
pop ebp
; 12. Test whether we found a new EBR and should continue the loop.
; 12a. If there was no next EBR, return.
test ebp, ebp
jz .done
; Ok, we have EBR.
; 12b. EBRs addresses are relative to the start of extended partition.
; For simplicity, just abort if an 32-bit overflow occurs; large disks
; are most likely partitioned with GPT, not MBR scheme, since the precise
; calculation here would increase limit just twice at the price of big
; compatibility problems.
pop eax ; load extended partition
add ebp, eax
jc .mbr_failed
; 12c. If extended partition has not yet started, start it.
test eax, eax
jnz @f
mov eax, ebp
@@:
; 12c. If the limit is not exceeded, continue the loop.
dec dword [esp]
push eax ; store extended partition
jnz .new_mbr
.mbr_failed:
.done:
; 13. Cleanup after the loop.
pop eax ; not important anymore
pop eax ; not important anymore
pop ebp ; restore ebp
; 14. Release the buffer.
; 14a. Test whether it is the global buffer or we have allocated it.
cmp ebx, mbr_buffer
jz .release_partition_buffer
; 14b. If we have allocated it, free it.
xchg eax, ebx
call free
jmp .nothing
; 14c. Otherwise, release reference.
.release_partition_buffer:
lock dec [partition_buffer_users]
.nothing:
; 15. Return.
ret
 
; This is an internal function called from disk_scan_partitions. It checks
; whether the entry pointed to by ecx is a valid entry of partition table.
; The entry is valid if the first byte is 0 or 80h, the first sector plus the
; length is less than twice the size of media. Multiplication by two is
; required since the size mentioned in the partition table can be slightly
; greater than the real size.
is_partition_table_entry:
; 1. Check .Bootable field.
mov al, [ecx+PARTITION_TABLE_ENTRY.Bootable]
and al, 7Fh
jnz .invalid
; 3. Calculate first sector + length. Note that .FirstAbsSector is relative
; to the MBR/EBR, so the real sum is ebp + .FirstAbsSector + .Length.
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
add eax, [ecx+PARTITION_TABLE_ENTRY.Length]
adc edx, 0
; 4. Divide by two.
shr edx, 1
rcr eax, 1
; 5. Compare with capacity. If the subtraction (edx:eax) - .Capacity does not
; overflow, this is bad.
sub eax, dword [esi+DISK.MediaInfo.Capacity]
sbb edx, dword [esi+DISK.MediaInfo.Capacity+4]
jnc .invalid
.valid:
; 5. Return success: CF is cleared.
clc
ret
.invalid:
; 6. Return fail: CF is set.
stc
ret
 
; This is an internal function called from disk_scan_partitions. It processes
; the entry pointed to by ecx.
; * If the entry is invalid, just ignore this entry.
; * If the type is zero, just ignore this entry.
; * If the type is one of types for extended partition, store the address
; of this partition as the new MBR in [esp+4].
; * Otherwise, add the partition to the list of partitions for this disk.
; We don't use the type from the entry to identify the file system;
; fs-specific checks do this more reliably.
process_partition_table_entry:
; 1. Check for valid entry. If invalid, return (go to 5).
call is_partition_table_entry
jc .nothing
; 2. Check for empty entry. If invalid, return (go to 5).
mov al, [ecx+PARTITION_TABLE_ENTRY.Type]
test al, al
jz .nothing
; 3. Check for extended partition. If extended, go to 6.
irp type,\
0x05,\ ; DOS: extended partition
0x0f,\ ; WIN95: extended partition, LBA-mapped
0xc5,\ ; DRDOS/secured: extended partition
0xd5 ; Old Multiuser DOS secured: extended partition
{
cmp al, type
jz .extended
}
; 4. If we are here, that is a normal partition. Add it to the list.
; Note that the first sector is relative to MBR/EBR.
mov eax, ebp
xor edx, edx
add eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
adc edx, 0
push ecx
stdcall disk_add_partition, eax, edx, \
[ecx+PARTITION_TABLE_ENTRY.Length], 0
pop ecx
.nothing:
; 5. Return.
ret
.extended:
; 6. If we are here, that is an extended partition. Store the address.
mov eax, [ecx+PARTITION_TABLE_ENTRY.FirstAbsSector]
mov [esp+4], eax
ret
 
; This is an internal function called from disk_scan_partitions and
; process_partition_table_entry. It adds one partition to the list of
; partitions for the media.
proc disk_add_partition stdcall uses ebx edi, start:qword, length:qword
; 1. Check that this partition will not exceed the limit on total number.
cmp [esi+DISK.NumPartitions], MAX_NUM_PARTITIONS
jae .nothing
; 2. Check that this partition does not overlap with any already registered
; partition. Since any file system assumes that the disk data will not change
; outside of its control, such overlap could be destructive.
; Since the number of partitions is usually very small and is guaranteed not
; to be large, the simple linear search is sufficient.
; 2a. Prepare the loop: edi will point to the current item of .Partitions
; array, ecx will be the current item, ebx will hold number of items left.
mov edi, [esi+DISK.Partitions]
mov ebx, [esi+DISK.NumPartitions]
test ebx, ebx
jz .partitionok
.scan_existing:
; 2b. Get the next partition.
mov ecx, [edi]
add edi, 4
; The range [.FirstSector, .FirstSector+.Length) must be either entirely to
; the left of [start, start+length) or entirely to the right.
; 2c. Subtract .FirstSector - start. The possible overflow distinguish between
; cases "to the left" (2e) and "to the right" (2d).
mov eax, dword [ecx+PARTITION.FirstSector]
mov edx, dword [ecx+PARTITION.FirstSector+4]
sub eax, dword [start]
sbb edx, dword [start+4]
jb .less
; 2d. .FirstSector is greater than or equal to start. Check that .FirstSector
; is greater than or equal to start+length; the subtraction
; (.FirstSector-start) - length must not cause overflow. Go to 2g if life is
; good or to 2f in the other case.
sub eax, dword [length]
sbb edx, dword [length+4]
jb .overlap
jmp .next_existing
.less:
; 2e. .FirstSector is less than start. Check that .FirstSector+.Length is less
; than or equal to start. If the addition (.FirstSector-start) + .Length does
; not cause overflow, then .FirstSector + .Length is strictly less than start;
; since the equality is also valid, use decrement preliminarily. Go to 2g or
; 2f depending on the overflow.
sub eax, 1
sbb edx, 0
add eax, dword [ecx+PARTITION.Length]
adc edx, dword [ecx+PARTITION.Length+4]
jnc .next_existing
.overlap:
; 2f. The partition overlaps with previously registered partition. Say warning
; and return with nothing done.
dbgstr 'two partitions overlap, ignoring the last one'
jmp .nothing
.next_existing:
; 2g. The partition does not overlap with the current partition. Continue the
; loop.
dec ebx
jnz .scan_existing
.partitionok:
; 3. The partition has passed tests. Reallocate the partitions array for a new
; entry.
; 3a. Call the allocator.
mov eax, [esi+DISK.NumPartitions]
inc eax ; one more entry
shl eax, 2 ; each entry is dword
call malloc
; 3b. Test the result. If failed, return with nothing done.
test eax, eax
jz .nothing
; 3c. Copy the old array to the new array.
mov edi, eax
push esi
mov ecx, [esi+DISK.NumPartitions]
mov esi, [esi+DISK.Partitions]
rep movsd
pop esi
; 3d. Set the field in the DISK structure to the new array.
xchg [esi+DISK.Partitions], eax
; 3e. Free the old array.
call free
; 4. Recognize the file system.
; 4a. Call the filesystem recognizer. It will allocate the PARTITION structure
; with possible filesystem-specific fields.
call disk_detect_partition
; 4b. Check return value. If zero, return with list not changed; so far only
; the array was reallocated, this is ok for other code.
test eax, eax
jz .nothing
; 5. Insert the new partition to the list.
stosd
inc [esi+DISK.NumPartitions]
; 6. Return.
.nothing:
ret
endp
 
; This is an internal function called from disk_add_partition.
; It tries to recognize the file system on the partition and allocates the
; corresponding PARTITION structure with filesystem-specific fields.
disk_detect_partition:
; This function inherits the stack frame from disk_add_partition. In stdcall
; with ebp-based frame arguments start from ebp+8, since [ebp]=saved ebp
; and [ebp+4]=return address.
virtual at ebp+8
.start dq ?
.length dq ?
end virtual
; Currently no file systems are supported, so just allocate the PARTITION
; structure without extra fields.
; 1. Allocate and check result.
push sizeof.PARTITION
pop eax
call malloc
test eax, eax
jz .nothing
; 2. Fill the common fields: copy .start and .length.
mov edx, dword [.start]
mov dword [eax+PARTITION.FirstSector], edx
mov edx, dword [.start+4]
mov dword [eax+PARTITION.FirstSector+4], edx
mov edx, dword [.length]
mov dword [eax+PARTITION.Length], edx
mov edx, dword [.length+4]
mov dword [eax+PARTITION.Length+4], edx
.nothing:
; 3. Return with eax = pointer to PARTITION or NULL.
ret
 
; This function is called from file_system_lfn.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
; in: esi -> name
; ebp = 0 or rest of name relative to esi
; out: if the handler processes path, it must not return in file_system_lfn,
; but instead pop return address and return directly to the caller
; otherwise simply return
dyndisk_handler:
push ebx edi ; save registers used in file_system_lfn
; 1. Acquire the mutex.
mov ecx, disk_list_mutex
call mutex_lock
; 2. Loop over the list of DISK structures.
; 2a. Initialize.
mov ebx, disk_list
.scan:
; 2b. Get the next item.
mov ebx, [ebx+DISK.Next]
; 2c. Check whether the list is done. If so, go to 3.
cmp ebx, disk_list
jz .notfound
; 2d. Compare names. If names match, go to 5.
mov edi, [ebx+DISK.Name]
push esi
@@:
; esi points to the name from fs operation; it is terminated by zero or slash.
lodsb
test al, al
jz .eoin_dec
cmp al, '/'
jz .eoin
; edi points to the disk name.
inc edi
; edi points to lowercase name, this is a requirement for the driver.
; Characters at esi can have any register. Lowercase the current character.
; This lowercasing works for latin letters and digits; since the disk name
; should not contain other symbols, this is ok.
or al, 20h
cmp al, [edi-1]
jz @b
.wrongname:
; 2f. Names don't match. Continue the loop.
pop esi
jmp .scan
.notfound:
; The loop is done and no name matches.
; 3. Release the mutex.
call mutex_unlock
; 4. Return normally.
pop edi ebx ; restore registers used in file_system_lfn
ret
; part of 2d: the name matches partially, but we must check that this is full
; equality.
.eoin_dec:
dec esi
.eoin:
cmp byte [edi], 0
jnz .wrongname
; We found the addressed DISK structure.
; 5. Reference the disk.
lock inc [ebx+DISK.RefCount]
; 6. Now we are sure that the DISK structure is not going to die at least
; while we are working with it, so release the global mutex.
call mutex_unlock
; 7. Acquire the mutex for media object.
pop edi ; restore edi
lea ecx, [ebx+DISK.MediaLock]
call mutex_lock
; 8. Get the media object. If it is not NULL, reference it.
xor edx, edx
cmp [ebx+DISK.MediaInserted], dl
jz @f
mov edx, ebx
inc [ebx+DISK.MediaRefCount]
@@:
; 9. Now we are sure that the media object, if it exists, is not going to die
; at least while we are working with it, so release the mutex for media object.
call mutex_unlock
mov ecx, ebx
pop ebx eax ; restore ebx, pop return address
; 10. Check whether the fs operation wants to enumerate partitions (go to 11)
; or work with some concrete partition (go to 12).
cmp byte [esi], 0
jnz .haspartition
; 11. The fs operation wants to enumerate partitions.
; 11a. Only "list directory" operation is applicable to /<diskname> path. Check
; the operation code. If wrong, go to 13.
cmp dword [ebx], 1
jnz .access_denied
; 11b. If the media is inserted, use 'fs_dyndisk_next' as an enumeration
; procedure. Otherwise, use 'fs_dyndisk_next_nomedia'.
mov esi, fs_dyndisk_next_nomedia
test edx, edx
jz @f
mov esi, fs_dyndisk_next
@@:
; 11c. Let the procedure from fs_lfn.inc do the job.
jmp file_system_lfn.maindir_noesi
.haspartition:
; 12. The fs operation has specified some partition.
; 12a. Store parameters for callback functions.
push edx
push ecx
; 12b. Store callback functions.
push dyndisk_cleanup
push fs_dyndisk
mov edi, esp
; 12c. Let the procedure from fs_lfn.inc do the job.
jmp file_system_lfn.found2
.access_denied:
; 13. Fail the operation with the appropriate code.
mov dword [esp+32], ERROR_ACCESS_DENIED
.cleanup:
; 14. Cleanup.
mov esi, ecx ; disk*dereference assume that esi points to DISK
.cleanup_esi:
test edx, edx ; if there are no media, we didn't reference it
jz @f
call disk_media_dereference
@@:
call disk_dereference
; 15. Return.
ret
 
; This is a callback for cleaning up things called from file_system_lfn.found2.
dyndisk_cleanup:
mov esi, [edi+8]
mov edx, [edi+12]
jmp dyndisk_handler.cleanup_esi
 
; This is a callback for enumerating partitions called from
; file_system_lfn.maindir in the case of inserted media.
; It just increments eax until DISK.NumPartitions reached and then
; cleans up.
fs_dyndisk_next:
cmp eax, [ecx+DISK.NumPartitions]
jae .nomore
inc eax
clc
ret
.nomore:
pusha
mov esi, ecx
call disk_media_dereference
call disk_dereference
popa
stc
ret
 
; This is a callback for enumerating partitions called from
; file_system_lfn.maindir in the case of missing media.
; In this case we create one pseudo-partition.
fs_dyndisk_next_nomedia:
cmp eax, 1
jae .nomore
inc eax
clc
ret
.nomore:
pusha
mov esi, ecx
call disk_dereference
popa
stc
ret
 
; This is a callback for doing real work with selected partition.
; Currently this is just placeholder, since no file systems are supported.
; edi = esp -> {dd fs_dyndisk, dd dyndisk_cleanup, dd pointer to DISK, dd media object}
; ecx = partition number, esi+ebp = ASCIIZ name
fs_dyndisk:
dec ecx ; convert to zero-based partition index
pop edx edx edx eax ; edx = pointer to DISK, eax = NULL or edx
test eax, eax
jz .nomedia
.main:
cmp ecx, [edx+DISK.NumPartitions]
jae .notfound
mov dword [esp+32], ERROR_UNKNOWN_FS
.cleanup:
mov esi, edx
call disk_media_dereference
call disk_dereference
ret
.notfound:
mov dword [esp+32], ERROR_FILE_NOT_FOUND
jmp .cleanup
.nomedia:
test ecx, ecx
jnz .notfound
test byte [edx+DISK.DriverFlags], DISK_NO_INSERT_NOTIFICATION
jz .deverror
; if the driver does not support insert notifications and we are the only fs
; operation with this disk, issue the fake insert notification; if media is
; still not inserted, 'disk_media_changed' will detect this and do nothing
;;; push ebx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaRefCount], 1
jnz .noluck
call mutex_unlock
push edx
stdcall disk_media_changed, edx, 1
pop edx
lea ecx, [edx+DISK.MediaLock]
call mutex_lock
cmp [edx+DISK.MediaInserted], 0
jz .noluck
lock inc [edx+DISK.MediaRefCount]
call mutex_unlock
xor ecx, ecx
jmp .main
.noluck:
call mutex_unlock
.deverror:
mov dword [esp+32], ERROR_DEVICE
mov esi, edx
call disk_dereference
ret
 
; This function is called from file_system_lfn.
; This handler is called when virtual root is enumerated
; and must return all items which can be handled by this.
; It is called several times, first time with eax=0
; in: eax = 0 for first call, previously returned value for subsequent calls
; out: eax = 0 => no more items
; eax != 0 => buffer pointed to by edi contains name of item
dyndisk_enum_root:
push edx ; save register used in file_system_lfn
mov ecx, disk_list_mutex ; it will be useful
; 1. If this is the first call, acquire the mutex and initialize.
test eax, eax
jnz .notfirst
call mutex_lock
mov eax, disk_list
.notfirst:
; 2. Get next item.
mov eax, [eax+DISK.Next]
; 3. If there are no more items, go to 6.
cmp eax, disk_list
jz .last
; 4. Copy name from the DISK structure to edi.
push eax esi
mov esi, [eax+DISK.Name]
@@:
lodsb
stosb
test al, al
jnz @b
pop esi eax
; 5. Return with eax = item.
pop edx ; restore register used in file_system_lfn
ret
.last:
; 6. Release the mutex and return with eax = 0.
call mutex_unlock
xor eax, eax
pop edx ; restore register used in file_system_lfn
ret
/kernel/branches/net/blkdev/disk_cache.inc
0,0 → 1,592
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
; This function is intended to replace the old 'hd_read' function when
; [hdd_appl_data] = 0, so its input/output parameters are the same, except
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'.
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 0
call hd_read
mov [hdd_appl_data], 1 ; restore to default state
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
jmp fs_read32_common
 
; This function is intended to replace the old 'hd_read' function when
; [hdd_appl_data] = 1, so its input/output parameters are the same, except
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'.
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_read32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_read.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 1
jmp hd_read
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
 
; This label is the common part of fs_read32_sys and fs_read32_app.
fs_read32_common:
; 1. Check that the required sector is inside the partition. If no, return
; DISK_STATUS_END_OF_MEDIA.
cmp dword [ebp+PARTITION.Length+4], 0
jnz @f
cmp dword [ebp+PARTITION.Length], eax
ja @f
mov eax, DISK_STATUS_END_OF_MEDIA
pop ecx
ret
@@:
; 2. Get the absolute sector on the disk.
push edx
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
adc edx, dword [ebp+PARTITION.FirstSector+4]
; 3. If there is no cache for this disk, just pass the request to the driver.
cmp [ecx+DISKCACHE.pointer], 0
jnz .scancache
push 1
push esp ; numsectors
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov al, DISKFUNC.read
call disk_call_driver
pop ecx
pop edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push esi edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
.sector_hi dd ?
.cache dd ?
end virtual
; The following code is inherited from hd_read. The differences are:
; all code is protected by the cache lock; instead of static calls
; to hd_read_dma/hd_read_pio/bd_read the dynamic call to DISKFUNC.read is used;
; sector is 64-bit, not 32-bit.
call mutex_lock
mov eax, [.sector_lo]
mov edx, [.sector_hi]
mov esi, [ecx+DISKCACHE.pointer]
mov ecx, [ecx+DISKCACHE.sad_size]
add esi, 12
 
mov edi, 1
 
.hdreadcache:
 
cmp dword [esi+8], 0 ; empty
je .nohdcache
 
cmp [esi], eax ; correct sector
jne .nohdcache
cmp [esi+4], edx ; correct sector
je .yeshdcache
 
.nohdcache:
 
add esi, 12
inc edi
dec ecx
jnz .hdreadcache
 
mov esi, [.cache]
call find_empty_slot64 ; ret in edi
test eax, eax
jnz .read_done
 
push 1
push esp
push edx
push [.sector_lo+12]
mov ecx, [.cache]
mov eax, edi
shl eax, 9
add eax, [ecx+DISKCACHE.data]
push eax
mov esi, [ebp+PARTITION.Disk]
mov al, DISKFUNC.read
call disk_call_driver
pop ecx
dec ecx
jnz .read_done
 
mov ecx, [.cache]
lea eax, [edi*3]
mov esi, [ecx+DISKCACHE.pointer]
lea esi, [eax*4+esi]
 
mov eax, [.sector_lo]
mov edx, [.sector_hi]
mov [esi], eax ; sector number
mov [esi+4], edx ; sector number
mov dword [esi+8], 1; hd read - mark as same as in hd
 
.yeshdcache:
 
mov esi, edi
mov ecx, [.cache]
shl esi, 9
add esi, [ecx+DISKCACHE.data]
 
mov edi, ebx
mov ecx, 512/4
rep movsd ; move data
xor eax, eax ; successful read
.read_done:
mov ecx, [.cache]
push eax
call mutex_unlock
pop eax
add esp, 12
pop edi esi edx ecx
ret
 
; This function is intended to replace the old 'hd_write' function when
; [hdd_appl_data] = 0, so its input/output parameters are the same, except
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'.
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_sys:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 0
call hd_write
mov [hdd_appl_data], 1 ; restore to default state
ret
@@:
; In the normal case, save ecx, set ecx to SysCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.SysCache
jmp fs_write32_common
 
; This function is intended to replace the old 'hd_write' function when
; [hdd_appl_data] = 1, so its input/output parameters are the same, except
; that it can't use the global variables 'hd_error' and 'hdd_appl_data'.
; in: eax = sector, ebx = buffer, ebp = pointer to PARTITION structure
; eax is relative to partition start
; out: eax = error code; 0 = ok
fs_write32_app:
; Compatibility hack: if PARTITION.Disk is 'old', there is no DISK structure,
; this request should be processed by hd_write.
cmp [ebp+PARTITION.Disk], 'old'
jnz @f
mov [hdd_appl_data], 1
jmp hd_write
@@:
; In the normal case, save ecx, set ecx to AppCache and let the common part
; do its work.
push ecx
mov ecx, [ebp+PARTITION.Disk]
add ecx, DISK.AppCache
 
; This label is the common part of fs_read32_sys and fs_read32_app.
fs_write32_common:
; 1. Check that the required sector is inside the partition. If no, return
; DISK_STATUS_END_OF_MEDIA.
cmp dword [ebp+PARTITION.Length+4], 0
jnz @f
cmp dword [ebp+PARTITION.Length], eax
ja @f
mov eax, DISK_STATUS_END_OF_MEDIA
pop ecx
ret
@@:
push edx
; 2. Get the absolute sector on the disk.
xor edx, edx
add eax, dword [ebp+PARTITION.FirstSector]
adc edx, dword [ebp+PARTITION.FirstSector+4]
; 3. If there is no cache for this disk, just pass request to the driver.
cmp [ecx+DISKCACHE.pointer], 0
jnz .scancache
push 1
push esp ; numsectors
push edx ; startsector
push eax ; startsector
push ebx ; buffer
mov al, DISKFUNC.write
call disk_call_driver
pop ecx
pop edx
pop ecx
ret
.scancache:
; 4. Scan the cache.
push esi edi ecx ; scan cache
push edx eax
virtual at esp
.sector_lo dd ?
.sector_hi dd ?
.cache dd ?
end virtual
; The following code is inherited from hd_write. The differences are:
; all code is protected by the cache lock;
; sector is 64-bit, not 32-bit.
call mutex_lock
 
; check if the cache already has the sector and overwrite it
mov eax, [.sector_lo]
mov edx, [.sector_hi]
mov esi, [ecx+DISKCACHE.pointer]
mov ecx, [ecx+DISKCACHE.sad_size]
add esi, 12
 
mov edi, 1
 
.hdwritecache:
cmp dword [esi+8], 0 ; if cache slot is empty
je .not_in_cache_write
 
cmp [esi], eax ; if the slot has the sector
jne .not_in_cache_write
cmp [esi+4], edx ; if the slot has the sector
je .yes_in_cache_write
 
.not_in_cache_write:
 
add esi, 12
inc edi
dec ecx
jnz .hdwritecache
 
; sector not found in cache
; write the block to a new location
 
mov esi, [.cache]
call find_empty_slot64 ; ret in edi
test eax, eax
jne .hd_write_access_denied
 
mov ecx, [.cache]
lea eax, [edi*3]
mov esi, [ecx+DISKCACHE.pointer]
lea esi, [eax*4+esi]
 
mov eax, [.sector_lo]
mov edx, [.sector_hi]
mov [esi], eax ; sector number
mov [esi+4], edx ; sector number
 
.yes_in_cache_write:
 
mov dword [esi+4], 2 ; write - differs from hd
 
shl edi, 9
mov ecx, [.cache]
add edi, [ecx+DISKCACHE.data]
 
mov esi, ebx
mov ecx, 512/4
rep movsd ; move data
xor eax, eax ; success
.hd_write_access_denied:
mov ecx, [.cache]
push eax
call mutex_unlock
pop eax
add esp, 12
pop edi esi edx ecx
ret
 
; This internal function is called from fs_read32_* and fs_write32_*. It is the
; analogue of find_empty_slot for 64-bit sectors.
find_empty_slot64:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 12.5% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
.search_again:
mov ecx, [esi+DISKCACHE.sad_size]
mov edi, [esi+DISKCACHE.search_start]
shr ecx, 3
.search_for_empty:
inc edi
cmp edi, [esi+DISKCACHE.sad_size]
jbe .inside_cache
mov edi, 1
.inside_cache:
lea eax, [edi*3]
shl eax, 2
add eax, [esi+DISKCACHE.pointer]
cmp dword [eax+8], 2
jb .found_slot ; it's empty or read
dec ecx
jnz .search_for_empty
call write_cache64 ; no empty slots found, write all
test eax, eax
jne .found_slot_access_denied
jmp .search_again ; and start again
.found_slot:
mov [esi+DISKCACHE.search_start], edi
xor eax, eax ; success
.found_slot_access_denied:
ret
 
; This function is intended to replace the old 'write_cache' function.
proc write_cache64 uses ecx edx esi edi
locals
cache_chain_started dd ?
cache_chain_size dd ?
cache_chain_pos dd ?
cache_chain_ptr dd ?
endl
; If there is no cache for this disk, nothing to do.
cmp [esi+DISKCACHE.pointer], 0
jz .flush
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
 
; write difference ( 2 ) from cache to DISK
mov ecx, [esi+DISKCACHE.sad_size]
mov esi, [esi+DISKCACHE.pointer]
add esi, 12
mov edi, 1
.write_cache_more:
cmp dword [esi+8], 2 ; if cache slot is not different
jne .write_chain
mov dword [esi+8], 1 ; same as in hd
mov eax, [esi]
mov edx, [esi+4] ; edx:eax = sector to write
; Îáúåäèíÿåì çàïèñü öåïî÷êè ïîñëåäîâàòåëüíûõ ñåêòîðîâ â îäíî îáðàùåíèå ê äèñêó
cmp ecx, 1
jz .nonext
cmp dword [esi+12+8], 2
jnz .nonext
push eax edx
add eax, 1
adc edx, 0
cmp eax, [esi+12]
jnz @f
cmp edx, [esi+12+4]
@@:
pop edx 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], 16
jnz .continue
jmp .write_chain
.nonext:
call .flush_cache_chain
test eax, eax
jnz .nothing
mov [cache_chain_size], 1
mov [cache_chain_ptr], esi
call .write_cache_sector
test eax, eax
jnz .nothing
jmp .continue
.write_chain:
call .flush_cache_chain
test eax, eax
jnz .nothing
.continue:
add esi, 12
inc edi
dec ecx
jnz .write_cache_more
call .flush_cache_chain
test eax, eax
jnz .nothing
.flush:
mov esi, [ebp]
mov esi, [esi+PARTITION.Disk]
mov al, DISKFUNC.flush
call disk_call_driver
.nothing:
ret
 
.flush_cache_chain:
xor eax, eax
cmp [cache_chain_started], eax
jz @f
call .write_cache_chain
mov [cache_chain_started], 0
@@:
retn
 
.write_cache_sector:
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
.write_cache_chain:
pusha
mov edi, [cache_chain_pos]
mov ecx, [ebp-12]
shl edi, 9
add edi, [ecx+DISKCACHE.data]
mov ecx, [cache_chain_size]
push ecx
push esp ; numsectors
mov eax, [cache_chain_ptr]
pushd [eax+4]
pushd [eax] ; startsector
push edi ; buffer
mov esi, [ebp]
mov esi, [esi+PARTITION.Disk]
mov al, DISKFUNC.write
call disk_call_driver
pop ecx
mov [esp+28], eax
popa
retn
endp
 
; This internal function is called from disk_add to initialize the caching for
; a new DISK.
; The algorithm is inherited from getcache.inc: take 1/32 part of the available
; physical memory, round down to 8 pages, limit by 128K from below and by 1M
; from above. Reserve 1/8 part of the cache for system data and 7/8 for app
; data.
; After the size is calculated, but before the cache is allocated, the device
; driver can adjust the size. In particular, setting size to zero disables
; caching: there is no sense in a cache for a ramdisk. In fact, such action
; is most useful example of a non-trivial adjustment.
; esi = pointer to DISK structure
disk_init_cache:
; 1. Calculate the suggested cache size.
; 1a. Get the size of free physical memory in pages.
mov eax, [pg_data.pages_free]
; 1b. Use the value to calculate the size.
shl eax, 12 - 5 ; 1/32 of it in bytes
and eax, -8*4096 ; round down to the multiple of 8 pages
; 1c. Force lower and upper limits.
cmp eax, 1024*1024
jb @f
mov eax, 1024*1024
@@:
cmp eax, 128*1024
ja @f
mov eax, 128*1024
@@:
; 1d. Give a chance to the driver to adjust the size.
push eax
mov al, DISKFUNC.adjust_cache_size
call disk_call_driver
; Cache size calculated.
mov [esi+DISK.cache_size], eax
test eax, eax
jz .nocache
; 2. Allocate memory for the cache.
; 2a. Call the allocator.
stdcall kernel_alloc, eax
test eax, eax
jnz @f
; 2b. If it failed, say a message and return with eax = 0.
dbgstr 'no memory for disk cache'
jmp .nothing
@@:
; 3. Fill two DISKCACHE structures.
mov [esi+DISK.SysCache.pointer], eax
lea ecx, [esi+DISK.SysCache.mutex]
call mutex_init
lea ecx, [esi+DISK.AppCache.mutex]
call mutex_init
; The following code is inherited from getcache.inc.
mov edx, [esi+DISK.SysCache.pointer]
and [esi+DISK.SysCache.search_start], 0
and [esi+DISK.AppCache.search_start], 0
mov eax, [esi+DISK.cache_size]
shr eax, 3
mov [esi+DISK.SysCache.data_size], eax
add edx, eax
imul eax, 7
mov [esi+DISK.AppCache.data_size], eax
mov [esi+DISK.AppCache.pointer], edx
 
mov eax, [esi+DISK.SysCache.data_size]
push ebx
call calculate_for_hd
pop ebx
add eax, [esi+DISK.SysCache.pointer]
mov [esi+DISK.SysCache.data], eax
mov [esi+DISK.SysCache.sad_size], ecx
 
push edi
mov edi, [esi+DISK.SysCache.pointer]
lea ecx, [ecx*3]
xor eax, eax
rep stosd
pop edi
 
mov eax, [esi+DISK.AppCache.data_size]
push ebx
call calculate_for_hd
pop ebx
add eax, [esi+DISK.AppCache.pointer]
mov [esi+DISK.AppCache.data], eax
mov [esi+DISK.AppCache.sad_size], ecx
 
push edi
mov edi, [esi+DISK.AppCache.pointer]
lea ecx, [ecx*3]
xor eax, eax
rep stosd
pop edi
 
; 4. Return with nonzero al.
mov al, 1
; 5. Return.
.nothing:
ret
; No caching is required for this driver. Zero cache pointers and return with
; nonzero al.
.nocache:
mov [esi+DISK.SysCache.pointer], eax
mov [esi+DISK.AppCache.pointer], eax
mov al, 1
ret
 
; This internal function is called from disk_media_dereference to free the
; allocated cache, if there is one.
; esi = pointer to DISK structure
disk_free_cache:
; The algorithm is straightforward.
mov eax, [esi+DISK.SysCache.pointer]
test eax, eax
jz .nothing
stdcall kernel_free, eax
.nothing:
ret
/kernel/branches/net/blkdev/fdc.inc
10,62 → 10,62
 
iglobal
;function pointers.
fdc_irq_func dd fdc_null
fdc_irq_func dd fdc_null
endg
 
uglobal
dmasize db 0x0
dmamode db 0x0
dmasize db 0x0
dmamode db 0x0
endg
 
fdc_init: ;start with clean tracks.
mov edi,OS_BASE+0xD201
mov al,0
mov ecx,160
rep stosb
ret
fdc_init: ;start with clean tracks.
mov edi, OS_BASE+0xD201
mov al, 0
mov ecx, 160
rep stosb
ret
 
fdc_irq:
call [fdc_irq_func]
call [fdc_irq_func]
fdc_null:
ret
ret
 
save_image:
call reserve_flp
call restorefatchain
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_save_image
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
mov esi,RAMDISK
call SeekTrack
call reserve_flp
call restorefatchain
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_save_image
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 1; Ñåêòîð
mov esi, RAMDISK
call SeekTrack
save_image_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
push esi
call take_data_from_application_1
pop esi
add esi, 512
call WriteSectWithRetr
; call WriteSector
cmp [FDC_Status],0
jne unnecessary_save_image
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_image_1
mov [FDD_Sector],1
inc [FDD_Head]
cmp [FDD_Head],2
jne save_image_1
mov [FDD_Head],0
inc [FDD_Track]
call SeekTrack
cmp [FDD_Track],80
jne save_image_1
cmp [FDC_Status], 0
jne unnecessary_save_image
inc [FDD_Sector]
cmp [FDD_Sector], 19
jne save_image_1
mov [FDD_Sector], 1
inc [FDD_Head]
cmp [FDD_Head], 2
jne save_image_1
mov [FDD_Head], 0
inc [FDD_Track]
call SeekTrack
cmp [FDD_Track], 80
jne save_image_1
unnecessary_save_image:
mov [fdc_irq_func],fdc_null
popa
mov [flp_status],0
ret
mov [fdc_irq_func], fdc_null
popa
mov [flp_status], 0
ret
 
/kernel/branches/net/blkdev/flp_drv.inc
19,12 → 19,12
; mov edi,[edi+TASKDATA.mem_start]
; add edi,ecx
give_back_application_data_1:
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000
xor ecx, ecx
mov cx, 128
cld
rep movsd
ret
 
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè
; mov esi,[TASK_BASE]
31,12 → 31,12
; mov esi,[esi+TASKDATA.mem_start]
; add esi,ecx
take_data_from_application_1:
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000
xor ecx, ecx
mov cx, 128
cld
rep movsd
ret
 
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status)
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå
91,28 → 91,28
;*************************************
Init_FDC_DMA:
pushad
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov al,6 ; mask channel 2 so we can reprogram it.
out 0x0a,al
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b,al
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov eax,0xD000
out 0x04,al ; set the channel 2 starting address to 0
shr eax,8
out 0x04,al
shr eax,8
out 0x81,al
mov al,0
out 0x0c, al ; reset flip-flop
mov al, 0xff ;set count (actual size -1)
out 0x5, al
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5,al
mov al,2
out 0xa,al
mov al, 0
out 0x0c, al; reset the flip-flop to a known state.
mov al, 6 ; mask channel 2 so we can reprogram it.
out 0x0a, al
mov al, [dmamode]; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b, al
mov al, 0
out 0x0c, al; reset the flip-flop to a known state.
mov eax, 0xD000
out 0x04, al; set the channel 2 starting address to 0
shr eax, 8
out 0x04, al
shr eax, 8
out 0x81, al
mov al, 0
out 0x0c, al; reset flip-flop
mov al, 0xff;set count (actual size -1)
out 0x5, al
mov al, 0x1;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5, al
mov al, 2
out 0xa, al
popad
ret
 
123,30 → 123,30
;***********************************
FDCDataOutput:
; pusha
push eax ecx edx
mov AH,AL ;çàïîìíèòü áàéò â AH
push eax ecx edx
mov AH, AL ;çàïîìíèòü áàéò â AH
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà
mov [FDC_Status],FDC_Normal
mov [FDC_Status], FDC_Normal
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà
@@TestRS:
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS
and AL, 0C0h ;âûäåëèòü ðàçðÿäû 6 è 7
cmp AL, 80h ;ïðîâåðèòü ðàçðÿäû 6 è 7
je @@OutByteToFDC
loop @@TestRS
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
jmp @@End_5
mov [FDC_Status], FDC_TimeOut
jmp @@End_5
; Âûâåñòè áàéò â ïîðò äàííûõ
@@OutByteToFDC:
inc DX
mov AL,AH
out DX,AL
mov AL, AH
out DX, AL
@@End_5:
; popa
pop edx ecx eax
pop edx ecx eax
ret
 
;******************************************
159,24 → 159,25
push ECX
push DX
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà
mov [FDC_Status],FDC_Normal
mov [FDC_Status], FDC_Normal
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà
mov DX, 3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
xor CX, CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà
@@TestRS_1:
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7
in AL, DX ;ïðî÷èòàòü ðåãèñòð RS
and AL, 0C0h ;âûäëèòü ðàçðÿäû 6 è 7
cmp AL, 0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7
je @@GetByteFromFDC
loop @@TestRS_1
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
jmp @@End_6
mov [FDC_Status], FDC_TimeOut
jmp @@End_6
; Ââåñòè áàéò èç ïîðòà äàííûõ
@@GetByteFromFDC:
inc DX
in AL,DX
@@End_6: pop DX
in AL, DX
@@End_6:
pop DX
pop ECX
ret
 
185,7 → 186,7
;*********************************************
FDCInterrupt:
; Óñòàíîâèòü ôëàã ïðåðûâàíè
mov [FDD_IntFlag],1
mov [FDD_IntFlag], 1
ret
 
 
194,8 → 195,8
;* ÍÃÌÄ *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func],FDCInterrupt
ret
mov [fdc_irq_func], FDCInterrupt
ret
 
;*******************************************
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ *
203,26 → 204,27
WaitFDCInterrupt:
pusha
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè
mov [FDC_Status],FDC_Normal
mov [FDC_Status], FDC_Normal
; Ñáðîñèòü ôëàã ïðåðûâàíè
mov [FDD_IntFlag],0
mov [FDD_IntFlag], 0
; Îáíóëèòü ñ÷åò÷èê òèêîâ
mov eax,[timer_ticks]
mov [TickCounter],eax
mov eax, [timer_ticks]
mov [TickCounter], eax
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ
@@TestRS_2:
cmp [FDD_IntFlag],0
cmp [FDD_IntFlag], 0
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ
mov eax, [timer_ticks]
sub eax, [TickCounter]
cmp eax, 50 ;25 ;5 ;îæèäàòü 5 òèêîâ
jb @@TestRS_2
; jl @@TestRS_2
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
mov [FDC_Status], FDC_TimeOut
; mov [flp_status],0
@@End_7: popa
@@End_7:
popa
ret
 
;*********************************
232,40 → 234,40
pusha
; cmp [fdd_motor_status],1
; je fdd_motor_on
mov al,[flp_number]
cmp [fdd_motor_status],al
mov al, [flp_number]
cmp [fdd_motor_status], al
je fdd_motor_on
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,0
out DX,AL
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL, 0
out DX, AL
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà
cmp [flp_number],1
cmp [flp_number], 1
jne FDDMotorON_B
; call FDDMotorOFF_B
mov AL,1Ch ; Floppy A
mov AL, 1Ch ; Floppy A
jmp FDDMotorON_1
FDDMotorON_B:
; call FDDMotorOFF_A
mov AL,2Dh ; Floppy B
mov AL, 2Dh ; Floppy B
FDDMotorON_1:
out DX,AL
out DX, AL
; Îáíóëèòü ñ÷åò÷èê òèêîâ
mov eax,[timer_ticks]
mov [TickCounter],eax
mov eax, [timer_ticks]
mov [TickCounter], eax
; Îæèäàòü 0,5 ñ
@@dT:
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;10
mov eax, [timer_ticks]
sub eax, [TickCounter]
cmp eax, 50 ;10
jb @@dT
cmp [flp_number],1
cmp [flp_number], 1
jne fdd_motor_on_B
mov [fdd_motor_status],1
mov [fdd_motor_status], 1
jmp fdd_motor_on
fdd_motor_on_B:
mov [fdd_motor_status],2
mov [fdd_motor_status], 2
fdd_motor_on:
call save_timer_fdd_motor
popa
275,8 → 277,8
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ *
;*****************************************
save_timer_fdd_motor:
mov eax,[timer_ticks]
mov [timer_fdd_motor],eax
mov eax, [timer_ticks]
mov [timer_fdd_motor], eax
ret
 
;*****************************************
284,16 → 286,16
;*****************************************
align 4
check_fdd_motor_status:
cmp [fdd_motor_status],0
cmp [fdd_motor_status], 0
je end_check_fdd_motor_status_1
mov eax,[timer_ticks]
sub eax,[timer_fdd_motor]
cmp eax,500
mov eax, [timer_ticks]
sub eax, [timer_fdd_motor]
cmp eax, 500
jb end_check_fdd_motor_status
call FDDMotorOFF
mov [fdd_motor_status],0
mov [fdd_motor_status], 0
end_check_fdd_motor_status_1:
mov [flp_status],0
mov [flp_status], 0
end_check_fdd_motor_status:
ret
 
303,7 → 305,7
FDDMotorOFF:
push AX
push DX
cmp [flp_number],1
cmp [flp_number], 1
jne FDDMotorOFF_1
call FDDMotorOFF_A
jmp FDDMotorOFF_2
313,20 → 315,20
pop DX
pop AX
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè
mov [root_read],0
mov [flp_fat],0
mov [root_read], 0
mov [flp_fat], 0
ret
 
FDDMotorOFF_A:
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,0Ch ; Floppy A
out DX,AL
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL, 0Ch ; Floppy A
out DX, AL
ret
 
FDDMotorOFF_B:
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,5h ; Floppy B
out DX,AL
mov DX, 3F2h;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL, 5h ; Floppy B
out DX, AL
ret
 
;*******************************
336,9 → 338,9
pusha
call save_timer_fdd_motor
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà"
mov AL,07h
mov AL, 07h
call FDCDataOutput
mov AL,00h
mov AL, 00h
call FDCDataOutput
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè
call WaitFDCInterrupt
361,45 → 363,45
pusha
call save_timer_fdd_motor
; Ïîäàòü êîìàíäó "Ïîèñê"
mov AL,0Fh
mov AL, 0Fh
call FDCDataOutput
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë
mov AL,[FDD_Head]
shl AL,2
mov AL, [FDD_Head]
shl AL, 2
call FDCDataOutput
; Ïåðåäàòü áàéò íîìåðà äîðîæêè
mov AL,[FDD_Track]
mov AL, [FDD_Track]
call FDCDataOutput
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
cmp [FDC_Status], FDC_Normal
jne @@Exit
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà
mov AL,08h
mov AL, 08h
call FDCDataOutput
call FDCDataInput
mov [FDC_ST0],AL
mov [FDC_ST0], AL
call FDCDataInput
mov [FDC_C],AL
mov [FDC_C], AL
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà
; Ïîèñê çàâåðøåí?
test [FDC_ST0],100000b
test [FDC_ST0], 100000b
je @@Err
; Çàäàííûé òðåê íàéäåí?
mov AL,[FDC_C]
cmp AL,[FDD_Track]
mov AL, [FDC_C]
cmp AL, [FDD_Track]
jne @@Err
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì?
mov AL,[FDC_ST0]
and AL,100b
shr AL,2
cmp AL,[FDD_Head]
mov AL, [FDC_ST0]
and AL, 100b
shr AL, 2
cmp AL, [FDD_Head]
jne @@Err
; Îïåðàöèÿ çàâåðøåíà óñïåøíî
mov [FDC_Status],FDC_Normal
jmp @@Exit
mov [FDC_Status], FDC_Normal
jmp @@Exit
@@Err: ; Òðåê íå íàéäåí
mov [FDC_Status],FDC_TrackNotFound
mov [FDC_Status], FDC_TrackNotFound
; mov [flp_status],0
@@Exit:
call save_timer_fdd_motor
420,43 → 422,44
pushad
call save_timer_fdd_motor
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ
mov AX,0
mov DX,03F7h
out DX,AL
mov AX, 0
mov DX, 03F7h
out DX, AL
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè
mov [dmamode],0x46
mov [dmamode], 0x46
call Init_FDC_DMA
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ"
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå
mov AL, 0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
mov AL, [FDD_Head]
shl AL, 2
call FDCDataOutput
mov AL,[FDD_Track]
mov AL, [FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
mov AL, [FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
mov AL, [FDD_Sector]
call FDCDataOutput
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
call FDCDataOutput
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
mov AL, 18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
call FDCDataOutput
mov AL,1Bh ;çíà÷åíèå GPL
mov AL, 1Bh ;çíà÷åíèå GPL
call FDCDataOutput
mov AL,0FFh ;çíà÷åíèå DTL
mov AL, 0FFh;çíà÷åíèå DTL
call FDCDataOutput
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
cmp [FDC_Status], FDC_Normal
jne @@Exit_1
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè
call GetStatusInfo
test [FDC_ST0],11011000b
test [FDC_ST0], 11011000b
jnz @@Err_1
mov [FDC_Status],FDC_Normal
jmp @@Exit_1
@@Err_1: mov [FDC_Status],FDC_SectorNotFound
mov [FDC_Status], FDC_Normal
jmp @@Exit_1
@@Err_1:
mov [FDC_Status], FDC_SectorNotFound
; mov [flp_status],0
@@Exit_1:
call save_timer_fdd_motor
476,25 → 479,25
ReadSectWithRetr:
pusha
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè
mov [RecalRepCounter],0
mov [RecalRepCounter], 0
@@TryAgain:
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè
mov [ReadRepCounter],0
mov [ReadRepCounter], 0
@@ReadSector_1:
call ReadSector
cmp [FDC_Status],0
cmp [FDC_Status], 0
je @@Exit_2
cmp [FDC_Status],1
cmp [FDC_Status], 1
je @@Err_3
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè
inc [ReadRepCounter]
cmp [ReadRepCounter],3
cmp [ReadRepCounter], 3
jb @@ReadSector_1
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
cmp [RecalRepCounter], 3
jb @@TryAgain
; mov [flp_status],0
@@Exit_2:
501,7 → 504,7
popa
ret
@@Err_3:
mov [flp_status],0
mov [flp_status], 0
popa
ret
 
519,43 → 522,44
pushad
call save_timer_fdd_motor
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ
mov AX,0
mov DX,03F7h
out DX,AL
mov AX, 0
mov DX, 03F7h
out DX, AL
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè
mov [dmamode],0x4A
mov [dmamode], 0x4A
call Init_FDC_DMA
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ"
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå
mov AL, 0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
mov AL, [FDD_Head]
shl AL, 2
call FDCDataOutput
mov AL,[FDD_Track]
mov AL, [FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
mov AL, [FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
mov AL, [FDD_Sector]
call FDCDataOutput
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
mov AL, 2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
call FDCDataOutput
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
mov AL, 18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
call FDCDataOutput
mov AL,1Bh ;çíà÷åíèå GPL
mov AL, 1Bh ;çíà÷åíèå GPL
call FDCDataOutput
mov AL,0FFh ;çíà÷åíèå DTL
mov AL, 0FFh;çíà÷åíèå DTL
call FDCDataOutput
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
cmp [FDC_Status], FDC_Normal
jne @@Exit_3
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè
call GetStatusInfo
test [FDC_ST0],11000000b ;11011000b
test [FDC_ST0], 11000000b ;11011000b
jnz @@Err_2
mov [FDC_Status],FDC_Normal
jmp @@Exit_3
@@Err_2: mov [FDC_Status],FDC_SectorNotFound
mov [FDC_Status], FDC_Normal
jmp @@Exit_3
@@Err_2:
mov [FDC_Status], FDC_SectorNotFound
@@Exit_3:
call save_timer_fdd_motor
popad
574,31 → 578,31
WriteSectWithRetr:
pusha
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè
mov [RecalRepCounter],0
mov [RecalRepCounter], 0
@@TryAgain_1:
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè
mov [ReadRepCounter],0
mov [ReadRepCounter], 0
@@WriteSector_1:
call WriteSector
cmp [FDC_Status],0
cmp [FDC_Status], 0
je @@Exit_4
cmp [FDC_Status],1
cmp [FDC_Status], 1
je @@Err_4
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè
inc [ReadRepCounter]
cmp [ReadRepCounter],3
cmp [ReadRepCounter], 3
jb @@WriteSector_1
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
cmp [RecalRepCounter], 3
jb @@TryAgain_1
@@Exit_4:
popa
ret
@@Err_4:
mov [flp_status],0
mov [flp_status], 0
popa
ret
 
608,19 → 612,19
GetStatusInfo:
push AX
call FDCDataInput
mov [FDC_ST0],AL
mov [FDC_ST0], AL
call FDCDataInput
mov [FDC_ST1],AL
mov [FDC_ST1], AL
call FDCDataInput
mov [FDC_ST2],AL
mov [FDC_ST2], AL
call FDCDataInput
mov [FDC_C],AL
mov [FDC_C], AL
call FDCDataInput
mov [FDC_H],AL
mov [FDC_H], AL
call FDCDataInput
mov [FDC_R],AL
mov [FDC_R], AL
call FDCDataInput
mov [FDC_N],AL
mov [FDC_N], AL
pop AX
ret
 
/kernel/branches/net/blkdev/hd_drv.inc
19,33 → 19,33
; ebx = destination
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
push ecx esi edi ; scan cache
 
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
call calculate_cache
add esi,8
call calculate_cache
add esi, 8
 
mov edi,1
mov edi, 1
 
hdreadcache:
 
cmp dword [esi+4],0 ; empty
je nohdcache
cmp dword [esi+4], 0; empty
je nohdcache
 
cmp [esi],eax ; correct sector
je yeshdcache
cmp [esi], eax ; correct sector
je yeshdcache
 
nohdcache:
 
add esi,8
inc edi
dec ecx
jnz hdreadcache
add esi, 8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne return_01
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne return_01
; Read through BIOS?
cmp [hdpos], 0x80
jae .bios
72,90 → 72,90
jne return_01
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1
lea esi,[edi*8+esi]
call calculate_cache_1
lea esi, [edi*8+esi]
; pop eax
 
mov [esi],eax ; sector number
mov dword [esi+4],1 ; hd read - mark as same as in hd
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
mov esi, edi
shl esi, 9
; add esi,HD_CACHE+65536
push eax
call calculate_cache_2
add esi,eax
pop eax
push eax
call calculate_cache_2
add esi, eax
pop eax
 
mov edi,ebx
mov ecx,512/4
cld
rep movsd ; move data
mov edi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
return_01:
pop edi esi ecx
ret
pop edi esi ecx
ret
 
align 4
hd_read_pio:
push eax edx
push eax edx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_read_error
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
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
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_read_error
cmp [hd_error], 0
jne hd_read_error
 
cli
push edi
shl edi,9
cli
push edi
shl edi, 9
; add edi,HD_CACHE+65536
push eax
call calculate_cache_2
add edi,eax
pop eax
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
mov ecx, 256
mov edx, [hdbase]
cld
rep insw
pop edi
sti
 
pop edx eax
ret
pop edx eax
ret
 
disable_ide_int:
; mov edx,[hdbase]
179,153 → 179,153
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
 
; mov ecx,cache_max
; mov esi,HD_CACHE+8
call calculate_cache
add esi,8
call calculate_cache
add esi, 8
 
mov edi,1
mov edi, 1
 
hdwritecache:
 
cmp dword [esi+4],0 ; if cache slot is empty
je not_in_cache_write
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
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
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
call find_empty_slot ; ret in edi
cmp [hd_error], 0
jne hd_write_access_denied
 
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1
lea esi,[edi*8+esi]
call calculate_cache_1
lea esi, [edi*8+esi]
; pop eax
 
mov [esi],eax ; sector number
mov [esi], eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4],2 ; write - differs from hd
mov dword [esi+4], 2; write - differs from hd
 
shl edi,9
shl edi, 9
; add edi,HD_CACHE+65536
push eax
call calculate_cache_2
add edi,eax
pop eax
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
mov esi, ebx
mov ecx, 512/4
cld
rep movsd ; move data
hd_write_access_denied:
pop edi esi ecx
ret
pop edi esi ecx
ret
 
align 4
cache_write_pio:
cmp dword[esi],0x10000000
jae .bad
cmp dword[esi], 0x10000000
jae .bad
; call disable_ide_int
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_write_error
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
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
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_write_error
cmp [hd_error], 0
jne hd_write_error
 
push ecx esi
push ecx esi
 
cli
mov esi,edi
shl esi,9
cli
mov esi, edi
shl esi, 9
; add esi,HD_CACHE+65536 ; esi = from memory position
push eax
call calculate_cache_2
add esi,eax
pop eax
push eax
call calculate_cache_2
add esi, eax
pop eax
 
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
sti
mov ecx, 256
mov edx, [hdbase]
cld
rep outsw
sti
 
; call enable_ide_int
pop esi ecx
pop esi ecx
 
ret
ret
.bad:
inc [hd_error]
ret
inc [hd_error]
ret
 
save_hd_wait_timeout:
 
push eax
mov eax,[timer_ticks]
add eax,300 ; 3 sec timeout
mov [hd_wait_timeout],eax
pop eax
ret
push eax
mov eax, [timer_ticks]
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
jg hd_timeout_error
pop eax
mov [hd_error],0
ret
push eax
mov eax, [hd_wait_timeout]
cmp [timer_ticks], eax
jg hd_timeout_error
pop eax
mov [hd_error], 0
ret
 
;iglobal
; hd_timeout_str db 'K : FS - HD timeout',0
342,9 → 342,9
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD timeout\n"
 
mov [hd_error],1
pop eax
ret
mov [hd_error], 1
pop eax
ret
 
hd_read_error:
 
353,8 → 353,8
; mov esi,hd_read_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD read error\n"
pop edx eax
ret
pop edx eax
ret
 
hd_write_error:
 
363,7 → 363,7
; mov esi,hd_write_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD write error\n"
ret
ret
 
hd_write_error_dma:
; call clear_hd_cache
380,69 → 380,69
; mov esi,hd_lba_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD LBA error\n"
jmp LBA_read_ret
jmp LBA_read_ret
 
 
align 4
wait_for_hd_idle:
 
push eax edx
push eax edx
 
call save_hd_wait_timeout
call save_hd_wait_timeout
 
mov edx,[hdbase]
add edx,0x7
mov edx, [hdbase]
add edx, 0x7
 
wfhil1:
 
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
 
in al,dx
test al,128
jnz wfhil1
in al, dx
test al, 128
jnz wfhil1
 
@@:
 
pop edx eax
ret
pop edx eax
ret
 
 
align 4
wait_for_sector_buffer:
 
push eax edx
push eax edx
 
mov edx,[hdbase]
add edx,0x7
mov edx, [hdbase]
add edx, 0x7
 
call save_hd_wait_timeout
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
call check_hd_wait_timeout
cmp [hd_error], 0
jne @f
 
in al,dx
test al,8
jz hdwait_sbuf
in al, dx
test al, 8
jz hdwait_sbuf
 
mov [hd_error],0
mov [hd_error], 0
 
cmp [hd_setup],1 ; do not mark error for setup request
je buf_wait_ok
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
test al, 1 ; previous command ended up with an error
jz buf_wait_ok
@@:
mov [hd_error],1
mov [hd_error], 1
 
buf_wait_ok:
 
pop edx eax
ret
pop edx eax
ret
 
; \begin{Mario79}
align 4
578,8 → 578,8
hd_read_dma:
push eax
push edx
mov edx,[dma_hdpos]
cmp edx,[hdpos]
mov edx, [dma_hdpos]
cmp edx, [hdpos]
jne .notread
mov edx, [dma_cur_sector]
cmp eax, edx
595,14 → 595,14
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
push eax
call calculate_cache_2
add edi,eax
pop eax
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
rep movsd
pop edi esi ecx
pop edx
pop eax
609,7 → 609,7
ret
.notread:
mov eax, IDE_descriptor_table
mov dword [eax], IDE_DMA
mov dword [eax], IDE_DMA
mov word [eax+4], 0x2000
sub eax, OS_BASE
mov dx, [IDEContrRegsBaseAddr]
683,8 → 683,8
@@:
cmp [hd_error], 0
jnz hd_read_error
mov eax,[hdpos]
mov [dma_hdpos],eax
mov eax, [hdpos]
mov [dma_hdpos], eax
pop edx
pop eax
mov [dma_cur_sector], eax
692,28 → 692,28
 
align 4
write_cache_sector:
mov [cache_chain_size],1
mov [cache_chain_pos],edi
mov [cache_chain_size], 1
mov [cache_chain_pos], edi
write_cache_chain:
cmp [hdpos], 0x80
jae bd_write_cache_chain
mov eax,[cache_chain_ptr]
cmp dword[eax],0x10000000
mov eax, [cache_chain_ptr]
cmp dword[eax], 0x10000000
jae .bad
push esi
mov eax, IDE_descriptor_table
mov edx,eax
mov edx, eax
pusha
mov esi,[cache_chain_pos]
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi,eax
add esi, eax
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
movzx ecx, [cache_chain_size]
shl ecx, 9
mov word [edx+4], cx
shr ecx,2
shr ecx, 2
cld
rep movsd
popa
828,14 → 828,14
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
push eax
call calculate_cache_2
add edi,eax
pop eax
push eax
call calculate_cache_2
add edi, eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
rep movsd
pop edi esi ecx
pop edx
pop eax
872,7 → 872,7
movzx ecx, [cache_chain_size]
push ecx
shl ecx, 9-2
rep movsd
rep movsd
pop ecx
mov dl, 43h
mov eax, [cache_chain_ptr]
909,7 → 909,7
mov edi, ebx
mov ecx, v86_regs.size/4
xor eax, eax
rep stosd
rep stosd
mov byte [ebx+v86_regs.eax+1], dl
mov eax, [hdpos]
lea eax, [BiosDisksData+(eax-80h)*4]
933,9 → 933,9
mov [ebx+v86_regs.eflags], 20200h
mov esi, [sys_v86_machine]
mov ecx, 0x502
push fs
push fs
call v86_start
pop fs
pop fs
and [bios_hdpos], 0
pop edi esi ecx ebx
movzx edx, byte [OS_BASE + 512h]
/kernel/branches/net/blkdev/ide_cache.inc
29,78 → 29,78
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
call calculate_cache
add esi,8
mov edi,1
call calculate_cache
add esi, 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 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 [hdpos], 0x80
jae @f
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
cmp [allow_dma_access], 2
jae .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
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], 16
jnz .continue
jmp .write_chain
inc [cache_chain_size]
cmp [cache_chain_size], 16
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
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
call cache_write_pio
.write_chain:
call flush_cache_chain
call flush_cache_chain
.continue:
danger:
add esi,8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
add esi, 8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
return_02:
pop edi esi edx ecx eax
ret
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
cmp [cache_chain_started], 0
jz @f
call write_cache_chain
mov [cache_chain_started], 0
@@:
ret
ret
;--------------------------------------------------------------------
align 4
find_empty_slot:
111,35 → 111,35
; push ecx esi
 
search_again:
call calculate_cache_3
shr ecx,3
call calculate_cache_3
shr ecx, 3
search_for_empty:
inc edi
call calculate_cache_4
jbe inside_cache
mov edi,1
inc edi
call calculate_cache_4
jbe inside_cache
mov edi, 1
inside_cache:
push esi
call calculate_cache_1
cmp dword [edi*8+esi+4],2
pop esi
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
push esi
call calculate_cache_1
cmp dword [edi*8+esi+4], 2
pop esi
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:
call calculate_cache_5
call calculate_cache_5
found_slot_access_denied:
ret
ret
;--------------------------------------------------------------------
align 4
clear_hd_cache:
mov [fat_in_cache],-1
mov [fat_change],0
ret
mov [fat_in_cache], -1
mov [fat_change], 0
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
148,78 → 148,78
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov esi,[cache_ide0_pointer]
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov esi,[cache_ide0_data_pointer]
ret
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov esi,[cache_ide1_pointer]
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov esi,[cache_ide1_data_pointer]
ret
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov esi,[cache_ide2_pointer]
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov esi,[cache_ide2_data_pointer]
ret
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov esi,[cache_ide3_pointer]
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov esi,[cache_ide3_data_pointer]
ret
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
mov esi,[cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_1:
226,68 → 226,68
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov esi,[cache_ide0_pointer]
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi,[cache_ide0_data_pointer]
ret
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov esi,[cache_ide1_pointer]
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi,[cache_ide1_data_pointer]
ret
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov esi,[cache_ide2_pointer]
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi,[cache_ide2_data_pointer]
ret
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov esi,[cache_ide3_pointer]
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi,[cache_ide3_data_pointer]
ret
mov esi, [cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov esi,[cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov esi, [cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
mov esi, [cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
295,65 → 295,65
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov eax,[cache_ide0_system_data]
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax,[cache_ide0_appl_data]
ret
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov eax,[cache_ide1_system_data]
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax,[cache_ide1_appl_data]
ret
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov eax,[cache_ide2_system_data]
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax,[cache_ide2_appl_data]
ret
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov eax,[cache_ide3_system_data]
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax,[cache_ide3_appl_data]
ret
mov eax, [cache_ide3_appl_data]
ret
.noide:
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov eax,[cache_ide0_system_data-cache_ide0+eax]
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov eax, [cache_ide0_system_data-cache_ide0+eax]
ret
.bd_appl_data:
mov eax,[cache_ide0_appl_data-cache_ide0+eax]
ret
mov eax, [cache_ide0_appl_data-cache_ide0+eax]
ret
;--------------------------------------------------------------------
align 4
calculate_cache_3:
362,78 → 362,78
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov edi,[cache_ide0_search_start]
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_search_start]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov edi,[cache_ide0_appl_search_start]
ret
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov edi,[cache_ide1_search_start]
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov edi,[cache_ide1_appl_search_start]
ret
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov edi,[cache_ide2_search_start]
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov edi,[cache_ide2_appl_search_start]
ret
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov edi,[cache_ide3_search_start]
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov edi,[cache_ide3_appl_search_start]
ret
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_appl_search_start]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
mov edi,[cache_ide0_search_start-cache_ide0+eax]
pop eax
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov ecx, [cache_ide0_system_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_search_start-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
mov edi,[cache_ide0_appl_search_start-cache_ide0+eax]
pop eax
ret
mov ecx, [cache_ide0_appl_sad_size-cache_ide0+eax]
mov edi, [cache_ide0_appl_search_start-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_4:
440,68 → 440,68
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
cmp edi,[cache_ide0_system_sad_size]
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi,[cache_ide0_appl_sad_size]
ret
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
cmp edi,[cache_ide1_system_sad_size]
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi,[cache_ide1_appl_sad_size]
ret
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
cmp edi,[cache_ide2_system_sad_size]
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi,[cache_ide2_appl_sad_size]
ret
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
cmp edi,[cache_ide3_system_sad_size]
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi,[cache_ide3_appl_sad_size]
ret
cmp edi, [cache_ide3_appl_sad_size]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax]
pop eax
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
cmp edi, [cache_ide0_system_sad_size-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax]
pop eax
ret
cmp edi, [cache_ide0_appl_sad_size-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
509,68 → 509,68
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov [cache_ide0_search_start],edi
ret
cmp [hdpos], 1
jne .ide1
cmp [hdd_appl_data], 0
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start],edi
ret
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov [cache_ide1_search_start],edi
ret
cmp [hdpos], 2
jne .ide2
cmp [hdd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start],edi
ret
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov [cache_ide2_search_start],edi
ret
cmp [hdpos], 3
jne .ide3
cmp [hdd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start],edi
ret
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov [cache_ide3_search_start],edi
ret
cmp [hdpos], 4
jne .noide
cmp [hdd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start],edi
ret
mov [cache_ide3_appl_search_start], edi
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
push eax
mov eax, [hdpos]
sub eax, 80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax, byte [BiosDisksData+eax*4+2]
imul eax, cache_ide1-cache_ide0
add eax, cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
imul eax, cache_ide1-cache_ide0
add eax, BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov [cache_ide0_search_start-cache_ide0+eax],edi
pop eax
ret
cmp [hdd_appl_data], 0
jne .bd_appl_data
mov [cache_ide0_search_start-cache_ide0+eax], edi
pop eax
ret
.bd_appl_data:
mov [cache_ide0_appl_search_start-cache_ide0+eax],edi
pop eax
ret
mov [cache_ide0_appl_search_start-cache_ide0+eax], edi
pop eax
ret
 
;--------------------------------------------------------------------
align 4
580,69 → 580,69
; output : edi = cache slot
;-----------------------------------------------------------
.search_again:
call cd_calculate_cache_3
call cd_calculate_cache_3
.search_for_empty:
inc edi
call cd_calculate_cache_4
jbe .inside_cache
mov edi,1
inc edi
call cd_calculate_cache_4
jbe .inside_cache
mov edi, 1
.inside_cache:
call cd_calculate_cache_5
ret
call cd_calculate_cache_5
ret
;--------------------------------------------------------------------
clear_CD_cache:
pusha
pusha
.ide0:
xor eax,eax
cmp [cdpos],1
jne .ide1
mov [cache_ide0_search_start],eax
mov ecx,[cache_ide0_system_sad_size]
mov edi,[cache_ide0_pointer]
call .clear
mov [cache_ide0_appl_search_start],eax
mov ecx,[cache_ide0_appl_sad_size]
mov edi,[cache_ide0_data_pointer]
jmp .continue
xor eax, eax
cmp [cdpos], 1
jne .ide1
mov [cache_ide0_search_start], eax
mov ecx, [cache_ide0_system_sad_size]
mov edi, [cache_ide0_pointer]
call .clear
mov [cache_ide0_appl_search_start], eax
mov ecx, [cache_ide0_appl_sad_size]
mov edi, [cache_ide0_data_pointer]
jmp .continue
.ide1:
cmp [cdpos],2
jne .ide2
mov [cache_ide1_search_start],eax
mov ecx,[cache_ide1_system_sad_size]
mov edi,[cache_ide1_pointer]
call .clear
mov [cache_ide1_appl_search_start],eax
mov ecx,[cache_ide1_appl_sad_size]
mov edi,[cache_ide1_data_pointer]
jmp .continue
cmp [cdpos], 2
jne .ide2
mov [cache_ide1_search_start], eax
mov ecx, [cache_ide1_system_sad_size]
mov edi, [cache_ide1_pointer]
call .clear
mov [cache_ide1_appl_search_start], eax
mov ecx, [cache_ide1_appl_sad_size]
mov edi, [cache_ide1_data_pointer]
jmp .continue
.ide2:
cmp [cdpos],3
jne .ide3
mov [cache_ide2_search_start],eax
mov ecx,[cache_ide2_system_sad_size]
mov edi,[cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start],eax
mov ecx,[cache_ide2_appl_sad_size]
mov edi,[cache_ide2_data_pointer]
jmp .continue
cmp [cdpos], 3
jne .ide3
mov [cache_ide2_search_start], eax
mov ecx, [cache_ide2_system_sad_size]
mov edi, [cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start], eax
mov ecx, [cache_ide2_appl_sad_size]
mov edi, [cache_ide2_data_pointer]
jmp .continue
.ide3:
mov [cache_ide3_search_start],eax
mov ecx,[cache_ide3_system_sad_size]
mov edi,[cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start],eax
mov ecx,[cache_ide3_appl_sad_size]
mov edi,[cache_ide3_data_pointer]
mov [cache_ide3_search_start], eax
mov ecx, [cache_ide3_system_sad_size]
mov edi, [cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start], eax
mov ecx, [cache_ide3_appl_sad_size]
mov edi, [cache_ide3_data_pointer]
.continue:
call .clear
popa
ret
call .clear
popa
ret
.clear:
shl ecx,1
cld
rep stosd
ret
shl ecx, 1
cld
rep stosd
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache:
651,51 → 651,51
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov esi,[cache_ide0_pointer]
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov ecx, [cache_ide0_system_sad_size]
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov esi,[cache_ide0_data_pointer]
ret
mov ecx, [cache_ide0_appl_sad_size]
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov esi,[cache_ide1_pointer]
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov ecx, [cache_ide1_system_sad_size]
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov esi,[cache_ide1_data_pointer]
ret
mov ecx, [cache_ide1_appl_sad_size]
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov esi,[cache_ide2_pointer]
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov ecx, [cache_ide2_system_sad_size]
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov esi,[cache_ide2_data_pointer]
ret
mov ecx, [cache_ide2_appl_sad_size]
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov esi,[cache_ide3_pointer]
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov ecx, [cache_ide3_system_sad_size]
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov esi,[cache_ide3_data_pointer]
ret
mov ecx, [cache_ide3_appl_sad_size]
mov esi, [cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_1:
702,43 → 702,43
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov esi,[cache_ide0_pointer]
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov esi, [cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi,[cache_ide0_data_pointer]
ret
mov esi, [cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov esi,[cache_ide1_pointer]
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov esi, [cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi,[cache_ide1_data_pointer]
ret
mov esi, [cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov esi,[cache_ide2_pointer]
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov esi, [cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi,[cache_ide2_data_pointer]
ret
mov esi, [cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov esi,[cache_ide3_pointer]
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov esi, [cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi,[cache_ide3_data_pointer]
ret
mov esi, [cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_2:
745,43 → 745,43
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov eax,[cache_ide0_system_data]
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov eax, [cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax,[cache_ide0_appl_data]
ret
mov eax, [cache_ide0_appl_data]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov eax,[cache_ide1_system_data]
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov eax, [cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax,[cache_ide1_appl_data]
ret
mov eax, [cache_ide1_appl_data]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov eax,[cache_ide2_system_data]
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov eax, [cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax,[cache_ide2_appl_data]
ret
mov eax, [cache_ide2_appl_data]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov eax,[cache_ide3_system_data]
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov eax, [cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax,[cache_ide3_appl_data]
ret
mov eax, [cache_ide3_appl_data]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_3:
790,43 → 790,43
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov edi,[cache_ide0_search_start]
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov edi, [cache_ide0_search_start]
ret
.ide0_appl_data:
mov edi,[cache_ide0_appl_search_start]
ret
mov edi, [cache_ide0_appl_search_start]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov edi,[cache_ide1_search_start]
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov edi, [cache_ide1_search_start]
ret
.ide1_appl_data:
mov edi,[cache_ide1_appl_search_start]
ret
mov edi, [cache_ide1_appl_search_start]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov edi,[cache_ide2_search_start]
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov edi, [cache_ide2_search_start]
ret
.ide2_appl_data:
mov edi,[cache_ide2_appl_search_start]
ret
mov edi, [cache_ide2_appl_search_start]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov edi,[cache_ide3_search_start]
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov edi, [cache_ide3_search_start]
ret
.ide3_appl_data:
mov edi,[cache_ide3_appl_search_start]
ret
mov edi, [cache_ide3_appl_search_start]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_4:
833,43 → 833,43
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
cmp edi,[cache_ide0_system_sad_size]
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
cmp edi, [cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi,[cache_ide0_appl_sad_size]
ret
cmp edi, [cache_ide0_appl_sad_size]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
cmp edi,[cache_ide1_system_sad_size]
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
cmp edi, [cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi,[cache_ide1_appl_sad_size]
ret
cmp edi, [cache_ide1_appl_sad_size]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
cmp edi,[cache_ide2_system_sad_size]
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
cmp edi, [cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi,[cache_ide2_appl_sad_size]
ret
cmp edi, [cache_ide2_appl_sad_size]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
cmp edi,[cache_ide3_system_sad_size]
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
cmp edi, [cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi,[cache_ide3_appl_sad_size]
ret
cmp edi, [cache_ide3_appl_sad_size]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_5:
876,43 → 876,43
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov [cache_ide0_search_start],edi
ret
cmp [cdpos], 1
jne .ide1
cmp [cd_appl_data], 0
jne .ide0_appl_data
mov [cache_ide0_search_start], edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start],edi
ret
mov [cache_ide0_appl_search_start], edi
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov [cache_ide1_search_start],edi
ret
cmp [cdpos], 2
jne .ide2
cmp [cd_appl_data], 0
jne .ide1_appl_data
mov [cache_ide1_search_start], edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start],edi
ret
mov [cache_ide1_appl_search_start], edi
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov [cache_ide2_search_start],edi
ret
cmp [cdpos], 3
jne .ide3
cmp [cd_appl_data], 0
jne .ide2_appl_data
mov [cache_ide2_search_start], edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start],edi
ret
mov [cache_ide2_appl_search_start], edi
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov [cache_ide3_search_start],edi
ret
cmp [cd_appl_data], 0
jne .ide3_appl_data
mov [cache_ide3_search_start], edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start],edi
ret
mov [cache_ide3_appl_search_start], edi
ret
;--------------------------------------------------------------------
;align 4
;calculate_linear_to_real:
/kernel/branches/net/blkdev/rd.inc
16,73 → 16,73
 
calculatefatchain:
 
pushad
pushad
 
mov esi,RAMDISK+512
mov edi,RAMDISK_FAT
mov esi, RAMDISK+512
mov edi, RAMDISK_FAT
 
fcnew:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
mov dword [edi+4],ebx
mov dword [edi+8],ecx
mov dword [edi+12],edx
add edi,16
add esi,12
mov eax, dword [esi]
mov ebx, dword [esi+4]
mov ecx, dword [esi+8]
mov edx, ecx
shr edx, 4;8 ok
shr dx, 4;7 ok
xor ch, ch
shld ecx, ebx, 20;6 ok
shr cx, 4;5 ok
shld ebx, eax, 12
and ebx, 0x0fffffff;4 ok
shr bx, 4;3 ok
shl eax, 4
and eax, 0x0fffffff;2 ok
shr ax, 4;1 ok
mov dword [edi], eax
mov dword [edi+4], ebx
mov dword [edi+8], ecx
mov dword [edi+12], edx
add edi, 16
add esi, 12
 
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters
jnz fcnew
cmp edi, RAMDISK_FAT+2856*2;2849 clusters
jnz fcnew
 
popad
ret
popad
ret
 
 
restorefatchain: ; restore fat chain
 
pushad
pushad
 
mov esi,RAMDISK_FAT
mov edi,RAMDISK+512
mov esi, RAMDISK_FAT
mov edi, RAMDISK+512
 
fcnew2:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
mov word [edi+4],bx
add edi,6
add esi,8
mov eax, dword [esi]
mov ebx, dword [esi+4]
shl ax, 4
shl eax, 4
shl bx, 4
shr ebx, 4
shrd eax, ebx, 8
shr ebx, 8
mov dword [edi], eax
mov word [edi+4], bx
add edi, 6
add esi, 8
 
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT
jb fcnew2
cmp edi, RAMDISK+512+4278;4274 bytes - all used FAT
jb fcnew2
 
mov esi,RAMDISK+512 ; duplicate fat chain
mov edi,RAMDISK+512+0x1200
mov ecx,1069 ;4274/4
cld
rep movsd
mov esi, RAMDISK+512 ; duplicate fat chain
mov edi, RAMDISK+512+0x1200
mov ecx, 1069;4274/4
cld
rep movsd
 
popad
ret
popad
ret
 
 
ramdisk_free_space:
92,25 → 92,25
; rewr.by Mihasik
;---------------------------------------------
 
push eax ebx ecx
push eax ebx ecx
 
mov edi,RAMDISK_FAT ;start of FAT
xor ax,ax ;Free cluster=0x0000 in FAT
xor ebx,ebx ;counter
mov ecx,2849 ;2849 clusters
cld
mov edi, RAMDISK_FAT;start of FAT
xor ax, ax;Free cluster=0x0000 in FAT
xor ebx, ebx;counter
mov ecx, 2849;2849 clusters
cld
rdfs1:
repne scasw
jnz rdfs2 ;if last cluster not 0
inc ebx
test ecx, ecx
jnz rdfs1
repne scasw
jnz rdfs2 ;if last cluster not 0
inc ebx
test ecx, ecx
jnz rdfs1
rdfs2:
shl ebx,9 ;free clusters*512
mov edi,ebx
shl ebx, 9;free clusters*512
mov edi, ebx
 
pop ecx ebx eax
ret
pop ecx ebx eax
ret
 
 
expand_filename:
120,44 → 120,44
; eax - pointer to filename
;---------------------------------------------
 
push esi edi ebx
push esi edi ebx
 
mov edi,esp ; check for '.' in the name
add edi,12+8
mov edi, esp ; check for '.' in the name
add edi, 12+8
 
mov esi,eax
mov esi, eax
 
mov eax,edi
mov [eax+0],dword ' '
mov [eax+4],dword ' '
mov [eax+8],dword ' '
mov eax, edi
mov [eax+0], dword ' '
mov [eax+4], dword ' '
mov [eax+8], dword ' '
 
flr1:
 
cmp [esi],byte '.'
jne flr2
mov edi,eax
add edi,7
jmp flr3
cmp [esi], byte '.'
jne flr2
mov edi, eax
add edi, 7
jmp flr3
 
flr2:
 
mov bl,[esi]
mov [edi],bl
mov bl, [esi]
mov [edi], bl
 
flr3:
 
inc esi
inc edi
inc esi
inc edi
 
mov ebx,eax
add ebx,11
mov ebx, eax
add ebx, 11
 
cmp edi,ebx
jbe flr1
cmp edi, ebx
jbe flr1
 
pop ebx edi esi
ret
pop ebx edi esi
ret
 
fileread:
;----------------------------------------------------------------
174,129 → 174,129
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
test ebx,ebx ;if ebx=0 - set to 1
jnz frfl5
inc ebx
test ebx, ebx;if ebx=0 - set to 1
jnz frfl5
inc ebx
frfl5:
test ecx,ecx ;if ecx=0 - set to 1
jnz frfl6
inc ecx
test ecx, ecx;if ecx=0 - set to 1
jnz frfl6
inc ecx
frfl6:
test esi,esi ; return ramdisk root
jnz fr_noroot ;if not root
cmp ebx,14 ;14 clusters=root dir
ja oorr
cmp ecx,14
ja oorr
jmp fr_do
test esi, esi ; return ramdisk root
jnz fr_noroot ;if not root
cmp ebx, 14 ;14 clusters=root dir
ja oorr
cmp ecx, 14
ja oorr
jmp fr_do
oorr:
mov eax,5 ;out of root range (fnf)
xor ebx,ebx
dec ebx ;0xffffffff
ret
mov eax, 5 ;out of root range (fnf)
xor ebx, ebx
dec ebx ;0xffffffff
ret
 
fr_do: ;reading rootdir
mov edi,edx
dec ebx
push edx
mov edx,ecx
add edx,ebx
cmp edx,15 ;ebx+ecx=14+1
pushf
jbe fr_do1
sub edx,14
sub ecx,edx
fr_do: ;reading rootdir
mov edi, edx
dec ebx
push edx
mov edx, ecx
add edx, ebx
cmp edx, 15 ;ebx+ecx=14+1
pushf
jbe fr_do1
sub edx, 14
sub ecx, edx
fr_do1:
shl ebx,9
mov esi,RAMDISK+512*19
add esi,ebx
shl ecx,7
cld
rep movsd
popf
pop edx
jae fr_do2
xor eax,eax ; ok read
xor ebx,ebx
ret
fr_do2: ;if last cluster
mov eax,6 ;end of file
xor ebx,ebx
ret
shl ebx, 9
mov esi, RAMDISK+512*19
add esi, ebx
shl ecx, 7
cld
rep movsd
popf
pop edx
jae fr_do2
xor eax, eax; ok read
xor ebx, ebx
ret
fr_do2: ;if last cluster
mov eax, 6;end of file
xor ebx, ebx
ret
 
fr_noroot:
 
sub esp,32
call expand_filename
sub esp, 32
call expand_filename
 
dec ebx
dec ebx
 
push eax
push eax
 
push eax ebx ecx edx esi edi
call rd_findfile
je fifound
add esp,32+28 ;if file not found
ret
push eax ebx ecx edx esi edi
call rd_findfile
je fifound
add esp, 32+28 ;if file not found
ret
 
fifound:
 
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi=cluster
mov ebx, [edi-11+28] ;file size
mov [esp+20], ebx
mov [esp+24], ebx
add edi, 0xf
movzx eax, word [edi]
mov edi, eax ;edi=cluster
 
frnew:
 
add eax,31 ;bootsector+2*fat+filenames
shl eax,9 ;*512
add eax,RAMDISK ;image base
mov ebx,[esp+8]
mov ecx,512 ;[esp+4]
add eax, 31 ;bootsector+2*fat+filenames
shl eax, 9 ;*512
add eax, RAMDISK ;image base
mov ebx, [esp+8]
mov ecx, 512 ;[esp+4]
 
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7
call memmove
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
je frnoread
jmp frfl8
cmp [esp+16], dword 0 ; wanted cluster ?
jne frfl7
call memmove
add [esp+8], dword 512
dec dword [esp+12] ; last wanted cluster ?
je frnoread
jmp frfl8
frfl7:
dec dword [esp+16]
dec dword [esp+16]
frfl8:
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
mov edi,eax
cmp edi,4095 ;eof - cluster
jz frnoread2
movzx eax, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
mov edi, eax
cmp edi, 4095 ;eof - cluster
jz frnoread2
 
cmp [esp+24],dword 512 ;eof - size
jb frnoread
sub [esp+24],dword 512
cmp [esp+24], dword 512 ;eof - size
jb frnoread
sub [esp+24], dword 512
 
jmp frnew
jmp frnew
 
frnoread2:
 
cmp [esp+16],dword 0 ; eof without read ?
je frnoread
cmp [esp+16], dword 0 ; eof without read ?
je frnoread
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
ret
pop edi esi edx ecx
add esp, 4
pop ebx ; ebx <- eax : size of file
add esp, 36
mov eax, 6 ; end of file
ret
 
frnoread:
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax ;read ok
ret
pop edi esi edx ecx
add esp, 4
pop ebx ; ebx <- eax : size of file
add esp, 36
xor eax, eax;read ok
ret
 
 
 
304,22 → 304,22
;by Mihasik
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
 
mov edi,RAMDISK+512*18+512 ;Point at directory
cld
mov edi, RAMDISK+512*18+512;Point at directory
cld
rd_newsearch:
mov esi,eax
mov ecx,11
rep cmpsb
je rd_ff
add cl,21
add edi,ecx
cmp edi,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
mov esi, eax
mov ecx, 11
rep cmpsb
je rd_ff
add cl, 21
add edi, ecx
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
rd_ff:
ret
ret
 
; \begin{diamond}
 
327,107 → 327,107
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
; in: esi->source, edi->buffer (may be esi=edi)
; destroys: eax,esi,edi
lodsw
test ax, ax
jz .done
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
lodsw
test ax, ax
jz .done
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
add al, 0xA0
.ascii:
.doit:
stosb
jmp uni2ansi_str
stosb
jmp uni2ansi_str
.done:
mov byte [edi], 0
ret
mov byte [edi], 0
ret
 
ansi2uni_char:
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
mov ah, 0
mov ah, 0
; 0x00-0x7F - trivial map
cmp al, 0x80
jb .ret
cmp al, 0x80
jb .ret
; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
.ret:
ret
ret
@@:
; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
ret
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
ret
; 0xF0 -> 0x401
; 0xF1 -> 0x451
@@:
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
.unk:
mov al, '_' ; ah=0
ret
mov al, '_' ; ah=0
ret
.yo1:
mov ax, 0x401
ret
mov ax, 0x401
ret
.yo2:
mov ax, 0x451
ret
mov ax, 0x451
ret
 
char_toupper:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'a'
jb .ret
cmp al, 'z'
jbe .az
cmp al, 'a'
jb .ret
cmp al, 'z'
jbe .az
cmp al, 'ñ'
jz .yo1
cmp al, ' '
jb .ret
cmp al, 'à'
jb .rus1
cmp al, 'ï'
ja .ret
cmp al, ' '
jb .ret
cmp al, 'à'
jb .rus1
cmp al, 'ï'
ja .ret
; 0xE0-0xEF -> 0x90-0x9F
sub al, 'à'-''
sub al, 'à'-''
.ret:
ret
ret
.rus1:
; 0xA0-0xAF -> 0x80-0x8F
.az:
and al, not 0x20
ret
and al, not 0x20
ret
.yo1:
; 0xF1 -> 0xF0
dec ax
440,148 → 440,148
; (maximum length of filename is 255 (wide) symbols without trailing 0,
; but implementation requires buffer 261 words)
; destroys eax
cmp byte [edi], 0
jz .no
cmp byte [edi], 0xE5
jnz @f
cmp byte [edi], 0
jz .no
cmp byte [edi], 0xE5
jnz @f
.no:
stc
ret
stc
ret
@@:
cmp byte [edi+11], 0xF
jz .longname
test byte [edi+11], 8
jnz .no
push ecx
push edi ebp
test byte [ebp-4], 1
jnz .unicode_short
cmp byte [edi+11], 0xF
jz .longname
test byte [edi+11], 8
jnz .no
push 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 eax, [edi]
mov ecx, [edi+4]
mov [ebp], eax
mov [ebp+4], ecx
 
mov ecx, 8
mov ecx, 8
@@:
cmp byte [ebp+ecx-1], ' '
loope @b
cmp byte [ebp+ecx-1], ' '
loope @b
 
mov eax, [edi+8]
cmp al, ' '
je .done
shl eax, 8
mov al, '.'
mov eax, [edi+8]
cmp al, ' '
je .done
shl eax, 8
mov al, '.'
 
lea ebp, [ebp+ecx+1]
mov [ebp], eax
mov ecx, 3
lea ebp, [ebp+ecx+1]
mov [ebp], eax
mov ecx, 3
@@:
rol eax, 8
cmp al, ' '
jne .done
loop @b
dec ebp
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
and byte [ebp+ecx+1], 0 ; CF=0
pop ebp edi ecx
ret
.unicode_short:
mov ecx, 8
push ecx
mov ecx, 8
push ecx
@@:
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
@@:
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
@@:
mov word [ebp], '.'
inc ebp
inc ebp
mov ecx, 3
push ecx
mov word [ebp], '.'
inc ebp
inc ebp
mov ecx, 3
push ecx
@@:
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
@@:
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
dec ebp
dec ebp
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
dec ebp
dec ebp
@@:
and word [ebp], 0 ; CF=0
pop ebp edi ecx
ret
and word [ebp], 0 ; CF=0
pop ebp edi ecx
ret
.longname:
; LFN
mov al, byte [edi]
and eax, 0x3F
dec eax
cmp al, 20
jae .no ; ignore invalid entries
mov word [ebp+260*2], 0 ; force null-terminating for orphans
imul eax, 13*2
add ebp, eax
test byte [edi], 0x40
jz @f
mov word [ebp+13*2], 0
mov al, byte [edi]
and eax, 0x3F
dec eax
cmp al, 20
jae .no ; ignore invalid entries
mov word [ebp+260*2], 0 ; force null-terminating for orphans
imul eax, 13*2
add ebp, eax
test byte [edi], 0x40
jz @f
mov word [ebp+13*2], 0
@@:
push eax
push eax
; now copy name from edi to ebp ...
mov eax, [edi+1]
mov [ebp], eax ; symbols 1,2
mov eax, [edi+5]
mov [ebp+4], eax ; 3,4
mov eax, [edi+9]
mov [ebp+8], ax ; 5
mov eax, [edi+14]
mov [ebp+10], eax ; 6,7
mov eax, [edi+18]
mov [ebp+14], eax ; 8,9
mov eax, [edi+22]
mov [ebp+18], eax ; 10,11
mov eax, [edi+28]
mov [ebp+22], eax ; 12,13
mov eax, [edi+1]
mov [ebp], eax ; symbols 1,2
mov eax, [edi+5]
mov [ebp+4], eax ; 3,4
mov eax, [edi+9]
mov [ebp+8], ax ; 5
mov eax, [edi+14]
mov [ebp+10], eax ; 6,7
mov eax, [edi+18]
mov [ebp+14], eax ; 8,9
mov eax, [edi+22]
mov [ebp+18], eax ; 10,11
mov eax, [edi+28]
mov [ebp+22], eax ; 12,13
; ... done
pop eax
sub ebp, eax
test eax, eax
jz @f
pop eax
sub ebp, eax
test eax, eax
jz @f
; if this is not first entry, more processing required
stc
ret
stc
ret
@@:
; if this is first entry:
test byte [ebp-4], 1
jnz .ret
test byte [ebp-4], 1
jnz .ret
; buffer at ebp contains UNICODE name, convert it to ANSI
push esi edi
mov esi, ebp
mov edi, ebp
call uni2ansi_str
pop edi esi
push esi edi
mov esi, ebp
mov edi, ebp
call uni2ansi_str
pop edi esi
.ret:
clc
ret
clc
ret
 
fat_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
589,300 → 589,300
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push ebp esi
push ebp esi
.loop:
mov al, [ebp]
inc ebp
call char_toupper
push eax
lodsb
call char_toupper
cmp al, [esp]
jnz .done
pop eax
test al, al
jnz .loop
dec esi
pop eax
pop ebp
xor eax, eax ; set ZF flag
ret
mov al, [ebp]
inc ebp
call char_toupper
push eax
lodsb
call char_toupper
cmp al, [esp]
jnz .done
pop eax
test al, al
jnz .loop
dec esi
pop eax
pop ebp
xor eax, eax ; set ZF flag
ret
.done:
cmp al, '/'
jnz @f
cmp byte [esp], 0
jnz @f
mov [esp+4], esi
cmp al, '/'
jnz @f
cmp byte [esp], 0
jnz @f
mov [esp+4], esi
@@:
pop eax
pop esi ebp
ret
pop eax
pop esi ebp
ret
 
fat_time_to_bdfe:
; in: eax=FAT time
; out: eax=BDFE time
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 11
shl eax, 16 ; hours
and edx, 0x1F
add edx, edx
mov al, dl ; seconds
shr ecx, 5
and ecx, 0x3F
mov ah, cl ; minutes
pop edx ecx
ret
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 11
shl eax, 16 ; hours
and edx, 0x1F
add edx, edx
mov al, dl ; seconds
shr ecx, 5
and ecx, 0x3F
mov ah, cl ; minutes
pop edx ecx
ret
 
fat_date_to_bdfe:
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 9
add ax, 1980
shl eax, 16 ; year
and edx, 0x1F
mov al, dl ; day
shr ecx, 5
and ecx, 0xF
mov ah, cl ; month
pop edx ecx
ret
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 9
add ax, 1980
shl eax, 16 ; year
and edx, 0x1F
mov al, dl ; day
shr ecx, 5
and ecx, 0xF
mov ah, cl ; month
pop edx ecx
ret
 
bdfe_to_fat_time:
push edx
mov edx, eax
shr eax, 16
and dh, 0x3F
shl eax, 6
or al, dh
shr dl, 1
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
push edx
mov edx, eax
shr eax, 16
and dh, 0x3F
shl eax, 6
or al, dh
shr dl, 1
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
 
bdfe_to_fat_date:
push edx
mov edx, eax
shr eax, 16
sub ax, 1980
and dh, 0xF
shl eax, 4
or al, dh
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
push edx
mov edx, eax
shr eax, 16
sub ax, 1980
and dh, 0xF
shl eax, 4
or al, dh
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
 
fat_entry_to_bdfe:
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
; destroys eax
mov eax, [ebp-4]
mov [esi+4], eax ; ASCII/UNICODE name
mov eax, [ebp-4]
mov [esi+4], eax ; ASCII/UNICODE name
fat_entry_to_bdfe2:
movzx eax, byte [edi+11]
mov [esi], eax ; attributes
movzx eax, word [edi+14]
call fat_time_to_bdfe
mov [esi+8], eax ; creation time
movzx eax, word [edi+16]
call fat_date_to_bdfe
mov [esi+12], eax ; creation date
and dword [esi+16], 0 ; last access time is not supported on FAT
movzx eax, word [edi+18]
call fat_date_to_bdfe
mov [esi+20], eax ; last access date
movzx eax, word [edi+22]
call fat_time_to_bdfe
mov [esi+24], eax ; last write time
movzx eax, word [edi+24]
call fat_date_to_bdfe
mov [esi+28], eax ; last write date
mov eax, [edi+28]
mov [esi+32], eax ; file size (low dword)
xor eax, eax
mov [esi+36], eax ; file size (high dword)
test ebp, ebp
jz .ret
push ecx edi
lea edi, [esi+40]
mov esi, ebp
test byte [esi-4], 1
jz .ansi
mov ecx, 260/2
rep movsd
mov [edi-2], ax
movzx eax, byte [edi+11]
mov [esi], eax ; attributes
movzx eax, word [edi+14]
call fat_time_to_bdfe
mov [esi+8], eax ; creation time
movzx eax, word [edi+16]
call fat_date_to_bdfe
mov [esi+12], eax ; creation date
and dword [esi+16], 0 ; last access time is not supported on FAT
movzx eax, word [edi+18]
call fat_date_to_bdfe
mov [esi+20], eax ; last access date
movzx eax, word [edi+22]
call fat_time_to_bdfe
mov [esi+24], eax ; last write time
movzx eax, word [edi+24]
call fat_date_to_bdfe
mov [esi+28], eax ; last write date
mov eax, [edi+28]
mov [esi+32], eax ; file size (low dword)
xor eax, eax
mov [esi+36], eax ; file size (high dword)
test ebp, ebp
jz .ret
push ecx edi
lea edi, [esi+40]
mov esi, ebp
test byte [esi-4], 1
jz .ansi
mov ecx, 260/2
rep movsd
mov [edi-2], ax
@@:
mov esi, edi
pop edi ecx
mov esi, edi
pop edi ecx
.ret:
ret
ret
.ansi:
mov ecx, 264/4
rep movsd
mov [edi-1], al
jmp @b
mov ecx, 264/4
rep movsd
mov [edi-1], al
jmp @b
 
bdfe_to_fat_entry:
; convert BDFE at edx to FAT entry at edi
; destroys eax
; attributes byte
test byte [edi+11], 8 ; volume label?
jnz @f
mov al, [edx]
and al, 0x27
and byte [edi+11], 0x10
or byte [edi+11], al
test byte [edi+11], 8 ; volume label?
jnz @f
mov al, [edx]
and al, 0x27
and byte [edi+11], 0x10
or byte [edi+11], al
@@:
mov eax, [edx+8]
call bdfe_to_fat_time
mov [edi+14], ax ; creation time
mov eax, [edx+12]
call bdfe_to_fat_date
mov [edi+16], ax ; creation date
mov eax, [edx+20]
call bdfe_to_fat_date
mov [edi+18], ax ; last access date
mov eax, [edx+24]
call bdfe_to_fat_time
mov [edi+22], ax ; last write time
mov eax, [edx+28]
call bdfe_to_fat_date
mov [edi+24], ax ; last write date
ret
mov eax, [edx+8]
call bdfe_to_fat_time
mov [edi+14], ax ; creation time
mov eax, [edx+12]
call bdfe_to_fat_date
mov [edi+16], ax ; creation date
mov eax, [edx+20]
call bdfe_to_fat_date
mov [edi+18], ax ; last access date
mov eax, [edx+24]
call bdfe_to_fat_time
mov [edi+22], ax ; last write time
mov eax, [edx+28]
call bdfe_to_fat_date
mov [edi+24], ax ; last write date
ret
 
ramdisk_root_first:
mov edi, RAMDISK+512*19
clc
ret
mov edi, RAMDISK+512*19
clc
ret
ramdisk_root_next:
add edi, 0x20
cmp edi, RAMDISK+512*33
cmc
ret
add edi, 0x20
cmp edi, RAMDISK+512*33
cmc
ret
 
ramdisk_root_extend_dir:
stc
ret
stc
ret
 
uglobal
; this is for delete support
rd_prev_sector dd ?
rd_prev_prev_sector dd ?
rd_prev_sector dd ?
rd_prev_prev_sector dd ?
endg
 
ramdisk_notroot_next:
add edi, 0x20
test edi, 0x1FF
jz ramdisk_notroot_next_sector
ret ; CF=0
add edi, 0x20
test edi, 0x1FF
jz ramdisk_notroot_next_sector
ret ; CF=0
ramdisk_notroot_next_sector:
push ecx
mov ecx, [eax]
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
mov [eax], ecx
pop ecx
push ecx
mov ecx, [eax]
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
mov [eax], ecx
pop ecx
ramdisk_notroot_first:
mov eax, [eax]
cmp eax, 2
jb .err
cmp eax, 2849
jae .err
shl eax, 9
lea edi, [eax+(31 shl 9)+RAMDISK]
clc
ret
mov eax, [eax]
cmp eax, 2
jb .err
cmp eax, 2849
jae .err
shl eax, 9
lea edi, [eax+(31 shl 9)+RAMDISK]
clc
ret
.err2:
pop ecx
pop ecx
.err:
stc
ret
stc
ret
ramdisk_notroot_next_write:
test edi, 0x1FF
jz ramdisk_notroot_next_sector
test edi, 0x1FF
jz ramdisk_notroot_next_sector
ramdisk_root_next_write:
ret
ret
 
ramdisk_notroot_extend_dir:
pusha
xor eax, eax
mov edi, RAMDISK_FAT
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF
sub edi, RAMDISK_FAT
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [RAMDISK_FAT+ecx*2], di
mov [eax], edi
shl edi, 9
add edi, (31 shl 9)+RAMDISK
mov [esp], edi
xor eax, eax
mov ecx, 128
rep stosd
popa
clc
ret
pusha
xor eax, eax
mov edi, RAMDISK_FAT
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF
sub edi, RAMDISK_FAT
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [RAMDISK_FAT+ecx*2], di
mov [eax], edi
shl edi, 9
add edi, (31 shl 9)+RAMDISK
mov [esp], edi
xor eax, eax
mov ecx, 128
rep stosd
popa
clc
ret
.notfound:
popa
stc
ret
popa
stc
ret
 
rd_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and edi->direntry
push esi edi
push 0
push ramdisk_root_first
push ramdisk_root_next
push esi edi
push 0
push ramdisk_root_first
push ramdisk_root_next
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
.continue:
test byte [edi+11], 10h
jz .notfound
movzx eax, word [edi+26]
mov [esp+8], eax
mov dword [esp+4], ramdisk_notroot_first
mov dword [esp], ramdisk_notroot_next
test eax, eax
jnz .loop
mov dword [esp+4], ramdisk_root_first
mov dword [esp], ramdisk_notroot_next
jmp .loop
test byte [edi+11], 10h
jz .notfound
movzx eax, word [edi+26]
mov [esp+8], eax
mov dword [esp+4], ramdisk_notroot_first
mov dword [esp], ramdisk_notroot_next
test eax, eax
jnz .loop
mov dword [esp+4], ramdisk_root_first
mov dword [esp], ramdisk_notroot_next
jmp .loop
.notfound:
add esp, 12
pop edi esi
stc
ret
add esp, 12
pop edi esi
stc
ret
.found:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
@@:
mov eax, [esp+8]
add esp, 16 ; CF=0
pop esi
ret
mov eax, [esp+8]
add esp, 16 ; CF=0
pop esi
ret
 
;----------------------------------------------------------------
;
899,81 → 899,81
;
;--------------------------------------------------------------
fs_RamdiskRead:
cmp byte [esi], 0
jnz @f
or ebx, -1
mov eax, 10 ; access denied
ret
cmp byte [esi], 0
jnz @f
or ebx, -1
mov eax, 10 ; access denied
ret
@@:
push edi
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, 5 ; file not found
ret
push edi
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, 5 ; file not found
ret
.found:
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; EOF
pop edi
ret
mov eax, 6 ; EOF
pop edi
ret
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6 ; EOF
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6 ; EOF
@@:
movzx edi, word [edi+26] ; cluster
movzx edi, word [edi+26] ; cluster
.new:
jecxz .done
test edi, edi
jz .eof
cmp edi, 0xFF8
jae .eof
lea eax, [edi+31] ; bootsector+2*fat+filenames
shl eax, 9 ; *512
add eax, RAMDISK ; image base
jecxz .done
test edi, edi
jz .eof
cmp edi, 0xFF8
jae .eof
lea eax, [edi+31] ; bootsector+2*fat+filenames
shl eax, 9 ; *512
add eax, RAMDISK ; image base
; now eax points to data of cluster
sub ebx, 512
jae .skip
lea eax, [eax+ebx+512]
neg ebx
push ecx
cmp ecx, ebx
jbe @f
mov ecx, ebx
sub ebx, 512
jae .skip
lea eax, [eax+ebx+512]
neg ebx
push ecx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
.skip:
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
jmp .new
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
jmp .new
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
 
;----------------------------------------------------------------
;
991,112 → 991,112
;
;--------------------------------------------------------------
fs_RamdiskReadFolder:
push edi
cmp byte [esi], 0
jz .root
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
push edi
cmp byte [esi], 0
jz .root
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
test byte [edi+11], 0x10
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
test byte [edi+11], 0x10
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
movzx eax, word [edi+26]
add eax, 31
push 0
jmp .doit
movzx eax, word [edi+26]
add eax, 31
push 0
jmp .doit
.root:
mov eax, 19
push 14
mov eax, 19
push 14
.doit:
push esi ecx ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names
mov ebx, [ebx]
push esi ecx ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names
mov ebx, [ebx]
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
pop ecx eax
mov esi, edi ; esi points to block of data of folder entry (BDFE)
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
pop ecx eax
mov esi, edi ; esi points to block of data of folder entry (BDFE)
.main_loop:
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
test edi, 0x1FF
jnz .do_bdfe
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
test edi, 0x1FF
jnz .do_bdfe
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
@@:
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
dec ebx
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
inc dword [edx+8] ; new file found
dec ebx
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
.l2:
add edi, 0x20
test edi, 0x1FF
jnz .l1
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
add edi, 0x20
test edi, 0x1FF
jnz .l1
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
@@:
jmp .main_loop
jmp .main_loop
.done:
add esp, 262*2+4
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
add esp, 262*2+4
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx esi edi edi
ret
pop ecx esi edi edi
ret
 
iglobal
label fat_legal_chars byte
1103,19 → 1103,19
; 0 = not allowed
; 1 = allowed only in long names
; 3 = allowed
times 32 db 0
times 32 db 0
; ! " # $ % & ' ( ) * + , - . /
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
; @ A B C D E F G H I J K L M N O
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; P Q R S T U V W X Y Z [ \ ] ^ _
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
; ` a b c d e f g h i j k l m n o
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; p q r s t u v w x y z { | } ~
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
endg
 
fat_name_is_legal:
1122,219 → 1122,220
; in: esi->(long) name
; out: CF set <=> legal
; destroys eax
push esi
xor eax, eax
push esi
xor eax, eax
@@:
lodsb
test al, al
jz .done
cmp al, 80h
jae .big
test [fat_legal_chars+eax], 1
jnz @b
lodsb
test al, al
jz .done
cmp al, 80h
jae .big
test [fat_legal_chars+eax], 1
jnz @b
.err:
pop esi
clc
ret
pop esi
clc
ret
.big:
; 0x80-0xAF, 0xE0-0xEF
cmp al, 0xB0
jb @b
cmp al, 0xE0
jb .err
cmp al, 0xF0
jb @b
jmp .err
cmp al, 0xB0
jb @b
cmp al, 0xE0
jb .err
cmp al, 0xF0
jb @b
jmp .err
.done:
sub esi, [esp]
cmp esi, 257
pop esi
ret
sub esi, [esp]
cmp esi, 257
pop esi
ret
 
fat_next_short_name:
; in: edi->8+3 name
; out: name corrected
; CF=1 <=> error
pushad
mov ecx, 8
mov al, '~'
std
push edi
add edi, 7
repnz scasb
pop edi
cld
jz .tilde
pushad
mov ecx, 8
mov al, '~'
std
push edi
add edi, 7
repnz scasb
pop edi
cld
jz .tilde
; tilde is not found, insert "~1" at end
add edi, 6
cmp word [edi], ' '
jnz .insert_tilde
@@: dec edi
cmp byte [edi], ' '
jz @b
inc edi
add edi, 6
cmp word [edi], ' '
jnz .insert_tilde
@@:
dec edi
cmp byte [edi], ' '
jz @b
inc edi
.insert_tilde:
mov word [edi], '~1'
popad
clc
ret
mov word [edi], '~1'
popad
clc
ret
.tilde:
push edi
add edi, 7
xor ecx, ecx
push edi
add edi, 7
xor ecx, ecx
@@:
; after tilde may be only digits and trailing spaces
cmp byte [edi], '~'
jz .break
cmp byte [edi], ' '
jz .space
cmp byte [edi], '9'
jnz .found
dec edi
jmp @b
cmp byte [edi], '~'
jz .break
cmp byte [edi], ' '
jz .space
cmp byte [edi], '9'
jnz .found
dec edi
jmp @b
.space:
dec edi
inc ecx
jmp @b
dec edi
inc ecx
jmp @b
.found:
inc byte [edi]
add dword [esp], 8
jmp .zerorest
inc byte [edi]
add dword [esp], 8
jmp .zerorest
.break:
jecxz .noplace
inc edi
mov al, '1'
jecxz .noplace
inc edi
mov al, '1'
@@:
xchg al, [edi]
inc edi
cmp al, ' '
mov al, '0'
jnz @b
xchg al, [edi]
inc edi
cmp al, ' '
mov al, '0'
jnz @b
.succ:
pop edi
popad
clc
ret
pop edi
popad
clc
ret
.noplace:
dec edi
cmp edi, [esp]
jz .err
add dword [esp], 8
mov word [edi], '~1'
inc edi
inc edi
dec edi
cmp edi, [esp]
jz .err
add dword [esp], 8
mov word [edi], '~1'
inc edi
inc edi
@@:
mov byte [edi], '0'
mov byte [edi], '0'
.zerorest:
inc edi
cmp edi, [esp]
jb @b
pop edi
popad
;clc ; automatically
ret
inc edi
cmp edi, [esp]
jb @b
pop edi
popad
;clc ; automatically
ret
.err:
pop edi
popad
stc
ret
pop edi
popad
stc
ret
 
fat_gen_short_name:
; in: esi->long name
; edi->buffer (8+3=11 chars)
; out: buffer filled
pushad
mov eax, ' '
push edi
stosd
stosd
stosd
pop edi
xor eax, eax
push 8
pop ebx
lea ecx, [edi+8]
pushad
mov eax, ' '
push edi
stosd
stosd
stosd
pop edi
xor eax, eax
push 8
pop ebx
lea ecx, [edi+8]
.loop:
lodsb
test al, al
jz .done
call char_toupper
cmp al, ' '
jz .space
cmp al, 80h
ja .big
test [fat_legal_chars+eax], 2
jnz .symbol
lodsb
test al, al
jz .done
call char_toupper
cmp al, ' '
jz .space
cmp al, 80h
ja .big
test [fat_legal_chars+eax], 2
jnz .symbol
.inv_symbol:
mov al, '_'
or bh, 1
mov al, '_'
or bh, 1
.symbol:
cmp al, '.'
jz .dot
cmp al, '.'
jz .dot
.normal_symbol:
dec bl
jns .store
mov bl, 0
dec bl
jns .store
mov bl, 0
.space:
or bh, 1
jmp .loop
or bh, 1
jmp .loop
.store:
stosb
jmp .loop
stosb
jmp .loop
.big:
cmp al, 0xB0
jb .normal_symbol
cmp al, 0xE0
jb .inv_symbol
cmp al, 0xF0
jb .normal_symbol
jmp .inv_symbol
cmp al, 0xB0
jb .normal_symbol
cmp al, 0xE0
jb .inv_symbol
cmp al, 0xF0
jb .normal_symbol
jmp .inv_symbol
.dot:
test bh, 2
jz .firstdot
pop ebx
add ebx, edi
sub ebx, ecx
push ebx
cmp ebx, ecx
jb @f
pop ebx
push ecx
test bh, 2
jz .firstdot
pop ebx
add ebx, edi
sub ebx, ecx
push ebx
cmp ebx, ecx
jb @f
pop ebx
push ecx
@@:
cmp edi, ecx
jbe .skip
cmp edi, ecx
jbe .skip
@@:
dec edi
mov al, [edi]
dec ebx
mov [ebx], al
mov byte [edi], ' '
cmp edi, ecx
ja @b
dec edi
mov al, [edi]
dec ebx
mov [ebx], al
mov byte [edi], ' '
cmp edi, ecx
ja @b
.skip:
mov bh, 3
jmp @f
mov bh, 3
jmp @f
.firstdot:
cmp bl, 8
jz .space
push edi
or bh, 2
cmp bl, 8
jz .space
push edi
or bh, 2
@@:
mov edi, ecx
mov bl, 3
jmp .loop
mov edi, ecx
mov bl, 3
jmp .loop
.done:
test bh, 2
jz @f
pop edi
test bh, 2
jz @f
pop edi
@@:
lea edi, [ecx-8]
test bh, 1
jz @f
call fat_next_short_name
lea edi, [ecx-8]
test bh, 1
jz @f
call fat_next_short_name
@@:
popad
ret
popad
ret
 
;----------------------------------------------------------------
;
1351,444 → 1352,444
;
;--------------------------------------------------------------
@@:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
 
fs_RamdiskCreateFolder:
mov al, 1 ; create folder
jmp fs_RamdiskRewrite.common
mov al, 1 ; create folder
jmp fs_RamdiskRewrite.common
 
fs_RamdiskRewrite:
xor eax, eax ; create file
xor eax, eax ; create file
.common:
cmp byte [esi], 0
jz @b
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
cmp byte [esi], 0
jz @b
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
@@:
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
push ramdisk_root_extend_dir
push ramdisk_root_next_write
push edi
push ramdisk_root_first
push ramdisk_root_next
jmp .common1
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
push ramdisk_root_extend_dir
push ramdisk_root_next_write
push edi
push ramdisk_root_first
push ramdisk_root_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call rd_find_lfn
pop esi
jc .notfound0
jmp .common0
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call rd_find_lfn
pop esi
jc .notfound0
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
; check existence
mov byte [edi], 0
push edi
call rd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
mov byte [edi], 0
push edi
call rd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
.notfound0:
mov eax, ERROR_FILE_NOT_FOUND
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
inc esi
inc esi
.common0:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
movzx ebp, word [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
cmp ebp, 2849
jae .ret1
push ramdisk_notroot_extend_dir
push ramdisk_notroot_next_write
push ebp
push ramdisk_notroot_first
push ramdisk_notroot_next
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
movzx ebp, word [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
cmp ebp, 2849
jae .ret1
push ramdisk_notroot_extend_dir
push ramdisk_notroot_next_write
push ebp
push ramdisk_notroot_first
push ramdisk_notroot_next
.common1:
call fat_find_lfn
jc .notfound
call fat_find_lfn
jc .notfound
; found
test byte [edi+11], 10h
jz .exists_file
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
add esp, 20
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
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
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
cmp byte [esp+20+28], 0
jz @f
add esp, 20
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
@@:
; delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
cmp eax, 0xFF8
jae .done1
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 20
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
call fat_name_is_legal
jc @f
add esp, 20
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
call dword [eax-4]
jc .found
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
add esp, 12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+12+8+12+8]
mov [eax], ebp
call dword [eax-4]
pop eax
xor ecx, ecx
push eax
lea eax, [esp+12+8+12+8]
mov [eax], ebp
call dword [eax-4]
pop eax
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+12+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
push eax
lea eax, [esp+12+8+12+8]
call dword [eax+8] ; extend directory
pop eax
jnc .scan_dir
add esp, 8+8+12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
push eax
lea eax, [esp+12+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
push eax
lea eax, [esp+12+8+12+8]
call dword [eax+8] ; extend directory
pop eax
jnc .scan_dir
add esp, 8+8+12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+8+8+12+8]
mov [esp+4], ecx
xor ecx, ecx
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+8+8+12+8]
mov [esp+4], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+8]
mov ecx, 11
xor eax, eax
push esi ecx
mov esi, [esp+8+8]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+8]
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+8]
; edi points to last entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
mov al, 40h
dec ecx
jz .nolfn
push esi
push eax
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call .read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call .read_symbols
xor eax, eax
stosw
mov cl, 2
call .read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+4] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call .read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call .read_symbols
xor eax, eax
stosw
mov cl, 2
call .read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+4] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
cmp byte [esp+20+28], 0
jz .doit
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
cmp byte [esp+20+28], 0
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov ecx, 32*2
mov edx, edi
mov byte [edi+11], 10h ; attributes: folder
mov ecx, 32*2
mov edx, edi
.doit:
push edx
push ecx
push edi
add edi, 26 ; edi points to low word of cluster
push edi
jecxz .done
mov ecx, 2849
mov edi, RAMDISK_FAT
push edx
push ecx
push edi
add edi, 26 ; edi points to low word of cluster
push edi
jecxz .done
mov ecx, 2849
mov edi, RAMDISK_FAT
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
jnz .disk_full2
dec edi
dec edi
xor eax, eax
repnz scasw
jnz .disk_full2
dec edi
dec edi
 
; lea eax, [edi-(RAMDISK_FAT)]
 
mov eax, edi
sub eax, RAMDISK_FAT
mov eax, edi
sub eax, RAMDISK_FAT
 
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp]
stosw
pop edi
push edi
inc ecx
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp]
stosw
pop edi
push edi
inc ecx
; write data
cmp byte [esp+16+20+28], 0
jnz .writedir
shl eax, 9
add eax, RAMDISK+31*512
cmp byte [esp+16+20+28], 0
jnz .writedir
shl eax, 9
add eax, RAMDISK+31*512
.writefile:
mov ebx, edx
xchg eax, ebx
push ecx
mov ecx, 512
cmp dword [esp+12], ecx
jae @f
mov ecx, [esp+12]
mov ebx, edx
xchg eax, ebx
push ecx
mov ecx, 512
cmp dword [esp+12], ecx
jae @f
mov ecx, [esp+12]
@@:
call memmove
add edx, ecx
sub [esp+12], ecx
pop ecx
jnz .write_loop
call memmove
add edx, ecx
sub [esp+12], ecx
pop ecx
jnz .write_loop
.done:
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
xor eax, eax
ret
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
xor eax, eax
ret
.disk_full2:
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
push ERROR_DISK_FULL
pop eax
ret
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
push ERROR_DISK_FULL
pop eax
ret
.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
xor eax, eax
mov ecx, (512-32*2)/4
rep stosd
pop edi edi ecx edx
add esp, 20
popad
xor eax, eax
xor ebx, ebx
ret
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
xor eax, eax
mov ecx, (512-32*2)/4
rep stosd
pop edi edi ecx edx
add esp, 20
popad
xor eax, eax
xor ebx, ebx
ret
 
.read_symbol:
or ax, -1
test esi, esi
jz .retFFFF
lodsb
test al, al
jnz ansi2uni_char
xor eax, eax
xor esi, esi
or ax, -1
test esi, esi
jz .retFFFF
lodsb
test al, al
jnz ansi2uni_char
xor eax, eax
xor esi, esi
.retFFFF:
ret
ret
 
.read_symbols:
call .read_symbol
stosw
loop .read_symbols
ret
call .read_symbol
stosw
loop .read_symbols
ret
 
;----------------------------------------------------------------
;
1805,110 → 1806,110
;
;--------------------------------------------------------------
@@:
push ERROR_ACCESS_DENIED
push ERROR_ACCESS_DENIED
fs_RamdiskWrite.ret0:
pop eax
xor ebx, ebx
ret
pop eax
xor ebx, ebx
ret
 
fs_RamdiskWrite:
cmp byte [esi], 0
jz @b
pushad
call rd_find_lfn
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
cmp byte [esi], 0
jz @b
pushad
call rd_find_lfn
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
.found:
; must not be directory
test byte [edi+11], 10h
jz @f
popad
push ERROR_ACCESS_DENIED
jmp .ret0
test byte [edi+11], 10h
jz @f
popad
push ERROR_ACCESS_DENIED
jmp .ret0
@@:
; FAT does not support files larger than 4GB
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
.eof:
popad
push ERROR_END_OF_FILE
jmp .ret0
popad
push ERROR_END_OF_FILE
jmp .ret0
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
call fat_update_datetime
call fat_update_datetime
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push 0 ; return value=0
cmp ecx, [edi+28]
jbe .length_ok
cmp ecx, ebx
jz .length_ok
call ramdisk_extend_file
jnc .length_ok
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push 0 ; return value=0
cmp ecx, [edi+28]
jbe .length_ok
cmp ecx, ebx
jz .length_ok
call ramdisk_extend_file
jnc .length_ok
; ramdisk_extend_file can return two error codes: FAT table error or disk full.
; First case is fatal error, in second case we may write some data
mov [esp], eax
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
mov [esp+28], eax
popad
xor ebx, ebx
ret
mov [esp], eax
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
mov [esp+28], eax
popad
xor ebx, ebx
ret
.disk_full:
; correct number of bytes to write
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
.ret:
pop eax
mov [esp+28], eax ; eax=return value
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
pop eax
mov [esp+28], eax ; eax=return value
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
.length_ok:
; now ebx=start pos, ecx=end pos, both lie inside file
sub ecx, ebx
jz .ret
movzx edi, word [edi+26] ; starting cluster
sub ecx, ebx
jz .ret
movzx edi, word [edi+26] ; starting cluster
.write_loop:
sub ebx, 0x200
jae .next_cluster
push ecx
neg ebx
cmp ecx, ebx
jbe @f
mov ecx, ebx
sub ebx, 0x200
jae .next_cluster
push ecx
neg ebx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
mov eax, edi
shl eax, 9
add eax, RAMDISK+31*512+0x200
sub eax, ebx
mov ebx, eax
mov eax, edx
call memmove
xor ebx, ebx
add edx, ecx
sub [esp], ecx
pop ecx
jz .ret
mov eax, edi
shl eax, 9
add eax, RAMDISK+31*512+0x200
sub eax, ebx
mov ebx, eax
mov eax, edx
call memmove
xor ebx, ebx
add edx, ecx
sub [esp], ecx
pop ecx
jz .ret
.next_cluster:
movzx edi, word [edi*2+RAMDISK_FAT]
jmp .write_loop
movzx edi, word [edi*2+RAMDISK_FAT]
jmp .write_loop
 
ramdisk_extend_file.zero_size:
xor eax, eax
jmp ramdisk_extend_file.start_extend
xor eax, eax
jmp ramdisk_extend_file.start_extend
 
; extends file on ramdisk to given size, new data area is filled by 0
; in: edi->direntry, ecx=new size
1915,108 → 1916,108
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
ramdisk_extend_file:
push ecx
push ecx
; find the last cluster of file
movzx eax, word [edi+26] ; first cluster
mov ecx, [edi+28]
jecxz .zero_size
movzx eax, word [edi+26] ; first cluster
mov ecx, [edi+28]
jecxz .zero_size
@@:
sub ecx, 0x200
jbe @f
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
jz .fat_err
cmp eax, 0xFF8
jb @b
sub ecx, 0x200
jbe @f
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
jz .fat_err
cmp eax, 0xFF8
jb @b
.fat_err:
pop ecx
push ERROR_FAT_TABLE
pop eax
stc
ret
pop ecx
push ERROR_FAT_TABLE
pop eax
stc
ret
@@:
push eax
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
pop eax
jb .fat_err
push eax
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
pop eax
jb .fat_err
; set length to full number of sectors and make sure that last sector is zero-padded
sub [edi+28], ecx
push eax edi
mov edi, eax
shl edi, 9
lea edi, [edi+RAMDISK+31*512+0x200+ecx]
neg ecx
xor eax, eax
rep stosb
pop edi eax
sub [edi+28], ecx
push eax edi
mov edi, eax
shl edi, 9
lea edi, [edi+RAMDISK+31*512+0x200+ecx]
neg ecx
xor eax, eax
rep stosb
pop edi eax
.start_extend:
pop ecx
pop ecx
; now do extend
push edx esi
mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2
mov edx, 2847 ; number of clusters to scan
push edx esi
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
jae .extend_done
cmp [edi+28], ecx
jae .extend_done
; add new sector
push ecx
mov ecx, edx
push edi
mov edi, esi
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
mov esi, edi
mov edx, ecx
sub edi, RAMDISK_FAT
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [RAMDISK_FAT+eax*2], di
jmp @f
push ecx
mov ecx, edx
push edi
mov edi, esi
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
mov esi, edi
mov edx, ecx
sub edi, RAMDISK_FAT
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [RAMDISK_FAT+eax*2], di
jmp @f
.first_cluster:
pop eax ; eax->direntry
push eax
mov [eax+26], di
pop eax ; eax->direntry
push eax
mov [eax+26], di
@@:
push edi
shl edi, 9
add edi, RAMDISK+31*512
xor eax, eax
mov ecx, 512/4
rep stosd
pop eax ; eax=new cluster
pop edi ; edi->direntry
pop ecx ; ecx=required size
add dword [edi+28], 0x200
jmp .extend_loop
push edi
shl edi, 9
add edi, RAMDISK+31*512
xor eax, eax
mov ecx, 512/4
rep stosd
pop eax ; eax=new cluster
pop edi ; edi->direntry
pop ecx ; ecx=required size
add dword [edi+28], 0x200
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop esi edx
xor eax, eax ; CF=0
ret
mov [edi+28], ecx
pop esi edx
xor eax, eax ; CF=0
ret
.disk_full:
pop edi ecx
pop esi edx
stc
push ERROR_DISK_FULL
pop eax
ret
pop edi ecx
pop esi edx
stc
push ERROR_DISK_FULL
pop eax
ret
 
fat_update_datetime:
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
ret
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
ret
 
;----------------------------------------------------------------
;
2031,140 → 2032,140
;
;--------------------------------------------------------------
fs_RamdiskSetFileEnd:
cmp byte [esi], 0
jnz @f
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call rd_find_lfn
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
push edi
call rd_find_lfn
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
.ret:
pop eax
ret
pop eax
ret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop edi
xor eax, eax
ret
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop edi
xor eax, eax
ret
.expand:
push ecx
mov ecx, eax
call ramdisk_extend_file
pop ecx
pop edi
ret
push ecx
mov ecx, eax
call ramdisk_extend_file
pop ecx
pop edi
ret
.truncate:
mov [edi+28], eax
push ecx
movzx ecx, word [edi+26]
test eax, eax
jz .zero_size
mov [edi+28], eax
push ecx
movzx ecx, word [edi+26]
test eax, eax
jz .zero_size
; find new last sector
@@:
sub eax, 0x200
jbe @f
movzx ecx, word [RAMDISK_FAT+ecx*2]
jmp @b
sub eax, 0x200
jbe @f
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+RAMDISK+31*512+eax+0x200]
mov ecx, eax
neg ecx
xor eax, eax
rep stosb
pop ecx
push ecx
mov edi, ecx
shl edi, 9
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, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
mov word [ecx], 0xFFF
pop ecx
and ecx, 0xFFF
jmp .delete
lea ecx, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
mov word [ecx], 0xFFF
pop ecx
and ecx, 0xFFF
jmp .delete
.zero_size:
and word [edi+26], 0
and word [edi+26], 0
.delete:
; delete FAT chain starting with ecx
; mark all clusters as free
cmp ecx, 0xFF8
jae .deleted
lea ecx, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
and word [ecx], 0
pop ecx
and ecx, 0xFFF
jmp .delete
cmp ecx, 0xFF8
jae .deleted
lea ecx, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
and word [ecx], 0
pop ecx
and ecx, 0xFFF
jmp .delete
.deleted:
pop ecx
pop edi
xor eax, eax
ret
pop ecx
pop edi
xor eax, eax
ret
 
fs_RamdiskGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call rd_find_lfn
push edi
call rd_find_lfn
fs_GetFileInfo_finish:
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
push esi ebp
xor ebp, ebp
mov esi, edx
and dword [esi+4], 0
call fat_entry_to_bdfe2
pop ebp esi
pop edi
xor eax, eax
ret
push esi ebp
xor ebp, ebp
mov esi, edx
and dword [esi+4], 0
call fat_entry_to_bdfe2
pop ebp esi
pop edi
xor eax, eax
ret
 
fs_RamdiskSetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call rd_find_lfn
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
push edi
call rd_find_lfn
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
call bdfe_to_fat_entry
pop edi
xor eax, eax
ret
call bdfe_to_fat_entry
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;
2176,97 → 2177,97
;
;--------------------------------------------------------------
fs_RamdiskDelete:
cmp byte [esi], 0
jnz @f
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
push ERROR_ACCESS_DENIED
.pop_ret:
pop eax
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
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
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
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
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
pop ebx
.access_denied2:
pop edi
jmp .access_denied
pop edi
jmp .access_denied
.empty:
pop ebx
pop ebx
.dodel:
movzx eax, word [edi+26]
movzx eax, word [edi+26]
; delete folder entry
mov byte [edi], 0xE5
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
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
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
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
pop edi
xor eax, eax
ret
 
; \end{diamond}
/kernel/branches/net/blkdev/rdsave.inc
24,7 → 24,7
mov ebx, saverd_fileinfo
mov [saverd_fileinfo.name], ecx
pushad
call file_system_lfn ;in ebx
call file_system_lfn ;in ebx
popad
mov [esp+32], eax
ret
/kernel/branches/net/bus/pci/PCIe.inc
0,0 → 1,119
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; PCIe.INC ;;
;; ;;
;; Extended PCI express services ;;
;; ;;
;; art_zh <artem@jerdev.co.uk> ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 1463 $
 
;***************************************************************************
; Function
; pci_ext_config:
;
; Description
; PCIe extended (memory-mapped) config space detection
;
; WARNINGs:
; 1) Very Experimental!
; 2) direct HT-detection (no ACPI or BIOS service used)
; 3) Only AMD/HT processors currently supported
;
;***************************************************************************
 
PCIe_CONFIG_SPACE equ 0xF0000000 ; to be moved to const.inc
mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here
mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address
 
 
align 4
 
pci_ext_config:
 
mov ebx, [mmio_pcie_cfg_addr]
or ebx, ebx
jz @f
or ebx, 0x7FFFFFFF ; required by PCI-SIG standards
jnz .pcie_failed
add ebx, 0x0FFFFC
cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct?
ja .pcie_failed
jmp .pcie_cfg_mapped
@@:
mov ebx, [cpu_vendor]
cmp ebx, dword [AMD_str]
jne .pcie_failed
mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h
 
.check_HT_mmio:
mov cx, bx
mov ax, 0x0002 ; bus = 0, 1dword to read
call pci_read_reg
mov bx, cx
sub bl, 4
and al, 0x80 ; check the NP bit
jz .no_pcie_cfg
shl eax, 8 ; bus:[27..20], dev:[19:15]
or eax, 0x00007FFC ; fun:[14..12], reg:[11:2]
mov [mmio_pcie_cfg_lim], eax
mov cl, bl
mov ax, 0x0002 ; bus = 0, 1dword to read
call pci_read_reg
mov bx, cx
test al, 0x03 ; MMIO Base RW enabled?
jz .no_pcie_cfg
test al, 0x0C ; MMIO Base locked?
jnz .no_pcie_cfg
xor al, al
shl eax, 8
test eax, 0x000F0000 ; MMIO Base must be bus0-aligned
jnz .no_pcie_cfg
mov [mmio_pcie_cfg_addr], eax
add eax, 0x000FFFFC
sub eax, [mmio_pcie_cfg_lim]; MMIO must cover at least one bus
ja .no_pcie_cfg
 
; -- it looks like a true PCIe config space;
mov eax, [mmio_pcie_cfg_addr] ; physical address
or eax, (PG_SHARED + PG_LARGE + PG_USER)
mov ebx, PCIe_CONFIG_SPACE ; linear address
mov ecx, ebx
shr ebx, 20
add ebx, sys_pgdir ; PgDir entry @
@@:
mov dword[ebx], eax ; map 4 buses
invlpg [ecx]
cmp bl, 4
jz .pcie_cfg_mapped ; fix it later
add bl, 4 ; next PgDir entry
add eax, 0x400000 ; eax += 4M
add ecx, 0x400000
jmp @b
 
.pcie_cfg_mapped:
; -- glad to have the extended PCIe config field found
; mov esi, boot_pcie_ok
; call boot_log
ret ; <<<<<<<<<<< OK >>>>>>>>>>>
.no_pcie_cfg:
 
xor eax, eax
mov [mmio_pcie_cfg_addr], eax
mov [mmio_pcie_cfg_lim], eax
add bl, 12
cmp bl, 0xC0 ; MMIO regs lay below this offset
jb .check_HT_mmio
.pcie_failed:
; mov esi, boot_pcie_fail
; call boot_log
ret ; <<<<<<<<< FAILURE >>>>>>>>>
 
/kernel/branches/net/bus/pci/pci16.inc
22,30 → 22,30
 
pushad
 
xor ax,ax
mov es,ax
mov byte [es:0x9020],1 ;default mechanism:1
mov ax,0xb101
int 0x1a
or ah,ah
jnz pci16skip
xor ax, ax
mov es, ax
mov byte [es:0x9020], 1;default mechanism:1
mov ax, 0xb101
int 0x1a
or ah, ah
jnz pci16skip
 
mov [es:0x9021],cl ;last PCI bus in system
mov [es:0x9022],bx
mov [es:0x9024],edi
mov [es:0x9021], cl;last PCI bus in system
mov [es:0x9022], bx
mov [es:0x9024], edi
 
; we have a PCI BIOS, so check which configuration mechanism(s)
; it supports
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
test al,1
jnz pci16skip
test al,2
jz pci16skip
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
test al, 1
jnz pci16skip
test al, 2
jz pci16skip
mov byte [es:0x9020], 2; if (al&3)==2 => mechanism 2
 
pci16skip:
 
mov ax,0x1000
mov es,ax
mov ax, 0x1000
mov es, ax
 
popad
/kernel/branches/net/bus/pci/pci32.inc
30,67 → 30,95
; Description
; entry point for system PCI calls
;***************************************************************************
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO
 
iglobal
align 4
f62call:
dd pci_fn_0
dd pci_fn_1
dd pci_fn_2
dd pci_service_not_supported ;3
dd pci_read_reg ;4 byte
dd pci_read_reg ;5 word
dd pci_read_reg ;6 dword
dd pci_service_not_supported ;7
dd pci_write_reg ;8 byte
dd pci_write_reg ;9 word
dd pci_write_reg ;10 dword
if defined mmio_pci_addr
dd pci_mmio_init ;11
dd pci_mmio_map ;12
dd pci_mmio_unmap ;13
end if
 
endg
 
align 4
 
pci_api:
 
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
;cross
mov eax, ebx
mov ebx, ecx
mov ecx, edx
 
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [BOOT_VAR+0x9022]
ret
cmp [pci_access_enabled], 1
jne pci_service_not_supported
 
pci_fn_1:
cmp al,1
jnz pci_fn_2
movzx edx, al
 
; PCI function 1: get last bus in AL
mov al,[BOOT_VAR+0x9021]
ret
if defined mmio_pci_addr
cmp al, 13
ja pci_service_not_supported
else
cmp al, 10
ja pci_service_not_supported
end if
 
pci_fn_2:
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[BOOT_VAR+0x9020]
ret
pci_fn_3:
call dword [f62call+edx*4]
mov dword [esp+32], eax
ret
 
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
 
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
align 4
pci_api_drv:
 
if defined mmio_pci_addr
cmp al,11 ; user-level MMIO functions
jz pci_mmio_init
cmp al,12
jz pci_mmio_map
cmp al,13
jz pci_mmio_unmap
end if
cmp [pci_access_enabled], 1
jne .fail
 
no_pci_access_for_applications:
cmp eax, 2
ja .fail
 
or eax,-1
jmp dword [f62call+eax*4]
 
ret
.fail:
or eax, -1
ret
 
 
;; ============================================
 
pci_fn_0:
; PCI function 0: get pci version (AH.AL)
movzx eax, word [BOOT_VAR+0x9022]
ret
 
pci_fn_1:
; PCI function 1: get last bus in AL
mov al, [BOOT_VAR+0x9021]
ret
 
pci_fn_2:
; PCI function 2: get pci access mechanism
mov al, [BOOT_VAR+0x9020]
ret
 
pci_service_not_supported:
or eax, -1
mov dword [esp+32], eax
ret
 
;***************************************************************************
; Function
; pci_make_config_cmd
107,11 → 135,11
align 4
 
pci_make_config_cmd:
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
and eax,0xffffff
or eax,0x80000000
ret
shl eax, 8 ; move bus to bits 16-23
mov ax, bx ; combine all
and eax, 0xffffff
or eax, 0x80000000
ret
 
;***************************************************************************
; Function
127,120 → 155,120
align 4
 
pci_read_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
cmp byte [BOOT_VAR+0x9020], 2;what mechanism will we use?
je pci_read_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
; mechanism 1
push esi ; save register size into ESI
mov esi, eax
and esi, 3
 
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
call pci_make_config_cmd
mov ebx, eax
; get current state
mov dx, 0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax, ebx
and al, 0xfc; make address dword-aligned
out dx, eax
; get requested DWORD of config data
mov dl, 0xfc
and bl, 3
or dl, bl ; add to port address first 2 bits of register address
 
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
or esi, esi
jz pci_read_byte1
cmp esi, 1
jz pci_read_word1
cmp esi, 2
jz pci_read_dword1
jmp pci_fin_read1
 
pci_read_byte1:
in al,dx
jmp pci_fin_read1
in al, dx
jmp pci_fin_read1
pci_read_word1:
in ax,dx
jmp pci_fin_read1
in ax, dx
jmp pci_fin_read1
pci_read_dword1:
in eax,dx
jmp pci_fin_read1
in eax, dx
jmp pci_fin_read1
pci_fin_read1:
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
; restore configuration control
xchg eax, [esp]
mov dx, 0xcf8
out dx, eax
 
pop eax
pop esi
ret
pop eax
pop esi
ret
pci_read_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
test bh, 128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
push esi; save register size into ESI
mov esi, eax
and esi, 3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
push eax
;store current state of config space
mov dx, 0xcf8
in al, dx
mov ah, al
mov dl, 0xfa
in al, dx
 
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
xchg eax, [esp]
; out 0xcfa,bus
mov al, ah
out dx, al
; out 0xcf8,0x80
mov dl, 0xf8
mov al, 0x80
out dx, al
; compute addr
shr bh, 3; func is ignored in mechanism 2
or bh, 0xc0
mov dx, bx
 
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
or esi, esi
jz pci_read_byte2
cmp esi, 1
jz pci_read_word2
cmp esi, 2
jz pci_read_dword2
jmp pci_fin_read2
 
pci_read_byte2:
in al,dx
jmp pci_fin_read2
in al, dx
jmp pci_fin_read2
pci_read_word2:
in ax,dx
jmp pci_fin_read2
in ax, dx
jmp pci_fin_read2
pci_read_dword2:
in eax,dx
in eax, dx
; jmp pci_fin_read2
pci_fin_read2:
 
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
; restore configuration space
xchg eax, [esp]
mov dx, 0xcfa
out dx, al
mov dl, 0xf8
mov al, ah
out dx, al
 
pop eax
pop esi
ret
pop eax
pop esi
ret
 
pci_read_reg_err:
xor eax,eax
dec eax
ret
xor eax, eax
dec eax
ret
 
 
;***************************************************************************
258,129 → 286,129
align 4
 
pci_write_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
cmp byte [BOOT_VAR+0x9020], 2;what mechanism will we use?
je pci_write_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
; mechanism 1
push esi ; save register size into ESI
mov esi, eax
and esi, 3
 
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
call pci_make_config_cmd
mov ebx, eax
; get current state into ecx
mov dx, 0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax, ebx
and al, 0xfc; make address dword-aligned
out dx, eax
; write DWORD of config data
mov dl, 0xfc
and bl, 3
or dl, bl
mov eax, ecx
 
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
or esi, esi
jz pci_write_byte1
cmp esi, 1
jz pci_write_word1
cmp esi, 2
jz pci_write_dword1
jmp pci_fin_write1
 
pci_write_byte1:
out dx,al
jmp pci_fin_write1
out dx, al
jmp pci_fin_write1
pci_write_word1:
out dx,ax
jmp pci_fin_write1
out dx, ax
jmp pci_fin_write1
pci_write_dword1:
out dx,eax
jmp pci_fin_write1
out dx, eax
jmp pci_fin_write1
pci_fin_write1:
 
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
; restore configuration control
pop eax
mov dl, 0xf8
out dx, eax
 
xor eax,eax
pop esi
xor eax, eax
pop esi
 
ret
ret
pci_write_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
test bh, 128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
 
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
push esi; save register size into ESI
mov esi, eax
and esi, 3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
push eax
;store current state of config space
mov dx, 0xcf8
in al, dx
mov ah, al
mov dl, 0xfa
in al, dx
xchg eax, [esp]
; out 0xcfa,bus
mov al, ah
out dx, al
; out 0xcf8,0x80
mov dl, 0xf8
mov al, 0x80
out dx, al
; compute addr
shr bh, 3; func is ignored in mechanism 2
or bh, 0xc0
mov dx, bx
; write register
mov eax, ecx
 
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
or esi, esi
jz pci_write_byte2
cmp esi, 1
jz pci_write_word2
cmp esi, 2
jz pci_write_dword2
jmp pci_fin_write2
 
pci_write_byte2:
out dx,al
jmp pci_fin_write2
out dx, al
jmp pci_fin_write2
pci_write_word2:
out dx,ax
jmp pci_fin_write2
out dx, ax
jmp pci_fin_write2
pci_write_dword2:
out dx,eax
jmp pci_fin_write2
out dx, eax
jmp pci_fin_write2
pci_fin_write2:
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
; restore configuration space
pop eax
mov dx, 0xcfa
out dx, al
mov dl, 0xf8
mov al, ah
out dx, al
 
xor eax,eax
pop esi
ret
xor eax, eax
pop esi
ret
 
pci_write_reg_err:
xor eax,eax
dec eax
ret
xor eax, eax
dec eax
ret
 
if defined mmio_pci_addr ; must be set above
if defined mmio_pci_addr ; must be set above
;***************************************************************************
; Function
; pci_mmio_init
; pci_mmio_init
;
; Description
; IN: bx = device's PCI bus address (bbbbbbbbdddddfff)
391,23 → 419,23
; eax = -3 : user heap initialization failure
;***************************************************************************
pci_mmio_init:
cmp bx, mmio_pci_addr
jz @f
mov eax,-2
ret
cmp bx, mmio_pci_addr
jz @f
mov eax, -2
ret
@@:
call init_heap ; (if not initialized yet)
or eax,eax
jz @f
ret
call init_heap ; (if not initialized yet)
or eax, eax
jz @f
ret
@@:
mov eax,-3
ret
mov eax, -3
ret
 
 
;***************************************************************************
; Function
; pci_mmio_map
; pci_mmio_map
;
; Description
; maps a block of PCI memory to user-accessible linear address
431,69 → 459,70
;***************************************************************************
 
pci_mmio_map:
and edx,0x0ffff
cmp ah,6
jc .bar_0_5
jz .bar_rom
mov eax,-2
ret
and edx, 0x0ffff
cmp ah, 6
jc .bar_0_5
jz .bar_rom
mov eax, -2
ret
.bar_rom:
mov ah, 8 ; bar6 = Expansion ROM base address
mov ah, 8 ; bar6 = Expansion ROM base address
.bar_0_5:
push ecx
add ebx, 4095
and ebx,-4096
push ebx
mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6
shl bl, 1
shl bl, 1
add bl, 0x10 ; now bl = BAR offset in PCI config. space
mov ax, mmio_pci_addr
mov bh, al ; bh = dddddfff
mov al, 2 ; al : DW to read
call pci_read_reg
or eax, eax
jnz @f
mov eax,-3 ; empty I/O space
jmp mmio_ret_fail
push ecx
add ebx, 4095
and ebx, -4096
push ebx
mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6
shl bl, 1
shl bl, 1
add bl, 0x10; now bl = BAR offset in PCI config. space
mov ax, mmio_pci_addr
mov bh, al ; bh = dddddfff
mov al, 2 ; al : DW to read
call pci_read_reg
or eax, eax
jnz @f
mov eax, -3 ; empty I/O space
jmp mmio_ret_fail
@@:
test eax, 1
jz @f
mov eax,-4 ; damned ports (not MMIO space)
jmp mmio_ret_fail
test eax, 1
jz @f
mov eax, -4 ; damned ports (not MMIO space)
jmp mmio_ret_fail
@@:
pop ecx ; ecx = block size, bytes (expanded to whole page)
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx
push eax ; store MMIO physical address + keep 2DWords in the stack
stdcall user_alloc, ecx
or eax, eax
jnz mmio_map_over
mov eax,-5 ; problem with page allocation
pop ecx ; ecx = block size, bytes (expanded to whole page)
mov ebx, ecx; user_alloc destroys eax, ecx, edx, but saves ebx
and eax, 0xFFFFFFF0
push eax ; store MMIO physical address + keep 2DWords in the stack
stdcall user_alloc, ecx
or eax, eax
jnz mmio_map_over
mov eax, -5 ; problem with page allocation
 
mmio_ret_fail:
pop ecx
pop edx
ret
pop ecx
pop edx
ret
 
mmio_map_over:
mov ecx, ebx ; ecx = size (bytes, expanded to whole page)
shr ecx, 12 ; ecx = number of pages
mov ebx, eax ; ebx = linear address
pop eax ; eax = MMIO start
pop edx ; edx = MMIO shift (pages)
shl edx, 12 ; edx = MMIO shift (bytes)
add eax, edx ; eax = uMMIO physical address
or eax, PG_SHARED
or eax, PG_UW
or eax, PG_NOCACHE
mov edi, ebx
call commit_pages
mov eax, edi
ret
mov ecx, ebx; ecx = size (bytes, expanded to whole page)
shr ecx, 12 ; ecx = number of pages
mov ebx, eax; ebx = linear address
pop eax ; eax = MMIO start
pop edx ; edx = MMIO shift (pages)
shl edx, 12 ; edx = MMIO shift (bytes)
add eax, edx; eax = uMMIO physical address
or eax, PG_SHARED
or eax, PG_UW
or eax, PG_NOCACHE
mov edi, ebx
call commit_pages
mov eax, edi
ret
 
;***************************************************************************
; Function
; pci_mmio_unmap_page
; pci_mmio_unmap_page
;
; Description
; unmaps the linear space previously tied to a PCI memory block
507,8 → 536,8
;***************************************************************************
 
pci_mmio_unmap:
stdcall user_free, ebx
ret
stdcall user_free, ebx
ret
 
end if
 
516,110 → 545,116
uglobal
align 4
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
pci_emu_dat: times 30*10 db 0
pci_emu_dat:
times 30*10 db 0
endg
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
align 4
sys_pcibios:
cmp [pci_access_enabled], 1
jne .unsupported_func
cmp [pci_bios_entry], 0
jz .emulate_bios
cmp [pci_access_enabled], 1
jne .unsupported_func
cmp [pci_bios_entry], 0
jz .emulate_bios
 
push ds
mov ax, pci_data_sel
mov ds, ax
mov eax, ebp
mov ah, 0B1h
call pword [cs:pci_bios_entry]
pop ds
push ds
mov ax, pci_data_sel
mov ds, ax
mov eax, ebp
mov ah, 0B1h
call pword [cs:pci_bios_entry]
pop ds
 
jmp .return
;-=-=-=-=-=-=-=-=
jmp .return
;-=-=-=-=-=-=-=-=
.emulate_bios:
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [OS_BASE+0x2F0000 + 0x9020]
mov bx, [OS_BASE+0x2F0000 + 0x9022]
mov cl, [OS_BASE+0x2F0000 + 0x9021]
xor ah, ah
jmp .return_abcd
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [BOOT_VAR + 0x9020]
mov bx, [BOOT_VAR + 0x9022]
mov cl, [BOOT_VAR + 0x9021]
xor ah, ah
jmp .return_abcd
 
.not_PCI_BIOS_PRESENT:
cmp ebp, 2 ; FIND_PCI_DEVICE
jne .not_FIND_PCI_DEVICE
mov ebx, pci_emu_dat
..nxt: cmp [ebx], dx
jne ..no
cmp [ebx + 2], cx
jne ..no
dec si
jns ..no
mov bx, [ebx + 4]
xor ah, ah
jmp .return_ab
..no: cmp word[ebx], 0
je ..dev_not_found
add ebx, 10
jmp ..nxt
cmp ebp, 2 ; FIND_PCI_DEVICE
jne .not_FIND_PCI_DEVICE
mov ebx, pci_emu_dat
..nxt:
cmp [ebx], dx
jne ..no
cmp [ebx + 2], cx
jne ..no
dec si
jns ..no
mov bx, [ebx + 4]
xor ah, ah
jmp .return_ab
..no:
cmp word[ebx], 0
je ..dev_not_found
add ebx, 10
jmp ..nxt
..dev_not_found:
mov ah, 0x86 ; DEVICE_NOT_FOUND
jmp .return_a
mov ah, 0x86 ; DEVICE_NOT_FOUND
jmp .return_a
 
.not_FIND_PCI_DEVICE:
cmp ebp, 3 ; FIND_PCI_CLASS_CODE
jne .not_FIND_PCI_CLASS_CODE
mov esi, pci_emu_dat
shl ecx, 8
..nxt2: cmp [esi], ecx
jne ..no2
mov bx, [esi]
xor ah, ah
jmp .return_ab
..no2: cmp dword[esi], 0
je ..dev_not_found
add esi, 10
jmp ..nxt2
cmp ebp, 3 ; FIND_PCI_CLASS_CODE
jne .not_FIND_PCI_CLASS_CODE
mov esi, pci_emu_dat
shl ecx, 8
..nxt2:
cmp [esi], ecx
jne ..no2
mov bx, [esi]
xor ah, ah
jmp .return_ab
..no2:
cmp dword[esi], 0
je ..dev_not_found
add esi, 10
jmp ..nxt2
 
.not_FIND_PCI_CLASS_CODE:
cmp ebp, 8 ; READ_CONFIG_*
jb .not_READ_CONFIG
cmp ebp, 0x0A
ja .not_READ_CONFIG
mov eax, ebp
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_read_reg
mov ecx, eax
xor ah, ah ; SUCCESSFUL
jmp .return_abc
cmp ebp, 8 ; READ_CONFIG_*
jb .not_READ_CONFIG
cmp ebp, 0x0A
ja .not_READ_CONFIG
mov eax, ebp
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_read_reg
mov ecx, eax
xor ah, ah ; SUCCESSFUL
jmp .return_abc
.not_READ_CONFIG:
cmp ebp, 0x0B ; WRITE_CONFIG_*
jb .not_WRITE_CONFIG
cmp ebp, 0x0D
ja .not_WRITE_CONFIG
lea eax, [ebp+1]
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_write_reg
xor ah, ah ; SUCCESSFUL
jmp .return_abc
cmp ebp, 0x0B ; WRITE_CONFIG_*
jb .not_WRITE_CONFIG
cmp ebp, 0x0D
ja .not_WRITE_CONFIG
lea eax, [ebp+1]
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_write_reg
xor ah, ah ; SUCCESSFUL
jmp .return_abc
.not_WRITE_CONFIG:
.unsupported_func:
mov ah, 0x81 ; FUNC_NOT_SUPPORTED
.return:mov dword[esp + 4 ], edi
mov dword[esp + 8], esi
mov ah, 0x81 ; FUNC_NOT_SUPPORTED
.return:
mov dword[esp + 4 ], edi
mov dword[esp + 8], esi
.return_abcd:
mov dword[esp + 24], edx
mov dword[esp + 24], edx
.return_abc:
mov dword[esp + 28], ecx
mov dword[esp + 28], ecx
.return_ab:
mov dword[esp + 20], ebx
mov dword[esp + 20], ebx
.return_a:
mov dword[esp + 32], eax
ret
mov dword[esp + 32], eax
ret
/kernel/branches/net/const.inc
143,45 → 143,42
 
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM)
 
IRQ_PIC equ 0
IRQ_APIC equ 1
 
struc TSS
{
._back rw 2
._esp0 rd 1
._ss0 rw 2
._esp1 rd 1
._ss1 rw 2
._esp2 rd 1
._ss2 rw 2
._cr3 rd 1
._eip rd 1
._eflags rd 1
._eax rd 1
._ecx rd 1
._edx rd 1
._ebx rd 1
._esp rd 1
._ebp rd 1
._esi rd 1
._edi rd 1
._es rw 2
._cs rw 2
._ss rw 2
._ds rw 2
._fs rw 2
._gs rw 2
._ldt rw 2
._trap rw 1
._io rw 1
rb 24
._io_map_0 rb 4096
._io_map_1 rb 4096
}
struct TSS
_back rw 2
_esp0 rd 1
_ss0 rw 2
_esp1 rd 1
_ss1 rw 2
_esp2 rd 1
_ss2 rw 2
_cr3 rd 1
_eip rd 1
_eflags rd 1
_eax rd 1
_ecx rd 1
_edx rd 1
_ebx rd 1
_esp rd 1
_ebp rd 1
_esi rd 1
_edi rd 1
_es rw 2
_cs rw 2
_ss rw 2
_ds rw 2
_fs rw 2
_gs rw 2
_ldt rw 2
_trap rw 1
_io rw 1
rb 24
_io_map_0 rb 4096
_io_map_1 rb 4096
ends
 
virtual at 0
TSS TSS
end virtual
 
TSS_SIZE equ (128+8192)
 
OS_BASE equ 0x80000000
247,19 → 244,20
;unused ? only one reference
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF)
 
LFBAddress equ (OS_BASE+0x000FE80)
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
 
Screen_Max_X equ (OS_BASE+0x000FE00)
Screen_Max_Y equ (OS_BASE+0x000FE04)
BytesPerScanLine equ (OS_BASE+0x000FE08)
SCR_MODE equ (OS_BASE+0x000FE0C)
 
LFBAddress equ (OS_BASE+0x000FE80)
BTN_ADDR equ (OS_BASE+0x000FE88)
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
 
SYS_SHUTDOWN equ (OS_BASE+0x000FF00)
TASK_ACTIVATE equ (OS_BASE+0x000FF01)
 
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0)
BACKGROUND_CHANGED equ (OS_BASE+0x000FFF1)
BANK_RW equ (OS_BASE+0x000FFF2)
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4)
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5)
285,33 → 283,35
RAMDISK_FAT equ (OS_BASE+0x0280000)
FLOPPY_FAT equ (OS_BASE+0x0282000)
 
CLEAN_ZONE equ 0x284000
IDE_DMA equ 0x284000
 
BgrAuxTable equ (OS_BASE+0x0298000)
; unused?
SB16Buffer equ (OS_BASE+0x2A0000)
SB16Buffer equ (OS_BASE+0x02A0000)
SB16_Status equ (OS_BASE+0x02B0000)
 
BUTTON_INFO equ (OS_BASE+0x02C0000)
RESERVED_PORTS equ (OS_BASE+0x02D0000)
IRQ_SAVE equ (OS_BASE+0x02E0000)
BOOT_VAR equ (OS_BASE+0x02f0000)
BOOT_VAR equ (OS_BASE+0x02E0000)
 
stack_data_start equ (OS_BASE+0x0300000)
eth_data_start equ (OS_BASE+0x0300000)
stack_data equ (OS_BASE+0x0304000)
stack_data_end equ (OS_BASE+0x031ffff)
resendQ equ (OS_BASE+0x0320000)
VMODE_BASE equ (OS_BASE+0x0328000)
skin_data equ (OS_BASE+0x0330000)
draw_data equ (OS_BASE+0x0338000);
stack_data_start equ (OS_BASE+0x02F0000)
eth_data_start equ (OS_BASE+0x02F0000)
stack_data equ (OS_BASE+0x02F4000)
stack_data_end equ (OS_BASE+0x030ffff)
resendQ equ (OS_BASE+0x0310000)
 
BgrDrawMode equ (OS_BASE+0x033BFF4)
BgrDataWidth equ (OS_BASE+0x033BFF8)
BgrDataHeight equ (OS_BASE+0x033BFFC)
skin_data equ (OS_BASE+0x0318000)
draw_data equ (OS_BASE+0x0320000)
 
sys_pgmap equ (OS_BASE+0x033C000)
BgrDrawMode equ (OS_BASE+0x0323FF4)
BgrDataWidth equ (OS_BASE+0x0323FF8)
BgrDataHeight equ (OS_BASE+0x0323FFC)
 
sys_pgmap equ (OS_BASE+0x0324000)
 
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
 
virtual at (OS_BASE+0x05FFF80)
tss TSS
end virtual
587,20 → 587,6
display_t display_t
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 ?
639,7 → 625,7
end virtual
 
struc MEM_STATE
{ .mutex rd 1
{ .mutex MUTEX
.smallmap rd 1
.treemap rd 1
.topsize rd 1
658,7 → 644,7
.kernel_pages dd ?
.kernel_tables dd ?
.sys_page_dir dd ?
.pg_mutex dd ?
.mutex MUTEX
}
 
;struc LIB
765,3 → 751,27
virtual at 0
CSYM COFF_SYM
end virtual
 
struc LHEAD
{
.next dd ? ;next object in list
.prev dd ? ;prev object in list
.sizeof:
}
 
virtual at 0
LHEAD LHEAD
end virtual
 
struc IRQH
{
.list LHEAD
.handler dd ? ;handler roututine
.data dd ? ;user-specific data
.sizeof:
}
 
virtual at 0
IRQH IRQH
end virtual
 
/kernel/branches/net/core/apic.inc
0,0 → 1,417
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
iglobal
IRQ_COUNT dd 24
endg
 
uglobal
irq_mode rd 1
IOAPIC_base rd 1
LAPIC_BASE rd 1
endg
 
APIC_ID equ 0x20
APIC_TPR equ 0x80
APIC_EOI equ 0xb0
APIC_LDR equ 0xd0
APIC_DFR equ 0xe0
APIC_SVR equ 0xf0
APIC_ISR equ 0x100
APIC_ESR equ 0x280
APIC_ICRL equ 0x300
APIC_ICRH equ 0x310
APIC_LVT_LINT0 equ 0x350
APIC_LVT_LINT1 equ 0x360
APIC_LVT_err equ 0x370
 
; APIC timer
APIC_LVT_timer equ 0x320
APIC_timer_div equ 0x3e0
APIC_timer_init equ 0x380
APIC_timer_cur equ 0x390
; IOAPIC
IOAPIC_ID equ 0x0
IOAPIC_VER equ 0x1
IOAPIC_ARB equ 0x2
IOAPIC_REDTBL equ 0x10
 
align 4
APIC_init:
mov [irq_mode], IRQ_PIC
 
cmp [acpi_ioapic_base], 0
jz .no_apic
 
cmp [acpi_lapic_base], 0
jz .no_apic
 
stdcall load_file, dev_data_path
test eax, eax
jz .no_apic
 
mov [acpi_dev_data], eax
mov [acpi_dev_size], ebx
 
call IRQ_mask_all
 
; IOAPIC init
stdcall map_io_mem, [acpi_ioapic_base], 0x20, PG_SW
mov [IOAPIC_base], eax
 
mov eax, IOAPIC_VER
call IOAPIC_read
shr eax, 16
inc al
movzx eax, al
cmp al, IRQ_RESERVED
jbe @f
 
mov al, IRQ_RESERVED
@@:
mov [IRQ_COUNT], eax
 
; Reroute IOAPIC & mask all interrupts
xor ecx, ecx
mov eax, IOAPIC_REDTBL
@@:
mov ebx, eax
call IOAPIC_read
mov ah, 0x09; Delivery Mode: Lowest Priority, Destination Mode: Logical
mov al, cl
add al, 0x20; vector
or eax, 0x10000; Mask Interrupt
cmp ecx, 16
jb .set
 
or eax, 0xa000;<<< level-triggered active-low for IRQ16+
.set:
xchg eax, ebx
call IOAPIC_write
inc eax
mov ebx, eax
call IOAPIC_read
or eax, 0xff000000; Destination Field
xchg eax, ebx
call IOAPIC_write
inc eax
inc ecx
cmp ecx, [IRQ_COUNT]
jb @b
 
call LAPIC_init
 
mov [irq_mode], IRQ_APIC
 
mov al, 0x70
out 0x22, al
mov al, 1
out 0x23, al
 
call pci_irq_fixup
.no_apic:
 
ret
 
;===========================================================
align 4
LAPIC_init:
; Check MSR support
;....
; Get LAPIC base address
; mov ecx, 0x1b
; rdmsr ; it may be replaced to
; and ax, 0xf000 ; mov eax, 0xfee00000
 
stdcall map_io_mem, [acpi_lapic_base], 0x1000, PG_SW
mov [LAPIC_BASE], eax
mov esi, eax
 
; Program Destination Format Register for Flat mode.
mov eax, [esi + APIC_DFR]
or eax, 0xf0000000
mov [esi + APIC_DFR], eax
 
; Program Logical Destination Register.
mov eax, [esi + APIC_LDR]
;and eax, 0xff000000
and eax, 0x00ffffff
or eax, 0x01000000;!!!!!!!!!!!!
mov [esi + APIC_LDR], eax
 
; Task Priority Register initialization.
mov eax, [esi + APIC_TPR]
and eax, 0xffffff00
mov [esi + APIC_TPR], eax
 
; Flush the queue
mov edx, 0
.nxt2:
mov ecx, 32
mov eax, [esi + APIC_ISR + edx]
.nxt:
shr eax, 1
jnc @f
mov dword [esi + APIC_EOI], 0; EOI
@@:
loop .nxt
 
add edx, 0x10
cmp edx, 0x170
jbe .nxt2
 
; Spurious-Interrupt Vector Register initialization.
mov eax, [esi + APIC_SVR]
or eax, 0x1ff
and eax, 0xfffffdff
mov [esi + APIC_SVR], eax
 
; Initialize LVT LINT0 register. (INTR)
mov eax, 0x00700
; mov eax, 0x10700
mov [esi + APIC_LVT_LINT0], eax
 
; Initialize LVT LINT1 register. (NMI)
mov eax, 0x00400
mov [esi + APIC_LVT_LINT1], eax
 
; Initialize LVT Error register.
mov eax, [esi + APIC_LVT_err]
or eax, 0x10000; bit 16
mov [esi + APIC_LVT_err], eax
 
; LAPIC timer
; pre init
mov dword[esi + APIC_timer_div], 1011b; 1
mov dword[esi + APIC_timer_init], 0xffffffff; max val
push esi
mov esi, 640 ; wait 0.64 sec
call delay_ms
pop esi
mov eax, [esi + APIC_timer_cur]; read current tick couner
xor eax, 0xffffffff ; eax = 0xffffffff - eax
shr eax, 6 ; eax /= 64; APIC ticks per 0.01 sec
 
; Start (every 0.01 sec)
mov dword[esi + APIC_LVT_timer], 0x30020; periodic int 0x20
mov dword[esi + APIC_timer_init], eax
ret
 
;===========================================================
; IOAPIC implementation
align 4
IOAPIC_read:
; in : EAX - IOAPIC register
; out: EAX - readed value
push esi
mov esi, [IOAPIC_base]
mov [esi], eax
mov eax, [esi + 0x10]
pop esi
ret
 
align 4
IOAPIC_write:
; in : EAX - IOAPIC register
; EBX - value
; out: none
push esi
mov esi, [IOAPIC_base]
mov [esi], eax
mov [esi + 0x10], ebx
pop esi
ret
;===========================================================
; Remap all IRQ to 0x20+ Vectors
; IRQ0 to vector 0x20, IRQ1 to vector 0x21....
align 4
PIC_init:
cli
mov al, 0x11 ; icw4, edge triggered
out 0x20, al
out 0xA0, al
 
mov al, 0x20 ; generate 0x20 +
out 0x21, al
mov al, 0x28 ; generate 0x28 +
out 0xA1, al
 
mov al, 0x04 ; slave at irq2
out 0x21, al
mov al, 0x02 ; at irq9
out 0xA1, al
 
mov al, 0x01 ; 8086 mode
out 0x21, al
out 0xA1, al
 
call IRQ_mask_all
; mov dword[irq_type_to_set], IRQ_TYPE_PIC
ret
 
; -----------------------------------------
; TIMER SET TO 1/100 S
align 4
PIT_init:
mov al, 0x34 ; set to 100Hz
out 0x43, al
mov al, 0x9b ; lsb 1193180 / 1193
out 0x40, al
mov al, 0x2e ; msb
out 0x40, al
ret
 
; -----------------------------------------
align 4
unmask_timer:
cmp [irq_mode], IRQ_APIC
je @f
 
stdcall enable_irq, 0
ret
@@:
; use PIT
; in some systems PIT no connected to IOAPIC
; mov eax, 0x14
; call IOAPIC_read
; mov ah, 0x09 ; Delivery Mode: Lowest Priority, Destination Mode: Logical
; mov al, 0x20
; or eax, 0x10000 ; Mask Interrupt
; mov ebx, eax
; mov eax, 0x14
; call IOAPIC_write
; stdcall enable_irq, 2
; ret
 
; use LAPIC timer
mov esi, [LAPIC_BASE]
mov eax, [esi + APIC_LVT_timer]
and eax, 0xfffeffff
mov [esi + APIC_LVT_timer], eax
ret
 
; -----------------------------------------
; Disable all IRQ
align 4
IRQ_mask_all:
cmp [irq_mode], IRQ_APIC
je .APIC
 
mov al, 0xFF
out 0x21, al
out 0xA1, al
mov ecx, 0x1000
ret
.APIC:
mov ecx, [IRQ_COUNT]
mov eax, 0x10
@@:
mov ebx, eax
call IOAPIC_read
or eax, 0x10000; bit 16
xchg eax, ebx
call IOAPIC_write
inc eax
inc eax
loop @b
ret
 
; -----------------------------------------
; End Of Interrupt
; cl - IRQ number
align 4
irq_eoi: ; __fastcall
cmp [irq_mode], IRQ_APIC
je .APIC
 
cmp cl, 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
ret
 
.APIC:
mov eax, [LAPIC_BASE]
mov dword [eax + APIC_EOI], 0; EOI
ret
 
; -----------------------------------------
; from dll.inc
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
cmp [irq_mode], IRQ_APIC
je .APIC
 
mov edx, 0x21
cmp ebx, 8
jb @F
 
mov edx, 0xA1
sub ebx, 8
@@:
in al, dx
btr eax, ebx
out dx, al
ret
.APIC:
shl ebx, 1
add ebx, 0x10
mov eax, ebx
call IOAPIC_read
and eax, 0xfffeffff; bit 16
xchg eax, ebx
call IOAPIC_write
ret
endp
 
align 4
pci_irq_fixup:
 
push ebp
 
mov esi, [acpi_dev_data]
mov ebx, [acpi_dev_size]
 
lea edi, [esi+ebx]
 
.iterate:
 
cmp esi, edi
jae .done
 
mov eax, [esi]
 
cmp eax, -1
je .done
 
movzx ebx, al
movzx ebp, ah
 
stdcall pci_read32, ebp, ebx, 0
 
cmp eax, [esi+4]
jne .skip
 
mov eax, [esi+8]
stdcall pci_write8, ebp, ebx, 0x3C, eax
.skip:
add esi, 16
jmp .iterate
 
.done:
.fail:
pop ebp
ret
 
 
 
 
 
/kernel/branches/net/core/conf_lib.inc
13,7 → 13,8
$Revision$
 
iglobal
conf_path_sect: db 'path',0
conf_path_sect:
db 'path',0
 
conf_fname db '/sys/sys.conf',0
endg
27,30 → 28,30
;[gui]
;mouse_speed
 
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed,\
eax,30, ugui_mouse_speed_def
pop eax
stdcall strtoint,eax
lea eax, [par]
push eax
invoke ini.get_str, conf_fname, ugui, ugui_mouse_speed, \
eax,30, ugui_mouse_speed_def
pop eax
stdcall strtoint, eax
mov [mouse_speed_factor], ax
 
;mouse_delay
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay,\
eax,30, ugui_mouse_delay_def
pop eax
stdcall strtoint,eax
lea eax, [par]
push eax
invoke ini.get_str, conf_fname, ugui, ugui_mouse_delay, \
eax,30, ugui_mouse_delay_def
pop eax
stdcall strtoint, eax
mov [mouse_delay], eax
 
 
;midibase
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def
pop eax
stdcall strtoint,eax
lea eax, [par]
push eax
invoke ini.get_str, conf_fname, udev, udev_midibase, eax, 30, udev_midibase_def
pop eax
stdcall strtoint, eax
 
cmp eax, 0x100
jb @f
75,223 → 76,135
udev_midibase db 'midibase',0
udev_midibase_def db '0x320',0
endg
;set up netvork configuration
proc set_network_conf
locals
par db 30 dup(?)
endl
pushad
 
;[net]
;active
lea eax,[par]
invoke ini.get_int,conf_fname, unet, unet_active, 0
or eax,eax
jz .do_not_set_net
mov eax, [stack_config]
and eax, 0xFFFFFF80
add eax, 3
mov [stack_config], eax
call ash_eth_enable
 
;addr
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [stack_ip], eax
 
;mask
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [subnet_mask], eax
 
;gate
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [gateway_ip], eax
.do_not_set_net:
popad
ret
 
 
endp
iglobal
unet db 'net',0
unet_active db 'active',0
unet_addr db 'addr',0
unet_mask db 'mask',0
unet_gate db 'gate',0
unet_def db 0
endg
; convert string to DWord
proc strtoint stdcall,strs
pushad
pushad
 
mov eax,[strs]
inc eax
mov bl,[eax]
cmp bl,'x'
je .hex
cmp bl,'X'
je .hex
jmp .dec
mov eax, [strs]
inc eax
mov bl, [eax]
cmp bl, 'x'
je .hex
cmp bl, 'X'
je .hex
jmp .dec
.hex:
inc eax
stdcall strtoint_hex,eax
jmp .exit
inc eax
stdcall strtoint_hex, eax
jmp .exit
.dec:
dec eax
stdcall strtoint_dec,eax
dec eax
stdcall strtoint_dec, eax
.exit:
mov [esp+28],eax
popad
ret
mov [esp+28], eax
popad
ret
endp
 
; convert string to DWord for decimal value
proc strtoint_dec stdcall,strs
pushad
xor edx,edx
pushad
xor edx, edx
; ¯®¨áª ª®­æ 
mov esi,[strs]
mov esi, [strs]
@@:
lodsb
or al,al
jnz @b
mov ebx,esi
mov esi,[strs]
dec ebx
sub ebx,esi
mov ecx,1
lodsb
or al, al
jnz @b
mov ebx, esi
mov esi, [strs]
dec ebx
sub ebx, esi
mov ecx, 1
 
@@:
dec ebx
or ebx,ebx
jz @f
imul ecx,ecx,10 ; ¯®à冷ª
jmp @b
dec ebx
or ebx, ebx
jz @f
imul ecx, ecx, 10; ¯®à冷ª
jmp @b
@@:
 
xchg ebx,ecx
xchg ebx, ecx
 
 
xor ecx,ecx
xor ecx, ecx
 
 
@@:
xor eax,eax
lodsb
cmp al,0
je .eend
xor eax, eax
lodsb
cmp al, 0
je .eend
 
sub al,30h
imul ebx
add ecx,eax
push ecx
xchg eax,ebx
mov ecx,10
div ecx
xchg eax,ebx
pop ecx
jmp @b
sub al, 30h
imul ebx
add ecx, eax
push ecx
xchg eax, ebx
mov ecx, 10
div ecx
xchg eax, ebx
pop ecx
jmp @b
 
.eend:
mov [esp+28],ecx
popad
ret
mov [esp+28], ecx
popad
ret
endp
 
;convert string to DWord for hex value
proc strtoint_hex stdcall,strs
pushad
xor edx,edx
pushad
xor edx, edx
 
mov esi,[strs]
mov ebx,1
add esi,1
mov esi, [strs]
mov ebx, 1
add esi, 1
 
@@:
lodsb
or al,al
jz @f
shl ebx,4
jmp @b
lodsb
or al, al
jz @f
shl ebx, 4
jmp @b
@@:
xor ecx,ecx
mov esi,[strs]
xor ecx, ecx
mov esi, [strs]
 
@@:
xor eax,eax
lodsb
cmp al,0
je .eend
xor eax, eax
lodsb
cmp al, 0
je .eend
 
cmp al,'a'
jae .bm
cmp al,'A'
jae .bb
jmp .cc
cmp al, 'a'
jae .bm
cmp al, 'A'
jae .bb
jmp .cc
.bm: ; 57h
sub al,57h
jmp .do
sub al, 57h
jmp .do
 
.bb: ; 37h
sub al,37h
jmp .do
sub al, 37h
jmp .do
 
.cc: ; 30h
sub al,30h
sub al, 30h
 
.do:
imul ebx
add ecx,eax
shr ebx,4
imul ebx
add ecx, eax
shr ebx, 4
 
jmp @b
jmp @b
 
.eend:
mov [esp+28],ecx
popad
ret
mov [esp+28], ecx
popad
ret
endp
 
 
; convert string to DWord for IP addres
proc do_inet_adr stdcall,strs
pushad
 
mov esi,[strs]
mov ebx,0
.next:
push esi
@@:
lodsb
or al,al
jz @f
cmp al,'.'
jz @f
jmp @b
@@:
mov cl, al
mov [esi-1],byte 0
;pop eax
call strtoint_dec
rol eax,24
ror ebx,8
add ebx,eax
or cl,cl
jz @f
jmp .next
@@:
mov [esp+28],ebx
popad
ret
endp
/kernel/branches/net/core/debug.inc
13,7 → 13,8
cmp ebx, 9
ja @f
jmp dword [sys_debug_services_table+ebx*4]
@@: ret
@@:
ret
iglobal
align 4
sys_debug_services_table:
76,7 → 77,7
shr ecx, 5
; push 2
; pop ebx
mov edx,esi
mov edx, esi
jmp sysfn_terminate
 
debug_suspend:
93,7 → 94,8
cmp cl, 5
jnz .ret
mov cl, 2
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
.2:
mov [CURRENT_TASK+eax+TASKDATA.state], cl
.ret:
sti
ret
108,9 → 110,12
cmp cl, 2
jnz .ret
mov cl, 5
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
.ret: ret
.1: dec ecx
.2:
mov [CURRENT_TASK+eax+TASKDATA.state], cl
.ret:
ret
.1:
dec ecx
jmp .2
 
debug_resume:
122,7 → 127,8
shl eax, 5
jz .ret
call do_resume
.ret: sti
.ret:
sti
ret
 
debug_getcontext:
142,8 → 148,8
call get_debuggee_slot
jc .ret
mov edi, esi
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea esi, [eax+RING0_STACK_SIZE]
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea esi, [eax+RING0_STACK_SIZE]
 
.ring0:
; note that following code assumes that all interrupt/exception handlers
193,8 → 199,8
call get_debuggee_slot
jc .stiret
; mov esi, edx
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea edi, [eax+RING0_STACK_SIZE]
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea edi, [eax+RING0_STACK_SIZE]
 
.ring0:
sub edi, 8+12+20h
233,15 → 239,15
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
; [eax+10]=dr7
cmp esi, OS_BASE
jae .errret
jae .errret
cmp dl, 3
ja .errret
mov ecx, dr7
;fix me
xchg ecx,edx
xchg ecx, edx
shr edx, cl
shr edx, cl
xchg ecx,edx
xchg ecx, edx
 
test ecx, 2 ; bit 1+2*index = G0..G3, global break enable
jnz .errret2
256,7 → 262,7
jnz .okret
; imul eax, ebp, tss_step/32
; and byte [eax + tss_data + TSS._trap], not 1
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1
.okret:
and dword [esp+32], 0
sti
283,7 → 289,7
cmp cl, 2
jz .errret
 
mov ebx,esi
mov ebx, esi
test bl, dl
 
jnz .errret
303,7 → 309,7
or [eax+10h+2], dx ; set R/W and LEN fields
; imul eax, ebp, tss_step/32
; or byte [eax + tss_data + TSS._trap], 1
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1
jmp .okret
 
debug_read_process_memory:
323,7 → 329,7
call get_debuggee_slot
jc .err
shr eax, 5
; mov ebx, esi
mov ecx, edi
call read_process_memory
sti
mov dword [esp+32], eax
349,7 → 355,7
call get_debuggee_slot
jc debug_read_process_memory.err
shr eax, 5
; mov ebx, esi
mov ecx, edi
call write_process_memory
sti
mov [esp+32], eax
368,8 → 374,8
.1:
mov eax, ebp
shl eax, 8
mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
test edx, edx
mov esi, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
test esi, esi
jz .ret
; read buffer header
push ecx
376,15 → 382,15
push eax
push eax
mov eax, ebp
mov ebx, esp
mov ecx, 8
mov ecx, esp
mov edx, 8
call read_process_memory
cmp eax, ecx
cmp eax, edx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ebx], 0
cmp dword [ecx], 0
jg @f
.2:
pop ecx
400,26 → 406,26
cli
jmp .1
@@:
mov ecx, [ebx+8]
add ecx, [ebx+4]
cmp ecx, [ebx]
mov edx, [ecx+8]
add edx, [ecx+4]
cmp edx, [ecx]
ja .2
; advance buffer position
push ecx
mov ecx, 4
sub ebx, ecx
push edx
mov edx, 4
sub ecx, edx
mov eax, ebp
add edx, ecx
add esi, edx
call write_process_memory
pop eax
; write message
mov eax, ebp
add edx, ecx
add edx, [ebx+8]
add ebx, 20
pop ecx
pop ecx
pop ecx
add esi, edx
add esi, [ecx+8]
add ecx, 20
pop edx
pop edx
pop edx
call write_process_memory
; new debug event
mov eax, ebp
/kernel/branches/net/core/dll.inc
9,327 → 9,151
 
 
DRV_COMPAT equ 5 ;minimal required drivers version
DRV_CURRENT equ 5 ;current drivers model version
DRV_CURRENT equ 6 ;current drivers model version
 
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
PID_KERNEL equ 1 ;os_idle thread
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword
 
push ebx
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's
ja .err
mov eax, [handler]
test eax, eax
jz .err
cmp [irq_owner + 4 * ebx], 0
je @f
 
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden
test ecx, ecx
jnz .err
 
@@:
mov [irq_tab+ebx*4], eax
 
mov eax, [access_rights]
mov [irq_rights + 4 * ebx], eax
 
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel
 
stdcall enable_irq, [irq]
pop ebx
mov eax, 1
ret
.err:
pop ebx
xor eax, eax
ret
endp
 
uglobal
 
irq_rights rd 16
 
endg
 
proc get_int_handler stdcall, irq:dword
 
mov eax, [irq]
 
cmp [irq_rights + 4 * eax], dword 1
ja .err
 
mov eax, [irq_tab + 4 * eax]
ret
 
.err:
xor eax, eax
ret
 
endp
 
align 4
proc detach_int_handler
 
ret
endp
 
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
mov edx, 0x21
cmp ebx, 8
jb @F
mov edx, 0xA1
sub ebx,8
@@:
in al,dx
btr eax, ebx
out dx, al
ret
endp
 
align 16
;; proc irq_serv
 
irq_serv:
 
.irq_1:
push 1
jmp .main
align 4
.irq_2:
push 2
jmp .main
align 4
.irq_3:
push 3
jmp .main
align 4
.irq_4:
push 4
jmp .main
align 4
.irq_5:
push 5
jmp .main
; align 4
; .irq_6:
; push 6
; jmp .main
align 4
.irq_7:
push 7
jmp .main
align 4
.irq_8:
push 8
jmp .main
align 4
.irq_9:
push 9
jmp .main
align 4
.irq_10:
push 10
jmp .main
align 4
.irq_11:
push 11
jmp .main
align 4
.irq_12:
push 12
jmp .main
; align 4
; .irq_13:
; push 13
; jmp .main
; align 4
; .irq_14:
; push 14
; jmp .main
; align 4
; .irq_15:
; push 15
; jmp .main
 
align 16
.main:
save_ring3_context
mov eax, [esp + 32]
mov bx, app_data ;os_data
mov ds, bx
mov es, bx
 
cmp [v86_irqhooks+eax*8], 0
jnz v86_irq
 
mov ebx, [irq_tab+eax*4]
test ebx, ebx
jz .exit
 
call ebx
mov [check_idle_semaphore],5
 
.exit:
 
cmp dword [esp + 32], 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
restore_ring3_context
add esp, 4
 
iret
 
align 4
proc get_notify stdcall, p_ev:dword
 
.wait:
mov ebx,[current_slot]
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
jz @f
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+APPDATA.event]
mov dword [edi+4], eax
ret
mov ebx, [current_slot]
test dword [ebx+APPDATA.event_mask], EVENT_NOTIFY
jz @f
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+APPDATA.event]
mov dword [edi+4], eax
ret
@@:
call change_task
jmp .wait
call change_task
jmp .wait
endp
 
align 4
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 5
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 5
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
align 4
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 9
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 9
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
align 4
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx edx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 10
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop edx ebx
ret
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 10
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
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
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
 
align 4
proc srv_handler stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
mov esi, [ioctl]
test esi, esi
jz .err
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV.sizeof
jne .fail
cmp [edi+SRV.size], SRV.sizeof
jne .fail
 
stdcall [edi+SRV.srv_proc], esi
ret
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
xor eax, eax
not eax
ret
endp
 
; param
340,21 → 164,21
 
align 4
srv_handlerEx:
cmp ecx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jae .fail
 
mov eax, [ecx+handle]
cmp [eax+SRV.magic], ' SRV'
jne .fail
mov eax, [ecx+handle]
cmp [eax+SRV.magic], ' SRV'
jne .fail
 
cmp [eax+SRV.size], SRV.sizeof
jne .fail
cmp [eax+SRV.size], SRV.sizeof
jne .fail
 
stdcall [eax+SRV.srv_proc], ecx
ret
stdcall [eax+SRV.srv_proc], ecx
ret
.fail:
or eax, -1
ret
or eax, -1
ret
 
restore handle
restore io_code
365,100 → 189,100
 
align 4
proc get_service stdcall, sz_name:dword
mov eax, [sz_name]
test eax, eax
jnz @F
ret
mov eax, [sz_name]
test eax, eax
jnz @F
ret
@@:
mov edx, [srv.fd]
mov edx, [srv.fd]
@@:
cmp edx, srv.fd-SRV_FD_OFFSET
je .not_load
cmp edx, srv.fd-SRV_FD_OFFSET
je .not_load
 
stdcall strncmp, edx, [sz_name], 16
test eax, eax
je .ok
stdcall strncmp, edx, [sz_name], 16
test eax, eax
je .ok
 
mov edx, [edx+SRV.fd]
jmp @B
mov edx, [edx+SRV.fd]
jmp @B
.not_load:
pop ebp
jmp load_driver
pop ebp
jmp load_driver
.ok:
mov eax, edx
ret
mov eax, edx
ret
endp
 
align 4
proc reg_service stdcall, name:dword, handler:dword
 
push ebx
push ebx
 
xor eax, eax
xor eax, eax
 
cmp [name], eax
je .fail
cmp [name], eax
je .fail
 
cmp [handler], eax
je .fail
cmp [handler], eax
je .fail
 
mov eax, SRV.sizeof
call malloc
test eax, eax
jz .fail
mov eax, SRV.sizeof
call malloc
test eax, eax
jz .fail
 
push esi
push edi
mov edi, eax
mov esi, [name]
movsd
movsd
movsd
movsd
pop edi
pop esi
push esi
push edi
mov edi, eax
mov esi, [name]
movsd
movsd
movsd
movsd
pop edi
pop esi
 
mov [eax+SRV.magic], ' SRV'
mov [eax+SRV.size], SRV.sizeof
mov [eax+SRV.magic], ' SRV'
mov [eax+SRV.size], SRV.sizeof
 
mov ebx, srv.fd-SRV_FD_OFFSET
mov edx, [ebx+SRV.fd]
mov [eax+SRV.fd], edx
mov [eax+SRV.bk], ebx
mov [ebx+SRV.fd], eax
mov [edx+SRV.bk], eax
mov ebx, srv.fd-SRV_FD_OFFSET
mov edx, [ebx+SRV.fd]
mov [eax+SRV.fd], edx
mov [eax+SRV.bk], ebx
mov [ebx+SRV.fd], eax
mov [edx+SRV.bk], eax
 
mov ecx, [handler]
mov [eax+SRV.srv_proc], ecx
pop ebx
ret
mov ecx, [handler]
mov [eax+SRV.srv_proc], ecx
pop ebx
ret
.fail:
xor eax, eax
pop ebx
ret
xor eax, eax
pop ebx
ret
endp
 
align 4
proc get_proc stdcall, exp:dword, sz_name:dword
 
mov edx, [exp]
mov edx, [exp]
.next:
mov eax, [edx]
test eax, eax
jz .end
mov eax, [edx]
test eax, eax
jz .end
 
push edx
stdcall strncmp, eax, [sz_name], 16
pop edx
test eax, eax
jz .ok
push edx
stdcall strncmp, eax, [sz_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
add edx, 8
jmp .next
.ok:
mov eax, [edx+4]
mov eax, [edx+4]
.end:
ret
ret
endp
 
align 4
465,91 → 289,89
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
 
@@:
stdcall strncmp, [pSym], [sz_sym], 8
test eax,eax
jz .ok
add [pSym], 18
dec [count]
jnz @b
xor eax, eax
ret
stdcall strncmp, [pSym], [sz_sym], 8
test eax, eax
jz .ok
add [pSym], 18
dec [count]
jnz @b
xor eax, eax
ret
.ok:
mov eax, [pSym]
mov eax, [eax+8]
ret
mov eax, [pSym]
mov eax, [eax+8]
ret
endp
 
align 4
proc get_curr_task
mov eax,[CURRENT_TASK]
shl eax, 8
ret
mov eax, [CURRENT_TASK]
shl eax, 8
ret
endp
 
align 4
proc get_fileinfo stdcall, file_name:dword, info:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [info]
xor eax, eax
mov ebx, [file_name]
mov ecx, [info]
 
mov [cmd], 5
mov [offset], eax
mov [offset+4], eax
mov [count], eax
mov [buff], ecx
mov byte [buff+4], al
mov [name], ebx
mov [cmd], 5
mov [offset], eax
mov [offset+4], eax
mov [count], eax
mov [buff], ecx
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
int 0x40
ret
mov eax, 70
lea ebx, [cmd]
int 0x40
ret
endp
 
align 4
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
bytes:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
bytes:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [off]
mov edx, [bytes]
mov esi, [buffer]
xor eax, eax
mov ebx, [file_name]
mov ecx, [off]
mov edx, [bytes]
mov esi, [buffer]
 
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
 
pushad
push eax
lea eax, [cmd]
call file_system_lfn
pop eax
popad
ret
pushad
lea ebx, [cmd]
call file_system_lfn
popad
ret
endp
 
; description
568,82 → 390,84
 
align 4
proc load_file stdcall, file_name:dword
locals
attr dd ?
flags dd ?
cr_time dd ?
cr_date dd ?
acc_time dd ?
acc_date dd ?
mod_time dd ?
mod_date dd ?
file_size dd ?
locals
attr dd ?
flags dd ?
cr_time dd ?
cr_date dd ?
acc_time dd ?
acc_date dd ?
mod_time dd ?
mod_date dd ?
file_size dd ?
 
file dd ?
file2 dd ?
endl
file dd ?
file2 dd ?
endl
 
push esi
push edi
push esi
push edi
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
 
mov eax, [file_size]
cmp eax, 1024*1024*16
ja .fail
mov eax, [file_size]
cmp eax, 1024*1024*16
ja .fail
 
stdcall kernel_alloc, [file_size]
mov [file], eax
stdcall kernel_alloc, [file_size]
mov [file], eax
test eax, eax
jz .fail
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
 
mov eax, [file]
cmp dword [eax], 0x4B43504B
jne .exit
mov ebx, [eax+4]
mov [file_size], ebx
stdcall kernel_alloc, ebx
mov eax, [file]
cmp dword [eax], 0x4B43504B
jne .exit
mov ebx, [eax+4]
mov [file_size], ebx
stdcall kernel_alloc, ebx
 
test eax, eax
jz .cleanup
test eax, eax
jz .cleanup
 
mov [file2], eax
pushfd
cli
stdcall unpack, [file], eax
popfd
stdcall kernel_free, [file]
mov eax, [file2]
mov ebx, [file_size]
mov [file2], eax
pushfd
cli
stdcall unpack, [file], eax
popfd
stdcall kernel_free, [file]
mov eax, [file2]
mov ebx, [file_size]
.exit:
push eax
lea edi, [eax+ebx] ;cleanup remain space
mov ecx, 4096 ;from file end
and ebx, 4095
jz @f
sub ecx, ebx
xor eax, eax
cld
rep stosb
push eax
lea edi, [eax+ebx] ;cleanup remain space
mov ecx, 4096 ;from file end
and ebx, 4095
jz @f
sub ecx, ebx
xor eax, eax
cld
rep stosb
@@:
mov ebx, [file_size]
pop eax
pop edi
pop esi
ret
mov ebx, [file_size]
pop eax
pop edi
pop esi
ret
.cleanup:
stdcall kernel_free, [file]
stdcall kernel_free, [file]
.fail:
xor eax, eax
xor ebx, ebx
pop edi
pop esi
ret
xor eax, eax
xor ebx, ebx
pop edi
pop esi
ret
endp
 
align 4
650,372 → 474,373
proc get_proc_ex stdcall, proc_name:dword, imports:dword
 
.look_up:
mov edx, [imports]
test edx, edx
jz .end
mov edx, [edx]
test edx, edx
jz .end
mov edx, [imports]
test edx, edx
jz .end
mov edx, [edx]
test edx, edx
jz .end
.next:
mov eax, [edx]
test eax, eax
jz .next_table
mov eax, [edx]
test eax, eax
jz .next_table
 
push edx
stdcall strncmp, eax, [proc_name], 256
pop edx
test eax, eax
jz .ok
push edx
stdcall strncmp, eax, [proc_name], 256
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
add edx, 8
jmp .next
.next_table:
add [imports], 4
jmp .look_up
add [imports], 4
jmp .look_up
.ok:
mov eax, [edx+4]
ret
mov eax, [edx+4]
ret
.end:
xor eax, eax
ret
xor eax, eax
ret
endp
 
align 4
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
sym_count:dword, strings:dword, imports:dword
locals
retval dd ?
endl
sym_count:dword, strings:dword, imports:dword
locals
retval dd ?
endl
 
mov edi, [symbols]
mov [retval], 1
mov edi, [symbols]
mov [retval], 1
.fix:
movzx ebx, [edi+CSYM.SectionNumber]
test ebx, ebx
jnz .internal
mov eax, dword [edi+CSYM.Name]
test eax, eax
jnz @F
movzx ebx, [edi+CSYM.SectionNumber]
test ebx, ebx
jnz .internal
mov eax, dword [edi+CSYM.Name]
test eax, eax
jnz @F
 
mov edi, [edi+4]
add edi, [strings]
mov edi, [edi+4]
add edi, [strings]
@@:
push edi
stdcall get_proc_ex, edi,[imports]
pop edi
push edi
stdcall get_proc_ex, edi, [imports]
pop edi
 
xor ebx, ebx
test eax, eax
jnz @F
xor ebx, ebx
test eax, eax
jnz @F
 
mov esi, msg_unresolved
call sys_msg_board_str
mov esi, edi
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_unresolved
call sys_msg_board_str
mov esi, edi
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov [retval],0
mov [retval], 0
@@:
mov edi, [symbols]
mov [edi+CSYM.Value], eax
jmp .next
mov edi, [symbols]
mov [edi+CSYM.Value], eax
jmp .next
.internal:
cmp bx, -1
je .next
cmp bx, -2
je .next
cmp bx, -1
je .next
cmp bx, -2
je .next
 
dec ebx
shl ebx, 3
lea ebx, [ebx+ebx*4]
add ebx, [sec]
dec ebx
shl ebx, 3
lea ebx, [ebx+ebx*4]
add ebx, [sec]
 
mov eax, [ebx+CFS.VirtualAddress]
add [edi+CSYM.Value], eax
mov eax, [ebx+CFS.VirtualAddress]
add [edi+CSYM.Value], eax
.next:
add edi, CSYM_SIZE
mov [symbols], edi
dec [sym_count]
jnz .fix
mov eax, [retval]
ret
add edi, CSYM_SIZE
mov [symbols], edi
dec [sym_count]
jnz .fix
mov eax, [retval]
ret
endp
 
align 4
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
delta:dword
locals
n_sec dd ?
endl
delta:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
.fix_sec:
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.reloc_loop:
mov ebx, [edi+CRELOC.SymIndex]
add ebx,ebx
lea ebx,[ebx+ebx*8]
add ebx, [sym]
mov ebx, [edi+CRELOC.SymIndex]
add ebx, ebx
lea ebx, [ebx+ebx*8]
add ebx, [sym]
 
mov edx, [ebx+CSYM.Value]
mov edx, [ebx+CSYM.Value]
 
cmp [edi+CRELOC.Type], 6
je .dir_32
cmp [edi+CRELOC.Type], 6
je .dir_32
 
cmp [edi+CRELOC.Type], 20
jne .next_reloc
cmp [edi+CRELOC.Type], 20
jne .next_reloc
.rel_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
sub edx, eax
sub edx, 4
jmp .fix
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
sub edx, eax
sub edx, 4
jmp .fix
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
.fix:
add eax, [delta]
add [eax], edx
add eax, [delta]
add [eax], edx
.next_reloc:
add edi, 10
dec ecx
jnz .reloc_loop
add edi, 10
dec ecx
jnz .reloc_loop
.next:
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
.exit:
ret
ret
endp
 
align 4
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
delta:dword
locals
n_sec dd ?
endl
delta:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
mov edx, [delta]
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
mov edx, [delta]
.fix_sec:
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.reloc_loop:
cmp [edi+CRELOC.Type], 6
jne .next_reloc
cmp [edi+CRELOC.Type], 6
jne .next_reloc
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
add [eax+edx], edx
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
add [eax+edx], edx
.next_reloc:
add edi, 10
dec ecx
jnz .reloc_loop
add edi, 10
dec ecx
jnz .reloc_loop
.next:
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
.exit:
ret
ret
endp
 
align 4
proc load_driver stdcall, driver_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
exports dd ? ;fake exports table
dd ?
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
endl
exports dd ? ;fake exports table
dd ?
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
endl
 
lea edx, [file_name]
mov dword [edx], '/sys'
mov dword [edx+4], '/dri'
mov dword [edx+8], 'vers'
mov byte [edx+12], '/'
mov esi, [driver_name]
lea edx, [file_name]
mov dword [edx], '/sys'
mov dword [edx+4], '/dri'
mov dword [edx+8], 'vers'
mov byte [edx+12], '/'
mov esi, [driver_name]
.redo:
lea edx, [file_name]
lea edi, [edx+13]
mov ecx, 16
lea edx, [file_name]
lea edi, [edx+13]
mov ecx, 16
@@:
lodsb
test al, al
jz @f
stosb
loop @b
lodsb
test al, al
jz @f
stosb
loop @b
@@:
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
 
test eax, eax
jz .exit
test eax, eax
jz .exit
 
mov [coff], eax
mov [coff], eax
 
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
 
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx, ecx
lea ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea ebx, [exports]
mov dword [ebx], kernel_export
mov dword [ebx+4], 0
lea eax, [edx+20]
lea ebx, [exports]
mov dword [ebx], kernel_export
mov dword [ebx+4], 0
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], ebx
test eax, eax
jz .link_fail
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols], \
[strings], ebx
test eax, eax
jz .link_fail
 
mov ebx, [coff]
stdcall fix_coff_relocs, ebx, [sym], 0
mov ebx, [coff]
stdcall fix_coff_relocs, ebx, [sym], 0
 
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
test eax, eax
jz .link_fail
stdcall get_coff_sym, [sym], [ebx+CFH.nSymbols], szVersion
test eax, eax
jz .link_fail
 
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
 
cmp eax, DRV_CURRENT
ja .ver_fail
cmp eax, DRV_CURRENT
ja .ver_fail
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
mov [start], eax
mov ebx, [coff]
stdcall get_coff_sym, [sym], [ebx+CFH.nSymbols], szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
stdcall kernel_free, [coff]
 
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
cmp dword [file_name+13], 'SOUN'
jnz @f
cmp dword [file_name+17], 'D.ob'
jnz @f
cmp word [file_name+21], 'j'
jnz @f
mov esi, aSis
jmp .redo
stdcall kernel_free, [img_base]
cmp dword [file_name+13], 'SOUN'
jnz @f
cmp dword [file_name+17], 'D.ob'
jnz @f
cmp word [file_name+21], 'j'
jnz @f
mov esi, aSis
jmp .redo
@@:
xor eax, eax
ret
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
 
.ver_fail:
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
 
.link_fail:
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
.cleanup:
stdcall kernel_free,[img_base]
stdcall kernel_free, [img_base]
.fail:
stdcall kernel_free, [coff]
stdcall kernel_free, [coff]
.exit:
xor eax, eax
ret
xor eax, eax
ret
endp
 
; in: edx -> COFF_SECTION struct
1025,391 → 850,391
; - if alignment is not given, use default = 4K;
; - if alignment is given and is no more than 4K, use it;
; - if alignment is more than 4K, revert to 4K.
push ecx
mov cl, byte [edx+CFS.Characteristics+2]
mov eax, 1
shr cl, 4
dec cl
js .default
cmp cl, 12
jbe @f
push ecx
mov cl, byte [edx+CFS.Characteristics+2]
mov eax, 1
shr cl, 4
dec cl
js .default
cmp cl, 12
jbe @f
.default:
mov cl, 12
mov cl, 12
@@:
shl eax, cl
pop ecx
dec eax
ret
shl eax, cl
pop ecx
dec eax
ret
 
align 4
proc load_library stdcall, file_name:dword
locals
fullname rb 260
fileinfo rb 40
coff dd ?
img_base dd ?
endl
locals
fullname rb 260
fileinfo rb 40
coff dd ?
img_base dd ?
endl
 
cli
cli
 
; resolve file name
mov ebx, [file_name]
lea edi, [fullname+1]
mov byte [edi-1], '/'
stdcall get_full_file_name, edi, 259
test al, al
jz .fail
mov ebx, [file_name]
lea edi, [fullname+1]
mov byte [edi-1], '/'
stdcall get_full_file_name, edi, 259
test al, al
jz .fail
 
; scan for required DLL in list of already loaded for this process,
; ignore timestamp
mov esi, [CURRENT_TASK]
shl esi, 8
lea edi, [fullname]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
test ebx, ebx
jz .not_in_process
mov esi, [ebx+HDLL.fd]
mov esi, [CURRENT_TASK]
shl esi, 8
lea edi, [fullname]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
test ebx, ebx
jz .not_in_process
mov esi, [ebx+HDLL.fd]
.scan_in_process:
cmp esi, ebx
jz .not_in_process
mov eax, [esi+HDLL.parent]
add eax, DLLDESCR.name
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .next_in_process
cmp esi, ebx
jz .not_in_process
mov eax, [esi+HDLL.parent]
add eax, DLLDESCR.name
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .next_in_process
; simple variant: load DLL which is already loaded in this process
; just increment reference counters and return address of exports table
inc [esi+HDLL.refcount]
mov ecx, [esi+HDLL.parent]
inc [ecx+DLLDESCR.refcount]
mov eax, [ecx+DLLDESCR.exports]
sub eax, [ecx+DLLDESCR.defaultbase]
add eax, [esi+HDLL.base]
ret
inc [esi+HDLL.refcount]
mov ecx, [esi+HDLL.parent]
inc [ecx+DLLDESCR.refcount]
mov eax, [ecx+DLLDESCR.exports]
sub eax, [ecx+DLLDESCR.defaultbase]
add eax, [esi+HDLL.base]
ret
.next_in_process:
mov esi, [esi+HDLL.fd]
jmp .scan_in_process
mov esi, [esi+HDLL.fd]
jmp .scan_in_process
.not_in_process:
 
; scan in full list, compare timestamp
lea eax, [fileinfo]
stdcall get_fileinfo, edi, eax
test eax, eax
jnz .fail
mov esi, [dll_list.fd]
lea eax, [fileinfo]
stdcall get_fileinfo, edi, eax
test eax, eax
jnz .fail
mov esi, [dll_list.fd]
.scan_for_dlls:
cmp esi, dll_list
jz .load_new
lea eax, [esi+DLLDESCR.name]
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .continue_scan
cmp esi, dll_list
jz .load_new
lea eax, [esi+DLLDESCR.name]
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .continue_scan
.test_prev_dll:
mov eax, dword [fileinfo+24] ; last modified time
mov edx, dword [fileinfo+28] ; last modified date
cmp dword [esi+DLLDESCR.timestamp], eax
jnz .continue_scan
cmp dword [esi+DLLDESCR.timestamp+4], edx
jz .dll_already_loaded
mov eax, dword [fileinfo+24]; last modified time
mov edx, dword [fileinfo+28]; last modified date
cmp dword [esi+DLLDESCR.timestamp], eax
jnz .continue_scan
cmp dword [esi+DLLDESCR.timestamp+4], edx
jz .dll_already_loaded
.continue_scan:
mov esi, [esi+DLLDESCR.fd]
jmp .scan_for_dlls
mov esi, [esi+DLLDESCR.fd]
jmp .scan_for_dlls
 
; new DLL
.load_new:
; load file
stdcall load_file, edi
test eax, eax
jz .fail
mov [coff], eax
mov dword [fileinfo+32], ebx
stdcall load_file, edi
test eax, eax
jz .fail
mov [coff], eax
mov dword [fileinfo+32], ebx
 
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
mov esi, edi
mov ecx, -1
xor eax, eax
repnz scasb
not ecx
lea eax, [ecx+DLLDESCR.sizeof]
push ecx
call malloc
pop ecx
test eax, eax
jz .fail_and_free_coff
mov esi, edi
mov ecx, -1
xor eax, eax
repnz scasb
not ecx
lea eax, [ecx+DLLDESCR.sizeof]
push ecx
call malloc
pop ecx
test eax, eax
jz .fail_and_free_coff
; save timestamp
lea edi, [eax+DLLDESCR.name]
rep movsb
mov esi, eax
mov eax, dword [fileinfo+24]
mov dword [esi+DLLDESCR.timestamp], eax
mov eax, dword [fileinfo+28]
mov dword [esi+DLLDESCR.timestamp+4], eax
lea edi, [eax+DLLDESCR.name]
rep movsb
mov esi, eax
mov eax, dword [fileinfo+24]
mov dword [esi+DLLDESCR.timestamp], eax
mov eax, dword [fileinfo+28]
mov dword [esi+DLLDESCR.timestamp+4], eax
; initialize DLLDESCR struct
and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
mov [esi+DLLDESCR.fd], dll_list
mov eax, [dll_list.bk]
mov [dll_list.bk], esi
mov [esi+DLLDESCR.bk], eax
mov [eax+DLLDESCR.fd], esi
and dword [esi+DLLDESCR.refcount], 0; no HDLLs yet; later it will be incremented
mov [esi+DLLDESCR.fd], dll_list
mov eax, [dll_list.bk]
mov [dll_list.bk], esi
mov [esi+DLLDESCR.bk], eax
mov [eax+DLLDESCR.fd], esi
 
; calculate size of loaded DLL
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
xor ebx, ebx
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
xor ebx, ebx
 
add edx, 20
add edx, 20
@@:
call coff_get_align
add ebx, eax
not eax
and ebx, eax
add ebx, [edx+CFS.SizeOfRawData]
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
call coff_get_align
add ebx, eax
not eax
and ebx, eax
add ebx, [edx+CFS.SizeOfRawData]
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
; it must be nonzero and not too big
mov [esi+DLLDESCR.size], ebx
test ebx, ebx
jz .fail_and_free_dll
cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
ja .fail_and_free_dll
mov [esi+DLLDESCR.size], ebx
test ebx, ebx
jz .fail_and_free_dll
cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
ja .fail_and_free_dll
; allocate memory for kernel-side image
stdcall kernel_alloc, ebx
test eax, eax
jz .fail_and_free_dll
mov [esi+DLLDESCR.data], eax
stdcall kernel_alloc, ebx
test eax, eax
jz .fail_and_free_dll
mov [esi+DLLDESCR.data], eax
; calculate preferred base address
add ebx, 0x1FFF
and ebx, not 0xFFF
mov ecx, [dll_cur_addr]
lea edx, [ecx+ebx]
cmp edx, MAX_DEFAULT_DLL_ADDR
jb @f
mov ecx, MIN_DEFAULT_DLL_ADDR
lea edx, [ecx+ebx]
add ebx, 0x1FFF
and ebx, not 0xFFF
mov ecx, [dll_cur_addr]
lea edx, [ecx+ebx]
cmp edx, MAX_DEFAULT_DLL_ADDR
jb @f
mov ecx, MIN_DEFAULT_DLL_ADDR
lea edx, [ecx+ebx]
@@:
mov [esi+DLLDESCR.defaultbase], ecx
mov [dll_cur_addr], edx
mov [esi+DLLDESCR.defaultbase], ecx
mov [dll_cur_addr], edx
 
; copy sections and set correct values for VirtualAddress'es in headers
push esi
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, eax
add edx, 20
cld
push esi
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, eax
add edx, 20
cld
@@:
call coff_get_align
add ecx, eax
add edi, eax
not eax
and ecx, eax
and edi, eax
mov [edx+CFS.VirtualAddress], ecx
add ecx, [edx+CFS.SizeOfRawData]
mov esi, [edx+CFS.PtrRawData]
push ecx
mov ecx, [edx+CFS.SizeOfRawData]
test esi, esi
jnz .copy
xor eax, eax
rep stosb
jmp .next
call coff_get_align
add ecx, eax
add edi, eax
not eax
and ecx, eax
and edi, eax
mov [edx+CFS.VirtualAddress], ecx
add ecx, [edx+CFS.SizeOfRawData]
mov esi, [edx+CFS.PtrRawData]
push ecx
mov ecx, [edx+CFS.SizeOfRawData]
test esi, esi
jnz .copy
xor eax, eax
rep stosb
jmp .next
.copy:
add esi, [coff]
rep movsb
add esi, [coff]
rep movsb
.next:
pop ecx
add edx, COFF_SECTION_SIZE
dec ebx
jnz @B
pop esi
pop ecx
add edx, COFF_SECTION_SIZE
dec ebx
jnz @B
pop esi
 
; save some additional data from COFF file
; later we will use COFF header, headers for sections and symbol table
; and also relocations table for all sections
mov edx, [coff]
mov ebx, [edx+CFH.pSymTable]
mov edi, dword [fileinfo+32]
sub edi, ebx
jc .fail_and_free_data
mov [esi+DLLDESCR.symbols_lim], edi
add ebx, edx
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea edi, [edi+ecx*8+20]
add edx, 20
mov edx, [coff]
mov ebx, [edx+CFH.pSymTable]
mov edi, dword [fileinfo+32]
sub edi, ebx
jc .fail_and_free_data
mov [esi+DLLDESCR.symbols_lim], edi
add ebx, edx
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea edi, [edi+ecx*8+20]
add edx, 20
@@:
movzx eax, [edx+CFS.NumReloc]
lea eax, [eax*5]
lea edi, [edi+eax*2]
add edx, COFF_SECTION_SIZE
sub ecx, 5
jnz @b
stdcall kernel_alloc, edi
test eax, eax
jz .fail_and_free_data
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea ecx, [ecx*2+5]
mov [esi+DLLDESCR.coff_hdr], eax
push esi
mov esi, edx
mov edi, eax
rep movsd
pop esi
mov [esi+DLLDESCR.symbols_ptr], edi
push esi
mov ecx, [edx+CFH.nSymbols]
mov [esi+DLLDESCR.symbols_num], ecx
mov ecx, [esi+DLLDESCR.symbols_lim]
mov esi, ebx
rep movsb
pop esi
mov ebx, [esi+DLLDESCR.coff_hdr]
push esi
movzx eax, [edx+CFH.nSections]
lea edx, [ebx+20]
movzx eax, [edx+CFS.NumReloc]
lea eax, [eax*5]
lea edi, [edi+eax*2]
add edx, COFF_SECTION_SIZE
sub ecx, 5
jnz @b
stdcall kernel_alloc, edi
test eax, eax
jz .fail_and_free_data
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea ecx, [ecx*2+5]
mov [esi+DLLDESCR.coff_hdr], eax
push esi
mov esi, edx
mov edi, eax
rep movsd
pop esi
mov [esi+DLLDESCR.symbols_ptr], edi
push esi
mov ecx, [edx+CFH.nSymbols]
mov [esi+DLLDESCR.symbols_num], ecx
mov ecx, [esi+DLLDESCR.symbols_lim]
mov esi, ebx
rep movsb
pop esi
mov ebx, [esi+DLLDESCR.coff_hdr]
push esi
movzx eax, [edx+CFH.nSections]
lea edx, [ebx+20]
@@:
movzx ecx, [edx+CFS.NumReloc]
lea ecx, [ecx*5]
mov esi, [edx+CFS.PtrReloc]
mov [edx+CFS.PtrReloc], edi
sub [edx+CFS.PtrReloc], ebx
add esi, [coff]
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
add edx, COFF_SECTION_SIZE
dec eax
jnz @b
pop esi
movzx ecx, [edx+CFS.NumReloc]
lea ecx, [ecx*5]
mov esi, [edx+CFS.PtrReloc]
mov [edx+CFS.PtrReloc], edi
sub [edx+CFS.PtrReloc], ebx
add esi, [coff]
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
add edx, COFF_SECTION_SIZE
dec eax
jnz @b
pop esi
 
; fixup symbols
mov edx, ebx
mov eax, [ebx+CFH.nSymbols]
add edx, 20
mov ecx, [esi+DLLDESCR.symbols_num]
lea ecx, [ecx*9]
add ecx, ecx
add ecx, [esi+DLLDESCR.symbols_ptr]
mov edx, ebx
mov eax, [ebx+CFH.nSymbols]
add edx, 20
mov ecx, [esi+DLLDESCR.symbols_num]
lea ecx, [ecx*9]
add ecx, ecx
add ecx, [esi+DLLDESCR.symbols_ptr]
 
stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
ecx, 0
; test eax, eax
; jnz @F
stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax, \
ecx, 0
; test eax, eax
; jnz @F
;
;@@:
 
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
test eax, eax
jnz @F
stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+CFH.nSymbols], szEXPORTS
test eax, eax
jnz @F
 
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
stdcall get_coff_sym, [esi+DLLDESCR.symbols_ptr], [ebx+CFH.nSymbols], sz_EXPORTS
@@:
mov [esi+DLLDESCR.exports], eax
mov [esi+DLLDESCR.exports], eax
 
; fix relocs in the hidden copy in kernel memory to default address
; it is first fix; usually this will be enough, but second fix
; can be necessary if real load address will not equal assumption
mov eax, [esi+DLLDESCR.data]
sub eax, [esi+DLLDESCR.defaultbase]
stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
mov eax, [esi+DLLDESCR.data]
sub eax, [esi+DLLDESCR.defaultbase]
stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
 
stdcall kernel_free, [coff]
stdcall kernel_free, [coff]
 
.dll_already_loaded:
inc [esi+DLLDESCR.refcount]
push esi
call init_heap
pop esi
inc [esi+DLLDESCR.refcount]
push esi
call init_heap
pop esi
 
mov edi, [esi+DLLDESCR.size]
stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
test eax, eax
jnz @f
stdcall user_alloc, edi
test eax, eax
jz .fail_and_dereference
mov edi, [esi+DLLDESCR.size]
stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
test eax, eax
jnz @f
stdcall user_alloc, edi
test eax, eax
jz .fail_and_dereference
@@:
mov [img_base], eax
mov eax, HDLL.sizeof
call malloc
test eax, eax
jz .fail_and_free_user
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov edx, [CURRENT_TASK+ebx+TASKDATA.pid]
mov [eax+HDLL.pid], edx
push eax
call init_dlls_in_thread
pop ebx
test eax, eax
jz .fail_and_free_user
mov edx, [eax+HDLL.fd]
mov [ebx+HDLL.fd], edx
mov [ebx+HDLL.bk], eax
mov [eax+HDLL.fd], ebx
mov [edx+HDLL.bk], ebx
mov eax, ebx
mov ebx, [img_base]
mov [eax+HDLL.base], ebx
mov [eax+HDLL.size], edi
mov [eax+HDLL.refcount], 1
mov [eax+HDLL.parent], esi
mov edx, ebx
shr edx, 12
or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
mov [img_base], eax
mov eax, HDLL.sizeof
call malloc
test eax, eax
jz .fail_and_free_user
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov edx, [CURRENT_TASK+ebx+TASKDATA.pid]
mov [eax+HDLL.pid], edx
push eax
call init_dlls_in_thread
pop ebx
test eax, eax
jz .fail_and_free_user
mov edx, [eax+HDLL.fd]
mov [ebx+HDLL.fd], edx
mov [ebx+HDLL.bk], eax
mov [eax+HDLL.fd], ebx
mov [edx+HDLL.bk], ebx
mov eax, ebx
mov ebx, [img_base]
mov [eax+HDLL.base], ebx
mov [eax+HDLL.size], edi
mov [eax+HDLL.refcount], 1
mov [eax+HDLL.parent], esi
mov edx, ebx
shr edx, 12
or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
; copy entries of page table from kernel-side image to usermode
; use copy-on-write for user-mode image, so map as readonly
xor edi, edi
mov ecx, [esi+DLLDESCR.data]
shr ecx, 12
xor edi, edi
mov ecx, [esi+DLLDESCR.data]
shr ecx, 12
.map_pages_loop:
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
or al, PG_USER
xchg eax, [page_tabs+edx*4]
test al, 1
jz @f
call free_page
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
or al, PG_USER
xchg eax, [page_tabs+edx*4]
test al, 1
jz @f
call free_page
@@:
invlpg [ebx+edi]
inc ecx
inc edx
add edi, 0x1000
cmp edi, [esi+DLLDESCR.size]
jb .map_pages_loop
invlpg [ebx+edi]
inc ecx
inc edx
add edi, 0x1000
cmp edi, [esi+DLLDESCR.size]
jb .map_pages_loop
 
; if real user-mode base is not equal to preferred base, relocate image
sub ebx, [esi+DLLDESCR.defaultbase]
jz @f
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
sub ebx, [esi+DLLDESCR.defaultbase]
jz @f
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
@@:
 
mov eax, [esi+DLLDESCR.exports]
sub eax, [esi+DLLDESCR.defaultbase]
add eax, [img_base]
ret
mov eax, [esi+DLLDESCR.exports]
sub eax, [esi+DLLDESCR.defaultbase]
add eax, [img_base]
ret
.fail_and_free_data:
stdcall kernel_free, [esi+DLLDESCR.data]
stdcall kernel_free, [esi+DLLDESCR.data]
.fail_and_free_dll:
mov eax, esi
call free
mov eax, esi
call free
.fail_and_free_coff:
stdcall kernel_free, [coff]
stdcall kernel_free, [coff]
.fail:
xor eax, eax
ret
xor eax, eax
ret
.fail_and_free_user:
stdcall user_free, [img_base]
stdcall user_free, [img_base]
.fail_and_dereference:
mov eax, 1 ; delete 1 reference
call dereference_dll
xor eax, eax
ret
mov eax, 1 ; delete 1 reference
call dereference_dll
xor eax, eax
ret
endp
 
; initialize [APPDATA.dlls_list_ptr] for given thread
1418,155 → 1243,155
; out: eax = APPDATA.dlls_list_ptr if all is OK,
; NULL if memory allocation failed
init_dlls_in_thread:
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.dlls_list_ptr]
test eax, eax
jnz .ret
push [ebx+APPDATA.dir_table]
mov eax, 8
call malloc
pop edx
test eax, eax
jz .ret
mov [eax], eax
mov [eax+4], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.dlls_list_ptr]
test eax, eax
jnz .ret
push [ebx+APPDATA.dir_table]
mov eax, 8
call malloc
pop edx
test eax, eax
jz .ret
mov [eax], eax
mov [eax+4], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256
.set:
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
@@:
add ebx, 256
dec ecx
jnz .set
add ebx, 256
dec ecx
jnz .set
.ret:
ret
ret
 
; in: eax = number of references to delete, esi -> DLLDESCR struc
dereference_dll:
sub [esi+DLLDESCR.refcount], eax
jnz .ret
mov eax, [esi+DLLDESCR.fd]
mov edx, [esi+DLLDESCR.bk]
mov [eax+DLLDESCR.bk], edx
mov [edx+DLLDESCR.fd], eax
stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
stdcall kernel_free, [esi+DLLDESCR.data]
mov eax, esi
call free
sub [esi+DLLDESCR.refcount], eax
jnz .ret
mov eax, [esi+DLLDESCR.fd]
mov edx, [esi+DLLDESCR.bk]
mov [eax+DLLDESCR.bk], edx
mov [edx+DLLDESCR.fd], eax
stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
stdcall kernel_free, [esi+DLLDESCR.data]
mov eax, esi
call free
.ret:
ret
ret
 
destroy_hdll:
push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size]
push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size]
; The following actions require the context of application where HDLL is mapped.
; However, destroy_hdll can be called in the context of OS thread when
; cleaning up objects created by the application which is destroyed.
; So remember current cr3 and set it to page table of target.
mov eax, [ecx+APPDATA.dir_table]
mov eax, [ecx+APPDATA.dir_table]
; Because we cheat with cr3, disable interrupts: task switch would restore
; page table from APPDATA of current thread.
; Also set [current_slot] because it is used by user_free.
pushf
cli
push [current_slot]
mov [current_slot], ecx
mov ecx, cr3
push ecx
mov cr3, eax
push ebx ; argument for user_free
mov eax, ebx
shr ebx, 12
push ebx
mov esi, [esi+DLLDESCR.data]
shr esi, 12
pushf
cli
push [current_slot]
mov [current_slot], ecx
mov ecx, cr3
push ecx
mov cr3, eax
push ebx ; argument for user_free
mov eax, ebx
shr ebx, 12
push ebx
mov esi, [esi+DLLDESCR.data]
shr esi, 12
.unmap_loop:
push eax
mov eax, 2
xchg eax, [page_tabs+ebx*4]
mov ecx, [page_tabs+esi*4]
and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page
push eax
mov eax, 2
xchg eax, [page_tabs+ebx*4]
mov ecx, [page_tabs+esi*4]
and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page
@@:
pop eax
invlpg [eax]
add eax, 0x1000
inc ebx
inc esi
sub edx, 0x1000
ja .unmap_loop
pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
pop eax
invlpg [eax]
add eax, 0x1000
inc ebx
inc esi
sub edx, 0x1000
ja .unmap_loop
pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
; Restore context.
pop eax
mov cr3, eax
pop [current_slot]
popf
pop eax
mov cr3, eax
pop [current_slot]
popf
; Ok, cheating is done.
pop eax
push eax
mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount]
call dereference_dll
pop eax
mov edx, [eax+HDLL.bk]
mov ebx, [eax+HDLL.fd]
mov [ebx+HDLL.bk], edx
mov [edx+HDLL.fd], ebx
call free
pop edi esi ecx ebx
ret
pop eax
push eax
mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount]
call dereference_dll
pop eax
mov edx, [eax+HDLL.bk]
mov ebx, [eax+HDLL.fd]
mov [ebx+HDLL.bk], edx
mov [edx+HDLL.fd], ebx
call free
pop edi esi ecx ebx
ret
 
; ecx -> APPDATA for slot, esi = dlls_list_ptr
destroy_all_hdlls:
test esi, esi
jz .ret
test esi, esi
jz .ret
.loop:
mov eax, [esi+HDLL.fd]
cmp eax, esi
jz free
call destroy_hdll
jmp .loop
mov eax, [esi+HDLL.fd]
cmp eax, esi
jz free
call destroy_hdll
jmp .loop
.ret:
ret
ret
 
align 4
stop_all_services:
push ebp
mov edx, [srv.fd]
push ebp
mov edx, [srv.fd]
.next:
cmp edx, srv.fd-SRV_FD_OFFSET
je .done
cmp [edx+SRV.magic], ' SRV'
jne .next
cmp [edx+SRV.size], SRV.sizeof
jne .next
cmp edx, srv.fd-SRV_FD_OFFSET
je .done
cmp [edx+SRV.magic], ' SRV'
jne .next
cmp [edx+SRV.size], SRV.sizeof
jne .next
 
mov ebx, [edx+SRV.entry]
mov edx, [edx+SRV.fd]
test ebx, ebx
jz .next
mov ebx, [edx+SRV.entry]
mov edx, [edx+SRV.fd]
test ebx, ebx
jz .next
 
push edx
mov ebp, esp
push 0
push -1
call ebx
mov esp, ebp
pop edx
jmp .next
push edx
mov ebp, esp
push 0
push -1
call ebx
mov esp, ebp
pop edx
jmp .next
.done:
pop ebp
ret
pop ebp
ret
 
; param
; eax= size
1575,27 → 1400,27
align 4
create_kernel_object:
 
push ebx
call malloc
pop ebx
test eax, eax
jz .fail
push ebx
call malloc
pop ebx
test eax, eax
jz .fail
 
mov ecx,[current_slot]
add ecx, APP_OBJ_OFFSET
mov ecx, [current_slot]
add ecx, APP_OBJ_OFFSET
 
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [eax+APPOBJ.pid], ebx
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [eax+APPOBJ.pid], ebx
 
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
.fail:
ret
ret
 
; param
; eax= object
1603,87 → 1428,20
align 4
destroy_kernel_object:
 
pushfd
cli
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
popfd
pushfd
cli
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
popfd
 
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
 
call free ;release object memory
ret
 
 
 
if 0
 
irq:
 
.irq0:
pusfd
pushad
push IRQ_0
jmp .master
.irq_1:
pusfd
pushad
push IRQ_1
jmp .master
 
.master:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
cmp [irq_actids+ecx*4], 0
je @F
in al, 0x21
bts eax, ecx
out 0x21, al
mov al, 0x20
out 0x20, al
jmp .restart
 
.slave:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
sub ecx, 8
cmp [irq_actids+ecx*4], 0
je @F
in al, 0xA1
bts eax, ecx
out 0xA1, al
mov al, 0x20
out 0xA0, al
out 0x20, al
.restart:
mov ebx, [next_slot]
test ebx, ebx
jz @F
mov [next_task],0
mov esi, [prev_slot]
call do_change_task
add esp, 4
iretd
 
end if
 
 
 
 
call free ;release object memory
ret
/kernel/branches/net/core/export.inc
28,7 → 28,8
local name
dd (name-OS_BASE)
common
ordinal: count = 0
ordinal:
count = 0
forward
dw count
count = count+1
/kernel/branches/net/core/exports.inc
9,34 → 9,38
 
 
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
szKernel db 'KERNEL', 0
szVersion db 'version',0
 
szRegService db 'RegService',0
szGetService db 'GetService',0
szRegService db 'RegService',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szAttachIntHandler db 'AttachIntHandler',0
szGetIntHandler db 'GetIntHandler', 0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
; szGetIntHandler db 'GetIntHandler', 0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
szReservePortArea db 'ReservePortArea',0
szBoot_Log db 'Boot_Log',0
szBoot_Log db 'Boot_Log',0
 
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead16 db 'PciRead16', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szPciWrite16 db 'PciWrite16',0
szPciWrite32 db 'PciWrite32',0
szMutexInit db 'MutexInit',0
szMutexLock db 'MutexLock',0
szMutexUnlock db 'MutexUnlock',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
szMapIoMem db 'MapIoMem',0
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead16 db 'PciRead16', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szPciWrite16 db 'PciWrite16',0
szPciWrite32 db 'PciWrite32',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
szMapIoMem db 'MapIoMem',0
szCommitPages db 'CommitPages',0
szReleasePages db 'ReleasePages',0
 
43,46 → 47,56
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
szKernelFree db 'KernelFree',0
szUserAlloc db 'UserAlloc',0
szUserFree db 'UserFree',0
szKmalloc db 'Kmalloc',0
szKfree db 'Kfree',0
szCreateRingBuffer db 'CreateRingBuffer',0
 
szGetPid db 'GetPid',0
szGetPid db 'GetPid',0
szCreateObject db 'CreateObject',0
szDestroyObject db 'DestroyObject',0
szCreateEvent db 'CreateEvent',0
szRaiseEvent db 'RaiseEvent',0
szWaitEvent db 'WaitEvent',0
szRaiseEvent db 'RaiseEvent',0
szWaitEvent db 'WaitEvent',0
szDestroyEvent db 'DestroyEvent',0
szClearEvent db 'ClearEvent',0
szClearEvent db 'ClearEvent',0
 
szLoadCursor db 'LoadCursor',0
szLoadCursor db 'LoadCursor',0
 
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szSysMsgBoardChar db 'SysMsgBoardChar', 0
szGetCurrentTask db 'GetCurrentTask',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szSetMouseData db 'SetMouseData',0
szSleep db 'Sleep',0
szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',0
 
szStrncat db 'strncat',0
szStrncpy db 'strncpy',0
szstrncmp db 'strncmp',0
szStrnlen db 'strnlen',0
szStrchr db 'strchr',0
szStrrchr db 'strrchr',0
szGetDisplay db 'GetDisplay',0
szSetScreen db 'SetScreen',0
 
szNetRegDev db 'NetRegDev',0
szStrncat db 'strncat',0
szStrncpy db 'strncpy',0
szstrncmp db 'strncmp',0
szStrnlen db 'strnlen',0
szStrchr db 'strchr',0
szStrrchr db 'strrchr',0
 
szDiskAdd db 'DiskAdd',0
szDiskDel db 'DiskDel',0
szDiskMediaChanged db 'DiskMediaChanged',0
 
szTimerHS db 'TimerHS',0
szCancelTimerHS db 'CancelTimerHS',0
 
szNetRegDev db 'NetRegDev',0
szNetUnRegDev db 'NetUnRegDev',0
szNetPtrToNum db 'NetPtrToNum',0
szEthReceiver db 'EthReceiver',0
szIPv4_input db 'IPv4_input',0
szIPv4_input db 'IPv4_input',0
 
 
align 16
91,13 → 105,17
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szAttachIntHandler, attach_int_handler
dd szGetIntHandler , get_int_handler
dd szFpuSave , fpu_save
; dd szGetIntHandler , get_int_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd szReservePortArea , r_f_port_area
dd szBoot_Log , boot_log
 
dd szPciApi , pci_api
dd szMutexInit , mutex_init ;gcc fastcall
dd szMutexLock , mutex_lock ;gcc fastcall
dd szMutexUnlock , mutex_unlock ;gcc fastcall
 
dd szPciApi , pci_api_drv
dd szPciRead32 , pci_read32
dd szPciRead16 , pci_read16
dd szPciRead8 , pci_read8
105,53 → 123,63
dd szPciWrite16 , pci_write16
dd szPciWrite32 , pci_write32
 
dd szAllocPage , alloc_page ;stdcall
dd szAllocPages , alloc_pages ;stdcall
dd szAllocPage , alloc_page ;stdcall
dd szAllocPages , alloc_pages ;stdcall
dd szFreePage , free_page
dd szMapPage , map_page ;stdcall
dd szMapPage , map_page ;stdcall
dd szMapSpace , map_space
dd szMapIoMem , map_io_mem ;stdcall
dd szMapIoMem , map_io_mem ;stdcall
dd szGetPgAddr , get_pg_addr
dd szCommitPages , commit_pages ;not implemented
dd szCommitPages , commit_pages ;not implemented
dd szReleasePages , release_pages
 
dd szAllocKernelSpace, alloc_kernel_space ;stdcall
dd szFreeKernelSpace , free_kernel_space ;stdcall
dd szKernelAlloc , kernel_alloc ;stdcall
dd szKernelFree , kernel_free ;stdcall
dd szUserAlloc , user_alloc ;stdcall
dd szUserFree , user_free ;stdcall
dd szKmalloc , malloc
dd szKfree , free
dd szKernelAlloc , kernel_alloc ;stdcall
dd szKernelFree , kernel_free ;stdcall
dd szUserAlloc , user_alloc ;stdcall
dd szUserFree , user_free ;stdcall
dd szKmalloc , malloc
dd szKfree , free
dd szCreateRingBuffer, create_ring_buffer ;stdcall
 
dd szGetPid , get_pid
dd szGetPid , get_pid
dd szCreateObject , create_kernel_object
dd szDestroyObject , destroy_kernel_object
dd szCreateEvent , create_event ;see EVENT.inc for specification
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
dd szWaitEvent , wait_event ;see EVENT.inc for specification
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
dd szClearEvent , clear_event ;see EVENT.inc for specification
dd szCreateEvent , create_event ;see EVENT.inc for specification
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
dd szWaitEvent , wait_event ;see EVENT.inc for specification
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
dd szClearEvent , clear_event ;see EVENT.inc for specification
 
dd szLoadCursor , load_cursor ;stdcall
dd szLoadCursor , load_cursor ;stdcall
 
dd szSysMsgBoardStr , sys_msg_board_str
dd szSysMsgBoardChar , sys_msg_board
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSleep , delay_ms
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
 
dd szStrncat , strncat
dd szStrncpy , strncpy
dd szstrncmp , strncmp
dd szStrnlen , strnlen
dd szStrchr , strchr
dd szStrrchr , strrchr
dd szGetDisplay , get_display
dd szSetScreen , set_screen
 
dd szStrncat , strncat
dd szStrncpy , strncpy
dd szstrncmp , strncmp
dd szStrnlen , strnlen
dd szStrchr , strchr
dd szStrrchr , strrchr
 
dd szDiskAdd , disk_add
dd szDiskDel , disk_del
dd szDiskMediaChanged, disk_media_changed
 
dd szTimerHS , timer_hs
dd szCancelTimerHS , cancel_timer_hs
 
dd szNetRegDev , NET_add_device
dd szNetUnRegDev , NET_remove_device
dd szNetPtrToNum , NET_ptr_to_num
160,6 → 188,6
 
exp_lfb:
dd szLFBAddress , 0
dd 0 ;terminator, must be zero
dd 0 ;terminator, must be zero
 
endg
/kernel/branches/net/core/ext_lib.inc
63,255 → 63,268
exports dd ?
endl
 
cli
cli
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [coff], eax
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
mov [coff], eax
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, [img_size]
stdcall kernel_alloc, [img_size]
 
test eax, eax
jz .fail
mov [img_base], eax
test eax, eax
jz .fail
mov [img_base], eax
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx, ecx
lea ecx, [ecx+ecx*8];ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea eax, [edx+20]
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], dword 0
test eax, eax
jnz @F
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols], \
[strings], dword 0
test eax, eax
jnz @F
 
@@:
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, 0
lea eax, [edx+20]
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, 0
lea eax, [edx+20]
@@:
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
add edx, 20
stdcall fix_coff_relocs, [coff], edx, [sym]
add edx, 20
stdcall fix_coff_relocs, [coff], edx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
mov [exports], eax
mov ebx, [coff]
stdcall get_coff_sym, [sym], [ebx+CFH.nSymbols], szEXPORTS
mov [exports], eax
 
stdcall kernel_free, [coff]
stdcall kernel_free, [coff]
 
mov eax, [exports]
ret
mov eax, [exports]
ret
.fail:
xor eax, eax
ret
xor eax, eax
ret
endp
 
 
proc dll.Load, import_table:dword
mov esi,[import_table]
.next_lib: mov edx,[esi]
or edx,edx
jz .exit
push esi
mov esi, [import_table]
.next_lib:
mov edx, [esi]
or edx, edx
jz .exit
push esi
 
mov edi,s_libname
mov edi, s_libname
 
mov al, '/'
stosb
mov esi,sysdir_path
@@: lodsb
stosb
or al,al
jnz @b
dec edi
mov [edi], dword '/lib'
mov [edi+4],byte '/'
add edi,5
pop esi
push esi
mov esi,[esi+4]
@@: lodsb
stosb
or al,al
jnz @b
mov al, '/'
stosb
mov esi, sysdir_path
@@:
lodsb
stosb
or al, al
jnz @b
dec edi
mov [edi], dword '/lib'
mov [edi+4], byte '/'
add edi, 5
pop esi
push esi
mov esi, [esi+4]
@@:
lodsb
stosb
or al, al
jnz @b
 
pushad
stdcall load_k_library,s_libname
mov [esp+28],eax
popad
or eax,eax
jz .fail
stdcall dll.Link,eax,edx
stdcall dll.Init,[eax+4]
pop esi
add esi,8
jmp .next_lib
.exit: xor eax,eax
ret
.fail: add esp,4
xor eax,eax
inc eax
ret
pushad
stdcall load_k_library, s_libname
mov [esp+28], eax
popad
or eax, eax
jz .fail
stdcall dll.Link, eax, edx
stdcall dll.Init, [eax+4]
pop esi
add esi, 8
jmp .next_lib
.exit:
xor eax, eax
ret
.fail:
add esp, 4
xor eax, eax
inc eax
ret
endp
 
proc dll.Link, exp:dword,imp:dword
push eax
mov esi,[imp]
test esi,esi
jz .done
.next: lodsd
test eax,eax
jz .done
stdcall dll.GetProcAddress,[exp],eax
or eax,eax
jz @f
mov [esi-4],eax
jmp .next
@@: mov dword[esp],0
.done: pop eax
ret
push eax
mov esi, [imp]
test esi, esi
jz .done
.next:
lodsd
test eax, eax
jz .done
stdcall dll.GetProcAddress, [exp], eax
or eax, eax
jz @f
mov [esi-4], eax
jmp .next
@@:
mov dword[esp], 0
.done:
pop eax
ret
endp
 
proc dll.Init, dllentry:dword
pushad
mov eax,mem.Alloc
mov ebx,mem.Free
mov ecx,mem.ReAlloc
mov edx,dll.Load
stdcall [dllentry]
popad
ret
pushad
mov eax, mem.Alloc
mov ebx, mem.Free
mov ecx, mem.ReAlloc
mov edx, dll.Load
stdcall [dllentry]
popad
ret
endp
 
proc dll.GetProcAddress, exp:dword,sz_name:dword
mov edx,[exp]
.next: test edx,edx
jz .end
stdcall strncmp,[edx],[sz_name], dword -1
test eax,eax
jz .ok
add edx,8
jmp .next
.ok: mov eax,[edx+4]
.end: ret
mov edx, [exp]
.next:
test edx, edx
jz .end
stdcall strncmp, [edx], [sz_name], dword -1
test eax, eax
jz .ok
add edx, 8
jmp .next
.ok:
mov eax, [edx+4]
.end:
ret
endp
 
;-----------------------------------------------------------------------------
proc mem.Alloc size ;/////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx
; mov eax,[size]
; lea ecx,[eax+4+4095]
; and ecx,not 4095
; stdcall kernel_alloc, ecx
; add ecx,-4
; mov [eax],ecx
; add eax,4
push ebx ecx
; mov eax,[size]
; lea ecx,[eax+4+4095]
; and ecx,not 4095
; stdcall kernel_alloc, ecx
; add ecx,-4
; mov [eax],ecx
; add eax,4
 
stdcall kernel_alloc, [size]
stdcall kernel_alloc, [size]
 
pop ecx ebx
ret
pop ecx ebx
ret
endp
 
;-----------------------------------------------------------------------------
proc mem.ReAlloc mptr,size;///////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx esi edi eax
mov eax,[mptr]
mov ebx,[size]
or eax,eax
jz @f
lea ecx,[ebx+4+4095]
and ecx,not 4095
add ecx,-4
cmp ecx,[eax-4]
je .exit
@@: mov eax,ebx
call mem.Alloc
xchg eax,[esp]
or eax,eax
jz .exit
mov esi,eax
xchg eax,[esp]
mov edi,eax
mov ecx,[esi-4]
cmp ecx,[edi-4]
jbe @f
mov ecx,[edi-4]
@@: add ecx,3
shr ecx,2
cld
rep movsd
xchg eax,[esp]
call mem.Free
push ebx ecx esi edi eax
mov eax, [mptr]
mov ebx, [size]
or eax, eax
jz @f
lea ecx, [ebx+4+4095]
and ecx, not 4095
add ecx, -4
cmp ecx, [eax-4]
je .exit
@@:
mov eax, ebx
call mem.Alloc
xchg eax, [esp]
or eax, eax
jz .exit
mov esi, eax
xchg eax, [esp]
mov edi, eax
mov ecx, [esi-4]
cmp ecx, [edi-4]
jbe @f
mov ecx, [edi-4]
@@:
add ecx, 3
shr ecx, 2
cld
rep movsd
xchg eax, [esp]
call mem.Free
.exit:
pop eax edi esi ecx ebx
ret
pop eax edi esi ecx ebx
ret
endp
 
;-----------------------------------------------------------------------------
proc mem.Free mptr ;//////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
; mov eax,[mptr]
; or eax,eax
; jz @f
; push ebx ecx
; lea ecx,[eax-4]
; stdcall kernel_free, ecx
; pop ecx ebx
; mov eax,[mptr]
; or eax,eax
; jz @f
; push ebx ecx
; lea ecx,[eax-4]
; stdcall kernel_free, ecx
; pop ecx ebx
; @@: ret
stdcall kernel_free, [mptr]
ret
stdcall kernel_free, [mptr]
ret
endp
 
uglobal
/kernel/branches/net/core/fpu.inc
9,41 → 9,41
 
 
init_fpu:
clts
fninit
clts
fninit
 
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
mov ebx, cr4
mov ecx, cr0
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT
mov cr4, ebx
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
and ecx, not (CR0_MP+CR0_EM)
or ecx, CR0_NE
mov cr0, ecx
 
mov dword [esp-4], SSE_INIT
ldmxcsr [esp-4]
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
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
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
50,119 → 50,119
 
align 4
fpu_save:
push ecx
push esi
push edi
push ecx
push esi
push edi
 
pushfd
cli
pushfd
cli
 
clts
mov edi, eax
clts
mov edi, eax
 
mov ecx, [fpu_owner]
mov esi, [CURRENT_TASK]
cmp ecx, esi
jne .save
mov ecx, [fpu_owner]
mov esi, [CURRENT_TASK]
cmp ecx, esi
jne .save
 
call save_context
jmp .exit
call save_context
jmp .exit
.save:
mov [fpu_owner], esi
mov [fpu_owner], esi
 
shl ecx, 8
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state]
shl ecx, 8
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state]
 
call save_context
call save_context
 
shl esi, 8
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
fninit
shl esi, 8
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
fninit
.exit:
popfd
pop edi
pop esi
pop ecx
ret
popfd
pop edi
pop esi
pop ecx
ret
 
align 4
save_context:
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
fxsave [eax]
ret
fxsave [eax]
ret
.no_SSE:
fnsave [eax]
ret
fnsave [eax]
ret
 
align 4
fpu_restore:
push ecx
push esi
push ecx
push esi
 
mov esi, eax
mov esi, eax
 
pushfd
cli
pushfd
cli
 
mov ecx, [fpu_owner]
mov eax, [CURRENT_TASK]
cmp ecx, eax
jne .copy
mov ecx, [fpu_owner]
mov eax, [CURRENT_TASK]
cmp ecx, eax
jne .copy
 
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
fxrstor [esi]
popfd
pop esi
pop ecx
ret
fxrstor [esi]
popfd
pop esi
pop ecx
ret
.no_SSE:
fnclex ;fix possible problems
frstor [esi]
popfd
pop esi
pop ecx
ret
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
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
except_7: ;#NM exception handler
save_ring3_context
clts
mov ax, app_data ;
mov ds, ax
mov es, ax
mov ax, app_data;
mov ds, ax
mov es, ax
 
mov ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
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
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]
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
169,12 → 169,12
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]
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
 
/kernel/branches/net/core/heap.inc
9,17 → 9,17
 
 
struc MEM_BLOCK
{ .next_block dd ?
{
.list LHEAD
.next_block dd ? ;+8
.prev_block dd ? ;+4
.list_fd dd ? ;+8
.list_bk dd ? ;+12
.base dd ? ;+16
.size dd ? ;+20
.flags dd ? ;+24
.handle dd ? ;+28
.sizeof:
}
 
MEM_LIST_OFFSET equ 8
FREE_BLOCK equ 4
USED_BLOCK equ 8
DONT_FREE_BLOCK equ 10h
28,12 → 28,11
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
list_fd equ MEM_BLOCK.list.next
list_bk equ MEM_BLOCK.list.prev
block_base equ MEM_BLOCK.base
block_size equ MEM_BLOCK.size
block_flags equ MEM_BLOCK.flags
40,121 → 39,167
 
macro calc_index op
{ shr op, 12
dec op
cmp op, 63
jna @f
mov op, 63
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
}
align 4
md:
.add_to_used:
mov eax, [esi+block_base]
mov ebx, [esi+block_base]
shr ebx, 6
add eax, ebx
shr ebx, 6
add eax, ebx
shr eax, 12
and eax, 63
inc [mem_hash_cnt+eax*4]
 
macro remove_from_free op
{
remove_from_list op
lea ecx, [mem_used_list+eax*8]
list_add esi, ecx
mov [esi+block_flags], USED_BLOCK
mov eax, [esi+block_size]
sub [heap_free], eax
ret
align 4
.find_used:
mov ecx, eax
mov ebx, eax
shr ebx, 6
add ecx, ebx
shr ebx, 6
add ecx, ebx
shr ecx, 12
and ecx, 63
 
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
@@:
}
lea ebx, [mem_used_list+ecx*8]
mov esi, ebx
.next:
mov esi, [esi+list_fd]
cmp esi, ebx
je .fail
 
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
}
cmp eax, [esi+block_base]
jne .next
 
ret
.fail:
xor esi, esi
ret
 
align 4
proc init_kernel_heap
.del_from_used:
call .find_used
test esi, esi
jz .done
 
mov ecx, 64
mov edi, mem_block_list
xor eax, eax
cld
rep stosd
cmp [esi+block_flags], USED_BLOCK
jne .fatal
 
mov ecx, 512/4
mov edi, mem_block_map
not eax
rep stosd
dec [mem_hash_cnt+ecx*4]
list_del esi
.done:
ret
.fatal: ;FIXME panic here
xor esi, esi
ret
 
mov [mem_block_start], mem_block_map
mov [mem_block_end], mem_block_map+512
mov [mem_block_arr], HEAP_BASE
;Initial heap state
;
;+heap_size terminator USED_BLOCK
;+4096*MEM_BLOCK.sizeof free space FREE_BLOCK
;HEAP_BASE heap_descriptors USED_BLOCK
;
 
mov eax, mem_used.fd-MEM_LIST_OFFSET
mov [mem_used.fd], eax
mov [mem_used.bk], eax
align 4
proc init_kernel_heap
 
stdcall alloc_pages, dword 32
mov ecx, 32
mov edx, eax
mov edi, HEAP_BASE
mov ecx, 64
mov edi, mem_block_list
@@:
mov eax, edi
stosd
stosd
loop @B
 
mov ecx, 64
mov edi, mem_used_list
@@:
mov eax, edi
stosd
stosd
loop @B
 
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
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 edi, HEAP_BASE ;descriptors
mov ebx, HEAP_BASE+MEM_BLOCK.sizeof ;free space
mov ecx, HEAP_BASE+MEM_BLOCK.sizeof*2 ;terminator
 
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
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.sizeof
mov [edi+block_flags], USED_BLOCK
 
mov ecx, [pg_data.kernel_pages]
shl ecx, 12
sub ecx, HEAP_BASE-OS_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 [ecx+block_next], eax
mov [ecx+block_prev], ebx
mov [edi+list_fd], eax
mov [edi+list_bk], eax
mov [edi+block_base], eax
mov [edi+block_size], eax
mov [edi+block_flags], USED_BLOCK
 
mov [mem_block_mask], eax
mov [mem_block_mask+4],0x80000000
mov [ebx+block_next], ecx
mov [ebx+block_prev], edi
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK.sizeof
 
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
and [heap_mutex], 0
mov [heap_blocks], 4095
mov [free_blocks], 4094
ret
mov ecx, [pg_data.kernel_pages]
shl ecx, 12
sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK.sizeof
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 ecx, mem_block_list+63*8
list_add ebx, ecx
 
mov ecx, 4096-3-1
mov eax, HEAP_BASE+MEM_BLOCK.sizeof*4
 
mov [next_memblock], HEAP_BASE+MEM_BLOCK.sizeof*3
@@:
mov [eax-MEM_BLOCK.sizeof], eax
add eax, MEM_BLOCK.sizeof
loop @B
 
mov [eax-MEM_BLOCK.sizeof], dword 0
 
mov ecx, heap_mutex
call mutex_init
mov [heap_blocks], 4094
mov [free_blocks], 4093
ret
endp
 
; param
166,367 → 211,263
 
align 4
get_small_block:
mov ecx, eax
shr ecx, 12
dec ecx
cmp ecx, 63
jle .get_index
mov ecx, 63
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
lea esi, [mem_block_mask]
xor ebx, ebx
or edx, -1
 
cmp ecx, 32
jb .bit_test
cmp ecx, 32
jb .bit_test
 
sub ecx, 32
add ebx, 32
add esi, 4
sub ecx, 32
add ebx, 32
add esi, 4
.bit_test:
shl edx, cl
and edx, [esi]
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
bsf edi, edx
jz .high_mask
add ebx, edi
lea ecx, [mem_block_list+ebx*8]
mov edi, ecx
.next:
mov edi, [edi+list_fd]
test edi, edi
jnz .check_size
mov edi, [edi+list_fd]
cmp edi, ecx
je .err
cmp eax, [edi+block_size]
ja .next
ret
.err:
xor edi, edi
ret
xor edi, edi
ret
 
align 4
alloc_mem_block:
.high_mask:
add esi, 4
cmp esi, mem_block_mask+8
jae .err
add ebx, 32
mov edx, [esi]
jmp .find
 
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
align 4
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
mov ebx, [next_memblock]
mov [eax], ebx
mov [next_memblock], eax
xor ebx, ebx
 
sub eax, [mem_block_arr]
shr eax, 5
mov dword [eax+4], ebx
mov dword [eax+8], ebx
mov dword [eax+12], ebx
mov dword [eax+16], ebx
; mov dword [eax+20], 0 ;don't clear block size
mov dword [eax+24], ebx
mov dword [eax+28], ebx
inc [free_blocks]
ret
 
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
 
align 4
proc alloc_kernel_space stdcall, size:dword
local block_ind:DWORD
 
push ebx
push esi
push edi
push ebx
push esi
push edi
 
mov eax, [size]
add eax, 4095
and eax, not 4095
mov [size], eax
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
 
cmp eax, [heap_free]
ja .error
mov ecx, heap_mutex
call mutex_lock
 
call get_small_block ; eax
test edi, edi
jz .error
mov eax, [size]
 
cmp [edi+block_flags], FREE_BLOCK
jne .error
call get_small_block ; eax
test edi, edi
jz .error_unlock
 
mov [block_ind], ebx ;index of allocated block
cmp [edi+block_flags], FREE_BLOCK
jne .error_unlock
 
mov eax, [edi+block_size]
cmp eax, [size]
je .m_eq_size
mov [block_ind], ebx ;index of allocated block
 
call alloc_mem_block
and eax, eax
jz .error
mov eax, [edi+block_size]
cmp eax, [size]
je .m_eq_size
 
mov esi, eax ;esi - splitted block
mov esi, [next_memblock] ;new memory block
test esi, esi
jz .error_unlock
 
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
dec [free_blocks]
mov eax, [esi]
mov [next_memblock], eax
 
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
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
mov [eax+block_next], esi
 
remove_from_list edi
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 ecx, [block_ind]
mov [mem_block_list+ecx*4], edx
mov eax, [edi+block_size]
calc_index eax
cmp eax, [block_ind]
je .add_used
 
test edx, edx
jnz @f
btr [mem_block_mask], ecx
list_del edi
 
mov ecx, [block_ind]
lea edx, [mem_block_list+ecx*8]
cmp 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
bts [mem_block_mask], eax
lea edx, [mem_block_list+eax*8] ;edx= list head
list_add edi, edx
.add_used:
 
mov [esi+block_flags], USED_BLOCK
mov eax, [esi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
pop edi
pop esi
pop ebx
ret
call md.add_to_used
 
mov ecx, heap_mutex
call mutex_unlock
mov eax, [esi+block_base]
pop edi
pop esi
pop ebx
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
list_del edi
lea edx, [mem_block_list+ebx*8]
cmp 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 esi, edi
jmp .add_used
 
mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
pop edi
pop esi
pop ebx
ret
.error_unlock:
mov ecx, heap_mutex
call mutex_unlock
.error:
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
ret
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
push ebx
push esi
push edi
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
mov ecx, heap_mutex
call mutex_lock
 
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, [base]
 
mov eax, [esi+block_size]
add [heap_free], eax
call md.del_from_used
test esi, esi
jz .fail
 
mov edi, [esi+block_next]
test edi, edi
jz .prev
mov eax, [esi+block_size]
add [heap_free], eax
 
cmp [edi+block_flags], FREE_BLOCK
jne .prev
mov edi, [esi+block_next]
cmp [edi+block_flags], FREE_BLOCK
jne .prev
 
remove_from_free edi
list_del edi
 
mov edx, [edi+block_next]
mov [esi+block_next], edx
test edx, edx
jz @f
mov edx, [edi+block_next]
mov [esi+block_next], edx
mov [edx+block_prev], esi
mov ecx, [edi+block_size]
add [esi+block_size], ecx
 
mov [edx+block_prev], esi
calc_index ecx
 
lea edx, [mem_block_list+ecx*8]
cmp edx, [edx]
jne @F
btr [mem_block_mask], ecx
@@:
mov ecx, [edi+block_size]
add [esi+block_size], ecx
 
mov eax, edi
call free_mem_block
mov eax, edi
call free_mem_block
.prev:
mov edi, [esi+block_prev]
test edi, edi
jz .insert
mov edi, [esi+block_prev]
cmp [edi+block_flags], FREE_BLOCK
jne .insert
 
cmp [edi+block_flags], FREE_BLOCK
jne .insert
mov edx, [esi+block_next]
mov [edi+block_next], edx
mov [edx+block_prev], edi
 
remove_from_used esi
mov eax, esi
call free_mem_block
 
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
 
mov ecx, [edi+block_size]
mov eax, [esi+block_size]
add eax, ecx
mov [edi+block_size], eax
calc_index eax ;new index
calc_index ecx ;old index
cmp eax, ecx
je .m_eq
 
calc_index eax
calc_index ecx
cmp eax, ecx
je .m_eq
push ecx
list_del edi
pop ecx
 
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
lea edx, [mem_block_list+ecx*8]
cmp edx, [edx]
jne .add_block
btr [mem_block_mask], ecx
.add_block:
bts [mem_block_mask], eax
lea edx, [mem_block_list+eax*8]
list_add edi, edx
.m_eq:
xor eax, eax
mov [heap_mutex], eax
dec eax
pop edi
pop esi
pop ebx
ret
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
not eax
ret
.insert:
remove_from_used esi
 
mov eax, [esi+block_size]
mov [esi+block_flags], FREE_BLOCK
mov eax, [esi+block_size]
calc_index eax
mov edi, esi
jmp .add_block
 
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
pop edi
pop esi
pop ebx
ret
.fail:
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
ret
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
ret
endp
 
align 4
536,108 → 477,102
pages_count dd ?
endl
 
push ebx
push edi
push ebx
push edi
 
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
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
stdcall alloc_kernel_space, eax
test eax, eax
jz .err
mov [lin_addr], eax
 
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
 
shr ecx, 3
jz .next
shr ecx, 3
jz .next
 
and ebx, not 7
push ebx
stdcall alloc_pages, ebx
pop ecx ; yes ecx!!!
and eax, eax
jz .err
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]
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
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
mov ecx, [pages_count]
and ecx, 7
jz .end
@@:
push ecx
call alloc_page
pop ecx
test eax, eax
jz .err
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
stdcall map_page, edx, eax, dword PG_SW
add edx, 0x1000
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
pop edi
pop ebx
ret
mov eax, [lin_addr]
pop edi
pop ebx
ret
.err:
xor eax, eax
pop edi
pop ebx
ret
xor eax, eax
pop edi
pop ebx
ret
endp
 
align 4
proc kernel_free stdcall, base:dword
push ebx esi
 
mov ebx, heap_mutex
call wait_mutex ;ebx
push ebx esi
 
mov eax, [base]
mov esi, [mem_used.fd]
@@:
cmp esi, mem_used.fd-MEM_LIST_OFFSET
je .fail
mov ecx, heap_mutex
call mutex_lock
 
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, [base]
call md.find_used
 
and [heap_mutex], 0
mov ecx, heap_mutex
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
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
call mutex_unlock
 
mov eax, [esi+block_base]
mov ecx, [esi+block_size]
shr ecx, 12
call release_pages ;eax, ecx
stdcall free_kernel_space, [base]
pop esi ebx
ret
.fail:
and [heap_mutex], 0
pop esi ebx
ret
call mutex_unlock
xor eax, eax
pop esi ebx
ret
endp
 
restore block_next
654,151 → 589,151
align 4
proc init_heap
 
mov ebx,[current_slot]
mov eax, [ebx+APPDATA.heap_top]
test eax, eax
jz @F
sub eax,[ebx+APPDATA.heap_base]
sub eax, 4096
ret
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.heap_top]
test eax, eax
jz @F
sub eax, [ebx+APPDATA.heap_base]
sub eax, 4096
ret
@@:
mov esi, [ebx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov [ebx+APPDATA.mem_size], esi
mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
mov esi, [ebx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov [ebx+APPDATA.mem_size], esi
mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
 
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
endp
 
align 4
proc user_alloc stdcall, alloc_size:dword
 
push ebx
push esi
push edi
push ebx
push esi
push edi
 
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
 
mov ebx, [current_slot]
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
mov ebx, [current_slot]
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
l_0:
cmp esi, edi
jae m_exit
cmp esi, edi
jae m_exit
 
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
jz @f
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
jz @f
 
lea edx, [esi+ecx]
sub eax, ecx
or al, FREE_BLOCK
shr edx, 12
mov [page_tabs+edx*4], eax
lea edx, [esi+ecx]
sub eax, ecx
or al, FREE_BLOCK
shr edx, 12
mov [page_tabs+edx*4], eax
@@:
or ecx, USED_BLOCK
mov [page_tabs+ebx*4], ecx
shr ecx, 12
inc ebx
dec ecx
jz .no
or ecx, USED_BLOCK
mov [page_tabs+ebx*4], ecx
shr ecx, 12
inc ebx
dec ecx
jz .no
@@:
mov dword [page_tabs+ebx*4], 2
inc ebx
dec ecx
jnz @B
mov dword [page_tabs+ebx*4], 2
inc ebx
dec ecx
jnz @B
.no:
 
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
lea eax, [esi+4096]
lea eax, [esi+4096]
 
pop edi
pop esi
pop ebx
ret
pop edi
pop esi
pop ebx
ret
test_used:
test al, USED_BLOCK
jz m_exit
test al, USED_BLOCK
jz m_exit
 
and eax, 0xFFFFF000
and eax, 0xFFFFF000
m_next:
add esi, eax
jmp l_0
add esi, eax
jmp l_0
m_exit:
xor eax, eax
pop edi
pop esi
pop ebx
ret
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc user_alloc_at stdcall, address:dword, alloc_size:dword
 
push ebx
push esi
push edi
push ebx
push esi
push edi
 
mov ebx, [current_slot]
mov edx, [address]
and edx, not 0xFFF
mov [address], edx
sub edx, 0x1000
jb .error
mov esi, [ebx+APPDATA.heap_base]
mov edi, [ebx+APPDATA.heap_top]
cmp edx, esi
jb .error
mov ebx, [current_slot]
mov edx, [address]
and edx, not 0xFFF
mov [address], edx
sub edx, 0x1000
jb .error
mov esi, [ebx+APPDATA.heap_base]
mov edi, [ebx+APPDATA.heap_top]
cmp edx, esi
jb .error
.scan:
cmp esi, edi
jae .error
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
mov ecx, eax
and ecx, 0xFFFFF000
add ecx, esi
cmp edx, ecx
jb .found
mov esi, ecx
jmp .scan
cmp esi, edi
jae .error
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
mov ecx, eax
and ecx, 0xFFFFF000
add ecx, esi
cmp edx, ecx
jb .found
mov esi, ecx
jmp .scan
.error:
xor eax, eax
pop edi
pop esi
pop ebx
ret
xor eax, eax
pop edi
pop esi
pop ebx
ret
.found:
test al, FREE_BLOCK
jz .error
mov eax, ecx
sub eax, edx
sub eax, 0x1000
cmp eax, [alloc_size]
jb .error
test al, FREE_BLOCK
jz .error
mov eax, ecx
sub eax, edx
sub eax, 0x1000
cmp eax, [alloc_size]
jb .error
 
; Here we have 1 big free block which includes requested area.
; In general, 3 other blocks must be created instead:
806,117 → 741,117
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
; First or third block (or both) may be absent.
mov eax, edx
sub eax, esi
jz .nofirst
or al, FREE_BLOCK
mov [page_tabs+ebx*4], eax
mov eax, edx
sub eax, esi
jz .nofirst
or al, FREE_BLOCK
mov [page_tabs+ebx*4], eax
.nofirst:
mov eax, [alloc_size]
add eax, 0x1FFF
and eax, not 0xFFF
mov ebx, edx
add edx, eax
shr ebx, 12
or al, USED_BLOCK
mov [page_tabs+ebx*4], eax
shr eax, 12
dec eax
jz .second_nofill
inc ebx
mov eax, [alloc_size]
add eax, 0x1FFF
and eax, not 0xFFF
mov ebx, edx
add edx, eax
shr ebx, 12
or al, USED_BLOCK
mov [page_tabs+ebx*4], eax
shr eax, 12
dec eax
jz .second_nofill
inc ebx
.fill:
mov dword [page_tabs+ebx*4], 2
inc ebx
dec eax
jnz .fill
mov dword [page_tabs+ebx*4], 2
inc ebx
dec eax
jnz .fill
.second_nofill:
sub ecx, edx
jz .nothird
or cl, FREE_BLOCK
mov [page_tabs+ebx*4], ecx
sub ecx, edx
jz .nothird
or cl, FREE_BLOCK
mov [page_tabs+ebx*4], ecx
.nothird:
 
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
mov eax, [address]
mov eax, [address]
 
pop edi
pop esi
pop ebx
ret
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc user_free stdcall, base:dword
 
push esi
push esi
 
mov esi, [base]
test esi, esi
jz .exit
mov esi, [base]
test esi, esi
jz .exit
 
push ebx
push ebx
 
xor ebx, ebx
shr esi, 12
mov eax, [page_tabs+(esi-1)*4]
test al, USED_BLOCK
jz .cantfree
test al, DONT_FREE_BLOCK
jnz .cantfree
xor ebx, ebx
shr esi, 12
mov eax, [page_tabs+(esi-1)*4]
test al, USED_BLOCK
jz .cantfree
test al, DONT_FREE_BLOCK
jnz .cantfree
 
and eax, not 4095
mov ecx, eax
or al, FREE_BLOCK
mov [page_tabs+(esi-1)*4], eax
sub ecx, 4096
mov ebx, ecx
shr ecx, 12
jz .released
and eax, not 4095
mov ecx, eax
or al, FREE_BLOCK
mov [page_tabs+(esi-1)*4], eax
sub ecx, 4096
mov ebx, ecx
shr ecx, 12
jz .released
.release:
xor eax, eax
xchg eax, [page_tabs+esi*4]
test al, 1
jz @F
test eax, PG_SHARED
jnz @F
call free_page
mov eax, esi
shl eax, 12
invlpg [eax]
xor eax, eax
xchg eax, [page_tabs+esi*4]
test al, 1
jz @F
test eax, PG_SHARED
jnz @F
call free_page
mov eax, esi
shl eax, 12
invlpg [eax]
@@:
inc esi
dec ecx
jnz .release
inc esi
dec ecx
jnz .release
.released:
push edi
push edi
 
mov edx, [current_slot]
mov esi, dword [edx+APPDATA.heap_base]
mov edi, dword [edx+APPDATA.heap_top]
sub ebx, [edx+APPDATA.mem_size]
neg ebx
call update_mem_size
call user_normalize
pop edi
pop ebx
pop esi
ret
mov edx, [current_slot]
mov esi, dword [edx+APPDATA.heap_base]
mov edi, dword [edx+APPDATA.heap_top]
sub ebx, [edx+APPDATA.mem_size]
neg ebx
call update_mem_size
call user_normalize
pop edi
pop ebx
pop esi
ret
.exit:
xor eax, eax
inc eax
pop esi
ret
xor eax, eax
inc eax
pop esi
ret
.cantfree:
xor eax, eax
pop ebx
pop esi
ret
xor eax, eax
pop ebx
pop esi
ret
endp
 
user_normalize:
923,48 → 858,48
; in: esi=heap_base, edi=heap_top
; out: eax=0 <=> OK
; destroys: ebx,edx,esi,edi
shr esi, 12
shr edi, 12
shr esi, 12
shr edi, 12
@@:
mov eax, [page_tabs+esi*4]
test al, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
mov eax, [page_tabs+esi*4]
test al, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
.test_free:
test al, FREE_BLOCK
jz .err
mov edx, eax
shr edx, 12
add edx, esi
cmp edx, edi
jae .exit
test al, 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 bl, USED_BLOCK
jz .next_free
mov ebx, [page_tabs+edx*4]
test bl, USED_BLOCK
jz .next_free
 
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
.next_free:
test bl, 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
test bl, 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
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
xor eax, eax
ret
 
user_realloc:
; in: eax = pointer, ebx = new size
1108,7 → 1043,7
sub ebx, edx
mov ecx, ebx
cld
rep stosd
rep stosd
pop edi
mov edx, [current_slot]
shl ebx, 12
1199,36 → 1134,36
if 0
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
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
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
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
btr [srv_map], eax
popf
shl eax, 0x02
lea eax, [srv_tab+eax+eax*8] ;srv_tab+eax*36
ret
endp
 
end if
1243,38 → 1178,38
align 4
destroy_smap:
 
pushfd
cli
pushfd
cli
 
push esi
push edi
push esi
push edi
 
mov edi, eax
mov esi, [eax+SMAP.parent]
test esi, esi
jz .done
mov edi, eax
mov esi, [eax+SMAP.parent]
test esi, esi
jz .done
 
lock dec [esi+SMEM.refcount]
jnz .done
lock dec [esi+SMEM.refcount]
jnz .done
 
mov ecx, [esi+SMEM.bk]
mov edx, [esi+SMEM.fd]
mov ecx, [esi+SMEM.bk]
mov edx, [esi+SMEM.fd]
 
mov [ecx+SMEM.fd], edx
mov [edx+SMEM.bk], ecx
mov [ecx+SMEM.fd], edx
mov [edx+SMEM.bk], ecx
 
stdcall kernel_free, [esi+SMEM.base]
mov eax, esi
call free
stdcall kernel_free, [esi+SMEM.base]
mov eax, esi
call free
.done:
mov eax, edi
call destroy_kernel_object
mov eax, edi
call destroy_kernel_object
 
pop edi
pop esi
popfd
pop edi
pop esi
popfd
 
ret
ret
 
E_NOTFOUND equ 5
E_ACCESS equ 10
1300,239 → 1235,240
mapped dd ?
endl
 
push ebx
push esi
push edi
push ebx
push esi
push edi
 
mov [mapped], 0
mov [owner_access], 0
mov [mapped], 0
mov [owner_access], 0
 
pushfd ;mutex required
cli
pushfd ;mutex required
cli
 
mov eax, [access]
and eax, SHM_OPEN_MASK
mov [action], eax
mov eax, [access]
and eax, SHM_OPEN_MASK
mov [action], eax
 
mov ebx, [name]
test ebx, ebx
mov edx, E_PARAM
jz .fail
mov ebx, [name]
test ebx, ebx
mov edx, E_PARAM
jz .fail
 
mov esi, [shmem_list.fd]
mov esi, [shmem_list.fd]
align 4
@@:
cmp esi, shmem_list
je .not_found
cmp esi, shmem_list
je .not_found
 
lea edx, [esi+SMEM.name] ; link , base, size
stdcall strncmp, edx, ebx, 32
test eax, eax
je .found
lea edx, [esi+SMEM.name]; link , base, size
stdcall strncmp, edx, ebx, 32
test eax, eax
je .found
 
mov esi, [esi+SMEM.fd]
jmp @B
mov esi, [esi+SMEM.fd]
jmp @B
 
.not_found:
mov eax, [action]
mov eax, [action]
 
cmp eax, SHM_OPEN
mov edx, E_NOTFOUND
je .fail
cmp eax, SHM_OPEN
mov edx, E_NOTFOUND
je .fail
 
cmp eax, SHM_CREATE
mov edx, E_PARAM
je .create_shm
cmp eax, SHM_CREATE
mov edx, E_PARAM
je .create_shm
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
cmp eax, SHM_OPEN_ALWAYS
jne .fail
 
.create_shm:
 
mov ecx, [size]
test ecx, ecx
jz .fail
mov ecx, [size]
test ecx, ecx
jz .fail
 
add ecx, 4095
and ecx, -4096
mov [size], ecx
add ecx, 4095
and ecx, -4096
mov [size], ecx
 
mov eax, SMEM.sizeof
call malloc
test eax, eax
mov esi, eax
mov edx, E_NOMEM
jz .fail
mov eax, SMEM.sizeof
call malloc
test eax, eax
mov esi, eax
mov edx, E_NOMEM
jz .fail
 
stdcall kernel_alloc, [size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup
stdcall kernel_alloc, [size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup
 
mov ecx, [size]
mov edx, [access]
and edx, SHM_ACCESS_MASK
mov ecx, [size]
mov edx, [access]
and edx, SHM_ACCESS_MASK
 
mov [esi+SMEM.base], eax
mov [esi+SMEM.size], ecx
mov [esi+SMEM.access], edx
mov [esi+SMEM.refcount], 0
mov [esi+SMEM.name+28], 0
mov [esi+SMEM.base], eax
mov [esi+SMEM.size], ecx
mov [esi+SMEM.access], edx
mov [esi+SMEM.refcount], 0
mov [esi+SMEM.name+28], 0
 
lea eax, [esi+SMEM.name]
stdcall strncpy, eax, [name], 31
lea eax, [esi+SMEM.name]
stdcall strncpy, eax, [name], 31
 
mov eax, [shmem_list.fd]
mov [esi+SMEM.bk], shmem_list
mov [esi+SMEM.fd], eax
mov eax, [shmem_list.fd]
mov [esi+SMEM.bk], shmem_list
mov [esi+SMEM.fd], eax
 
mov [eax+SMEM.bk], esi
mov [shmem_list.fd], esi
mov [eax+SMEM.bk], esi
mov [shmem_list.fd], esi
 
mov [action], SHM_OPEN
mov [owner_access], SHM_WRITE
mov [action], SHM_OPEN
mov [owner_access], SHM_WRITE
 
.found:
mov eax, [action]
mov eax, [action]
 
cmp eax, SHM_CREATE
mov edx, E_ACCESS
je .exit
cmp eax, SHM_CREATE
mov edx, E_ACCESS
je .exit
 
cmp eax, SHM_OPEN
mov edx, E_PARAM
je .create_map
cmp eax, SHM_OPEN
mov edx, E_PARAM
je .create_map
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
cmp eax, SHM_OPEN_ALWAYS
jne .fail
 
.create_map:
 
mov eax, [access]
and eax, SHM_ACCESS_MASK
cmp eax, [esi+SMEM.access]
mov [access], eax
mov edx, E_ACCESS
ja .fail
mov eax, [access]
and eax, SHM_ACCESS_MASK
cmp eax, [esi+SMEM.access]
mov [access], eax
mov edx, E_ACCESS
ja .fail
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov eax, SMAP.sizeof
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov eax, SMAP.sizeof
 
call create_kernel_object
test eax, eax
mov edi, eax
mov edx, E_NOMEM
jz .fail
call create_kernel_object
test eax, eax
mov edi, eax
mov edx, E_NOMEM
jz .fail
 
inc [esi+SMEM.refcount]
inc [esi+SMEM.refcount]
 
mov [edi+SMAP.magic], 'SMAP'
mov [edi+SMAP.destroy], destroy_smap
mov [edi+SMAP.parent], esi
mov [edi+SMAP.base], 0
mov [edi+SMAP.magic], 'SMAP'
mov [edi+SMAP.destroy], destroy_smap
mov [edi+SMAP.parent], esi
mov [edi+SMAP.base], 0
 
stdcall user_alloc, [esi+SMEM.size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup2
stdcall user_alloc, [esi+SMEM.size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup2
 
mov [edi+SMAP.base], eax
mov [edi+SMAP.base], eax
 
mov ecx, [esi+SMEM.size]
mov [size], ecx
mov ecx, [esi+SMEM.size]
mov [size], ecx
 
shr ecx, 12
shr eax, 10
shr ecx, 12
shr eax, 10
 
mov esi, [esi+SMEM.base]
shr esi, 10
lea edi, [page_tabs+eax]
add esi, page_tabs
mov esi, [esi+SMEM.base]
shr esi, 10
lea edi, [page_tabs+eax]
add esi, page_tabs
 
mov edx, [access]
or edx, [owner_access]
shl edx, 1
or edx, PG_USER+PG_SHARED
mov edx, [access]
or edx, [owner_access]
shl edx, 1
or edx, PG_USER+PG_SHARED
@@:
lodsd
and eax, 0xFFFFF000
or eax, edx
stosd
loop @B
lodsd
and eax, 0xFFFFF000
or eax, edx
stosd
loop @B
 
xor edx, edx
xor edx, edx
 
cmp [owner_access], 0
jne .fail
cmp [owner_access], 0
jne .fail
.exit:
mov edx, [size]
mov edx, [size]
.fail:
mov eax, [mapped]
mov eax, [mapped]
 
popfd
pop edi
pop esi
pop ebx
ret
popfd
pop edi
pop esi
pop ebx
ret
.cleanup:
mov [size], edx
mov eax, esi
call free
jmp .exit
mov [size], edx
mov eax, esi
call free
jmp .exit
 
.cleanup2:
mov [size], edx
mov eax, edi
call destroy_smap
jmp .exit
mov [size], edx
mov eax, edi
call destroy_smap
jmp .exit
endp
 
align 4
proc shmem_close stdcall, name:dword
 
mov eax, [name]
test eax, eax
jz .fail
mov eax, [name]
test eax, eax
jz .fail
 
push esi
push edi
pushfd
cli
push esi
push edi
pushfd
cli
 
mov esi, [current_slot]
add esi, APP_OBJ_OFFSET
mov esi, [current_slot]
add esi, APP_OBJ_OFFSET
.next:
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
 
cmp eax, esi
mov esi, eax
je @F
cmp eax, esi
mov esi, eax
je @F
 
cmp [eax+SMAP.magic], 'SMAP'
jne .next
cmp [eax+SMAP.magic], 'SMAP'
jne .next
 
mov edi, [eax+SMAP.parent]
test edi, edi
jz .next
mov edi, [eax+SMAP.parent]
test edi, edi
jz .next
 
lea eax, [edi+SMEM.name]
stdcall strncmp, [name], edi, 32
test eax, eax
jne .next
lea edi, [edi+SMEM.name]
stdcall strncmp, [name], edi, 32
test eax, eax
jne .next
 
stdcall user_free, [esi+SMAP.base]
stdcall user_free, [esi+SMAP.base]
 
call [esi+APPOBJ.destroy]
mov eax, esi
call [esi+APPOBJ.destroy]
@@:
popfd
pop edi
pop esi
popfd
pop edi
pop esi
.fail:
ret
ret
endp
/kernel/branches/net/core/irq.inc
0,0 → 1,229
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
IRQ_RESERVED equ 24
 
IRQ_POOL_SIZE equ 48
 
uglobal
 
align 16
irqh_tab rd LHEAD.sizeof * IRQ_RESERVED / 4
 
irqh_pool rd IRQH.sizeof * IRQ_POOL_SIZE /4
next_irqh rd 1
 
irq_active_set rd 1
irq_failed rd IRQ_RESERVED
 
endg
 
align 4
init_irqs:
 
mov ecx, IRQ_RESERVED
mov edi, irqh_tab
@@:
mov eax, edi
stosd
stosd
loop @B
 
mov ecx, IRQ_POOL_SIZE-1
mov eax, irqh_pool+IRQH.sizeof
mov [next_irqh], irqh_pool
@@:
mov [eax-IRQH.sizeof], eax
add eax, IRQH.sizeof
loop @B
 
mov [eax-IRQH.sizeof], dword 0
ret
 
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
locals
.irqh dd ?
endl
 
and [.irqh], 0
 
push ebx
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
 
cmp ebx, IRQ_RESERVED
jae .err
 
mov edx, [handler]
test edx, edx
jz .err
 
pushfd
cli
 
;allocate handler
 
mov ecx, [next_irqh]
test ecx, ecx
jz .fail
 
mov eax, [ecx]
mov [next_irqh], eax
mov [.irqh], ecx
 
mov [irq_failed+ebx*4], 0;clear counter
 
mov eax, [user_data]
mov [ecx+IRQH.handler], edx
mov [ecx+IRQH.data], eax
 
lea edx, [irqh_tab+ebx*8]
list_add_tail ecx, edx ;clobber eax
stdcall enable_irq, ebx
 
.fail:
popfd
.err:
pop ebx
mov eax, [.irqh]
ret
 
endp
 
if 0
align 4
proc get_int_handler stdcall, irq:dword
 
mov eax, [irq]
cmp eax, 15
ja .fail
mov eax, [irq_tab + 4 * eax]
ret
.fail:
xor eax, eax
ret
endp
end if
 
 
align 4
proc detach_int_handler
 
ret
endp
 
 
macro irq_serv_h [num] {
forward
align 4
.irq_#num :
push num
jmp .main
}
 
align 16
irq_serv:
 
; .irq_1:
; push 1
; jmp .main
; etc...
 
irq_serv_h 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15
irq_serv_h 16, 17, 18, 19, 20, 21, 22, 23
 
purge irq_serv_h
 
align 16
.main:
save_ring3_context
 
mov ebp, [esp + 32]
mov bx, app_data;os_data
mov ds, bx
mov es, bx
 
cmp [v86_irqhooks+ebp*8], 0
jnz v86_irq
 
cmp bp, 6
jnz @f
push ebp
call [fdc_irq_func]
pop ebp
@@:
 
cmp bp, 14
jnz @f
push ebp
call [irq14_func]
pop ebp
@@:
cmp bp, 15
jnz @f
push ebp
call [irq15_func]
pop ebp
@@:
bts [irq_active_set], ebp
 
lea esi, [irqh_tab+ebp*8] ; esi= list head
mov ebx, esi
.next:
mov ebx, [ebx+IRQH.list.next]; ebx= irqh pointer
cmp ebx, esi
je .done
 
push ebx ; FIX THIS
push edi
push esi
 
push [ebx+IRQH.data]
call [ebx+IRQH.handler]
add esp, 4
 
pop esi
pop edi
pop ebx
 
test eax, eax
jz .next
 
btr [irq_active_set], ebp
jmp .next
 
.done:
btr [irq_active_set], ebp
jnc .exit
 
inc [irq_failed+ebp*4]
.exit:
mov [check_idle_semaphore], 5
 
mov ecx, ebp
call irq_eoi
 
restore_ring3_context
add esp, 4
iret
 
align 4
irqD:
push eax
push ecx
xor eax, eax
out 0xf0, al
mov cl, 13
call irq_eoi
pop ecx
pop eax
iret
 
/kernel/branches/net/core/malloc.inc
20,35 → 20,35
; esi= nb
; ebx= idx
;
align 16
align 4
malloc:
push esi
push esi
 
; nb = ((size+7)&~7)+8;
 
mov esi, eax ;size
add esi, 7
and esi, -8
add esi, 8
mov esi, eax ;size
add esi, 7
and esi, -8
add esi, 8
 
mov ebx, mst.mutex
call wait_mutex ;ebx
mov ecx, mst.mutex
call mutex_lock
 
cmp esi, 256
jae .large
cmp esi, 256
jae .large
 
mov ecx, esi
shr ecx, 3
or eax, -1
shl eax, cl
and eax, [mst.smallmap]
jz .small
mov ecx, esi
shr ecx, 3
or eax, -1
shl eax, cl
and eax, [mst.smallmap]
jz .small
 
push ebp
push edi
push ebp
push edi
 
bsf eax, eax
mov ebx, eax
bsf eax, eax
mov ebx, eax
 
; psize= idx<<3;
; B = &ms.smallbins[idx];
56,19 → 56,19
; 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
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
cmp edi, eax
jne @F
 
btr [mst.smallmap], ebx
btr [mst.smallmap], ebx
@@:
 
; B->fd = F;
75,158 → 75,161
; F->bk = B;
; if(rsize<16)
 
cmp ecx, 16
mov [edi+8], eax
mov [eax+12], edi
jae .split
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
lea eax, [edx+8]
or dword [edx+ebp+4], 1
 
or ebp, 3
mov [edx+4], ebp
or ebp, 3
mov [edx+4], ebp
 
pop edi
pop ebp
pop edi
pop ebp
.done:
pop esi
mov [mst.mutex], 0
ret
mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi
ret
 
.split:
lea ebx, [edx+8] ;ebx=mem
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
lea eax, [edx+esi] ;eax= r
or esi, 3
mov [edx+4], esi
 
mov edx, ecx
or edx, 1
mov [eax+4], edx
mov edx, ecx
or edx, 1
mov [eax+4], edx
 
; (r + rsize)->prev_foot = rsize;
 
mov [eax+ecx], ecx
mov [eax+ecx], ecx
 
; I = rsize>>3;
 
shr ecx, 3
shr ecx, 3
 
; ms.smallmap |= 1<< I;
bts [mst.smallmap], ecx
bts [mst.smallmap], ecx
 
; B = &ms.smallbins[I];
 
shl ecx, 4
pop edi
pop ebp
add ecx, mst.smallbins ;ecx= B
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
mov [mst.mutex], 0
ret
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
jmp .done
 
.small:
 
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
;;;;;;;;;;; start a change <lrz>
mov eax,[mst.treemap]
test eax,eax
mov eax, [mst.treemap]
test eax, eax
;;;;;;;;;;; end the change <lrz>
; cmp [mst.treemap], 0
jz .from_top
mov eax, esi
call malloc_small
test eax, eax
jz .from_top
pop esi
and [mst.mutex], 0
ret
jz .from_top
mov eax, esi
call malloc_small
test eax, eax
jz .from_top
jmp .done
 
.large:
 
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
 
cmp [mst.treemap], 0
je .from_top
cmp [mst.treemap], 0
je .from_top
 
call malloc_large ;esi= nb
test eax, eax
jne .done
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
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
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
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]
jmp .done
 
.fail:
xor eax, eax
pop esi
and [mst.mutex], 0
ret
xor eax, eax
jmp .done
 
; param
; eax= mem
 
align 4
free:
push edi
mov edi, eax
add edi, -8
test eax, eax
jz .exit
 
push edi
mov edi, eax
add edi, -8
 
; if(p->head & CINUSE_BIT)
 
test byte [edi+4], 2
je .fail
test byte [edi+4], 2
je .fail
 
mov ebx, mst.mutex
call wait_mutex ;ebx
mov ecx, mst.mutex
call mutex_lock
 
; psize = p->head & (~3);
 
mov eax, [edi+4]
push esi
mov esi, eax
and esi, -4
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
test al, 1
lea ebx, [esi+edi]
jne .next
 
; prevsize = p->prev_foot;
; prev=p - prevsize;
233,133 → 236,138
; psize += prevsize;
; p = prev;
 
mov ecx, [edi] ;ecx= prevsize
add esi, ecx ;esi= psize
sub edi, ecx ;edi= p
mov ecx, [edi] ;ecx= prevsize
add esi, ecx ;esi= psize
sub edi, ecx ;edi= p
 
; if (prevsize < 256)
 
cmp ecx, 256
jae .unlink_large
cmp ecx, 256
jae .unlink_large
 
mov eax, [edi+8] ;F = p->fd;
mov edx, [edi+12] ;B = p->bk;
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
btr [mst.smallmap], ecx
shr ecx, 3
cmp eax, edx
jne @F
btr [mst.smallmap], ecx
@@:
mov [eax+12], edx ;F->bk = B;
mov [edx+8], eax ;B->fd = F
jmp .next
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
mov edx, edi
call unlink_large_chunk
.next:
 
; if(next->head & PINUSE_BIT)
 
mov eax, [ebx+4]
test al, 1
jz .fail2
mov eax, [ebx+4]
test al, 1
jz .fail2
 
; if (! (next->head & CINUSE_BIT))
 
test al, 2
jnz .fix_next
test al, 2
jnz .fix_next
 
; if (next == ms.top)
 
cmp ebx, [mst.top]
jne @F
cmp ebx, [mst.top]
jne @F
 
; tsize = ms.topsize += psize;
 
mov eax, [mst.topsize]
add eax, esi
mov [mst.topsize], eax
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
or eax, 1
mov [mst.top], edi
mov [edi+4], eax
.fail2:
and [mst.mutex], 0
pop esi
mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi
.fail:
pop edi
ret
pop edi
.exit:
ret
 
@@:
 
; nsize = next->head & ~INUSE_BITS;
 
and eax, -4
add esi, eax ;psize += nsize;
and eax, -4
add esi, eax ;psize += nsize;
 
; if (nsize < 256)
 
cmp eax, 256
jae .unl_large
cmp eax, 256
jae .unl_large
 
mov edx, [ebx+8] ;F = next->fd
mov ebx, [ebx+12] ;B = next->bk
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
cmp edx, ebx
jne @F
mov ecx, eax
shr ecx, 3
btr [mst.smallmap], ecx
@@:
mov [edx+12], ebx ;F->bk = B
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
mov ecx, esi
mov [ebx+8], edx
or ecx, 1
mov [edi+4], ecx
 
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
mov [esi+edi], esi
 
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
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
mov edx, ebx
call unlink_large_chunk
; p->head = psize|PINUSE_BIT;
 
mov ecx, esi
or ecx, 1
mov [edi+4], ecx
mov ecx, esi
or ecx, 1
mov [edi+4], ecx
 
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
mov [esi+edi], esi
 
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.fix_next:
 
; (p+psize)->prev_foot = psize;
366,22 → 374,22
; 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
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
mov [esi+edi], esi
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
 
; param
; ecx = chunk
389,35 → 397,37
 
insert_chunk:
 
cmp eax, 256
push esi
mov esi, ecx
jae .large
cmp eax, 256
push esi
mov esi, ecx
jae .large
 
; I = S>>3;
; ms.smallmap |= 1<< I;
 
shr eax, 3
bts [mst.smallmap], eax
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
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
mov ecx, mst.mutex
call mutex_unlock
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
and [mst.mutex], 0
ret
mov ebx, eax
call insert_large_chunk
pop esi
mov ecx, mst.mutex
call mutex_unlock
ret
 
 
; param
428,108 → 438,108
 
; 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]
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
mov dword [esi+28], ecx
 
; X->child[0] = X->child[1] = 0;
and dword [esi+20], 0
and dword [esi+16], 0
and dword [esi+20], 0
and dword [esi+16], 0
 
; H = &ms.treebins[I];
 
mov eax, ecx
lea edx, [mst.treebins+eax*4]
mov eax, ecx
lea edx, [mst.treebins+eax*4]
 
; if (!(ms.treemap & 1<<I))
bt [mst.treemap], ecx
jc .tree
bt [mst.treemap], ecx
jc .tree
 
; ms.treemap |= 1<<I;
bts [mst.treemap], ecx
bts [mst.treemap], ecx
; *H = X;
mov dword [edx], esi
jmp .done
mov dword [edx], esi
jmp .done
.tree:
 
; T = *H;
mov edx, [edx]
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
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
jmp .loop
.not_eq_size:
 
; C = &(T->child[(K >> 31) & 1]);
mov ecx, eax
shr ecx, 31
lea ecx, [edx+ecx*4+16]
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
mov edi, [ecx]
add eax, eax
test edi, edi
jz .insert_child
 
; T = *C;
mov edx, edi
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
mov ecx, [edx+4]
and ecx, not 3
cmp ecx, ebx
jne .not_eq_size
 
; F = T->fd;
mov eax, [edx+8]
mov eax, [edx+8]
 
; T->fd = F->bk = X;
mov [eax+12], esi
mov [edx+8], esi
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
and dword [esi+24], 0
mov [esi+8], eax
mov [esi+12], edx
ret
.insert_child:
 
; *C = X;
mov [ecx], esi
mov [ecx], esi
.done:
 
; X->parent = T;
mov [esi+24], edx
mov [esi+24], edx
 
; X->fd = X->bk = X;
mov [esi+12], esi
mov [esi+8], esi
ret
mov [esi+12], esi
mov [esi+8], esi
ret
 
 
; param
537,149 → 547,149
 
unlink_large_chunk:
 
mov eax, [edx+12]
cmp eax, edx
push edi
mov edi, [edx+24]
je @F
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 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+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
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+20], 0
lea ecx, [eax+20]
jne @F
 
cmp dword [eax+16], 0
lea ecx, [eax+16]
je .l1
cmp dword [eax+16], 0
lea ecx, [eax+16]
je .l1
@@:
mov eax, [ecx]
mov esi, ecx
jmp .loop
mov eax, [ecx]
mov esi, ecx
jmp .loop
.l1:
mov dword [esi], 0
mov dword [esi], 0
.l2:
pop esi
pop esi
.parent:
test edi, edi
je .done
test edi, edi
je .done
 
mov ecx, [edx+28]
cmp edx, [mst.treebins+ecx*4]
lea ecx, [mst.treebins+ecx*4]
jne .l3
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
test eax, eax
mov [ecx], eax
jne .l5
 
mov ecx, [edx+28]
btr [mst.treemap], ecx
pop edi
ret
mov ecx, [edx+28]
btr [mst.treemap], ecx
pop edi
ret
 
.l3:
cmp [edi+16], edx
jne @F
cmp [edi+16], edx
jne @F
 
mov [edi+16], eax
jmp .l4
mov [edi+16], eax
jmp .l4
 
@@:
mov [edi+20], eax
mov [edi+20], eax
 
.l4:
test eax, eax
je .done
test eax, eax
je .done
 
.l5:
mov [eax+24], edi
mov ecx, [edx+16]
test ecx, ecx
je .l6
mov [eax+24], edi
mov ecx, [edx+16]
test ecx, ecx
je .l6
 
mov [eax+16], ecx
mov [ecx+24], eax
mov [eax+16], ecx
mov [ecx+24], eax
 
.l6:
mov edx, [edx+20]
test edx, edx
je .done
mov edx, [edx+20]
test edx, edx
je .done
 
mov [eax+20], edx
mov [edx+24], eax
mov [eax+20], edx
mov [edx+24], eax
 
.done:
pop edi
ret
pop edi
ret
 
; param
; esi= nb
 
malloc_small:
push ebp
mov ebp, esi
push ebp
mov ebp, esi
 
push edi
push edi
 
bsf eax,[mst.treemap]
mov ecx, [mst.treebins+eax*4]
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
mov edi, [ecx+4]
and edi, -4
sub edi, esi
 
.loop:
mov ebx, ecx
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 eax, [ecx+16]
test eax, eax
jz @F
mov ecx, eax
jmp .l1
 
@@:
mov ecx, [ecx+20]
mov ecx, [ecx+20]
 
.l1:
test ecx, ecx
jz .unlink
test ecx, ecx
jz .unlink
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov eax, [ecx+4]
and eax, -4
sub eax, ebp
mov eax, [ecx+4]
and eax, -4
sub eax, ebp
 
; if (trem < rsize)
 
cmp eax, edi
jae .loop_1
cmp eax, edi
jae .loop_1
 
; rsize = trem;
 
mov edi, eax
jmp .loop
mov edi, eax
jmp .loop
.unlink:
 
 
686,32 → 696,32
; r = chunk_plus_offset((mchunkptr)v, nb);
; unlink_large_chunk(v);
 
mov edx, ebx
lea esi, [ebx+ebp]
call unlink_large_chunk
mov edx, ebx
lea esi, [ebx+ebp]
call unlink_large_chunk
 
; if (rsize < 16)
 
cmp edi, 16
jae .split
cmp edi, 16
jae .split
 
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
 
lea ecx, [edi+ebp]
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
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
lea eax, [ebx+8]
ret
 
.split:
 
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
718,42 → 728,42
; r->head = rsize|PINUSE_BIT;
; (r+rsize)->prev_foot = rsize;
 
or ebp, 3
mov edx, edi
or edx, 1
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
cmp edi, 256
mov [ebx+4], ebp
mov [esi+4], edx
mov [esi+edi], edi
jae .large
 
shr edi, 3
bts [mst.smallmap], edi
shr edi, 3
bts [mst.smallmap], edi
 
mov eax, edi
shl eax, 4
add eax, mst.smallbins
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
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
lea eax, [ebx+8]
push eax
mov ebx, edi
call insert_large_chunk
pop eax
pop edi
pop ebp
ret
 
 
; param
763,267 → 773,270
.idx equ esp+4
.rst equ esp
 
push ebp
push esi
push edi
sub esp, 8
push ebp
push esi
push edi
sub esp, 8
; v = 0;
; rsize = -nb;
 
mov edi, esi
mov ebx, esi
xor ebp, ebp
neg edi
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
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
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
cmp ecx, 31
jne @F
xor ecx, ecx
jmp .l1
 
@@:
mov edx, ecx
shr edx, 1
mov ecx, 37
sub ecx, edx
mov edx, ecx
shr edx, 1
mov ecx, 37
sub ecx, edx
 
.l1:
mov edx, ebx
shl edx, cl
mov edx, ebx
shl edx, cl
 
; rst = 0;
mov [.rst], ebp
mov [.rst], ebp
 
.loop:
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
 
; if (trem < rsize)
 
cmp ecx, edi
jae @F
cmp ecx, edi
jae @F
; v = t;
; if ((rsize = trem) == 0)
 
test ecx, ecx
mov ebp, eax
mov edi, ecx
je .l2
test ecx, ecx
mov ebp, eax
mov edi, ecx
je .l2
 
@@:
 
; rt = t->child[1];
 
mov ecx, [eax+20]
mov ecx, [eax+20]
 
; t = t->child[(sizebits >> 31) & 1];
 
mov esi, edx
shr esi, 31
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
test ecx, ecx
mov eax, [eax+esi*4+16]
jz @F
cmp ecx, eax
jz @F
 
; rst = rt;
mov [.rst], ecx
mov [.rst], ecx
 
@@:
; if (t == 0)
 
test eax, eax
jz @F
test eax, eax
jz @F
 
; sizebits <<= 1;
 
add edx, edx
jmp .loop
add edx, edx
jmp .loop
 
@@:
; t = rst;
mov eax, [.rst]
mov eax, [.rst]
 
.l2:
; if (t == 0 && v == 0)
 
test eax, eax
jne .l4
test ebp, ebp
jne .l7
mov ecx, [.idx]
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
or edx, -1
shl edx, cl
and edx, [mst.treemap]
jz @F
 
bsf eax, edx
bsf eax, edx
; t = ms.treebins[i];
mov eax, [mst.treebins+eax*4]
mov eax, [mst.treebins+eax*4]
 
@@:
 
; while (t != 0)
test eax, eax
jz .l5
test eax, eax
jz .l5
 
.l4:
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
 
; if (trem < rsize)
 
cmp ecx, edi
jae @F
cmp ecx, edi
jae @F
; rsize = trem;
 
mov edi, ecx
mov edi, ecx
; v = t;
mov ebp, eax
mov ebp, eax
 
@@:
 
; t = leftmost_child(t);
 
mov ecx, [eax+16]
test ecx, ecx
je @F
mov eax, ecx
jmp .l6
mov ecx, [eax+16]
test ecx, ecx
je @F
mov eax, ecx
jmp .l6
 
@@:
mov eax, [eax+20]
mov eax, [eax+20]
 
.l6:
 
; while (t != 0)
 
test eax, eax
jne .l4
test eax, eax
jne .l4
 
.l5:
 
; if (v != 0)
 
test ebp, ebp
jz .done
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
mov edx, ebp
lea esi, [ebx+ebp]
call unlink_large_chunk
 
; if (rsize < 16)
 
cmp edi, 16
jae .large
cmp edi, 16
jae .large
 
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
 
lea ecx, [edi+ebx]
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 esi
pop ebp
ret
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 esi
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
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
mov [esi+edi], edi
mov eax, edi
mov ecx, esi
call insert_chunk
 
lea eax, [ebp+8]
add esp, 8
pop edi
pop esi
pop ebp
ret
lea eax, [ebp+8]
add esp, 8
pop edi
pop esi
pop ebp
ret
 
.done:
add esp, 8
pop edi
pop esi
pop ebp
xor eax, eax
ret
add esp, 8
pop edi
pop esi
pop ebp
xor eax, eax
ret
 
init_malloc:
 
stdcall kernel_alloc, 0x40000
stdcall kernel_alloc, 0x40000
 
mov [mst.top], eax
mov [mst.topsize], 128*1024
mov dword [eax+4], (128*1024) or 1
mov eax, mst.smallbins
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
jb @B
mov [eax+8], eax
mov [eax+12], eax
add eax, 16
cmp eax, mst.smallbins+512
jb @B
 
ret
mov ecx, mst.mutex
call mutex_init
 
ret
 
/kernel/branches/net/core/memory.inc
11,130 → 11,130
align 4
proc alloc_page
 
pushfd
cli
push ebx
pushfd
cli
push ebx
;//-
cmp [pg_data.pages_free], 1
jle .out_of_memory
cmp [pg_data.pages_free], 1
jle .out_of_memory
;//-
 
mov ebx, [page_start]
mov ecx, [page_end]
mov ebx, [page_start]
mov ecx, [page_end]
.l1:
bsf eax,[ebx];
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
pop ebx
popfd
xor eax,eax
ret
bsf eax, [ebx];
jnz .found
add ebx, 4
cmp ebx, ecx
jb .l1
pop ebx
popfd
xor eax, eax
ret
.found:
;//-
dec [pg_data.pages_free]
jz .out_of_memory
dec [pg_data.pages_free]
jz .out_of_memory
;//-
btr [ebx], eax
mov [page_start],ebx
sub ebx, sys_pgmap
lea eax, [eax+ebx*8]
shl eax, 12
btr [ebx], eax
mov [page_start], ebx
sub ebx, sys_pgmap
lea eax, [eax+ebx*8]
shl eax, 12
;//- dec [pg_data.pages_free]
pop ebx
popfd
ret
pop ebx
popfd
ret
;//-
.out_of_memory:
mov [pg_data.pages_free], 1
xor eax, eax
pop ebx
popfd
ret
mov [pg_data.pages_free], 1
xor eax, eax
pop ebx
popfd
ret
;//-
endp
 
align 4
proc alloc_pages stdcall, count:dword
pushfd
push ebx
push edi
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
pushfd
push ebx
push edi
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
;//-
mov ebx, [pg_data.pages_free]
sub ebx, 9
js .out_of_memory
shr ebx, 3
cmp eax, ebx
jg .out_of_memory
mov ebx, [pg_data.pages_free]
sub ebx, 9
js .out_of_memory
shr ebx, 3
cmp eax, ebx
jg .out_of_memory
;//-
mov ecx, [page_start]
mov ebx, [page_end]
mov ecx, [page_start]
mov ebx, [page_end]
.find:
mov edx, [count]
mov edi, ecx
mov edx, [count]
mov edi, ecx
.match:
cmp byte [ecx], 0xFF
jne .next
dec edx
jz .ok
inc ecx
cmp ecx,ebx
jb .match
cmp byte [ecx], 0xFF
jne .next
dec edx
jz .ok
inc ecx
cmp ecx, ebx
jb .match
.out_of_memory:
.fail:
xor eax, eax
pop edi
pop ebx
popfd
ret
xor eax, eax
pop edi
pop ebx
popfd
ret
.next:
inc ecx
cmp ecx, ebx
jb .find
pop edi
pop ebx
popfd
xor eax, eax
ret
inc ecx
cmp ecx, ebx
jb .find
pop edi
pop ebx
popfd
xor eax, eax
ret
.ok:
sub ecx, edi
inc ecx
push esi
mov esi, edi
xor eax, eax
rep stosb
sub esi, sys_pgmap
shl esi, 3+12
mov eax, esi
mov ebx, [count]
shl ebx, 3
sub [pg_data.pages_free], ebx
pop esi
pop edi
pop ebx
popfd
ret
sub ecx, edi
inc ecx
push esi
mov esi, edi
xor eax, eax
rep stosb
sub esi, sys_pgmap
shl esi, 3+12
mov eax, esi
mov ebx, [count]
shl ebx, 3
sub [pg_data.pages_free], ebx
pop esi
pop edi
pop ebx
popfd
ret
endp
 
align 4
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
push ebx
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
pop ebx
ret
push ebx
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
pop ebx
ret
endp
 
align 4
141,70 → 141,73
map_space: ;not implemented
 
 
ret
ret
 
 
align 4
proc free_page
;arg: eax page address
pushfd
cli
shr eax, 12 ;page index
bts dword [sys_pgmap], eax ;that's all!
cmc
adc [pg_data.pages_free], 0
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, sys_pgmap
cmp [page_start], eax
ja @f
popfd
ret
pushfd
cli
shr eax, 12 ;page index
bts dword [sys_pgmap], eax ;that's all!
cmc
adc [pg_data.pages_free], 0
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, sys_pgmap
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
mov [page_start], eax
popfd
ret
endp
 
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
 
push ebx
push edi
mov eax, [size]
add eax, 4095
and eax, -4096
mov [size], eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
push eax
push ebx
push edi
mov eax, [size]
add eax, [base]
add eax, 4095
and eax, -4096
mov ecx, [base]
and ecx, -4096
sub eax, ecx
mov [size], eax
 
mov edi, 0x1000
mov ebx, eax
mov ecx,[size]
mov edx, [base]
shr eax, 12
shr ecx, 12
and edx, -4096
or edx, [flags]
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
push eax
 
mov edi, 0x1000
mov ebx, eax
mov ecx, [size]
mov edx, [base]
shr eax, 12
shr ecx, 12
and edx, -4096
or edx, [flags]
@@:
mov [page_tabs+eax*4], edx
; push eax
invlpg [ebx]
; pop eax
inc eax
add ebx, edi
add edx, edi
loop @B
mov [page_tabs+eax*4], edx
invlpg [ebx]
inc eax
add ebx, edi
add edx, edi
loop @B
 
pop eax
mov edx, [base]
and edx, 4095
add eax, edx
pop eax
mov edx, [base]
and edx, 4095
add eax, edx
.fail:
pop edi
pop ebx
ret
pop edi
pop ebx
ret
endp
 
; param
214,31 → 217,33
 
align 4
commit_pages:
push edi
test ecx, ecx
jz .fail
test ecx, ecx
jz .fail
 
mov edi, ebx
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
push edi
push eax
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
pop eax
 
mov edx, 0x1000
mov ebx, edi
shr ebx, 12
mov edi, ebx
shr edi, 12
lea edi, [page_tabs+edi*4]
@@:
mov [page_tabs+ebx*4], eax
; push eax
invlpg [edi]
; pop eax
add edi, edx
add eax, edx
inc ebx
dec ecx
jnz @B
mov [pg_data.pg_mutex],ecx
stosd
invlpg [ebx]
add eax, 0x1000
add ebx, 0x1000
loop @B
 
pop edi
 
mov ecx, pg_data.mutex
call mutex_unlock
.fail:
pop edi
ret
ret
 
 
; param
248,50 → 253,59
align 4
release_pages:
 
pushad
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
push ebp
push esi
push edi
push ebx
 
mov esi, eax
mov edi, eax
mov esi, eax
mov edi, eax
 
shr esi, 10
add esi, page_tabs
shr esi, 12
lea esi, [page_tabs+esi*4]
 
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
mov edx, sys_pgmap
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
 
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
mov edx, sys_pgmap
@@:
xor eax, eax
xchg eax, [esi]
push eax
invlpg [edi]
pop eax
xor eax, eax
xchg eax, [esi]
invlpg [edi]
 
test eax, 1
jz .next
test eax, 1
jz .next
 
shr eax, 12
bts [edx], eax
cmc
adc ebp, 0
shr eax, 3
and eax, -4
add eax, edx
cmp eax, ebx
jae .next
shr eax, 12
bts [edx], eax
cmc
adc ebp, 0
shr eax, 3
and eax, -4
add eax, edx
cmp eax, ebx
jae .next
 
mov ebx, eax
mov ebx, eax
.next:
add edi, 0x1000
add esi, 4
dec ecx
jnz @B
mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0
popad
ret
add edi, 0x1000
add esi, 4
loop @B
 
mov [pg_data.pages_free], ebp
mov ecx, pg_data.mutex
call mutex_unlock
 
pop ebx
pop edi
pop esi
pop ebp
ret
 
; param
; eax= base
; ecx= count
299,40 → 313,40
align 4
unmap_pages:
 
push edi
push edi
 
mov edi, eax
mov edx, eax
mov edi, eax
mov edx, eax
 
shr edi, 10
add edi, page_tabs
shr edi, 10
add edi, page_tabs
 
xor eax, eax
xor eax, eax
@@:
stosd
invlpg [edx]
add edx, 0x1000
loop @b
stosd
invlpg [edx]
add edx, 0x1000
loop @b
 
pop edi
ret
pop edi
ret
 
 
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
push ebx
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [master_tab+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, page_tabs
invlpg [eax]
pop ebx
ret
push ebx
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [master_tab+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, page_tabs
invlpg [eax]
pop ebx
ret
endp
 
align 4
341,208 → 355,213
pg_count dd ?
endl
 
cmp dword [LFBAddress], -1
jne @f
mov [BOOT_VAR+0x901c],byte 2
stdcall alloc_pages, (0x280000 / 4096)
cmp dword [LFBAddress], -1
jne @f
mov [BOOT_VAR+0x901c], byte 2
stdcall alloc_pages, (0x280000 / 4096)
 
push eax
call alloc_page
stdcall map_page_table, LFB_BASE, eax
pop eax
or eax, PG_UW
mov ebx, LFB_BASE
mov ecx, 0x280000 / 4096
call commit_pages
mov [LFBAddress], dword LFB_BASE
ret
push eax
call alloc_page
stdcall map_page_table, LFB_BASE, eax
pop eax
or eax, PG_UW
mov ebx, LFB_BASE
mov ecx, 0x280000 / 4096
call commit_pages
mov [LFBAddress], dword LFB_BASE
ret
@@:
test [SCR_MODE],word 0100000000000000b
jnz @f
mov [BOOT_VAR+0x901c],byte 2
ret
test [SCR_MODE], word 0100000000000000b
jnz @f
mov [BOOT_VAR+0x901c], byte 2
ret
@@:
call init_mtrr
call init_mtrr
 
mov edx, LFB_BASE
mov esi, [LFBAddress]
mov edi, 0x00C00000
mov dword [exp_lfb+4], edx
mov edx, LFB_BASE
mov esi, [LFBAddress]
mov edi, 0x00C00000
mov dword [exp_lfb+4], edx
 
shr edi, 12
mov [pg_count], edi
shr edi, 10
shr edi, 12
mov [pg_count], edi
shr edi, 10
 
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
or esi, PG_LARGE+PG_UW
mov edx, sys_pgdir+(LFB_BASE shr 20)
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
or esi, PG_LARGE+PG_UW
mov edx, sys_pgdir+(LFB_BASE shr 20)
@@:
mov [edx], esi
add edx, 4
add esi, 0x00400000
dec edi
jnz @B
mov [edx], esi
add edx, 4
add esi, 0x00400000
dec edi
jnz @B
 
bt [cpu_caps], CAPS_PGE
jnc @F
or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
bt [cpu_caps], CAPS_PGE
jnc @F
or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
@@:
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
 
.map_page_tables:
 
@@:
call alloc_page
stdcall map_page_table, edx, eax
add edx, 0x00400000
dec edi
jnz @B
call alloc_page
stdcall map_page_table, edx, eax
add edx, 0x00400000
dec edi
jnz @B
 
mov eax, [LFBAddress]
mov edi, page_tabs + (LFB_BASE shr 10)
or eax, PG_UW
mov ecx, [pg_count]
cld
mov eax, [LFBAddress]
mov edi, page_tabs + (LFB_BASE shr 10)
or eax, PG_UW
mov ecx, [pg_count]
cld
@@:
stosd
add eax, 0x1000
dec ecx
jnz @B
stosd
add eax, 0x1000
dec ecx
jnz @B
 
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
 
ret
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
 
mov edi, [new_size]
add edi,4095
and edi,not 4095
mov [new_size], edi
mov edi, [new_size]
add edi, 4095
and edi, not 4095
mov [new_size], edi
 
mov edx,[current_slot]
cmp [edx+APPDATA.heap_base],0
jne .exit
mov edx, [current_slot]
cmp [edx+APPDATA.heap_base], 0
jne .exit
 
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
jae .expand
cmp edi, esi
jae .expand
 
shr edi, 12
shr esi, 12
shr edi, 12
shr esi, 12
@@:
mov eax, [app_page_tabs+edi*4]
test eax, 1
jz .next
mov dword [app_page_tabs+edi*4], 2
mov ebx, edi
shl ebx, 12
push eax
invlpg [ebx]
pop eax
call free_page
mov eax, [app_page_tabs+edi*4]
test eax, 1
jz .next
mov dword [app_page_tabs+edi*4], 2
mov ebx, edi
shl ebx, 12
push eax
invlpg [ebx]
pop eax
call free_page
 
.next: add edi, 1
cmp edi, esi
jb @B
.next:
add edi, 1
cmp edi, esi
jb @B
 
.update_size:
mov ebx, [new_size]
call update_mem_size
mov ebx, [new_size]
call update_mem_size
 
xor eax, eax
dec [pg_data.pg_mutex]
ret
mov ecx, pg_data.mutex
call mutex_unlock
 
xor eax, eax
ret
.expand:
 
push esi
push edi
push esi
push edi
 
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
 
cmp esi, edi
jae .grow
cmp esi, edi
jae .grow
 
xchg esi, edi
xchg esi, edi
 
@@:
call alloc_page
test eax, eax
jz .exit_pop
call alloc_page
test eax, eax
jz .exit_pop
 
stdcall map_page_table, edi, eax
stdcall map_page_table, edi, eax
 
push edi
shr edi, 10
add edi, page_tabs
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
push edi
shr edi, 10
add edi, page_tabs
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
 
add edi, 0x00400000
cmp edi, esi
jb @B
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
;//-
pop edi
push edi
mov esi, [pg_data.pages_free]
sub esi, 1
shr edi, 12
cmp esi, edi
jle .out_of_memory
pop edi
push edi
mov esi, [pg_data.pages_free]
sub esi, 1
shr edi, 12
cmp esi, edi
jle .out_of_memory
;//-
pop edi
pop esi
pop edi
pop esi
@@:
call alloc_page
test eax, eax
jz .exit
stdcall map_page,esi,eax,dword PG_UW
call alloc_page
test eax, eax
jz .exit
stdcall map_page, esi, eax, dword PG_UW
 
push edi
mov edi, esi
xor eax, eax
mov ecx, 1024
cld
rep stosd
pop edi
push edi
mov edi, esi
xor eax, eax
mov ecx, 1024
cld
rep stosd
pop edi
 
add esi, 0x1000
cmp esi, edi
jb @B
add esi, 0x1000
cmp esi, edi
jb @B
 
jmp .update_size
jmp .update_size
;//-
.exit_pop:
.out_of_memory:
;//-
pop edi
pop esi
pop edi
pop esi
.exit:
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
mov ecx, pg_data.mutex
call mutex_unlock
 
xor eax, eax
inc eax
ret
endp
 
update_mem_size:
550,31 → 569,31
; ebx = new memory size
; destroys eax,ecx,edx
 
mov [APPDATA.mem_size+edx],ebx
mov [APPDATA.mem_size+edx], ebx
;search threads and update
;application memory size infomation
mov ecx,[APPDATA.dir_table+edx]
mov eax,2
mov ecx, [APPDATA.dir_table+edx]
mov eax, 2
 
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[TASK_COUNT]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [SLOT_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread?
jnz .search_threads_next
mov [SLOT_BASE+edx+APPDATA.mem_size],ebx ;update memory size
cmp eax, [TASK_COUNT]
jg .search_threads_end
mov edx, eax
shl edx, 5
cmp word [CURRENT_TASK+edx+TASKDATA.state], 9 ;if slot empty?
jz .search_threads_next
shl edx, 3
cmp [SLOT_BASE+edx+APPDATA.dir_table], ecx ;if it is our thread?
jnz .search_threads_next
mov [SLOT_BASE+edx+APPDATA.mem_size], ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
inc eax
jmp .search_threads
.search_threads_end:
ret
ret
 
; param
; eax= linear address
584,10 → 603,10
 
align 4
get_pg_addr:
shr eax, 12
mov eax, [page_tabs+eax*4]
and eax, 0xFFFFF000
ret
shr eax, 12
mov eax, [page_tabs+eax*4]
and eax, 0xFFFFF000
ret
 
 
align 4
655,7 → 674,7
test eax, eax
jz .fail
 
stdcall map_page,[.err_addr],eax,PG_UW
stdcall map_page, [.err_addr], eax, PG_UW
 
mov edi, [.err_addr]
and edi, 0xFFFFF000
662,9 → 681,9
mov ecx, 1024
xor eax, eax
;cld ;caller is duty for this
rep stosd
rep stosd
.exit: ;iret with repeat fault instruction
add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
add esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
restore_ring3_context
iretd
 
693,7 → 712,7
call alloc_page
test eax, eax
jz .fail
stdcall map_page,ebx,eax,PG_UW
stdcall map_page, ebx, eax, PG_UW
mov edi, ebx
mov ecx, 1024
sub ebx, [esi+HDLL.base]
700,7 → 719,7
mov esi, [esi+HDLL.parent]
mov esi, [esi+DLLDESCR.data]
add esi, ebx
rep movsd
rep movsd
jmp .exit
 
.kernel_space:
707,7 → 726,7
test eax, PG_MAP
jz .fail ;ñòðàíèöà íå ïðèñóòñòâóåò
 
test eax,12 ;U/S (+below)
test eax, 12 ;U/S (+below)
jnz .fail ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
;ÿäðà
;test eax, 8
730,7 → 749,7
jz .fail
 
push eax
stdcall map_page,[.err_addr],eax,dword PG_SW
stdcall map_page, [.err_addr], eax, dword PG_SW
pop eax
mov edi, [.err_addr]
and edi, -4096
745,7 → 764,7
add esi, [default_io_map]
mov ecx, 4096/4
;cld ;caller is duty for this
rep movsd
rep movsd
jmp .exit
endp
 
752,25 → 771,25
; returns number of mapped bytes
proc map_mem stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
push 0 ; initialize number of mapped bytes
 
cmp [buf_size], 0
jz .exit
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
stdcall map_page,[ipc_pdir],eax,PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page,edi,eax,PG_UW
stdcall map_page, [ipc_pdir], eax, PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, edi, eax, PG_UW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
779,90 → 798,92
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
 
.map:
stdcall safe_map_page,[slot],[req_access],[ofs]
jnc .exit
add dword [ebp-4], 4096
add [ofs], 4096
dec ecx
jz .exit
add edi, 0x1000
inc edx
cmp edx, 0x400
jnz .map
inc ebx
mov eax, [ipc_pdir]
mov eax, [eax+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page,esi,eax,PG_UW
xor edx, edx
jmp .map
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add dword [ebp-4], 4096
add [ofs], 4096
dec ecx
jz .exit
add edi, 0x1000
inc edx
cmp edx, 0x400
jnz .map
inc ebx
mov eax, [ipc_pdir]
mov eax, [eax+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page, esi, eax, PG_UW
xor edx, edx
jmp .map
 
.exit:
pop eax
ret
pop eax
ret
endp
 
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
push 0 ; initialize number of mapped bytes
 
cmp [buf_size], 0
jz .exit
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
stdcall map_page,[proc_mem_pdir],eax,PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,PG_UW
stdcall map_page, [proc_mem_pdir], eax, PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page, edi, eax, PG_UW
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
@@:
mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
 
.map:
stdcall safe_map_page,[slot],[req_access],[ofs]
jnc .exit
add dword [ebp-4], 0x1000
add edi, 0x1000
add [ofs], 0x1000
inc edx
dec ecx
jnz .map
stdcall safe_map_page, [slot], [req_access], [ofs]
jnc .exit
add dword [ebp-4], 0x1000
add edi, 0x1000
add [ofs], 0x1000
inc edx
dec ecx
jnz .map
.exit:
pop eax
ret
pop eax
ret
endp
 
; in: esi+edx*4 = pointer to page table entry
871,80 → 892,80
; out: CF cleared <=> failed
; destroys: only eax
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
mov eax, [esi+edx*4]
test al, PG_MAP
jz .not_present
test al, PG_WRITE
jz .resolve_readonly
mov eax, [esi+edx*4]
test al, PG_MAP
jz .not_present
test al, PG_WRITE
jz .resolve_readonly
; normal case: writable page, just map with requested access
.map:
stdcall map_page, edi, eax, [req_access]
stc
stdcall map_page, edi, eax, [req_access]
stc
.fail:
ret
ret
.not_present:
; check for alloc-on-demand page
test al, 2
jz .fail
test al, 2
jz .fail
; allocate new page, save it to source page table
push ecx
call alloc_page
pop ecx
test eax, eax
jz .fail
or al, PG_UW
mov [esi+edx*4], eax
jmp .map
push ecx
call alloc_page
pop ecx
test eax, eax
jz .fail
or al, PG_UW
mov [esi+edx*4], eax
jmp .map
.resolve_readonly:
; readonly page, probably copy-on-write
; check: readonly request of readonly page is ok
test [req_access], PG_WRITE
jz .map
test [req_access], PG_WRITE
jz .map
; find control structure for this page
pushf
cli
cld
push ebx ecx
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax+HDLL.fd]
pushf
cli
cld
push ebx ecx
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax+HDLL.fd]
.scan_hdll:
cmp ecx, eax
jz .no_hdll
mov ebx, [ofs]
and ebx, not 0xFFF
sub ebx, [ecx+HDLL.base]
cmp ebx, [ecx+HDLL.size]
jb .hdll_found
mov ecx, [ecx+HDLL.fd]
jmp .scan_hdll
cmp ecx, eax
jz .no_hdll
mov ebx, [ofs]
and ebx, not 0xFFF
sub ebx, [ecx+HDLL.base]
cmp ebx, [ecx+HDLL.size]
jb .hdll_found
mov ecx, [ecx+HDLL.fd]
jmp .scan_hdll
.no_hdll:
pop ecx ebx
popf
clc
ret
pop ecx ebx
popf
clc
ret
.hdll_found:
; allocate page, save it in page table, map it, copy contents from base
mov eax, [ecx+HDLL.parent]
add ebx, [eax+DLLDESCR.data]
call alloc_page
test eax, eax
jz .no_hdll
or al, PG_UW
mov [esi+edx*4], eax
stdcall map_page, edi, eax, [req_access]
push esi edi
mov esi, ebx
mov ecx, 4096/4
rep movsd
pop edi esi
pop ecx ebx
popf
stc
ret
mov eax, [ecx+HDLL.parent]
add ebx, [eax+DLLDESCR.data]
call alloc_page
test eax, eax
jz .no_hdll
or al, PG_UW
mov [esi+edx*4], eax
stdcall map_page, edi, eax, [req_access]
push esi edi
mov esi, ebx
mov ecx, 4096/4
rep movsd
pop edi esi
pop ecx ebx
popf
stc
ret
endp
 
sys_IPC:
957,40 → 978,41
; ecx=address of message
; edx=size of message
 
dec ebx
jnz @f
dec ebx
jnz @f
 
mov eax,[current_slot]
pushf
cli
mov [eax+APPDATA.ipc_start],ecx ;set fields in extended information area
mov [eax+APPDATA.ipc_size],edx
mov eax, [current_slot]
pushf
cli
mov [eax+APPDATA.ipc_start], ecx ;set fields in extended information area
mov [eax+APPDATA.ipc_size], edx
 
add edx, ecx
add edx, 4095
and edx, not 4095
add edx, ecx
add edx, 4095
and edx, not 4095
 
.touch: mov eax, [ecx]
add ecx, 0x1000
cmp ecx, edx
jb .touch
.touch:
mov eax, [ecx]
add ecx, 0x1000
cmp ecx, edx
jb .touch
 
popf
mov [esp+32], ebx ;ebx=0
ret
popf
mov [esp+32], ebx ;ebx=0
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;2
@@:
dec ebx
jnz @f
dec ebx
jnz @f
 
stdcall sys_ipc_send, ecx, edx, esi
mov [esp+32], eax
mov [esp+32], eax
ret
@@:
or eax,-1
mov [esp+32], eax
or eax, -1
mov [esp+32], eax
ret
 
;align 4
1024,119 → 1046,119
used_buf dd ?
endl
 
pushf
cli
pushf
cli
 
mov eax, [PID]
call pid_to_slot
test eax,eax
jz .no_pid
mov eax, [PID]
call pid_to_slot
test eax, eax
jz .no_pid
 
mov [dst_slot], eax
shl eax,8
mov edi,[eax+SLOT_BASE+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
mov [dst_slot], eax
shl eax, 8
mov edi, [eax+SLOT_BASE+0xa0] ;is ipc area defined?
test edi, edi
jz .no_ipc_area
 
mov ebx, edi
and ebx, 0xFFF
mov [dst_offset], ebx
mov ebx, edi
and ebx, 0xFFF
mov [dst_offset], ebx
 
mov esi, [eax+SLOT_BASE+0xa4]
mov [buf_size], esi
mov esi, [eax+SLOT_BASE+0xa4]
mov [buf_size], esi
 
mov ecx, [ipc_tmp]
cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
jbe @f
push esi edi
add esi,0x1000
stdcall alloc_kernel_space,esi
mov ecx, eax
pop edi esi
mov ecx, [ipc_tmp]
cmp esi, 0x40000-0x1000; size of [ipc_tmp] minus one page
jbe @f
push esi edi
add esi, 0x1000
stdcall alloc_kernel_space, esi
mov ecx, eax
pop edi esi
@@:
mov [used_buf], ecx
stdcall map_mem, ecx, [dst_slot],\
edi, esi, PG_SW
mov [used_buf], ecx
stdcall map_mem, ecx, [dst_slot], \
edi, esi, PG_SW
 
mov edi, [dst_offset]
add edi, [used_buf]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
mov edi, [dst_offset]
add edi, [used_buf]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
 
mov edx, dword [edi+4]
lea ebx, [edx+8]
add ebx, [msg_size]
cmp ebx, [buf_size]
ja .buffer_overflow ;esi<0 - not enough memory in buffer
mov edx, dword [edi+4]
lea ebx, [edx+8]
add ebx, [msg_size]
cmp ebx, [buf_size]
ja .buffer_overflow ;esi<0 - not enough memory in buffer
 
mov dword [edi+4], ebx
mov eax,[TASK_BASE]
mov eax, [eax+0x04] ;eax - our PID
add edi, edx
mov [edi], eax
mov ecx, [msg_size]
mov dword [edi+4], ebx
mov eax, [TASK_BASE]
mov eax, [eax+0x04] ;eax - our PID
add edi, edx
mov [edi], eax
mov ecx, [msg_size]
 
mov [edi+4], ecx
add edi, 8
mov esi, [msg_addr]
mov [edi+4], ecx
add edi, 8
mov esi, [msg_addr]
; add esi, new_app_base
cld
rep movsb
cld
rep movsb
 
mov ebx, [ipc_tmp]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
mov ebx, [ipc_tmp]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
 
mov eax, [dst_slot]
shl eax, 8
or [eax+SLOT_BASE+0xA8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
mov eax, [dst_slot]
shl eax, 8
or [eax+SLOT_BASE+0xA8], dword 0x40
cmp dword [check_idle_semaphore], 20
jge .ipc_no_cis
 
mov dword [check_idle_semaphore],5
mov dword [check_idle_semaphore], 5
.ipc_no_cis:
push 0
jmp .ret
push 0
jmp .ret
.no_pid:
popf
mov eax, 4
ret
popf
mov eax, 4
ret
.no_ipc_area:
popf
xor eax, eax
inc eax
ret
popf
xor eax, eax
inc eax
ret
.ipc_blocked:
push 2
jmp .ret
push 2
jmp .ret
.buffer_overflow:
push 3
push 3
.ret:
mov eax, [used_buf]
cmp eax, [ipc_tmp]
jz @f
stdcall free_kernel_space,eax
mov eax, [used_buf]
cmp eax, [ipc_tmp]
jz @f
stdcall free_kernel_space, eax
@@:
pop eax
popf
ret
pop eax
popf
ret
endp
 
align 4
1143,148 → 1165,148
sysfn_meminfo:
 
; add ecx, new_app_base
cmp ecx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jae .fail
 
mov eax, [pg_data.pages_count]
mov [ecx], eax
shl eax, 12
mov [esp+32], eax
mov eax, [pg_data.pages_free]
mov [ecx+4], eax
mov eax, [pg_data.pages_faults]
mov [ecx+8], eax
mov eax, [heap_size]
mov [ecx+12], eax
mov eax, [heap_free]
mov [ecx+16], eax
mov eax, [heap_blocks]
mov [ecx+20], eax
mov eax, [free_blocks]
mov [ecx+24], eax
ret
mov eax, [pg_data.pages_count]
mov [ecx], eax
shl eax, 12
mov [esp+32], eax
mov eax, [pg_data.pages_free]
mov [ecx+4], eax
mov eax, [pg_data.pages_faults]
mov [ecx+8], eax
mov eax, [heap_size]
mov [ecx+12], eax
mov eax, [heap_free]
mov [ecx+16], eax
mov eax, [heap_blocks]
mov [ecx+20], eax
mov eax, [free_blocks]
mov [ecx+24], eax
ret
.fail:
or dword [esp+32], -1
ret
or dword [esp+32], -1
ret
 
align 4
f68:
cmp ebx,4
jbe sys_sheduler
cmp ebx, 4
jbe sys_sheduler
 
cmp ebx, 11
jb .fail
cmp ebx, 11
jb .fail
 
cmp ebx, 25
ja .fail
cmp ebx, 25
ja .fail
 
jmp dword [f68call+ebx*4-11*4]
jmp dword [f68call+ebx*4-11*4]
.11:
call init_heap
mov [esp+32], eax
ret
call init_heap
mov [esp+32], eax
ret
.12:
stdcall user_alloc, ecx
mov [esp+32], eax
ret
stdcall user_alloc, ecx
mov [esp+32], eax
ret
.13:
stdcall user_free, ecx
mov [esp+32], eax
ret
stdcall user_free, ecx
mov [esp+32], eax
ret
.14:
cmp ecx, OS_BASE
jae .fail
mov edi,ecx
call get_event_ex
mov [esp+32], eax
ret
cmp ecx, OS_BASE
jae .fail
mov edi, ecx
call get_event_ex
mov [esp+32], eax
ret
.16:
test ecx, ecx
jz .fail
cmp ecx, OS_BASE
jae .fail
stdcall get_service, ecx
mov [esp+32], eax
ret
test ecx, ecx
jz .fail
cmp ecx, OS_BASE
jae .fail
stdcall get_service, ecx
mov [esp+32], eax
ret
.17:
call srv_handlerEx ;ecx
mov [esp+32], eax
ret
call srv_handlerEx ;ecx
mov [esp+32], eax
ret
.19:
cmp ecx, OS_BASE
jae .fail
stdcall load_library, ecx
mov [esp+32], eax
ret
cmp ecx, OS_BASE
jae .fail
stdcall load_library, ecx
mov [esp+32], eax
ret
.20:
mov eax, edx
mov ebx, ecx
call user_realloc ;in: eax = pointer, ebx = new size
mov [esp+32], eax
ret
mov eax, edx
mov ebx, ecx
call user_realloc ;in: eax = pointer, ebx = new size
mov [esp+32], eax
ret
.21:
cmp ecx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jae .fail
 
cmp ebx, OS_BASE
jae .fail
cmp ebx, OS_BASE
jae .fail
 
mov edi, edx
stdcall load_PE, ecx
mov esi, eax
test eax, eax
jz @F
mov edi, edx
stdcall load_PE, ecx
mov esi, eax
test eax, eax
jz @F
 
push edi
push DRV_ENTRY
call eax
add esp, 8
test eax, eax
jz @F
push edi
push DRV_ENTRY
call eax
add esp, 8
test eax, eax
jz @F
 
mov [eax+SRV.entry], esi
mov [eax+SRV.entry], esi
 
@@:
mov [esp+32], eax
ret
mov [esp+32], eax
ret
.22:
cmp ecx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jae .fail
 
stdcall shmem_open, ecx, edx, esi
mov [esp+24], edx
mov [esp+32], eax
ret
stdcall shmem_open, ecx, edx, esi
mov [esp+24], edx
mov [esp+32], eax
ret
 
.23:
cmp ecx, OS_BASE
jae .fail
cmp ecx, OS_BASE
jae .fail
 
stdcall shmem_close, ecx
mov [esp+32], eax
ret
stdcall shmem_close, ecx
mov [esp+32], eax
ret
.24:
mov eax, [current_slot]
xchg ecx, [eax+APPDATA.exc_handler]
xchg edx, [eax+APPDATA.except_mask]
mov [esp+32], ecx ; reg_eax+8
mov [esp+20], edx ; reg_ebx+8
ret
mov eax, [current_slot]
xchg ecx, [eax+APPDATA.exc_handler]
xchg edx, [eax+APPDATA.except_mask]
mov [esp+32], ecx ; reg_eax+8
mov [esp+20], edx ; reg_ebx+8
ret
.25:
cmp ecx,32
jae .fail
mov eax, [current_slot]
btr [eax+APPDATA.except_mask],ecx
setc byte[esp+32]
jecxz @f
bts [eax+APPDATA.except_mask],ecx
cmp ecx, 32
jae .fail
mov eax, [current_slot]
btr [eax+APPDATA.except_mask], ecx
setc byte[esp+32]
jecxz @f
bts [eax+APPDATA.except_mask], ecx
@@:
ret
ret
 
.fail:
xor eax, eax
mov [esp+32], eax
ret
xor eax, eax
mov [esp+32], eax
ret
 
 
align 4
1310,21 → 1332,21
align 4
proc load_pe_driver stdcall, file:dword
 
stdcall load_PE, [file]
test eax, eax
jz .fail
stdcall load_PE, [file]
test eax, eax
jz .fail
 
mov esi, eax
stdcall eax, DRV_ENTRY
test eax, eax
jz .fail
mov esi, eax
stdcall eax, DRV_ENTRY
test eax, eax
jz .fail
 
mov [eax+SRV.entry], esi
ret
mov [eax+SRV.entry], esi
ret
 
.fail:
xor eax, eax
ret
xor eax, eax
ret
endp
 
 
1331,135 → 1353,135
align 4
proc init_mtrr
 
cmp [BOOT_VAR+0x901c],byte 2
je .exit
cmp [BOOT_VAR+0x901c], byte 2
je .exit
 
bt [cpu_caps], CAPS_MTRR
jnc .exit
bt [cpu_caps], CAPS_MTRR
jnc .exit
 
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
mov ecx, 0x2FF
rdmsr ;
mov ecx, 0x2FF
rdmsr ;
; has BIOS already initialized MTRRs?
test ah, 8
jnz .skip_init
test ah, 8
jnz .skip_init
; rarely needed, so mainly placeholder
; main memory - cached
push eax
push eax
 
mov eax, [MEM_AMOUNT]
mov eax, [MEM_AMOUNT]
; round eax up to next power of 2
dec eax
bsr ecx, eax
mov ebx, 2
shl ebx, cl
dec ebx
dec eax
bsr ecx, eax
mov ebx, 2
shl ebx, cl
dec ebx
; base of memory range = 0, type of memory range = MEM_WB
xor edx, edx
mov eax, MEM_WB
mov ecx, 0x200
wrmsr
xor edx, edx
mov eax, MEM_WB
mov ecx, 0x200
wrmsr
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
; clear unused MTRRs
xor eax, eax
xor edx, edx
xor eax, eax
xor edx, edx
@@:
wrmsr
inc ecx
cmp ecx, 0x210
jb @b
wrmsr
inc ecx
cmp ecx, 0x210
jb @b
; enable MTRRs
pop eax
or ah, 8
and al, 0xF0 ; default memtype = UC
mov ecx, 0x2FF
wrmsr
pop eax
or ah, 8
and al, 0xF0; default memtype = UC
mov ecx, 0x2FF
wrmsr
.skip_init:
stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
stdcall set_mtrr, [LFBAddress], [LFBSize], MEM_WC
 
wbinvd ;again invalidate
wbinvd ;again invalidate
 
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
ret
endp
 
align 4
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
mov ecx, 0x201
@@:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0 ; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
; no free registers, ignore the call
.ret:
ret
ret
.found:
; found, write values
xor edx, edx
mov eax, [base]
or eax, [mem_type]
wrmsr
xor edx, edx
mov eax, [base]
or eax, [mem_type]
wrmsr
 
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x00000000
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x00000000
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
endp
 
align 4
proc stall stdcall, delay:dword
push ecx
push edx
push ebx
push eax
push ecx
push edx
push ebx
push eax
 
mov eax, [delay]
mul [stall_mcs]
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx,edx
mov eax, [delay]
mul [stall_mcs]
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx, edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
jb @B
rdtsc
sub eax, ebx
sbb edx, ecx
jb @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
align 4
1468,56 → 1490,56
buf_ptr dd ?
endl
 
mov eax, [size]
test eax, eax
jz .fail
mov eax, [size]
test eax, eax
jz .fail
 
add eax, eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
add eax, eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
 
push ebx
push ebx
 
mov [buf_ptr], eax
mov [buf_ptr], eax
 
mov ebx, [size]
shr ebx, 12
push ebx
mov ebx, [size]
shr ebx, 12
push ebx
 
stdcall alloc_pages, ebx
pop ecx
stdcall alloc_pages, ebx
pop ecx
 
test eax, eax
jz .mm_fail
test eax, eax
jz .mm_fail
 
push edi
push edi
 
or eax, [flags]
mov edi, [buf_ptr]
mov ebx, [buf_ptr]
mov edx, ecx
shl edx, 2
shr edi, 10
or eax, [flags]
mov edi, [buf_ptr]
mov ebx, [buf_ptr]
mov edx, ecx
shl edx, 2
shr edi, 10
@@:
mov [page_tabs+edi], eax
mov [page_tabs+edi+edx], eax
invlpg [ebx]
invlpg [ebx+0x10000]
add eax, 0x1000
add ebx, 0x1000
add edi, 4
dec ecx
jnz @B
mov [page_tabs+edi], eax
mov [page_tabs+edi+edx], eax
invlpg [ebx]
invlpg [ebx+0x10000]
add eax, 0x1000
add ebx, 0x1000
add edi, 4
dec ecx
jnz @B
 
mov eax, [buf_ptr]
pop edi
pop ebx
ret
mov eax, [buf_ptr]
pop edi
pop ebx
ret
.mm_fail:
stdcall free_kernel_space, [buf_ptr]
xor eax, eax
pop ebx
stdcall free_kernel_space, [buf_ptr]
xor eax, eax
pop ebx
.fail:
ret
ret
endp
/kernel/branches/net/core/peload.inc
18,34 → 18,34
base dd ?
endl
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [image], eax
mov [image], eax
 
mov edx, [eax+60]
mov edx, [eax+60]
 
stdcall kernel_alloc, [eax+80+edx]
test eax, eax
jz .cleanup
stdcall kernel_alloc, [eax+80+edx]
test eax, eax
jz .cleanup
 
mov [base], eax
mov [base], eax
 
stdcall map_PE, eax, [image]
stdcall map_PE, eax, [image]
 
mov [entry], eax
test eax, eax
jnz .cleanup
mov [entry], eax
test eax, eax
jnz .cleanup
 
stdcall kernel_free, [base]
stdcall kernel_free, [base]
.cleanup:
stdcall kernel_free, [image]
mov eax, [entry]
ret
stdcall kernel_free, [image]
mov eax, [entry]
ret
.fail:
xor eax, eax
ret
xor eax, eax
ret
endp
 
DWORD equ dword
53,227 → 53,227
 
align 4
map_PE: ;stdcall base:dword, image:dword
cld
cld
push ebp
push edi
push esi
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
push edi
push esi
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
 
shr ecx, 2
rep movsd
shr ecx, 2
rep movsd
 
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
L3:
mov eax, DWORD PTR [edx+264]
test eax, eax
je L4
mov esi, ebx
mov edi, ebp
add esi, DWORD PTR [edx+268]
mov ecx, eax
add edi, DWORD PTR [edx+260]
mov eax, DWORD PTR [edx+264]
test eax, eax
je L4
mov esi, ebx
mov edi, ebp
add esi, DWORD PTR [edx+268]
mov ecx, eax
add edi, DWORD PTR [edx+260]
 
shr ecx, 2
rep movsd
shr ecx, 2
rep movsd
 
L4:
mov ecx, DWORD PTR [edx+256]
add ecx, 4095
and ecx, -4096
cmp ecx, eax
jbe L6
sub ecx, eax
add eax, DWORD PTR [edx+260]
lea edi, [eax+ebp]
mov ecx, DWORD PTR [edx+256]
add ecx, 4095
and ecx, -4096
cmp ecx, eax
jbe L6
sub ecx, eax
add eax, DWORD PTR [edx+260]
lea edi, [eax+ebp]
 
xor eax, eax
rep stosb
xor eax, eax
rep stosb
 
L6:
inc DWORD PTR [esp+36]
add edx, 40
inc DWORD PTR [esp+36]
add edx, 40
L2:
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
mov esi, ebp
mov ecx, ebp
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+12], eax
jmp L11
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
mov esi, ebp
mov ecx, ebp
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+12], eax
jmp L11
L12:
lea ebx, [eax-8]
xor edi, edi
shr ebx,1
jmp L13
lea ebx, [eax-8]
xor edi, edi
shr ebx, 1
jmp L13
L14:
movzx eax, WORD PTR [ecx+8+edi*2]
mov edx, eax
shr eax, 12
and edx, 4095
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+12]
add WORD PTR [edx+ebp], ax
movzx eax, WORD PTR [ecx+8+edi*2]
mov edx, eax
shr eax, 12
and edx, 4095
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+12]
add WORD PTR [edx+ebp], ax
L17:
add WORD PTR [edx+ebp], si
add WORD PTR [edx+ebp], si
L18:
add DWORD PTR [edx+ebp], esi
add DWORD PTR [edx+ebp], esi
L15:
inc edi
inc edi
L13:
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
L11:
mov eax, DWORD PTR [ecx+4]
test eax, eax
jne L12
mov eax, DWORD PTR [ecx+4]
test eax, eax
jne L12
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
mov DWORD PTR [esp+52], 0
add ecx, ebp
add edx, ebp
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
mov DWORD PTR [esp+52], 0
add ecx, ebp
add edx, ebp
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
L26:
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
test eax, eax
je L27
test eax, eax
js L27
lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
lea esi, [edi+2]
push eax
push 32
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
test eax, eax
je L27
test eax, eax
js L27
lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
lea esi, [edi+2]
push eax
push 32
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop ebx
xor ebx, ebx
test eax, eax
jne L32
jmp L30
push eax
push esi
call strncmp
pop ebx
xor ebx, ebx
test eax, eax
jne L32
jmp L30
L33:
push ecx
push 32
mov ecx, DWORD PTR [esp+28]
push ecx
push 32
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop edx
test eax, eax
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
push eax
push esi
call strncmp
pop edx
test eax, eax
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
inc ebx
inc ebx
L32:
cmp ebx, DWORD PTR [__exports+24]
jb L33
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
jne L37
 
mov esi, msg_unresolved
call sys_msg_board_str
lea esi, [edi+2]
lea esi, [edi+2]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov DWORD PTR [esp+40], 1
jmp L37
mov DWORD PTR [esp+40], 1
jmp L37
L30:
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
add eax, OS_BASE
mov DWORD PTR [edx+edi*4], eax
mov DWORD PTR [edx+edi*4], eax
L37:
inc DWORD PTR [esp+52]
jmp L26
inc DWORD PTR [esp+52]
jmp L26
L27:
add DWORD PTR [esp+56], 20
jmp L22
add DWORD PTR [esp+56], 20
jmp L22
L25:
xor eax, eax
cmp DWORD PTR [esp+40], 0
jne L40
xor eax, eax
cmp DWORD PTR [esp+40], 0
jne L40
L20:
mov ecx, DWORD PTR [esp+32]
mov eax, ebp
add eax, DWORD PTR [ecx+40]
mov ecx, DWORD PTR [esp+32]
mov eax, ebp
add eax, DWORD PTR [ecx+40]
L40:
add esp, 60
pop ebx
pop esi
pop edi
pop ebp
add esp, 60
pop ebx
pop esi
pop edi
pop ebp
ret 8
 
align 16
283,10 → 283,18
alloc_page, 'AllocPage', \ ; gcc ABI
alloc_pages, 'AllocPages', \ ; stdcall
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
\
create_event, 'CreateEvent', \ ; ecx, esi
destroy_event, 'DestroyEvent', \ ;
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi
wait_event, 'WaitEvent', \ ; eax, ebx
get_event_ex, 'GetEvent', \ ; edi
\
create_kernel_object, 'CreateObject', \
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
destroy_kernel_object, 'DestroyObject', \
free_kernel_space, 'FreeKernelSpace', \ ; stdcall
free_page, 'FreePage', \ ; eax
kernel_alloc, 'KernelAlloc', \ ; stdcall
kernel_free, 'KernelFree', \ ; stdcall
malloc, 'Kmalloc', \
294,9 → 302,14
map_io_mem, 'MapIoMem', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
\
get_display, 'GetDisplay', \
set_screen, 'SetScreen', \
pci_api, 'PciApi', \
window._.get_rect, 'GetWindowRect', \ ; gcc fastcall
pci_api_drv, 'PciApi', \
pci_read8, 'PciRead8', \ ; stdcall
pci_read16, 'PciRead16', \ ; stdcall
pci_read32, 'PciRead32', \ ; stdcall
304,6 → 317,7
pci_write16, 'PciWrite16', \ ; stdcall
pci_write32, 'PciWrite32', \ ; stdcall
\
get_pid, 'GetPid', \
get_service, 'GetService', \ ;
reg_service, 'RegService', \ ; stdcall
attach_int_handler, 'AttachIntHandler', \ ; stdcall
311,8 → 325,12
user_free, 'UserFree', \ ; stdcall
unmap_pages, 'UnmapPages', \ ; eax, ecx
sys_msg_board_str, 'SysMsgBoardStr', \
get_timer_ticks, 'GetTimerTicks', \
get_stack_base, 'GetStackBase', \
delay_hs, 'Delay', \ ; ebx
set_mouse_data, 'SetMouseData'
set_mouse_data, 'SetMouseData', \ ;
set_keyboard_data, 'SetKeyboardData', \ ; gcc fastcall
timer_hs, 'TimerHs' ; stdcall
 
 
 
/kernel/branches/net/core/sched.inc
21,14 → 21,14
inc [timer_ticks]
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
sub eax,[next_usage_update]
cmp eax,100
sub eax, [next_usage_update]
cmp eax, 100
jb .nocounter
add [next_usage_update],100
add [next_usage_update], 100
call updatecputimes
.nocounter:
mov al,0x20 ; send End Of Interrupt signal
out 0x20,al
xor ecx, ecx ; send End Of Interrupt signal
call irq_eoi
btr dword[DONT_SWITCH], 0
jc .return
call find_next_task
60,7 → 60,8
end if
call find_next_task
jz .return ; the same task -> skip switch
@@: mov byte[DONT_SWITCH], 1
@@:
mov byte[DONT_SWITCH], 1
call do_change_task
.return:
popad
88,16 → 89,16
ret
align 4
updatecputimes:
xor eax,eax
xchg eax,[idleuse]
mov [idleusesec],eax
xor eax, eax
xchg eax, [idleuse]
mov [idleusesec], eax
mov ecx, [TASK_COUNT]
mov edi, TASK_DATA
.newupdate:
xor eax,eax
xchg eax,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],eax
add edi,0x20
xor eax, eax
xchg eax, [edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage], eax
add edi, 0x20
loop .newupdate
ret
 
117,12 → 118,13
call update_counters ; edi := [TASK_BASE]
Mov esi, ebx, [current_slot]
.loop:
cmp bh,[TASK_COUNT]
cmp bh, [TASK_COUNT]
jb @f
xor bh, bh
mov edi,CURRENT_TASK
@@: inc bh ; ebx += APPDATA.size
add edi,0x20 ; edi += TASKDATA.size
mov edi, CURRENT_TASK
@@:
inc bh ; ebx += APPDATA.size
add edi, 0x20; edi += TASKDATA.size
mov al, [edi+TASKDATA.state]
test al, al
jz .found ; state == 0
131,9 → 133,9
; state == 5
pushad ; more freedom for [APPDATA.wait_test]
call [ebx+APPDATA.wait_test]
mov [esp+28],eax
mov [esp+28], eax
popad
or eax,eax
or eax, eax
jnz @f
; testing for timeout
mov ecx, [timer_ticks]
140,13 → 142,14
sub ecx, [ebx+APPDATA.wait_begin]
cmp ecx, [ebx+APPDATA.wait_timeout]
jb .loop
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait
@@:
mov [ebx+APPDATA.wait_param], eax ; retval for wait
mov [edi+TASKDATA.state], 0
.found:
mov [CURRENT_TASK],bh
mov [TASK_BASE],edi
mov [CURRENT_TASK], bh
mov [TASK_BASE], edi
rdtsc ;call _rdtsc
mov [edi+TASKDATA.counter_add],eax ; for next using update_counters
mov [edi+TASKDATA.counter_add], eax; for next using update_counters
cmp ebx, esi ;esi - previous slot-base
ret
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
160,8 → 163,8
; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
; [current_slot] is the outcoming (old), and set here to a new value (ebx)
;scratched: eax,ecx,esi
mov esi,ebx
xchg esi,[current_slot]
mov esi, ebx
xchg esi, [current_slot]
; set new stack after saving old
mov [esi+APPDATA.saved_esp], esp
mov esp, [ebx+APPDATA.saved_esp]
179,17 → 182,17
 
Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
 
mov edx, [ebx+APPDATA.tls_base]
cmp edx, [esi+APPDATA.tls_base]
je @f
mov edx, [ebx+APPDATA.tls_base]
cmp edx, [esi+APPDATA.tls_base]
je @f
 
mov [tls_data_l+2],dx
shr edx,16
mov [tls_data_l+4],dl
mov [tls_data_l+7],dh
mov [tls_data_l+2], dx
shr edx, 16
mov [tls_data_l+4], dl
mov [tls_data_l+7], dh
 
mov dx, app_tls
mov fs, dx
mov dx, app_tls
mov fs, dx
@@:
; set gs selector unconditionally
Mov gs,ax,graph_data
207,17 → 210,103
jz @f
xor eax, eax
mov dr6, eax
lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
lea esi, [ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table];offset>0x7F
cld
macro lodsReg [reg] {
lodsd
mov reg,eax
mov reg, eax
} lodsReg dr0, dr1, dr2, dr3, dr7
purge lodsReg
@@: ret
@@:
ret
;end.
 
 
 
struct MUTEX_WAITER
list LHEAD
task dd ?
ends
 
;void __fastcall mutex_init(struct mutex *lock)
 
align 4
mutex_init:
mov [ecx+MUTEX.lhead.next], ecx
mov [ecx+MUTEX.lhead.prev], ecx
mov [ecx+MUTEX.count], 1
ret
 
 
;void __fastcall mutex_lock(struct mutex *lock)
 
align 4
mutex_lock:
 
dec [ecx+MUTEX.count]
jns .done
 
pushfd
cli
 
sub esp, sizeof.MUTEX_WAITER
 
list_add_tail esp, ecx ;esp= new waiter, ecx= list head
 
mov edx, [TASK_BASE]
mov [esp+MUTEX_WAITER.task], edx
 
.forever:
 
mov eax, -1
xchg eax, [ecx+MUTEX.count]
dec eax
jz @F
 
mov [edx+TASKDATA.state], 1
call change_task
jmp .forever
@@:
mov edx, [esp+MUTEX_WAITER.list.next]
mov eax, [esp+MUTEX_WAITER.list.prev]
 
mov [eax+MUTEX_WAITER.list.next], edx
mov [edx+MUTEX_WAITER.list.prev], eax
cmp [ecx+MUTEX.lhead.next], ecx
jne @F
 
mov [ecx+MUTEX.count], 0
@@:
add esp, sizeof.MUTEX_WAITER
 
popfd
.done:
ret
 
;void __fastcall mutex_unlock(struct mutex *lock)
 
align 4
mutex_unlock:
 
pushfd
cli
 
mov eax, [ecx+MUTEX.lhead.next]
cmp eax, ecx
mov [ecx+MUTEX.count], 1
je @F
 
mov eax, [eax+MUTEX_WAITER.task]
mov [eax+TASKDATA.state], 0
@@:
popfd
ret
 
 
purge MUTEX_WAITER
 
if 0
 
struc TIMER
{
.next dd ?
241,21 → 330,21
align 4
pick_task:
 
xor eax, eax
xor eax, eax
.pick:
mov ebx, [rdy_head+eax*4]
test ebx, ebx
jz .next
mov ebx, [rdy_head+eax*4]
test ebx, ebx
jz .next
 
mov [next_task], ebx
test [ebx+flags.billable]
jz @F
mov [bill_task], ebx
mov [next_task], ebx
test [ebx+flags.billable]
jz @F
mov [bill_task], ebx
@@:
ret
ret
.next:
inc eax
jmp .pick
inc eax
jmp .pick
 
; param
; eax= task
266,46 → 355,46
; ecx= front if 1 or back if 0
align 4
shed:
cmp [eax+.tics_left], 0 ;signed compare
mov ebx, [eax+.priority]
setg ecx
jg @F
cmp [eax+.tics_left], 0;signed compare
mov ebx, [eax+.priority]
setg ecx
jg @F
 
mov edx, [eax+.tics_quantum]
mov [eax+.ticks_left], edx
cmp ebx, (IDLE_PRIORITY-1)
je @F
inc ebx
mov edx, [eax+.tics_quantum]
mov [eax+.ticks_left], edx
cmp ebx, (IDLE_PRIORITY-1)
je @F
inc ebx
@@:
ret
ret
 
; param
; eax= task
align 4
enqueue:
call shed ;eax
cmp [rdy_head+ebx*4],0
jnz @F
call shed;eax
cmp [rdy_head+ebx*4], 0
jnz @F
 
mov [rdy_head+ebx*4], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
jmp .pick
mov [rdy_head+ebx*4], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
jmp .pick
@@:
test ecx, ecx
jz .back
test ecx, ecx
jz .back
 
mov ecx, [rdy_head+ebx*4]
mov [eax+.next_ready], ecx
mov [rdy_head+ebx*4], eax
jmp .pick
mov ecx, [rdy_head+ebx*4]
mov [eax+.next_ready], ecx
mov [rdy_head+ebx*4], eax
jmp .pick
.back:
mov ecx, [rdy_tail+ebx*4]
mov [ecx+.next_ready], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
mov ecx, [rdy_tail+ebx*4]
mov [ecx+.next_ready], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
.pick:
call pick_proc ;select next task
ret
call pick_proc;select next task
ret
 
end if
/kernel/branches/net/core/string.inc
27,162 → 27,162
; Look for the last occurrence a character in a string.
 
proc strncat stdcall, s1:dword, s2:dword, n:dword
push esi
push edi
mov edi, [s1] ; String s1
mov edx, [n] ; Maximum length
push esi
push edi
mov edi, [s1] ; String s1
mov edx, [n] ; Maximum length
 
mov ecx, -1
xor al, al ; Null byte
cld
repne scasb ; Look for the zero byte in s1
dec edi ; Back one up (and clear 'Z' flag)
push edi ; Save end of s1
mov edi, [s2] ; edi = string s2
mov ecx, edx ; Maximum count
repne scasb ; Look for the end of s2
jne @F
inc ecx ; Exclude null byte
mov ecx, -1
xor al, al ; Null byte
cld
repne scasb ; Look for the zero byte in s1
dec edi ; Back one up (and clear 'Z' flag)
push edi ; Save end of s1
mov edi, [s2] ; edi = string s2
mov ecx, edx ; Maximum count
repne scasb ; Look for the end of s2
jne @F
inc ecx ; Exclude null byte
@@:
sub edx, ecx ; Number of bytes in s2
mov ecx, edx
mov esi, [s2] ; esi = string s2
pop edi ; edi = end of string s1
rep movsb ; Copy bytes
stosb ; Add a terminating null
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
sub edx, ecx ; Number of bytes in s2
mov ecx, edx
mov esi, [s2] ; esi = string s2
pop edi ; edi = end of string s1
rep movsb ; Copy bytes
stosb ; Add a terminating null
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
endp
 
align 4
proc strncmp stdcall, s1:dword, s2:dword, n:dword
 
push esi
push edi
mov ecx, [n]
test ecx, ecx ; Max length is zero?
je .done
push esi
push edi
mov ecx, [n]
test ecx, ecx ; Max length is zero?
je .done
 
mov esi, [s1] ; esi = string s1
mov edi, [s2] ; edi = string s2
cld
mov esi, [s1] ; esi = string s1
mov edi, [s2] ; edi = string s2
cld
.compare:
cmpsb ; Compare two bytes
jne .done
cmp byte [esi-1], 0 ; End of string?
je .done
dec ecx ; Length limit reached?
jne .compare
cmpsb ; Compare two bytes
jne .done
cmp byte [esi-1], 0 ; End of string?
je .done
dec ecx ; Length limit reached?
jne .compare
.done:
seta al ; al = (s1 > s2)
setb ah ; ah = (s1 < s2)
sub al, ah
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
pop edi
pop esi
ret
seta al ; al = (s1 > s2)
setb ah ; ah = (s1 < s2)
sub al, ah
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
pop edi
pop esi
ret
endp
 
align 4
proc strncpy stdcall, s1:dword, s2:dword, n:dword
 
push esi
push edi
push esi
push edi
 
mov ecx, [n] ; Maximum length
mov edi, [s2] ; edi = string s2
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cld
repne scasb ; Look for end of s2
sub edx, ecx ; Number of bytes in s2 including null
xchg ecx, edx
mov esi, [s2] ; esi = string s2
mov edi, [s1] ; edi = string s1
rep movsb ; Copy bytes
mov ecx, [n] ; Maximum length
mov edi, [s2] ; edi = string s2
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cld
repne scasb ; Look for end of s2
sub edx, ecx ; Number of bytes in s2 including null
xchg ecx, edx
mov esi, [s2] ; esi = string s2
mov edi, [s1] ; edi = string s1
rep movsb ; Copy bytes
 
mov ecx, edx ; Number of bytes not copied
rep stosb ; strncpy always copies n bytes by null padding
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
mov ecx, edx ; Number of bytes not copied
rep stosb ; strncpy always copies n bytes by null padding
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
endp
 
align 4
proc strnlen stdcall, s:dword, n:dword
 
push edi
mov edi, [s] ; edi = string
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0
cld
repne scasb ; Look for zero
jne @F
inc ecx ; Don't count zero byte
push edi
mov edi, [s] ; edi = string
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0
cld
repne scasb ; Look for zero
jne @F
inc ecx ; Don't count zero byte
@@:
mov eax, edx
sub eax, ecx ; Compute bytes scanned
pop edi
ret
mov eax, edx
sub eax, ecx ; Compute bytes scanned
pop edi
ret
endp
 
align 4
proc strchr stdcall, s:dword, c:dword
push edi
cld
mov edi, [s] ; edi = string
mov edx, 16 ; Look at small chunks of the string
push edi
cld
mov edi, [s] ; edi = string
mov edx, 16 ; Look at small chunks of the string
.next:
shl edx, 1 ; Chunks become bigger each time
mov ecx, edx
xor al, al ; Look for the zero at the end
repne scasb
pushf ; Remember the flags
sub ecx, edx
neg ecx ; Some or all of the chunk
sub edi, ecx ; Step back
mov eax, [c] ; The character to look for
repne scasb
je .found
popf ; Did we find the end of string earlier?
jne .next ; No, try again
xor eax, eax ; Return NULL
pop edi
ret
shl edx, 1 ; Chunks become bigger each time
mov ecx, edx
xor al, al ; Look for the zero at the end
repne scasb
pushf ; Remember the flags
sub ecx, edx
neg ecx ; Some or all of the chunk
sub edi, ecx ; Step back
mov eax, [c] ; The character to look for
repne scasb
je .found
popf ; Did we find the end of string earlier?
jne .next ; No, try again
xor eax, eax ; Return NULL
pop edi
ret
.found:
pop eax ; Get rid of those flags
lea eax, [edi-1] ; Address of byte found
pop edi
ret
pop eax ; Get rid of those flags
lea eax, [edi-1] ; Address of byte found
pop edi
ret
 
endp
 
 
proc strrchr stdcall, s:dword, c:dword
push edi
mov edi, [s] ; edi = string
mov ecx, -1
xor al, al
cld
repne scasb ; Look for the end of the string
not ecx ; -1 - ecx = Length of the string + null
dec edi ; Put edi back on the zero byte
mov eax, [c] ; The character to look for
std ; Downwards search
repne scasb
cld ; Direction bit back to default
jne .fail
lea eax, [edi+1] ; Found it
pop edi
ret
push edi
mov edi, [s] ; edi = string
mov ecx, -1
xor al, al
cld
repne scasb ; Look for the end of the string
not ecx ; -1 - ecx = Length of the string + null
dec edi ; Put edi back on the zero byte
mov eax, [c] ; The character to look for
std ; Downwards search
repne scasb
cld ; Direction bit back to default
jne .fail
lea eax, [edi+1] ; Found it
pop edi
ret
.fail:
xor eax, eax ; Not there
pop edi
ret
xor eax, eax ; Not there
pop edi
ret
endp
 
 
/kernel/branches/net/core/sync.inc
26,34 → 26,34
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
cli
cmp [name], dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
mov [name],eax
pop eax
sti
push eax
mov eax, dword [TASK_BASE+second_base_address]
mov eax, [eax+TASKDATA.pid]
mov [name], eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
mov [name], dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
cmp [name], dword 0
jz ok
xor eax, eax
jmp try_end
ok=$
xor eax,eax
inc eax
xor eax, eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
67,50 → 67,50
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
push eax
mov eax, [TASK_BASE+second_base_address]
mov eax, [eax+TASKDATA.pid]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
cli
cmp [name], dword 0
jz first_wait
cmp [name], eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
mov [name], eax
mov [name+4], dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
inc dword [name+4]
end_wait=$
sti
pop eax
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
dec dword [name+4]
jnz release_end
mov [name], dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[CURRENT_TASK+second_base_address]
mov eax,[eax+TASKDATA.pid]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
mov eax, [CURRENT_TASK+second_base_address]
mov eax, [eax+TASKDATA.pid]
cmp [name], eax
jz ok
cmp [name], 0
jz ok
xor eax, eax
jmp try_end
ok=$
xor eax,eax
inc eax
xor eax, eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
/kernel/branches/net/core/sys32.inc
16,202 → 16,226
 
align 4 ;3A08
build_interrupt_table:
mov edi, idts
mov esi, sys_int
mov ecx, 0x40
mov eax, (10001110b shl 24) + os_code
@@: movsw ;low word of code-entry
stosd ;interrupt gate type : os_code selector
movsw ;high word of code-entry
loop @b
movsd ;copy low dword of trap gate for int 0x40
movsd ;copy high dword of trap gate for int 0x40
lidt [esi]
ret
mov edi, idts
mov esi, sys_int
mov ecx, 0x40
mov eax, (10001110b shl 24) + os_code
@@:
movsw ;low word of code-entry
stosd ;interrupt gate type : os_code selector
movsw ;high word of code-entry
loop @b
movsd ;copy low dword of trap gate for int 0x40
movsd ;copy high dword of trap gate for int 0x40
lidt [esi]
ret
 
iglobal
align 4
sys_int:
;exception handlers addresses (for interrupt gate construction)
dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15
dd e16, e17,e18, e19
times 12 dd unknown_interrupt ;int_20..int_31
dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15
dd e16, e17,e18, e19
times 12 dd unknown_interrupt ;int_20..int_31
 
;interrupt handlers addresses (for interrupt gate construction)
dd irq0, irq_serv.irq_1, irq_serv.irq_2
if USE_COM_IRQ
dd irq_serv.irq_3, irq_serv.irq_4
else
dd p_irq3, p_irq4 ;??? íåñòûêîâêà
end if
dd 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, irq_serv.irq_12, irqD,p_irq14,p_irq15
times 16 dd unknown_interrupt ;int_0x30..int_0x3F
; 0x20 .. 0x2F - IRQ handlers
dd irq0, irq_serv.irq_1, irq_serv.irq_2
dd irq_serv.irq_3, irq_serv.irq_4
dd irq_serv.irq_5, irq_serv.irq_6, irq_serv.irq_7
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10
dd irq_serv.irq_11, irq_serv.irq_12, irqD, irq_serv.irq_14, irq_serv.irq_15
dd irq_serv.irq_16
dd irq_serv.irq_17
dd irq_serv.irq_18
dd irq_serv.irq_19
dd irq_serv.irq_20
dd irq_serv.irq_21
dd irq_serv.irq_22
dd irq_serv.irq_23
 
times 32 - IRQ_RESERVED dd unknown_interrupt
;int_0x40 gate trap (for directly copied)
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
 
idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
dw 2*($-sys_int-4)-1
dd idts ;0x8000B100
dw 0 ;ïðîñòî âûðàâíèâàíèå
dw 2*($-sys_int-4)-1
dd idts ;0x8000B100
dw 0 ;ïðîñòî âûðàâíèâàíèå
 
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b
dd msg_exc_c,msg_exc_d,msg_exc_e
dd msg_exc_c,msg_exc_d,msg_exc_e
 
msg_exc_8 db "Double fault", 0
msg_exc_u db "Undefined Exception", 0
msg_exc_a db "Invalid TSS", 0
msg_exc_b db "Segment not present", 0
msg_exc_c db "Stack fault", 0
msg_exc_d db "General protection fault", 0
msg_exc_e db "Page fault", 0
msg_exc_8 db "Double fault", 0
msg_exc_u db "Undefined Exception", 0
msg_exc_a db "Invalid TSS", 0
msg_exc_b db "Segment not present", 0
msg_exc_c db "Stack fault", 0
msg_exc_d db "General protection fault", 0
msg_exc_e db "Page fault", 0
 
msg_sel_ker db "kernel", 0
msg_sel_app db "application", 0
msg_sel_ker db "kernel", 0
msg_sel_app db "application", 0
 
endg
 
macro save_ring3_context {
pushad
pushad
}
macro restore_ring3_context {
popad
popad
}
macro exc_wo_code [num] {
e#num :
save_ring3_context
mov bl, num
jmp exc_c
} exc_wo_code 0,1,2,3,4,5,6,15,16,19
save_ring3_context
mov bl, num
jmp exc_c
} exc_wo_code 0,1,2,3,4,5,6,15,16,19
 
macro exc_w_code [num] {
e#num :
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
} exc_w_code 8,9,10,11,12,13,17,18
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
} exc_w_code 8,9,10,11,12,13,17,18
 
 
uglobal
pf_err_code dd ?
pf_err_code dd ?
endg
 
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû...
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF
save_ring3_context
mov bl,14
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû...
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF
save_ring3_context
mov bl, 14
 
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM)
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM)
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü)
reg_ss equ esp+0x30
reg_esp3 equ esp+0x2C
reg_eflags equ esp+0x28
reg_cs3 equ esp+0x24
reg_eip equ esp+0x20
reg_ss equ esp+0x30
reg_esp3 equ esp+0x2C
reg_eflags equ esp+0x28
reg_cs3 equ esp+0x24
reg_eip equ esp+0x20
; ýòî ôðýéì îò pushad
reg_eax equ esp+0x1C
reg_ecx equ esp+0x18
reg_edx equ esp+0x14
reg_ebx equ esp+0x10
reg_esp0 equ esp+0x0C
reg_ebp equ esp+0x08
reg_esi equ esp+0x04
reg_edi equ esp+0x00
reg_eax equ esp+0x1C
reg_ecx equ esp+0x18
reg_edx equ esp+0x14
reg_ebx equ esp+0x10
reg_esp0 equ esp+0x0C
reg_ebp equ esp+0x08
reg_esi equ esp+0x04
reg_edi equ esp+0x00
 
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû
cld ; è ïðèâîäèì DF ê ñòàíäàðòó
movzx ebx,bl
mov ax, app_data ;èñêëþ÷åíèå
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ
mov es, ax ;â ðåãèñòðû
cld ; è ïðèâîäèì DF ê ñòàíäàðòó
movzx ebx, bl
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
test byte[reg_eflags+2],2
jnz v86_exc_c
cmp bl,14 ; #PF
jne @f
call page_fault_handler ; SEE: core/memory.inc
@@: mov esi, [current_slot]
btr [esi+APPDATA.except_mask], ebx
jnc @f
mov eax,[esi+APPDATA.exc_handler]
test eax, eax
jnz IRetToUserHook
@@: cli
mov eax, [esi+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
test byte[reg_eflags+2], 2
jnz v86_exc_c
cmp bl, 14 ; #PF
jne @f
call page_fault_handler ; SEE: core/memory.inc
@@:
mov esi, [current_slot]
btr [esi+APPDATA.except_mask], ebx
jnc @f
mov eax, [esi+APPDATA.exc_handler]
test eax, eax
jnz IRetToUserHook
@@:
cli
mov eax, [esi+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
call show_error_parameters ;; only ONE using, inline ???
call show_error_parameters ;; only ONE using, inline ???
;mov edx, [TASK_BASE]
mov [edx + TASKDATA.state], byte 4 ; terminate
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc
mov [edx + TASKDATA.state], byte 4 ; terminate
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
mov ecx,1 ; debug_message code=other_exception
cmp bl,1 ; #DB
jne .notify ; notify debugger and suspend ourself
mov ebx, dr6 ; debug_message data=DR6_image
xor edx, edx
mov dr6, edx
mov edx, dr7
mov cl, not 8
.l1: shl dl,2
jc @f
and bl, cl
@@: sar cl,1
jc .l1
mov cl, 3 ; debug_message code=debug_exception
mov ecx, 1 ; debug_message code=other_exception
cmp bl, 1 ; #DB
jne .notify ; notify debugger and suspend ourself
mov ebx, dr6 ; debug_message data=DR6_image
xor edx, edx
mov dr6, edx
mov edx, dr7
mov cl, not 8
.l1:
shl dl, 2
jc @f
and bl, cl
@@:
sar cl, 1
jc .l1
mov cl, 3 ; debug_message code=debug_exception
.notify:
push ebx ; debug_message data
mov ebx, [TASK_BASE]
push [ebx+TASKDATA.pid] ; PID
push ecx ; debug_message code ((here: ecx==1/3))
mov cl, 12 ; debug_message size
call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
add esp,12
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task ; SEE: core/shed.inc
restore_ring3_context
iretd
push ebx ; debug_message data
mov ebx, [TASK_BASE]
push [ebx+TASKDATA.pid] ; PID
push ecx ; debug_message code ((here: ecx==1/3))
mov cl, 12 ; debug_message size
call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
add esp, 12
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task ; SEE: core/shed.inc
restore_ring3_context
iretd
 
IRetToUserHook:
xchg eax, [reg_eip]
sub dword[reg_esp3], 8
mov edi, [reg_esp3]
stosd
mov [edi], ebx
restore_ring3_context
xchg eax, [reg_eip]
sub dword[reg_esp3], 8
mov edi, [reg_esp3]
stosd
mov [edi], ebx
restore_ring3_context
; simply return control to interrupted process
unknown_interrupt:
iretd
iretd
 
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
; bl - error vector
show_error_parameters:
mov edx,[TASK_BASE] ;not scratched below
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid]
cmp bl, 0x08
jb .l0
cmp bl, 0x0e
jbe .l1
.l0: mov bl, 0x09
.l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4]
DEBUGF 1, "K : %s\n", eax
mov eax, [reg_cs3+4]
mov edi, msg_sel_app
mov ebx, [reg_esp3+4]
cmp eax, app_code
je @f
mov edi, msg_sel_ker
mov ebx, [reg_esp0+4]
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
ret
cmp bl, 0x06
jnz .no_ud
push ebx
mov ebx, ud_user_message
mov ebp, notifyapp
call fs_execute_from_sysdir_param
pop ebx
.no_ud:
mov edx, [TASK_BASE];not scratched below
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid]
cmp bl, 0x08
jb .l0
cmp bl, 0x0e
jbe .l1
.l0:
mov bl, 0x09
.l1:
mov eax, [msg_fault_sel+ebx*4 - 0x08*4]
DEBUGF 1, "K : %s\n", eax
mov eax, [reg_cs3+4]
mov edi, msg_sel_app
mov ebx, [reg_esp3+4]
cmp eax, app_code
je @f
mov edi, msg_sel_ker
mov ebx, [reg_esp0+4]
@@:
DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
ret
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
restore reg_ss
228,186 → 252,40
restore reg_esi
restore reg_edi
 
; irq1 -> hid/keyboard.inc
macro irqh [num] {
p_irq#num :
mov edi, num
jmp irqhandler
}
 
 
 
p_irq6:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 6
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
call fdc_irq
call ready_for_next_irq
restore_ring3_context
iret
 
 
p_irq14:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 14
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq14_func]
call ready_for_next_irq_1
restore_ring3_context
iret
p_irq15:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 15
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq15_func]
call ready_for_next_irq_1
restore_ring3_context
iret
 
ready_for_next_irq:
mov eax,5
mov [check_idle_semaphore],eax
; mov al, 0x20
add eax,(0x20-0x5)
 
out 0x20, al
ret
;destroy eax
ready_for_next_irq_1:
mov eax,5
mov [check_idle_semaphore],eax
; mov al, 0x20
add eax,(0x20-0x5)
out 0xa0,al
out 0x20, al
ret
 
irqD:
push eax
xor eax,eax
out 0xf0,al
mov al,0x20
out 0xa0,al
out 0x20,al
pop eax
iret
 
 
irqh 2,3,4,5,7,8,9,10,11
 
irqhandler:
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,IRQ_SAVE
mov ecx,16
 
irqnewread:
dec ecx
js irqover
 
movzx edx, word [esi] ; 2+
 
test edx, edx ; 1
jz irqover
 
 
mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size
mov eax, 4000 ; + 0x4 dword - data begin offset
cmp ebx, eax
je irqfull
add ebx, [edi + 0x4] ; add data size to data begin offset
cmp ebx, eax ; if end of buffer, begin cycle again
jb @f
 
xor ebx, ebx
 
@@:
add ebx, edi
movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word
dec eax
jz irqbyte
dec eax
jnz noirqword
 
in ax,dx
cmp ebx, 3999 ; check for address odd in the end of buffer
jne .odd
mov [ebx + 0x10], ax
jmp .add_size
.odd:
mov [ebx + 0x10], al ; I could make mistake here :)
mov [edi + 0x10], ah
.add_size:
add dword [edi], 2
jmp nextport
 
 
irqbyte:
in al,dx
mov [ebx + 0x10],al
inc dword [edi]
nextport:
add esi,4
jmp irqnewread
 
 
noirqword:
irqfull:
irqover:
 
ret
 
 
 
align 4
set_application_table_status:
push eax
push eax
 
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
mov eax, [CURRENT_TASK]
shl eax, 5
add eax, CURRENT_TASK+TASKDATA.pid
mov eax, [eax]
 
mov [application_table_status],eax
mov [application_table_status], eax
 
pop eax
pop eax
 
ret
ret
 
 
align 4
clear_application_table_status:
push eax
push eax
 
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
mov eax, [CURRENT_TASK]
shl eax, 5
add eax, CURRENT_TASK+TASKDATA.pid
mov eax, [eax]
 
cmp eax,[application_table_status]
jne apptsl1
xor eax,eax
mov [application_table_status],eax
cmp eax, [application_table_status]
jne apptsl1
xor eax, eax
mov [application_table_status], eax
apptsl1:
 
pop eax
pop eax
 
ret
ret
 
; * eax = 64 - íîìåð ôóíêöèè
; * ebx = 1 - åäèíñòâåííàÿ ïîäôóíêöèÿ
416,423 → 294,407
; * eax = 0 - óñïåøíî
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè
 
align 4
sys_resize_app_memory:
; ebx = 1 - resize
; ecx = new amount of memory
; ebx = 1 - resize
; ecx = new amount of memory
 
; cmp eax,1
dec ebx
jnz .no_application_mem_resize
stdcall new_mem_resize, ecx
mov [esp+32], eax
dec ebx
jnz .no_application_mem_resize
stdcall new_mem_resize, ecx
mov [esp+32], eax
.no_application_mem_resize:
ret
ret
 
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
msg_obj_destroy db 'K : destroy app object',13,10,0
endg
 
; param
; esi= slot
 
align 4
terminate: ; terminate application
 
.slot equ esp ;locals
.slot equ esp ;locals
 
push esi ;save .slot
push esi ;save .slot
 
shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
pop esi
shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret
shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
pop esi
shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret
@@:
;mov esi,process_terminating
;call sys_msg_board_str
;mov esi,process_terminating
;call sys_msg_board_str
@@:
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp @b
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
 
; if the process is in V86 mode...
mov eax, [.slot]
shl eax, 8
mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
add esi, RING0_STACK_SIZE
cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi
jz .nov86
mov eax, [.slot]
shl eax, 8
mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
add esi, RING0_STACK_SIZE
cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi
jz .nov86
; ...it has page directory for V86 mode
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4]
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4]
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
; ...and I/O permission map for V86 mode
mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
.nov86:
 
mov esi, [.slot]
shl esi,8
add esi, SLOT_BASE+APP_OBJ_OFFSET
mov esi, [.slot]
shl esi, 8
add esi, SLOT_BASE+APP_OBJ_OFFSET
@@:
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
 
cmp eax, esi
je @F
cmp eax, esi
je @F
 
push esi
call [eax+APPOBJ.destroy]
DEBUGF 1,"%s",msg_obj_destroy
pop esi
jmp @B
push esi
call [eax+APPOBJ.destroy]
DEBUGF 1,"%s",msg_obj_destroy
pop esi
jmp @B
@@:
 
mov eax, [.slot]
shl eax, 8
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
mov eax, [.slot]
shl eax, 8
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
 
mov esi, [.slot]
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
jne @F
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
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]
fnclex
frstor [eax]
@@:
 
mov [KEY_COUNT],byte 0 ; empty keyboard buffer
mov [BTN_COUNT],byte 0 ; empty button buffer
mov [KEY_COUNT], byte 0 ; empty keyboard buffer
mov [BTN_COUNT], byte 0 ; empty button buffer
 
 
; remove defined hotkeys
mov eax, hotkey_list
mov eax, hotkey_list
.loop:
cmp [eax+8], esi
jnz .cont
mov ecx, [eax]
jecxz @f
push dword [eax+12]
pop dword [ecx+12]
cmp [eax+8], esi
jnz .cont
mov ecx, [eax]
jecxz @f
push dword [eax+12]
pop dword [ecx+12]
@@:
mov ecx, [eax+12]
push dword [eax]
pop dword [ecx]
xor ecx, ecx
mov [eax], ecx
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+12], ecx
mov ecx, [eax+12]
push dword [eax]
pop dword [ecx]
xor ecx, ecx
mov [eax], ecx
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+12], ecx
.cont:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; remove hotkeys in buffer
mov eax, hotkey_buffer
mov eax, hotkey_buffer
.loop2:
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
and dword [eax], 0
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
and dword [eax], 0
.cont2:
add eax, 8
cmp eax, hotkey_buffer+120*8
jb .loop2
add eax, 8
cmp eax, hotkey_buffer+120*8
jb .loop2
 
mov ecx,esi ; remove buttons
mov ecx, esi ; remove buttons
bnewba2:
mov edi,[BTN_ADDR]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
mov edi, [BTN_ADDR]
mov eax, edi
cld
movzx ebx, word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
dec bx
jz bnmba
add eax, 0x10
cmp cx, [eax]
jnz bnewba
pusha
mov ecx, ebx
inc ecx
shl ecx, 4
mov ebx, eax
add eax, 0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
 
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov eax,[esi+WDATA.box.left]
mov [draw_limits.left],eax
add eax,[esi+WDATA.box.width]
mov [draw_limits.right],eax
mov eax,[esi+WDATA.box.top]
mov [draw_limits.top],eax
add eax,[esi+WDATA.box.height]
mov [draw_limits.bottom],eax
pusha ; save window coordinates for window restoring
cld
shl esi, 5
add esi, window_data
mov eax, [esi+WDATA.box.left]
mov [draw_limits.left], eax
add eax, [esi+WDATA.box.width]
mov [draw_limits.right], eax
mov eax, [esi+WDATA.box.top]
mov [draw_limits.top], eax
add eax, [esi+WDATA.box.height]
mov [draw_limits.bottom], eax
 
xor eax, eax
mov [esi+WDATA.box.left],eax
mov [esi+WDATA.box.width],eax
mov [esi+WDATA.box.top],eax
mov [esi+WDATA.box.height],eax
mov [esi+WDATA.cl_workarea],eax
mov [esi+WDATA.cl_titlebar],eax
mov [esi+WDATA.cl_frames],eax
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn
lea edi, [esi-window_data+draw_data]
mov ecx,32/4
rep stosd
popa
xor eax, eax
mov [esi+WDATA.box.left], eax
mov [esi+WDATA.box.width], eax
mov [esi+WDATA.box.top], eax
mov [esi+WDATA.box.height], eax
mov [esi+WDATA.cl_workarea], eax
mov [esi+WDATA.cl_titlebar], eax
mov [esi+WDATA.cl_frames], eax
mov dword [esi+WDATA.reserved], eax; clear all flags: wstate, redraw, wdrawn
lea edi, [esi-window_data+draw_data]
mov ecx, 32/4
rep stosd
popa
 
; debuggee test
pushad
mov edi, esi
shl edi, 5
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID
push 2
call debugger_notify
pop ecx
pop ecx
pushad
mov edi, esi
shl edi, 5
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [CURRENT_TASK+edi+TASKDATA.pid]; PID
push 2
call debugger_notify
pop ecx
pop ecx
.nodebug:
popad
popad
 
mov ebx, [.slot]
shl ebx, 8
push ebx
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack]
mov ebx, [.slot]
shl ebx, 8
push ebx
mov ebx, [SLOT_BASE+ebx+APPDATA.pl0_stack]
 
stdcall kernel_free, ebx
stdcall kernel_free, ebx
 
pop ebx
mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir]
stdcall kernel_free, ebx
pop ebx
mov ebx, [SLOT_BASE+ebx+APPDATA.cur_dir]
stdcall kernel_free, ebx
 
mov edi, [.slot]
shl edi,8
add edi,SLOT_BASE
mov edi, [.slot]
shl edi, 8
add edi, SLOT_BASE
 
mov eax, [edi+APPDATA.io_map]
cmp eax, [SLOT_BASE+256+APPDATA.io_map]
je @F
call free_page
mov eax, [edi+APPDATA.io_map]
cmp eax, [SLOT_BASE+256+APPDATA.io_map]
je @F
call free_page
@@:
mov eax, [edi+APPDATA.io_map+4]
cmp eax, [SLOT_BASE+256+APPDATA.io_map+4]
je @F
call free_page
mov eax, [edi+APPDATA.io_map+4]
cmp eax, [SLOT_BASE+256+APPDATA.io_map+4]
je @F
call free_page
@@:
mov eax, 0x20202020
stosd
stosd
stosd
mov ecx,244/4
xor eax, eax
rep stosd
mov eax, 0x20202020
stosd
stosd
stosd
mov ecx, 244/4
xor eax, eax
rep stosd
 
; activate window
movzx eax, word [WIN_STACK + esi*2]
cmp eax, [TASK_COUNT]
jne .dont_activate
pushad
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, [WIN_POS+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
je .check_next_window
add edi, window_data
dec eax
cmp eax, 1
jbe .nothing_to_activate
lea esi, [WIN_POS+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
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
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .check_next_window
; \end{diamond}
call waredraw
call waredraw
.nothing_to_activate:
popad
popad
.dont_activate:
 
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
call free_hd_channel
and [hd1_status], 0
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
call free_hd_channel
and [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
call free_cd_channel
and [cd_status], 0
cmp [cd_status], esi
jnz @f
call free_cd_channel
and [cd_status], 0
@@:
cmp [flp_status], esi
jnz @f
and [flp_status], 0
cmp [flp_status], esi
jnz @f
and [flp_status], 0
@@:
pop esi
cmp [bgrlockpid], esi
jnz @f
and [bgrlockpid], 0
and [bgrlock], 0
pop esi
cmp [bgrlockpid], esi
jnz @f
and [bgrlockpid], 0
and [bgrlock], 0
@@:
 
pusha ; remove all irq reservations
mov eax,esi
shl eax, 5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov edi,irq_owner
xor ebx, ebx
xor edx, edx
newirqfree:
cmp [edi + 4 * ebx], eax
jne nofreeirq
mov [edi + 4 * ebx], edx ; remove irq reservation
mov [irq_tab + 4 * ebx], edx ; remove irq handler
mov [irq_rights + 4 * ebx], edx ; set access rights to full access
nofreeirq:
inc ebx
cmp ebx, 16
jb newirqfree
popa
pusha ; remove all port reservations
mov edx, esi
shl edx, 5
add edx, CURRENT_TASK
mov edx, [edx+TASKDATA.pid]
 
pusha ; remove all port reservations
mov edx,esi
shl edx, 5
add edx,CURRENT_TASK
mov edx,[edx+TASKDATA.pid]
 
rmpr0:
 
mov esi,[RESERVED_PORTS]
mov esi, [RESERVED_PORTS]
 
test esi,esi
jz rmpr9
test esi, esi
jz rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,RESERVED_PORTS
mov edi, esi
shl edi, 4
add edi, RESERVED_PORTS
 
cmp edx,[edi]
je rmpr4
cmp edx, [edi]
je rmpr4
 
dec esi
jnz rmpr3
dec esi
jnz rmpr3
 
jmp rmpr9
jmp rmpr9
 
rmpr4:
 
mov ecx,256
sub ecx,esi
shl ecx,4
mov ecx, 256
sub ecx, esi
shl ecx, 4
 
mov esi,edi
add esi,16
cld
rep movsb
mov esi, edi
add esi, 16
cld
rep movsb
 
dec dword [RESERVED_PORTS]
dec dword [RESERVED_PORTS]
 
jmp rmpr0
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9
popa
mov edi, esi ; do not run this process slot
shl edi, 5
mov [edi+CURRENT_TASK + TASKDATA.state], byte 9
; debugger test - terminate all debuggees
mov eax, 2
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
mov eax, 2
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
.xd0:
cmp eax, [TASK_COUNT]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ecx
mov ebx, 2
call sys_system
popad
cmp eax, [TASK_COUNT]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ecx
mov ebx, 2
call sys_system
popad
@@:
inc eax
add ecx, 0x100
jmp .xd0
inc eax
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
sti ; .. and life goes on
sti ; .. and life goes on
 
mov eax, [draw_limits.left]
mov ebx, [draw_limits.top]
mov ecx, [draw_limits.right]
mov edx, [draw_limits.bottom]
call calculatescreen
xor eax, eax
xor esi, esi
call redrawscreen
mov eax, [draw_limits.left]
mov ebx, [draw_limits.top]
mov ecx, [draw_limits.right]
mov edx, [draw_limits.bottom]
call calculatescreen
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse
mov [MOUSE_BACKGROUND], byte 0; no mouse background
mov [DONT_DRAW_MOUSE], byte 0; draw mouse
 
and [application_table_status],0
and [application_table_status], 0
;mov esi,process_terminated
;call sys_msg_board_str
 
mov eax, [.slot]
call SOCKET_process_end
 
add esp, 4
ret
add esp, 4
ret
restore .slot
 
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
if lang eq ru
boot_sched_1 db '‘®§¤ ­¨¥ GDT TSS 㪠§ â¥«ï',0
boot_sched_2 db '‘®§¤ ­¨¥ IDT â ¡«¨æë',0
else
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
end if
endg
 
 
build_scheduler:
 
mov esi,boot_sched_1
call boot_log
mov esi, boot_sched_1
call boot_log
; call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
 
ret
ret
/kernel/branches/net/core/syscall.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10,15 → 10,16
; Old style system call converter
align 16
cross_order:
; load all registers in crossed order
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
movzx edi, byte[esp+28 + 4]
call dword [servetable+edi*4]
ret
; load all registers in crossed order
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
movzx edi, byte[esp+28 + 4]
sub edi, 53
call dword [servetable+edi*4]
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
28,28 → 29,28
 
align 32
sysenter_entry:
; Íàñòðàèâàåì ñòåê
mov esp, [ss:tss._esp0]
sti
push ebp ; save app esp + 4
mov ebp, [ebp] ; ebp - original ebp
;------------------
pushad
cld
; Íàñòðàèâàåì ñòåê
mov esp, [ss:tss._esp0]
sti
push ebp ; save app esp + 4
mov ebp, [ebp] ; ebp - original ebp
;------------------
pushad
cld
 
movzx eax, al
call dword [servetable2 + eax * 4]
movzx eax, al
call dword [servetable2 + eax * 4]
 
popad
;------------------
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4
sub ecx, 4
xchg edx, [ecx] ; edx - return point, & save original edx
push edx
mov edx, [ss:esp + 4]
mov [ecx + 4], edx ; save original ecx
pop edx
sysexit
popad
;------------------
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4
sub ecx, 4
xchg edx, [ecx] ; edx - return point, & save original edx
push edx
mov edx, [ss:esp + 4]
mov [ecx + 4], edx ; save original ecx
pop edx
sysexit
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
59,12 → 60,12
 
align 16
i40:
pushad
cld
movzx eax, al
call dword [servetable2 + eax * 4]
popad
iretd
pushad
cld
movzx eax, al
call dword [servetable2 + eax * 4]
popad
iretd
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
74,25 → 75,25
align 32
syscall_entry:
; cli syscall clear IF
xchg esp, [ss:tss._esp0]
push ecx
lea ecx, [esp+4]
xchg ecx, [ss:tss._esp0]
sti
push ecx
mov ecx, [ecx]
;------------------
pushad
cld
xchg esp, [ss:tss._esp0]
push ecx
lea ecx, [esp+4]
xchg ecx, [ss:tss._esp0]
sti
push ecx
mov ecx, [ecx]
;------------------
pushad
cld
 
movzx eax, al
call dword [servetable2 + eax * 4]
movzx eax, al
call dword [servetable2 + eax * 4]
 
popad
;------------------
mov ecx, [ss:esp+4]
pop esp
sysret
popad
;------------------
mov ecx, [ss:esp+4]
pop esp
sysret
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
101,78 → 102,17
 
align 4
servetable:
 
dd 0
dd 0
dd 0
dd 0
dd 0
dd file_system ; 58-Common file system interface
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd sound_interface ; 55-Sound interface
dd 0
dd 0
dd file_system ; 58-Common file system interface
dd 0
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 0
dd syscall_putimage_palette; 65-PutImagePalette
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd 0
dd 0
dd file_system_lfn ; 70-Common file system interface, version 2
dd 0 ; 62-PCI functions
dd sys_msg_board ; 63-System message board
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NEW SYSTEM FUNCTIONS TABLE ;;
180,84 → 120,84
align 4
servetable2:
 
dd sys_drawwindow ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_draw_window ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd syscall_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd sys_system ; 18-System Services
dd paleholder ; 19-reserved
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd syscall_putimage ; 7-PutImage
dd syscall_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd sys_system ; 18-System Services
dd paleholder ; 19-reserved
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd undefined_syscall ; 25-reserved
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd undefined_syscall ; 27-reserved
dd undefined_syscall ; 28-reserved
dd sys_date ; 29-GetDate
dd sys_current_directory ; 30-Get/SetCurrentDirectory
dd undefined_syscall ; 31-reserved
dd undefined_syscall ; 32-reserved
dd undefined_syscall ; 33-reserved
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_getarea ; 36-GetArea
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd undefined_syscall ; 25-reserved
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd undefined_syscall ; 27-reserved
dd undefined_syscall ; 28-reserved
dd sys_date ; 29-GetDate
dd sys_current_directory ; 30-Get/SetCurrentDirectory
dd undefined_syscall ; 31-reserved
dd undefined_syscall ; 32-reserved
dd undefined_syscall ; 33-reserved
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_getarea ; 36-GetArea
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd undefined_syscall ; 41- deprecated GetIrqOwner
dd undefined_syscall ; 42- deprecated ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd undefined_syscall ; 44- deprecated ProgramIrqs
dd undefined_syscall ; 45- deprecated ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd display_number ; 47-WriteNum
dd syscall_display_settings ; 48-SetRedrawType and SetButtonType
dd sys_apm ; 49-Advanced Power Management (APM)
dd sys_apm ; 49-Advanced Power Management (APM)
dd syscall_set_window_shape ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd undefined_syscall ; 52-Stack driver status
dd undefined_syscall ; 53-Socket interface
dd undefined_syscall ; 54-reserved
dd cross_order ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd sys_pcibios ; 57-PCI BIOS32
dd cross_order ; 58-Common file system interface
dd undefined_syscall ; 59-reserved
dd cross_order ; 60-Inter Process Communication
dd cross_order ; 61-Direct graphics access
dd cross_order ; 62-PCI functions
dd cross_order ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd cross_order ; 65-PutImagePalette
dd cross_order ; 66-Process definitions - keyboard
dd cross_order ; 67-Window move or resize
dd f68 ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd cross_order ; 70-Common file system interface, version 2
dd syscall_windowsettings ; 71-Window settings
dd sys_sendwindowmsg ; 72-Send window message
dd undefined_syscall ; 73-reserved for blitter
dd sys_network ; 74-Network stack
dd sys_socket ; 75-Sockets
dd sys_protocols ; 76-Protocols
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall
dd sys_end ; -1-end application
dd syscall_threads ; 51-Threads
dd undefined_syscall ; 52 old network stack
dd undefined_syscall ; 53 old network stack
dd undefined_syscall ; 54-reserved
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd sys_pcibios ; 57-PCI BIOS32
dd cross_order ; 58-Common file system interface
dd undefined_syscall ; 59-reserved
dd sys_IPC ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd pci_api ;cross_order ; 62-PCI functions
dd cross_order ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd sys_putimage_palette ; 65-PutImagePalette
dd sys_process_def ; 66-Process definitions - keyboard
dd syscall_move_window ; 67-Window move or resize
dd f68 ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_window_settings ; 71-Window settings
dd sys_sendwindowmsg ; 72-Send window message
dd blit_32 ; 73-blitter;
dd sys_network ; 74-Network stack
dd sys_socket ; 75-Sockets
dd sys_protocols ; 76-Protocols
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall
dd sys_end ; -1-end application
 
endg
/kernel/branches/net/core/taskman.inc
41,15 → 41,16
 
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
xor eax, eax
cld
rep stosd
}
 
fs_execute_from_sysdir:
xor ebx, ebx
xor edx, edx
mov esi, sysdir_path
xor ebx, ebx
fs_execute_from_sysdir_param:
xor edx, edx
mov esi, sysdir_path
 
align 4
proc fs_execute
80,177 → 81,174
hdr_i_end dd ? ;0x14
endl
 
pushad
pushad
 
mov [flags], edx
mov [flags], edx
 
; [ebp] pointer to filename
 
lea edi, [filename]
lea ecx, [edi+1024]
mov al, '/'
stosb
lea edi, [filename]
lea ecx, [edi+1024]
mov al, '/'
stosb
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
mov esi, [ebp]
test esi, esi
jz .namecopied
mov byte [edi-1], '/'
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
mov esi, [ebp]
test esi, esi
jz .namecopied
mov byte [edi-1], '/'
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
jmp .namecopied
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
jmp .namecopied
.bigfilename:
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
 
.namecopied:
 
mov [cmdline], ebx
test ebx, ebx
jz @F
mov [cmdline], ebx
test ebx, ebx
jz @F
 
lea eax, [cmdline]
mov dword [eax+252], 0
stdcall strncpy, eax, ebx, 255
lea eax, [cmdline]
mov dword [eax+252], 0
stdcall strncpy, eax, ebx, 255
@@:
lea eax, [filename]
stdcall load_file, eax
mov ecx, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
lea eax, [filename]
stdcall load_file, eax
mov esi, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
 
mov [file_base], eax
mov [file_size], ebx
mov [file_base], eax
mov [file_size], ebx
 
lea ebx, [hdr_cmdline]
call test_app_header
mov ecx, -0x1F
test eax, eax
jz .err_hdr
lea ebx, [hdr_cmdline]
call test_app_header
mov esi, -0x1F
test eax, eax
jz .err_hdr
 
;mov esi, new_process_loading
;call sys_msg_board_str ; write message to message board
 
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
cmp [application_table_status], 0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
test eax, eax
jnz .wait_lock
mov eax, 1
xchg eax, [application_table_status]
test eax, eax
jnz .wait_lock
 
call set_application_table_status
call set_application_table_status
 
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
call get_new_process_place
test eax, eax
mov esi, -0x20 ; too many processes
jz .err
 
mov [slot], eax
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
mov [slot], eax
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
_clear_ 256 ;clean extended information about process
 
; write application name
lea eax, [filename]
stdcall strrchr, eax, '/' ; now eax points to name without path
lea eax, [filename]
stdcall strrchr, eax, '/' ; now eax points to name without path
 
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
@@:
mov ecx, 8 ; 8 chars for name
mov edi, [slot_base]
mov ecx, 8; 8 chars for name
mov edi, [slot_base]
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
 
mov ebx, cr3
mov [save_cr3], ebx
mov ebx, cr3
mov [save_cr3], ebx
 
stdcall create_app_space,[hdr_mem],[file_base],[file_size]
mov ecx, -30 ; no memory
test eax, eax
jz .failed
stdcall create_app_space, [hdr_mem], [file_base], [file_size]
mov esi, -30; no memory
test eax, eax
jz .failed
 
mov ebx,[slot_base]
mov [ebx+APPDATA.dir_table],eax
mov eax,[hdr_mem]
mov [ebx+APPDATA.mem_size],eax
mov ebx, [slot_base]
mov [ebx+APPDATA.dir_table], eax
mov eax, [hdr_mem]
mov [ebx+APPDATA.mem_size], eax
 
xor edx, edx
cmp word [6], '02'
jne @f
xor edx, edx
cmp word [6], '02'
jne @f
 
not edx
not edx
@@:
mov [ebx+APPDATA.tls_base],edx
mov [ebx+APPDATA.tls_base], edx
 
if GREEDY_KERNEL
else
mov ecx, [hdr_mem]
mov edi, [file_size]
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
mov ecx, [hdr_mem]
mov edi, [file_size]
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
 
xor eax, eax
cld
rep stosb
xor eax, eax
cld
rep stosb
@@:
end if
 
; release only virtual space, not phisical memory
 
stdcall free_kernel_space, [file_base]
lea eax, [hdr_cmdline]
lea ebx, [cmdline]
lea ecx, [filename]
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags]
stdcall free_kernel_space, [file_base]
lea eax, [hdr_cmdline]
lea ebx, [cmdline]
lea ecx, [filename]
stdcall set_app_params , [slot], eax, ebx, ecx, [flags]
 
mov eax, [save_cr3]
call set_cr3
mov eax, [save_cr3]
call set_cr3
 
xor ebx, ebx
mov [application_table_status],ebx ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
xor ebx, ebx
mov [application_table_status], ebx;unlock application_table_status mutex
mov eax, [process_number];set result
ret
.failed:
mov eax, [save_cr3]
call set_cr3
mov eax, [save_cr3]
call set_cr3
.err:
.err_hdr:
stdcall kernel_free,[file_base]
stdcall kernel_free, [file_base]
.err_file:
xor eax, eax
mov [application_table_status],eax
mov eax, ecx
ret
xor eax, eax
mov [application_table_status], eax
mov eax, esi
ret
endp
 
align 4
262,59 → 260,59
APP_HEADER_01 APP_HEADER_01
end virtual
 
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4],'ET'
jne .fail
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4], 'ET'
jne .fail
 
cmp [eax+6], word '00'
jne .check_01_header
cmp [eax+6], word '00'
jne .check_01_header
 
mov ecx,[APP_HEADER_00.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_00.mem_size]
mov [ebx+0x10], edx ;app_mem
shr edx,1
sub edx,0x10
mov [ebx+0x0C], edx ;app_esp
mov ecx,[APP_HEADER_00.i_param]
mov [ebx], ecx ;app_cmdline
mov [ebx+4], dword 0 ;app_path
mov edx, [APP_HEADER_00.i_end]
mov [ebx+0x14], edx
ret
mov ecx, [APP_HEADER_00.start]
mov [ebx+0x08], ecx ;app_eip
mov edx, [APP_HEADER_00.mem_size]
mov [ebx+0x10], edx ;app_mem
shr edx, 1
sub edx, 0x10
mov [ebx+0x0C], edx ;app_esp
mov ecx, [APP_HEADER_00.i_param]
mov [ebx], ecx ;app_cmdline
mov [ebx+4], dword 0 ;app_path
mov edx, [APP_HEADER_00.i_end]
mov [ebx+0x14], edx
ret
 
.check_01_header:
 
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
@@:
mov ecx,[APP_HEADER_01.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_01.mem_size]
mov ecx, [APP_HEADER_01.start]
mov [ebx+0x08], ecx ;app_eip
mov edx, [APP_HEADER_01.mem_size]
 
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx,[APP_HEADER_01.i_end]
jb .fail
cmp edx, [APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
 
mov [ebx+0x10], edx ;app_mem
mov ecx,[APP_HEADER_01.stack_top]
mov [ebx+0x0C], ecx ;app_esp
mov edx,[APP_HEADER_01.i_param]
mov [ebx], edx ;app_cmdline
mov ecx,[APP_HEADER_01.i_icon]
mov [ebx+4], ecx ;app_path
mov edx, [APP_HEADER_01.i_end]
mov [ebx+0x14], edx
ret
mov [ebx+0x10], edx ;app_mem
mov ecx, [APP_HEADER_01.stack_top]
mov [ebx+0x0C], ecx ;app_esp
mov edx, [APP_HEADER_01.i_param]
mov [ebx], edx ;app_cmdline
mov ecx, [APP_HEADER_01.i_icon]
mov [ebx+4], ecx ;app_path
mov edx, [APP_HEADER_01.i_end]
mov [ebx+0x14], edx
ret
.fail:
xor eax, eax
ret
xor eax, eax
ret
 
align 4
proc get_new_process_place
325,29 → 323,29
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax,CURRENT_TASK
mov ebx,[TASK_COUNT]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
mov eax, CURRENT_TASK
mov ebx, [TASK_COUNT]
inc ebx
shl ebx, 5
add ebx, eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
cmp eax, ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax, 0x20
cmp word [eax+0xa], 9;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,CURRENT_TASK
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
ret
mov ebx, eax
sub eax, CURRENT_TASK
shr eax, 5 ;calculate slot index
cmp eax, 256
jge .failed ;it should be <256
mov word [ebx+0xa], 9;set process state to 9 (for slot after hight boundary)
ret
.failed:
xor eax,eax
ret
xor eax, eax
ret
endp
 
align 4
359,239 → 357,242
app_tabs dd ?
endl
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
 
xor eax, eax
mov [dir_addr], eax
xor eax, eax
mov [dir_addr], eax
 
mov eax, [app_size]
add eax, 4095
and eax, NOT(4095)
mov [app_size], eax
mov ebx, eax
shr eax, 12
mov [app_pages], eax
mov eax, [app_size]
add eax, 4095
and eax, NOT(4095)
mov [app_size], eax
mov ebx, eax
shr eax, 12
mov [app_pages], eax
 
add ebx, 0x3FFFFF
and ebx, NOT(0x3FFFFF)
shr ebx, 22
mov [app_tabs], ebx
add ebx, 0x3FFFFF
and ebx, NOT(0x3FFFFF)
shr ebx, 22
mov [app_tabs], ebx
 
mov ecx, [img_size]
add ecx, 4095
and ecx, NOT(4095)
mov ecx, [img_size]
add ecx, 4095
and ecx, NOT(4095)
 
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
 
if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size
else
lea eax, [eax+ebx+2] ;all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
if GREEDY_KERNEL
lea eax, [ecx+ebx+2];only image size
else
lea eax, [eax+ebx+2];all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
 
call alloc_page
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
call alloc_page
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page, [tmp_task_pdir], eax, dword PG_SW
 
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
 
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_pgdir+(OS_BASE shr 20)
rep movsd
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_pgdir+(OS_BASE shr 20)
rep movsd
 
mov eax, [dir_addr]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
mov eax, [dir_addr]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
 
and eax, -4096
call set_cr3
and eax, -4096
call set_cr3
 
mov edx, [app_tabs]
mov edi, new_app_base
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
jz .fail
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
 
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
 
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
 
mov ecx, [img_pages]
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
add edi, page_tabs
mov ecx, [img_pages]
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
add edi, page_tabs
.remap:
lodsd
or eax, ebx ; force user level r/w access
stosd
add edx, 0x1000
dec [app_pages]
dec ecx
jnz .remap
lodsd
or eax, ebx; force user level r/w access
stosd
add edx, 0x1000
dec [app_pages]
dec ecx
jnz .remap
 
mov ecx, [app_pages]
test ecx, ecx
jz .done
mov ecx, [app_pages]
test ecx, ecx
jz .done
 
if GREEDY_KERNEL
mov eax, 0x02
rep stosd
mov eax, 0x02
rep stosd
else
 
.alloc:
call alloc_page
test eax, eax
jz .fail
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page,edx,eax,dword PG_UW
add edx, 0x1000
dec [app_pages]
jnz .alloc
stdcall map_page, edx, eax, dword PG_UW
add edx, 0x1000
dec [app_pages]
jnz .alloc
end if
 
.done:
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
stdcall map_page, [tmp_task_pdir], dword 0, dword PG_UNMAP
 
dec [pg_data.pg_mutex]
mov eax, [dir_addr]
ret
mov ecx, pg_data.mutex
call mutex_unlock
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
cmp [dir_addr], 0
je @f
stdcall destroy_app_space, [dir_addr], 0
mov ecx, pg_data.mutex
call mutex_unlock
cmp [dir_addr], 0
je @f
stdcall destroy_app_space, [dir_addr], 0
@@:
xor eax, eax
ret
xor eax, eax
ret
endp
 
align 4
set_cr3:
 
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], eax
mov cr3, eax
ret
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], eax
mov cr3, eax
ret
 
align 4
proc destroy_page_table stdcall, pg_tab:dword
 
push esi
push esi
 
mov esi, [pg_tab]
mov ecx, 1024
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
mov eax, [esi]
test eax, 1
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
 
align 4
proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
 
xor edx,edx
push edx
mov eax,0x2
mov ebx, [pg_dir]
xor edx, edx
push edx
mov eax, 0x2
mov ebx, [pg_dir]
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
jz @f ;skip empty slots
shl ecx,3
add ecx,SLOT_BASE
cmp [ecx+APPDATA.dir_table],ebx ;compare page directory addresses
jnz @f
mov [ebp-4],ecx
inc edx ;thread found
mov ecx, eax
shl ecx, 5
cmp byte [CURRENT_TASK+ecx+0xa], 9;if process running?
jz @f ;skip empty slots
shl ecx, 3
add ecx, SLOT_BASE
cmp [ecx+APPDATA.dir_table], ebx;compare page directory addresses
jnz @f
mov [ebp-4], ecx
inc edx ;thread found
@@:
inc eax
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes
jle .loop
inc eax
cmp eax, [TASK_COUNT] ;exit loop if we look through all processes
jle .loop
 
;edx = number of threads
;our process is zombi so it isn't counted
pop ecx
cmp edx,1
jg .ret
pop ecx
cmp edx, 1
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls
mov esi, [dlls_list]
call destroy_all_hdlls;ecx=APPDATA
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
 
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page,[tmp_task_pdir],eax,PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page, [tmp_task_pdir], eax, PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page,[tmp_task_ptab],eax,PG_SW
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page, [tmp_task_ptab], eax, PG_SW
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
add esi, 4
dec edi
jnz .destroy
 
mov eax, [pg_dir]
call free_page
mov eax, [pg_dir]
call free_page
.exit:
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
dec [pg_data.pg_mutex]
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
stdcall map_page, [tmp_task_pdir], 0, PG_UNMAP
mov ecx, pg_data.mutex
call mutex_unlock
.ret:
ret
ret
endp
 
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
 
pid_to_slot:
;Input:
599,35 → 600,35
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
push ebx
push ecx
mov ebx, [TASK_COUNT]
shl ebx, 5
mov ecx, 2*32
 
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
cmp byte [CURRENT_TASK+ecx+0xa], 9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4], eax;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
add ecx, 32
cmp ecx, ebx
jle .loop
 
pop ecx
pop ebx
xor eax,eax
ret
pop ecx
pop ebx
xor eax, eax
ret
 
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
shr ecx, 5
mov eax, ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
 
check_region:
;input:
636,7 → 637,7
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[CURRENT_TASK]
mov eax, [CURRENT_TASK]
; jmp check_process_region
;-----------------------------------------------------------------------------
;check_process_region:
648,18 → 649,18
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
 
test edx,edx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[SLOT_BASE+eax+0xb8]
test eax,eax
jz .failed
test edx, edx
jle .ok
shl eax, 5
cmp word [CURRENT_TASK+eax+0xa], 0
jnz .failed
shl eax, 3
mov eax, [SLOT_BASE+eax+0xb8]
test eax, eax
jz .failed
 
mov eax,1
ret
mov eax, 1
ret
 
 
; call MEM_Get_Linear_Address
701,8 → 702,8
; pop ecx
; pop ebx
.ok:
mov eax,1
ret
mov eax, 1
ret
;
;.failed1:
; pop edx
709,8 → 710,8
; pop ecx
; pop ebx
.failed:
xor eax,eax
ret
xor eax, eax
ret
 
align 4
proc read_process_memory
729,57 → 730,57
tmp_r_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ecx
and [r_count], 0
mov [tmp_r_cnt], edx
mov [offset], esi
mov [slot], eax
mov [buff], ecx
and [r_count], 0
mov [tmp_r_cnt], edx
mov [offset], esi
 
pushad
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
mov edx, [offset]
mov ebx, [tmp_r_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
mov ebx, [offset]
 
push ecx
stdcall map_memEx, [proc_mem_map],\
[slot], ebx, ecx, PG_MAP
pop ecx
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_MAP
pop ecx
 
mov esi, [offset]
and esi, 0xfff
sub eax, esi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_r_cnt], eax
mov esi, [offset]
and esi, 0xfff
sub eax, esi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_r_cnt], eax
@@:
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
 
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [r_count]
ret
popad
mov eax, [r_count]
ret
endp
 
align 4
800,57 → 801,57
tmp_w_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ecx
and [w_count], 0
mov [tmp_w_cnt], edx
mov [offset], esi
mov [slot], eax
mov [buff], ecx
and [w_count], 0
mov [tmp_w_cnt], edx
mov [offset], esi
 
pushad
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
mov edx, [offset]
mov ebx, [tmp_w_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
mov ebx, [offset]
; add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[slot], ebx, ecx, PG_SW
pop ecx
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_SW
pop ecx
 
mov edi, [offset]
and edi, 0xfff
sub eax, edi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_w_cnt], eax
mov edi, [offset]
and edi, 0xfff
sub eax, edi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_w_cnt], eax
@@:
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
 
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [w_count]
ret
popad
mov eax, [w_count]
ret
endp
 
align 4
864,129 → 865,111
app_mem dd ? ;0x10
endl
 
cmp ebx,1
jne .failed ;other subfunctions
cmp ebx, 1
jne .failed ;other subfunctions
 
xor eax,eax
mov [app_eip], ecx
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
xor eax, eax
mov [app_eip], ecx
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
;mov esi,new_process_loading
;call sys_msg_board_str
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
cmp [application_table_status], 0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
test eax, eax
jnz .wait_lock
mov eax, 1
xchg eax, [application_table_status]
test eax, eax
jnz .wait_lock
 
call set_application_table_status
call set_application_table_status
 
call get_new_process_place
test eax, eax
jz .failed
call get_new_process_place
test eax, eax
jz .failed
 
mov [slot], eax
mov [slot], eax
 
mov esi,[current_slot]
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov esi, [current_slot]
mov ebx, esi ;ebx=esi - pointer to extended information about current thread
 
mov edi, eax
shl edi,8
add edi,SLOT_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi,ebx
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov edi, eax
shl edi, 8
add edi, SLOT_BASE
mov edx, edi ;edx=edi - pointer to extended infomation about new thread
mov ecx, 256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi, ebx
mov edi, edx
mov ecx, 11
rep movsb ;copy process name
 
mov eax,[ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
mov eax, [ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
 
mov ecx,[ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
mov ecx, [ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
 
mov eax,[ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
mov eax, [ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
 
mov ecx,[ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table],ecx ;copy page directory
mov ecx, [ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table], ecx;copy page directory
 
mov eax,[ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr],eax
mov eax, [ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr], eax
 
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
 
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed1 ;eax=0
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed1;eax=0
@@:
mov [edx+APPDATA.tls_base], eax
mov [edx+APPDATA.tls_base], eax
 
lea eax, [app_cmdline]
stdcall set_app_params ,[slot],eax,dword 0,\
dword 0,dword 0
lea eax, [app_cmdline]
stdcall set_app_params , [slot], eax, dword 0, \
dword 0,dword 0
 
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
xor eax,eax
mov [application_table_status],eax ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
;call sys_msg_board_str ;output information about succefull startup
xor eax, eax
mov [application_table_status], eax ;unlock application_table_status mutex
mov eax, [process_number] ;set result
ret
.failed:
xor eax,eax
xor eax, eax
.failed1:
mov [application_table_status],eax
dec eax ;-1
ret
mov [application_table_status], eax
dec eax ;-1
ret
endp
 
; param
; ebx=mutex
 
align 4
wait_mutex:
;;Maxis use atomic bts for mutex 4.4.2009
push eax
push ebx
.do_wait:
bts dword [ebx],0
jnc .locked
call change_task
jmp .do_wait
.locked:
pop ebx
pop eax
ret
 
align 4
tls_app_entry:
 
call init_heap
call init_heap
stdcall user_alloc, 4096
 
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2],ax
shr eax,16
mov [tls_data_l+4],al
mov [tls_data_l+7],ah
mov dx, app_tls
mov fs, dx
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2], ax
shr eax, 16
mov [tls_data_l+4], al
mov [tls_data_l+7], ah
mov dx, app_tls
mov fs, dx
popad
iretd
 
1005,165 → 988,174
pl0_stack dd ?
endl
 
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [pl0_stack], eax
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [pl0_stack], eax
 
lea edi, [eax+RING0_STACK_SIZE]
lea edi, [eax+RING0_STACK_SIZE]
 
mov eax, [slot]
mov ebx, eax
mov eax, [slot]
mov ebx, eax
 
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
 
;set default io permission map
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [SLOT_BASE+256+APPDATA.io_map+4]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [SLOT_BASE+256+APPDATA.io_map+4]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
 
mov esi, fpu_data
mov ecx, 512/4
rep movsd
mov esi, fpu_data
mov ecx, 512/4
rep movsd
 
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
cmp ebx, [TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx
shl ebx, 8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx], edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx], edx
 
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx], edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx], edx
 
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx], ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx], eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
 
push ebx
stdcall kernel_alloc, 0x1000
pop ebx
mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir]
mov ecx,0x1000/4
mov edi,eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax
rep movsd
push ebx
stdcall kernel_alloc, 0x1000
pop ebx
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov ecx, 0x1000/4
mov edi, eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir], eax
rep movsd
 
shr ebx,3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10],eax
shr ebx, 3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10], eax
 
.add_command_line:
mov edx,[params]
mov edx,[edx] ;app_cmdline
test edx,edx
jz @f ;application doesn't need parameters
mov edx, [params]
mov edx, [edx] ;app_cmdline
test edx, edx
jz @f ;application doesn't need parameters
 
mov eax, edx
add eax, 256
jc @f
mov eax, edx
add eax, 256
jc @f
 
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
 
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
test eax, eax
jz @f
stdcall strncpy, edx, eax, 256
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
test eax, eax
jz @f
stdcall strncpy, edx, eax, 256
@@:
mov edx,[params]
mov edx, [edx+4] ;app_path
test edx,edx
jz @F ;application don't need path of file
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
mov edx, [params]
mov edx, [edx+4];app_path
test edx, edx
jz @F ;application don't need path of file
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data
mov ebx, [slot]
mov eax, ebx
shl ebx, 5
lea ecx, [draw_data+ebx];ecx - pointer to draw data
 
mov edx, irq0.return
cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1
jne @F
mov edx, tls_app_entry
mov edx, irq0.return
cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1
jne @F
mov edx, tls_app_entry
@@:
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx, CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number], al;set window number on screen = process slot
 
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
mov [ebx+TASKDATA.event_mask], dword 1+2+4;set default event flags (see 40 function)
 
inc dword [process_number]
mov eax,[process_number]
mov [ebx+4],eax ;set PID
inc dword [process_number]
mov eax, [process_number]
mov [ebx+4], eax ;set PID
 
;set draw data to full screen
xor eax,eax
mov [ecx+0],dword eax
mov [ecx+4],dword eax
mov eax,[Screen_Max_X]
mov [ecx+8],eax
mov eax,[Screen_Max_Y]
mov [ecx+12],eax
xor eax, eax
mov [ecx+0], dword eax
mov [ecx+4], dword eax
mov eax, [Screen_Max_X]
mov [ecx+8], eax
mov eax, [Screen_Max_Y]
mov [ecx+12], eax
 
mov ebx, [pl0_stack]
mov esi,[params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
mov ebx, [pl0_stack]
mov esi, [params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
 
mov [ebx+REG_RET], edx
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
mov [ebx+REG_RET], edx
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
 
mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax ;app_entry
mov [ebx+REG_CS], dword app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax;app_entry
mov [ebx+REG_CS], dword app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
 
mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax ;app_stack
mov [ebx+REG_SS], dword app_data
mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax;app_stack
mov [ebx+REG_SS], dword app_data
 
lea ecx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx
lea ecx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx
 
xor ecx, ecx ; process state - running
xor ecx, ecx; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
inc ecx ; process state - suspended
mov eax,[CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
test byte [flags], 1
jz .no_debug
inc ecx ; process state - suspended
mov eax, [CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
ret
ret
endp
 
 
align 4
 
get_stack_base:
mov eax, [current_slot]
mov eax, [eax+APPDATA.pl0_stack]
ret
 
 
include "debug.inc"
/kernel/branches/net/core/test_malloc.asm
1,157 → 1,157
; Tests of malloc()/free() from the kernel heap.
; This file is not included in the kernel, it is just test application.
use32
db 'MENUET01'
dd 1, start, i_end, mem, mem, 0, 0
db 'MENUET01'
dd 1, start, i_end, mem, mem, 0, 0
 
start:
; Zero-initialize uglobals (as in kernel at boot)
mov ecx, (zeroend - zerostart + 3) / 4
xor eax, eax
mov edi, zerostart
rep stosd
mov ecx, (zeroend - zerostart + 3) / 4
xor eax, eax
mov edi, zerostart
rep stosd
; Initialize small heap (as in kernel at boot)
call init_malloc
call init_malloc
; Run tests
call run_test1
call run_test2
call run_test3
call run_test1
call run_test2
call run_test3
; All is OK, return
or eax, -1
int 0x40
or eax, -1
int 0x40
 
run_test1:
; basic test
mov eax, 1
call malloc_with_test
mov byte [eax], 0xDD
mov esi, eax
mov eax, 1
call malloc_with_test
cmp byte [esi], 0xDD
jnz memory_destroyed
mov byte [eax], 0xEE
xchg eax, esi
call free
cmp byte [esi], 0xEE
jnz memory_destroyed
xchg eax, esi
call free
ret
mov eax, 1
call malloc_with_test
mov byte [eax], 0xDD
mov esi, eax
mov eax, 1
call malloc_with_test
cmp byte [esi], 0xDD
jnz memory_destroyed
mov byte [eax], 0xEE
xchg eax, esi
call free
cmp byte [esi], 0xEE
jnz memory_destroyed
xchg eax, esi
call free
ret
 
run_test2:
ret
ret
 
run_test3:
; 1024000 times run random operation.
; Randomly select malloc(random size from 1 to 1023)
; or free(random of previously allocated areas)
mov edi, 0x12345678
xor esi, esi ; 0 areas allocated
mov ebx, 1024000
mov edi, 0x12345678
xor esi, esi ; 0 areas allocated
mov ebx, 1024000
.loop:
imul edi, 1103515245
add edi, 12345
mov eax, edi
shr eax, 16
test ebx, 64
jz .prefer_free
imul edi, 1103515245
add edi, 12345
mov eax, edi
shr eax, 16
test ebx, 64
jz .prefer_free
.prefer_malloc:
test eax, 3
jz .free
jmp @f
test eax, 3
jz .free
jmp @f
.prefer_free:
test eax, 3
jnz .free
test eax, 3
jnz .free
@@:
shr eax, 2
and eax, 1023
jz .loop
push ebx
push eax
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], eax
call malloc_with_test
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
pop ecx
pop ebx
inc esi
push ecx eax
push edi
mov edi, eax
mov eax, esi
rep stosb
pop edi
jmp .common
shr eax, 2
and eax, 1023
jz .loop
push ebx
push eax
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], eax
call malloc_with_test
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
pop ecx
pop ebx
inc esi
push ecx eax
push edi
mov edi, eax
mov eax, esi
rep stosb
pop edi
jmp .common
.free:
test esi, esi
jz .loop
xor edx, edx
div esi
sub edx, esi
neg edx
dec edx
mov eax, [esp+edx*8]
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], -1
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
mov ecx, [esp+edx*8+4]
push edi eax
mov edi, eax
mov al, [edi]
repz scasb
jnz memory_destroyed
pop eax edi
push ebx edx
call free
pop edx ebx
dec esi
pop eax ecx
push edi
lea edi, [esp+4]
test esi, esi
jz .loop
xor edx, edx
div esi
sub edx, esi
neg edx
dec edx
mov eax, [esp+edx*8]
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], -1
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
mov ecx, [esp+edx*8+4]
push edi eax
mov edi, eax
mov al, [edi]
repz scasb
jnz memory_destroyed
pop eax edi
push ebx edx
call free
pop edx ebx
dec esi
pop eax ecx
push edi
lea edi, [esp+4]
@@:
dec edx
js @f
xchg eax, [edi]
xchg ecx, [edi+4]
add edi, 8
jmp @b
dec edx
js @f
xchg eax, [edi]
xchg ecx, [edi+4]
add edi, 8
jmp @b
@@:
pop edi
pop edi
.common:
dec ebx
jnz .loop
dec ebx
jnz .loop
@@:
dec esi
js @f
pop eax ecx
call free
jmp @b
dec esi
js @f
pop eax ecx
call free
jmp @b
@@:
ret
ret
 
malloc_with_test:
; calls malloc() and checks returned value
call malloc
test eax, eax
jz generic_malloc_fail
call check_mutex
call check_range
ret
call malloc
test eax, eax
jz generic_malloc_fail
call check_mutex
call check_range
ret
 
; Stubs for kernel procedures used by heap code
wait_mutex:
inc dword [ebx]
ret
inc dword [ebx]
ret
 
kernel_alloc:
cmp dword [esp+4], bufsize
jnz error1
mov eax, buffer
ret 4
cmp dword [esp+4], bufsize
jnz error1
mov eax, buffer
ret 4
 
macro $Revision [args]
{
159,37 → 159,37
 
; Error handlers
error1:
mov eax, 1
jmp error_with_code
mov eax, 1
jmp error_with_code
 
generic_malloc_fail:
mov eax, 2
jmp error_with_code
mov eax, 2
jmp error_with_code
 
check_mutex:
cmp [mst.mutex], 0
jnz @f
ret
cmp [mst.mutex], 0
jnz @f
ret
@@:
mov eax, 3
jmp error_with_code
mov eax, 3
jmp error_with_code
 
check_range:
cmp eax, buffer
jb @f
cmp eax, buffer+bufsize
jae @f
ret
cmp eax, buffer
jb @f
cmp eax, buffer+bufsize
jae @f
ret
@@:
mov eax, 4
jmp error_with_code
mov eax, 4
jmp error_with_code
 
memory_destroyed:
mov eax, 5
jmp error_with_code
mov eax, 5
jmp error_with_code
 
error_with_code:
mov edx, saved_state_num
mov edx, saved_state_num
; eax = error code
; 1 signals error in testing code (wrong bufsize)
; 2 = malloc() returned NULL
196,8 → 196,8
; 3 = mutex not released
; 4 = weird returned value from malloc()
; 5 = memory destroyed by malloc() or free()
int3 ; simplest way to report error
jmp $-1 ; just in case
int3 ; simplest way to report error
jmp $-1 ; just in case
 
; Include main heap code
include '../proc32.inc'
208,16 → 208,16
 
align 4
zerostart:
mst MEM_STATE
mst MEM_STATE
 
align 16
bufsize = 0x40000 ; change if malloc.inc changes
buffer rb bufsize
bufsize = 0x40000 ; change if malloc.inc changes
buffer rb bufsize
zeroend:
 
saved_state_num dd ?
saved_state rd 0x10000
saved_state_num dd ?
saved_state rd 0x10000
 
align 4
rb 0x10000 ; for stack
rb 0x10000 ; for stack
mem:
/kernel/branches/net/core/timers.inc
0,0 → 1,205
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
; Simple implementation of timers. All timers are organized in a double-linked
; list, and the OS loop after every timer tick processes the list.
 
; This structure describes a timer for the kernel.
struct TIMER
Next dd ?
Prev dd ?
; These fields organize a double-linked list of all timers.
TimerFunc dd ?
; Function to be called when the timer is activated.
UserData dd ?
; The value that is passed as is to .TimerFunc.
Time dd ?
; Time at which the timer should be activated.
Interval dd ?
; Interval between activations of the timer, in 0.01s.
ends
 
iglobal
align 4
; The head of timer list.
timer_list:
dd timer_list
dd timer_list
endg
uglobal
; These two variables are used to synchronize access to the global list.
; Logically, they form an recursive mutex. Physically, the first variable holds
; the slot number of the current owner or 0, the second variable holds the
; recursion count.
; The mutex should be recursive to allow a timer function to add/delete other
; timers or itself.
timer_list_owner dd 0
timer_list_numlocks dd 0
; A timer function can delete any timer, including itself and the next timer in
; the chain. To handle such situation correctly, we keep the next timer in a
; global variable, so the removing operation can update it.
timer_next dd 0
endg
 
; This internal function acquires the lock for the global list.
lock_timer_list:
mov edx, [CURRENT_TASK]
@@:
xor eax, eax
lock cmpxchg [timer_list_owner], edx
jz @f
cmp eax, edx
jz @f
call change_task
jmp @b
@@:
inc [timer_list_numlocks]
ret
 
; This internal function releases the lock for the global list.
unlock_timer_list:
dec [timer_list_numlocks]
jnz .nothing
mov [timer_list_owner], 0
.nothing:
ret
 
; This function adds a timer.
; If deltaStart is nonzero, the timer is activated after deltaStart hundredths
; of seconds starting from the current time. If interval is nonzero, the timer
; is activated every deltaWork hundredths of seconds starting from the first
; activation. The activated timer calls timerFunc as stdcall function with one
; argument userData.
; Return value is NULL if something has failed or some value which is opaque
; for the caller. Later this value can be used for cancel_timer_hs.
proc timer_hs stdcall uses ebx, deltaStart:dword, interval:dword, \
timerFunc:dword, userData:dword
; 1. Allocate memory for the TIMER structure.
; 1a. Call the allocator.
push sizeof.TIMER
pop eax
call malloc
; 1b. If allocation failed, return (go to 5) with eax = 0.
test eax, eax
jz .nothing
; 2. Setup the TIMER structure.
xchg ebx, eax
; 2a. Copy values from the arguments.
mov ecx, [interval]
mov [ebx+TIMER.Interval], ecx
mov ecx, [timerFunc]
mov [ebx+TIMER.TimerFunc], ecx
mov ecx, [userData]
mov [ebx+TIMER.UserData], ecx
; 2b. Get time of the next activation.
mov ecx, [deltaStart]
test ecx, ecx
jnz @f
mov ecx, [interval]
@@:
add ecx, [timer_ticks]
mov [ebx+TIMER.Time], ecx
; 3. Insert the TIMER structure to the global list.
; 3a. Acquire the lock.
call lock_timer_list
; 3b. Insert an item at ebx to the tail of the timer_list.
mov eax, timer_list
mov ecx, [eax+TIMER.Prev]
mov [ebx+TIMER.Next], eax
mov [ebx+TIMER.Prev], ecx
mov [eax+TIMER.Prev], ebx
mov [ecx+TIMER.Next], ebx
; 3c. Release the lock.
call unlock_timer_list
; 4. Return with eax = pointer to TIMER structure.
xchg ebx, eax
.nothing:
; 5. Returning.
ret
endp
 
; This function removes a timer.
; The only argument is [esp+4] = the value which was returned from timer_hs.
cancel_timer_hs:
push ebx ; save used register to be stdcall
; 1. Remove the TIMER structure from the global list.
; 1a. Acquire the lock.
call lock_timer_list
mov ebx, [esp+4+4]
; 1b. Delete an item at ebx from the double-linked list.
mov eax, [ebx+TIMER.Next]
mov ecx, [ebx+TIMER.Prev]
mov [eax+TIMER.Prev], ecx
mov [ecx+TIMER.Next], eax
; 1c. If we are removing the next timer in currently processing chain,
; the next timer for this timer becomes new next timer.
cmp ebx, [timer_next]
jnz @f
mov [timer_next], eax
@@:
; 1d. Release the lock.
call unlock_timer_list
; 2. Free the TIMER structure.
xchg eax, ebx
call free
; 3. Return.
pop ebx ; restore used register to be stdcall
ret 4 ; purge one dword argument to be stdcall
 
; This function is regularly called from osloop. It processes the global list
; and activates the corresponding timers.
check_timers:
; 1. Acquire the lock.
call lock_timer_list
; 2. Loop over all registered timers, checking time.
; 2a. Get the first item.
mov eax, [timer_list+TIMER.Next]
mov [timer_next], eax
.loop:
; 2b. Check for end of list.
cmp eax, timer_list
jz .done
; 2c. Get and store the next timer.
mov edx, [eax+TIMER.Next]
mov [timer_next], edx
; 2d. Check time for timer activation.
; We can't just compare [timer_ticks] and [TIMER.Time], since overflows are
; possible: if the current time is 0FFFFFFFFh ticks and timer should be
; activated in 3 ticks, the simple comparison will produce incorrect result.
; So we calculate the difference [timer_ticks] - [TIMER.Time]; if it is
; non-negative, the time is over; if it is negative, then either the time is
; not over or we have not processed this timer for 2^31 ticks, what is very
; unlikely.
mov edx, [timer_ticks]
sub edx, [eax+TIMER.Time]
js .next
; The timer should be activated now.
; 2e. Store the timer data in the stack. This is required since 2f can delete
; the timer, invalidating the content.
push [eax+TIMER.UserData] ; parameter for TimerFunc
push [eax+TIMER.TimerFunc] ; to be restored in 2g
; 2f. Calculate time of next activation or delete the timer if it is one-shot.
mov ecx, [eax+TIMER.Interval]
add [eax+TIMER.Time], ecx
test ecx, ecx
jnz .nodelete
stdcall cancel_timer_hs, eax
.nodelete:
; 2g. Activate timer, using data from the stack.
pop eax
call eax
.next:
; 2h. Advance to the next timer and continue the loop.
mov eax, [timer_next]
jmp .loop
.done:
; 3. Release the lock.
call unlock_timer_list
; 4. Return.
ret
/kernel/branches/net/core/v86.inc
61,11 → 61,11
; initialize tables
mov ecx, 2000h/4
xor eax, eax
rep stosd
rep stosd
mov [ebx+V86_machine.iopm], edi
dec eax
mov ecx, 2000h/4
rep stosd
rep stosd
pop eax
; page directory: first entry is page table...
mov edi, eax
80,21 → 80,21
push esi
mov esi, (OS_BASE shr 20) + sys_pgdir
mov ecx, 0x80000000 shr 22
rep movsd
rep movsd
 
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
call get_pg_addr ;used as page table
or al, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
mov [edi-4096+(page_tabs shr 20)], eax
 
pop esi
; now V86 specific: initialize known addresses in first Mb
pop eax
; first page - BIOS data (shared between all machines!)
; physical address = 0x2f0000
; linear address = BOOT_VAR = OS_BASE + 0x2f0000
mov dword [eax], (BOOT_VAR - OS_BASE) or 111b
mov dword [eax+800h], BOOT_VAR
; physical address = 0
; linear address = OS_BASE
mov dword [eax], 111b
mov dword [eax+800h], OS_BASE
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
; physical address = 0x9C000
; linear address = 0x8009C000
219,12 → 219,12
mov [sys_v86_machine], eax
test eax, eax
jz .ret
mov byte [BOOT_VAR + 0x500], 0xCD
mov byte [BOOT_VAR + 0x501], 0x13
mov byte [BOOT_VAR + 0x502], 0xF4
mov byte [BOOT_VAR + 0x503], 0xCD
mov byte [BOOT_VAR + 0x504], 0x10
mov byte [BOOT_VAR + 0x505], 0xF4
mov byte [OS_BASE + 0x500], 0xCD
mov byte [OS_BASE + 0x501], 0x13
mov byte [OS_BASE + 0x502], 0xF4
mov byte [OS_BASE + 0x503], 0xCD
mov byte [OS_BASE + 0x504], 0x10
mov byte [OS_BASE + 0x505], 0xF4
mov esi, eax
mov ebx, [eax+V86_machine.pagedir]
; one page for stack, two pages for results (0x2000 bytes = 16 sectors)
240,7 → 240,7
xor eax, eax
mov edi, ecx
mov ecx, 10000h/8/4
rep stosd
rep stosd
end if
.ret:
ret
323,12 → 323,12
mov esi, ebx
mov edi, esp
mov ecx, v86_regs.size/4
rep movsd
rep movsd
 
cmp edx, -1
jz .noirqhook
uglobal
v86_irqhooks rd 16*2
v86_irqhooks rd IRQ_RESERVED * 2
endg
cmp [v86_irqhooks+edx*8], 0
jz @f
367,11 → 367,12
 
v86_exc_c:
; Did we all that we have wanted to do?
cmp bl,1
cmp bl, 1
jne @f
xor eax, eax
mov dr6, eax
@@: mov eax, [esp+v86_regs.size+10h+18h]
@@:
mov eax, [esp+v86_regs.size+10h+18h]
cmp word [esp+v86_regs.eip], ax
jnz @f
shr eax, 16
787,7 → 788,7
mov edi, [esi+v86_regs.size+10h+10h]
add edi, v86_regs.size
mov ecx, v86_regs.size/4
rep movsd
rep movsd
mov esp, esi
 
cli
805,7 → 806,6
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
mov cr3, eax
; mov [irq_tab+5*4], 0
sti
 
popad
839,16 → 839,17
; mov byte [BOOT_VAR + 48Eh], 0FFh
; ret
 
align 4
v86_irq:
; push irq/pushad/jmp v86_irq
; eax = irq
; ebp = irq
lea esi, [esp+1Ch]
lea edi, [esi+4]
mov ecx, 8
std
rep movsd
rep movsd
cld
mov edi, eax
mov edi, ebp
pop eax
v86_irq2:
mov esi, [v86_irqhooks+edi*8] ; get VM handle
898,12 → 899,8
pop ecx
.cont:
loop .scan
mov al, 20h
out 20h, al
cmp edi, 8
jb @f
out 0A0h, al
@@:
mov ecx, edi
call irq_eoi
popad
iretd
.found:
/kernel/branches/net/data16.inc
12,7 → 12,8
preboot_lfb db 0
preboot_bootlog db 0
boot_drive db 0
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007]
bx_from_load:
dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007]
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1
 
22,10 → 23,12
dd 0
dw 0
 
if ~ defined extended_primary_loader ; restart from memory is not supported in extended primary loader cfg
kernel_restart_bootblock:
db 1 ; version
dw 1 ; floppy image is in memory
dd 0 ; cannot save parameters
end if
 
; table for move to extended memory (int 15h, ah=87h)
align 8
53,3 → 56,36
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
if defined extended_primary_loader
; look in PrimaryLoader.txt for the description
bootdevice dw 0 ; ax from primary loader
bootfs dw 0 ; bx from primary loader
bootcallback dd 0 ; ds:si from primary loader
; data for configuration file loading, look in PrimaryLoader.txt
config_file_struct:
dw 0, 4000h ; load to 4000:0000
dw 16 ; read no more than 16*4K = 64K
db 'config.ini',0
; data for configuration file parsing
macro config_variable string,parser
{
local len
len dw 0
db string
store word $ - len - 2 at len
dw parser
}
config_file_variables:
config_variable 'timeout', parse_timeout
config_variable 'resolution', parse_resolution
config_variable 'vbemode', parse_vbemode
; config_variable 'vrr', parse_vrr
config_variable 'biosdisks', parse_biosdisks
config_variable 'imgfrom', parse_imgfrom
dw 0
; data for image file loading, look in PrimaryLoader.txt
image_file_struct:
dw 0, 4000h ; load to 4000:0000
dw 16 ; read no more than 16*4K = 64K
db 'kolibri.img',0
end if
/kernel/branches/net/data32.inc
1,466 → 1,473
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
keymap:
 
db '6',27
db '1234567890-=',8,9
db 'qwertyuiop[]',13
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
keymap_shift:
db '6',27
db '!@#$%^&*()_+',8,9
db 'QWERTYUIOP{}',13
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
keymap_alt:
db ' ',27
db ' @ $ {[]}\ ',8,9
db ' ',13
db ' ',0,' ',0,'4',0,' '
db ' ',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
boot_memdetect db 'Determining amount of memory',0
boot_fonts db 'Fonts loaded',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
boot_timer db 'Setting timer',0
boot_irqs db 'Reprogramming IRQs',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_resirqports db 'Reserving IRQs & ports',0
boot_setrports db 'Setting addresses for IRQs',0
boot_setostask db 'Setting OS task',0
boot_allirqs db 'Unmasking all IRQs',0
boot_tsc db 'Reading TSC',0
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_mtrr db 'Setting MTRR',0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
 
;new_process_loading db 'K : New Process - loading',13,10,0
;new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
aSis db 'SIS',0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
;szSound db 'SOUND',0
;szInfinity db 'INFINITY',0
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0
 
szIMPORTS db 'IMPORTS',0
 
read_firstapp db '/sys/'
firstapp db 'LAUNCHER',0
 
char db '/sys/FONTS/CHAR.MT',0
char2 db '/sys/FONTS/CHAR2.MT',0
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
 
 
align 4
 
shmem_list:
.bk dd shmem_list
.fd dd shmem_list
 
dll_list:
.bk dd dll_list
.fd dd dll_list
 
MAX_DEFAULT_DLL_ADDR = 0x20000000
MIN_DEFAULT_DLL_ADDR = 0x10000000
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR
 
; supported videomodes
 
 
; mike.dld {
db 0
dd servetable-0x10000
draw_line dd __sys_draw_line
draw_pointer dd __sys_draw_pointer
;//mike.dld, 2006-08-02 [
;drawbar dd __sys_drawbar
drawbar dd __sys_drawbar.forced
;//mike.dld, 2006-08-02 ]
putpixel dd __sys_putpixel
; } mike.dld
 
 
align 4
keyboard dd 1
syslang dd 1
 
boot_y dd 10
 
pci_bios_entry dd 0
dw pci_code_sel
 
if __DEBUG__ eq 1
include_debug_strings
end if
 
IncludeIGlobals
 
align 16
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
; Attention! Do not change the order of the first four selectors. They are 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+0xF;
 
app_data_l:
dw 0xFFFF
dw 0
db 0
db drw3
dw G32+D32+0xF;
 
; ------------- PCI BIOS ------------------
 
pci_code_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db cpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
pci_data_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db dpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
; --------------- 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:
dw TSS_SIZE-1
dw tss and 0xFFFF
db (tss shr 16) and 0xFF
db 10001001b
dw (tss shr 16) and 0xFF00
 
tls_data_l:
dw 0x0FFF
dw 0
db 0
db drw3
dw D32
 
endofcode:
gdte:
 
align 16
cur_saved_data rb 4096
fpu_data: rb 512
 
; device irq owners
irq_owner rd 16 ; process id
 
; on irq read ports
 
irq00read rd 16
irq01read rd 16
irq02read rd 16
irq03read rd 16
irq04read rd 16
irq05read rd 16
irq06read rd 16
irq07read rd 16
irq08read rd 16
irq09read rd 16
irq10read rd 16
irq11read rd 16
irq12read rd 16
irq13read rd 16
irq14read rd 16
irq15read rd 16
 
irq_tab rd 16
 
mem_block_map rb 512
mem_block_list rd 64
large_block_list rd 31
mem_block_mask rd 2
large_block_mask rd 1
 
mem_used.fd rd 1
mem_used.bk rd 1
 
mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
 
heap_mutex rd 1
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
 
mst MEM_STATE
 
page_start rd 1
page_end rd 1
sys_page_map rd 1
os_stack_seg rd 1
 
 
srv.fd rd 1
srv.bk rd 1
 
 
align 16
 
_display display_t
 
_WinMapAddress rd 1
_WinMapSize rd 1
 
def_cursor rd 1
current_cursor rd 1
hw_cursor rd 1
cur_saved_base rd 1
 
cur.lock rd 1 ;1 - lock update, 2- hide
cur.left rd 1 ;cursor clip box
cur.top rd 1
cur.right rd 1
cur.bottom rd 1
cur.w rd 1
cur.h rd 1
 
ipc_tmp rd 1
ipc_pdir rd 1
ipc_ptab rd 1
 
proc_mem_map rd 1
proc_mem_pdir rd 1
proc_mem_tab rd 1
 
tmp_task_pdir rd 1
tmp_task_ptab rd 1
 
default_io_map rd 1
 
LFBSize rd 1
 
stall_mcs rd 1
current_slot rd 1
 
; status
hd1_status rd 1 ; 0 - free : other - pid
application_table_status rd 1 ; 0 - free : other - pid
 
; device addresses
mididp rd 1
midisp rd 1
 
cdbase rd 1
cdid rd 1
 
hdbase rd 1 ; for boot 0x1f0
hdid rd 1
hdpos rd 1 ; for boot 0x1
fat32part rd 1 ; for boot 0x1
cdpos rd 1
 
;CPUID information
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
cpu_caps rd 4
 
 
pg_data PG_DATA
heap_test rd 1
 
buttontype rd 1
windowtypechanged rd 1
 
hd_entries rd 1 ;unused ? 0xfe10
 
;* start code - Mario79
 
mouse_active rd 1
mouse_pause rd 1
MouseTickCounter rd 1
 
;* end code - Mario79
 
img_background rd 1
mem_BACKGROUND rd 1
static_background_data rd 1
 
cache_ide0:
cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use
cache_ide0_data_pointer rd 1
cache_ide0_system_data_size rd 1 ; not use
cache_ide0_appl_data_size rd 1 ; not use
cache_ide0_system_data rd 1
cache_ide0_appl_data rd 1
cache_ide0_system_sad_size rd 1
cache_ide0_appl_sad_size rd 1
cache_ide0_search_start rd 1
cache_ide0_appl_search_start rd 1
 
cache_ide1:
cache_ide1_pointer rd 1
cache_ide1_size rd 1 ; not use
cache_ide1_data_pointer rd 1
cache_ide1_system_data_size rd 1 ; not use
cache_ide1_appl_data_size rd 1 ; not use
cache_ide1_system_data rd 1
cache_ide1_appl_data rd 1
cache_ide1_system_sad_size rd 1
cache_ide1_appl_sad_size rd 1
cache_ide1_search_start rd 1
cache_ide1_appl_search_start rd 1
 
cache_ide2:
cache_ide2_pointer rd 1
cache_ide2_size rd 1 ; not use
cache_ide2_data_pointer rd 1
cache_ide2_system_data_size rd 1 ; not use
cache_ide2_appl_data_size rd 1 ; not use
cache_ide2_system_data rd 1
cache_ide2_appl_data rd 1
cache_ide2_system_sad_size rd 1
cache_ide2_appl_sad_size rd 1
cache_ide2_search_start rd 1
cache_ide2_appl_search_start rd 1
 
cache_ide3:
cache_ide3_pointer rd 1
cache_ide3_size rd 1 ; not use
cache_ide3_data_pointer rd 1
cache_ide3_system_data_size rd 1 ; not use
cache_ide3_appl_data_size rd 1 ; not use
cache_ide3_system_data rd 1
cache_ide3_appl_data rd 1
cache_ide3_system_sad_size rd 1
cache_ide3_appl_sad_size rd 1
cache_ide3_search_start rd 1
cache_ide3_appl_search_start rd 1
 
debug_step_pointer rd 1
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
timer_ticks_enable rb 1 ; for cd driver
 
NumBiosDisks rd 1
BiosDisksData rb 200h
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0)
BiosDiskPartitions rd 80h
 
IncludeUGlobals
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
keymap:
 
db '6',27
db '1234567890-=',8,9
db 'qwertyuiop[]',13
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
keymap_shift:
db '6',27
db '!@#$%^&*()_+',8,9
db 'QWERTYUIOP{}',13
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
keymap_alt:
db ' ',27
db ' @ $ {[]}\ ',8,9
db ' ',13
db ' ',0,' ',0,'4',0,' '
db ' ',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
 
if lang eq ru
boot_fonts db '˜à¨äâë § £à㦥­ë',0
boot_memdetect db 'Š®«¨ç¥á⢮ ®¯¥à â¨¢­®© ¯ ¬ïâ¨',' ',' Œ¡',0
boot_tss db '“áâ ­®¢ª  TSSs',0
boot_cpuid db '—⥭¨¥ CPUIDs',0
boot_devices db '®¨áª ãáâனáâ¢',0
boot_timer db '“áâ ­®¢ª  â ©¬¥à ',0
boot_irqs db '¥à¥®¯à¥¤¥«¥­¨¥ IRQ',0
boot_setmouse db '“áâ ­®¢ª  ¬ëè¨',0
boot_windefs db '“áâ ­®¢ª  ­ áâ஥ª ®ª®­ ¯® 㬮«ç ­¨î',0
boot_bgr db '“áâ ­®¢ª  ä®­ ',0
boot_resirqports db '¥§¥à¢¨à®¢ ­¨¥ IRQ ¨ ¯®à⮢',0
boot_setrports db '“áâ ­®¢ª   ¤à¥á®¢ IRQ',0
boot_setostask db '‘®§¤ ­¨¥ ¯à®æ¥áá  ï¤à ',0
boot_allirqs db 'Žâªàë⨥ ¢á¥å IRQ',0
boot_tsc db '—⥭¨¥ TSC',0
boot_cpufreq db '— áâ®â  ¯à®æ¥áá®à  ',' ',' Œƒæ',0
boot_pal_ega db '“áâ ­®¢ª  EGA/CGA 320x200 ¯ «¨âàë',0
boot_pal_vga db '“áâ ­®¢ª  VGA 640x480 ¯ «¨âàë',0
boot_failed db '‡ £à㧪  ¯¥à¢®£® ¯à¨«®¦¥­¨ï ­¥ 㤠« áì',0
boot_mtrr db '“áâ ­®¢ª  MTRR',0
if preboot_blogesc
boot_tasking db '‚ᥠ£®â®¢® ¤«ï § ¯ã᪠, ­ ¦¬¨âॠESC ¤«ï áâ àâ ',0
end if
else
boot_fonts db 'Fonts loaded',0
boot_memdetect db 'Determining amount of memory',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_resirqports db 'Reserving IRQs & ports',0
boot_setostask db 'Setting OS task',0
boot_allirqs db 'Unmasking IRQs',0
boot_tsc db 'Reading TSC',0
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_mtrr db 'Setting MTRR',0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
end if
 
boot_APIC_found db 'APIC enabled', 0
boot_APIC_nfound db 'APIC not found', 0
 
;new_process_loading db 'K : New Process - loading',13,10,0
;new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
aSis db 'SIS',0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
;szSound db 'SOUND',0
;szInfinity db 'INFINITY',0
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0
 
szIMPORTS db 'IMPORTS',0
 
read_firstapp db '/sys/'
firstapp db 'LAUNCHER',0
notifyapp db '@notify',0
if lang eq ru
ud_user_message db 'Žè¨¡ª : ­¥¯®¤¤¥à¦¨¢ ¥¬ ï ¨­áâàãªæ¨ï ¯à®æ¥áá®à ',0
else
ud_user_message db 'Error: unsupported processor instruction',0
end if
 
char db '/sys/FONTS/CHAR.MT',0
char2 db '/sys/FONTS/CHAR2.MT',0
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
;vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
 
dev_data_path db '/RD/1/DRIVERS/DEVICES.DAT',0
 
align 4
 
shmem_list:
.bk dd shmem_list
.fd dd shmem_list
 
dll_list:
.bk dd dll_list
.fd dd dll_list
 
MAX_DEFAULT_DLL_ADDR = 0x20000000
MIN_DEFAULT_DLL_ADDR = 0x10000000
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR
 
; supported videomodes
 
 
; mike.dld {
db 0
dd servetable-0x10000
draw_line dd __sys_draw_line
draw_pointer dd __sys_draw_pointer
;//mike.dld, 2006-08-02 [
;drawbar dd __sys_drawbar
drawbar dd __sys_drawbar.forced
;//mike.dld, 2006-08-02 ]
putpixel dd __sys_putpixel
; } mike.dld
 
 
align 4
keyboard dd 1
syslang dd 1
 
boot_y dd 10
 
pci_bios_entry dd 0
dw pci_code_sel
 
if __DEBUG__ eq 1
include_debug_strings
end if
 
IncludeIGlobals
 
align 16
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
; Attention! Do not change the order of the first four selectors. They are 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+0xF;
 
app_data_l:
dw 0xFFFF
dw 0
db 0
db drw3
dw G32+D32+0xF;
 
; ------------- PCI BIOS ------------------
 
pci_code_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db cpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
pci_data_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db dpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
; --------------- 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:
dw TSS_SIZE-1
dw tss and 0xFFFF
db (tss shr 16) and 0xFF
db 10001001b
dw (tss shr 16) and 0xFF00
 
tls_data_l:
dw 0x0FFF
dw 0
db 0
db drw3
dw D32
 
endofcode:
gdte:
 
align 16
cur_saved_data rb 4096
fpu_data:
rb 512
 
mem_block_list rd 64*2
mem_used_list rd 64*2
mem_hash_cnt rd 64
 
heap_mutex MUTEX
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
 
mem_block_mask rd 2
next_memblock rd 1
 
 
mst MEM_STATE
 
page_start rd 1
page_end rd 1
sys_page_map rd 1
os_stack_seg rd 1
 
 
srv.fd rd 1
srv.bk rd 1
 
 
align 16
 
_display display_t
 
_WinMapAddress rd 1
_WinMapSize rd 1
 
def_cursor rd 1
current_cursor rd 1
hw_cursor rd 1
cur_saved_base rd 1
 
cur.lock rd 1 ;1 - lock update, 2- hide
cur.left rd 1 ;cursor clip box
cur.top rd 1
cur.right rd 1
cur.bottom rd 1
cur.w rd 1
cur.h rd 1
 
ipc_tmp rd 1
ipc_pdir rd 1
ipc_ptab rd 1
 
proc_mem_map rd 1
proc_mem_pdir rd 1
proc_mem_tab rd 1
 
tmp_task_pdir rd 1
tmp_task_ptab rd 1
 
default_io_map rd 1
 
LFBSize rd 1
 
stall_mcs rd 1
current_slot rd 1
 
; status
hd1_status rd 1 ; 0 - free : other - pid
application_table_status rd 1 ; 0 - free : other - pid
 
; device addresses
mididp rd 1
midisp rd 1
 
cdbase rd 1
cdid rd 1
 
hdbase rd 1 ; for boot 0x1f0
hdid rd 1
hdpos rd 1 ; for boot 0x1
label known_part dword
fat32part rd 1 ; for boot 0x1
cdpos rd 1
 
;CPUID information
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
cpu_caps rd 4
 
 
pg_data PG_DATA
heap_test rd 1
 
buttontype rd 1
windowtypechanged rd 1
 
hd_entries rd 1 ;unused ? 0xfe10
 
;* start code - Mario79
 
mouse_active rd 1
mouse_pause rd 1
MouseTickCounter rd 1
 
;* end code - Mario79
 
img_background rd 1
mem_BACKGROUND rd 1
static_background_data rd 1
 
cache_ide0:
cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use
cache_ide0_data_pointer rd 1
cache_ide0_system_data_size rd 1 ; not use
cache_ide0_appl_data_size rd 1 ; not use
cache_ide0_system_data rd 1
cache_ide0_appl_data rd 1
cache_ide0_system_sad_size rd 1
cache_ide0_appl_sad_size rd 1
cache_ide0_search_start rd 1
cache_ide0_appl_search_start rd 1
 
cache_ide1:
cache_ide1_pointer rd 1
cache_ide1_size rd 1 ; not use
cache_ide1_data_pointer rd 1
cache_ide1_system_data_size rd 1 ; not use
cache_ide1_appl_data_size rd 1 ; not use
cache_ide1_system_data rd 1
cache_ide1_appl_data rd 1
cache_ide1_system_sad_size rd 1
cache_ide1_appl_sad_size rd 1
cache_ide1_search_start rd 1
cache_ide1_appl_search_start rd 1
 
cache_ide2:
cache_ide2_pointer rd 1
cache_ide2_size rd 1 ; not use
cache_ide2_data_pointer rd 1
cache_ide2_system_data_size rd 1 ; not use
cache_ide2_appl_data_size rd 1 ; not use
cache_ide2_system_data rd 1
cache_ide2_appl_data rd 1
cache_ide2_system_sad_size rd 1
cache_ide2_appl_sad_size rd 1
cache_ide2_search_start rd 1
cache_ide2_appl_search_start rd 1
 
cache_ide3:
cache_ide3_pointer rd 1
cache_ide3_size rd 1 ; not use
cache_ide3_data_pointer rd 1
cache_ide3_system_data_size rd 1 ; not use
cache_ide3_appl_data_size rd 1 ; not use
cache_ide3_system_data rd 1
cache_ide3_appl_data rd 1
cache_ide3_system_sad_size rd 1
cache_ide3_appl_sad_size rd 1
cache_ide3_search_start rd 1
cache_ide3_appl_search_start rd 1
 
debug_step_pointer rd 1
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
timer_ticks_enable rb 1 ; for cd driver
 
NumBiosDisks rd 1
BiosDisksData rb 200h
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0)
BiosDiskPartitions rd 80h
 
IncludeUGlobals
/kernel/branches/net/detect/biosdisk.inc
55,7 → 55,7
inc ax
cmp word [si], 170h
jz @f
or ax,-1
or ax, -1
; mov ax, -1
@@:
stosw
64,10 → 64,10
bddl:
mov al, dl
stosb
xor ax,ax
stosb
dec ax
stosw
xor ax, ax
stosb
dec ax
stosw
; mov al, 0
; stosb
; mov ax, -1
/kernel/branches/net/detect/dev_fd.inc
13,18 → 13,25
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD
; àâòîð Mario79
;***************************************************
xor eax,eax
mov edi,DRIVE_DATA
mov ecx,16384
xor eax, eax
mov edi, DRIVE_DATA
mov ecx, 16384
cld
rep stosd
rep stosd
 
mov al,0x10
out 0x70,al
mov cx,0xff
mov al, 0x10
out 0x70, al
mov cx, 0xff
wait_cmos:
dec cx
test cx,cx
jnz wait_cmos
in al,0x71
mov [DRIVE_DATA],al
dec cx
test cx, cx
jnz wait_cmos
in al, 0x71
mov [DRIVE_DATA], al
test al, al
jz @f
in al, 0x21
and al, 10111111b ; Enable IRQ6
out 0x21, al
@@:
 
/kernel/branches/net/detect/dev_hdcd.inc
18,8 → 18,8
;* ÏÎÈÑÊ HDD è CD *
;****************************************************
FindHDD:
mov [ChannelNumber],1
mov [DiskNumber],0
mov [ChannelNumber], 1
mov [DiskNumber], 0
call FindHDD_3
; mov ax,[Sector512+176]
; mov [DRIVE_DATA+6],ax
27,16 → 27,16
; mov [DRIVE_DATA+8],ax
; mov ax,[Sector512+128]
; mov [DRIVE_DATA+8],ax
mov [DiskNumber],1
mov [DiskNumber], 1
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+7],al
inc [ChannelNumber]
mov [DiskNumber],0
mov [DiskNumber], 0
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+8],al
mov [DiskNumber],1
mov [DiskNumber], 1
call FindHDD_1
; mov al,[Sector512+176]
; mov [DRIVE_DATA+9],al
45,21 → 45,21
 
FindHDD_1:
call ReadHDD_ID
cmp [DevErrorCode],0
cmp [DevErrorCode], 0
jne FindHDD_2
cmp [Sector512+6],word 16
cmp [Sector512+6], word 16
ja FindHDD_2
cmp [Sector512+12],word 255
cmp [Sector512+12], word 255
ja FindHDD_2
inc byte [DRIVE_DATA+1]
jmp FindHDD_2_2
FindHDD_2:
call DeviceReset
cmp [DevErrorCode],0
cmp [DevErrorCode], 0
jne FindHDD_2_2
call ReadCD_ID
cmp [DevErrorCode],0
jne FindHDD_2_2
cmp [DevErrorCode], 0
jne FindHDD_2_2
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1]
FindHDD_2_2:
67,7 → 67,7
 
FindHDD_3:
call FindHDD_1
shl byte [DRIVE_DATA+1],2
shl byte [DRIVE_DATA+1], 2
ret
 
 
86,45 → 86,46
;*************************************************
ReadHDD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
mov [ATAAddressMode], 0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATAHead],0
mov [ATACommand],0ECh
mov [ATAFeatures], 0
mov [ATAHead], 0
mov [ATACommand], 0ECh
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
mov DX,[ATABasePortAddr]
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíè
mov ecx,0xffff
mov DX, [ATABasePortAddr]
add DX, 7 ;àäðåñ ðåãèñòðà ñîñòîÿíè
mov ecx, 0xffff
@@WaitCompleet:
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
dec ecx
dec ecx
; cmp ecx,0
jz @@Error1 ;îøèáêà òàéì-àóòà
jz @@Error1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw ;ïðèíÿòü áëîê äàííûõ
ret
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];ðåãèñòð äàííûõ
mov CX, 256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw ;ïðèíÿòü áëîê äàííûõ
ret
; Çàïèñàòü êîä îøèáêè
@@Error1:
mov [DevErrorCode],1
ret
mov [DevErrorCode], 1
ret
@@Error6:
mov [DevErrorCode],6
@@End: ret
mov [DevErrorCode], 6
@@End:
ret
 
 
iglobal
174,99 → 175,104
;****************************************************
SendCommandToHDD:
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
cmp [ATAAddressMode],1
cmp [ATAAddressMode], 1
ja @@Err2
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3
cmp BX,2
cmp BX, 2
ja @@Err3
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
shl BX, 1
movzx ebx, bx
mov AX, [ebx+StandardATABases]
mov [ATABasePortAddr], AX
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
mov DX,[ATABasePortAddr]
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
mov DX, [ATABasePortAddr]
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL, [DiskNumber]
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4
shl AL,4
or AL,10100000b
out DX,AL
shl AL, 4
or AL, 10100000b
out DX, AL
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
inc DX
mov ecx,0xfff
mov ecx, 0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Ïðîâåðèòü âðåìÿ îæèäàíè
dec ecx
dec ecx
; cmp ecx,0
jz @@Err1
jz @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;îæèäàòü 300 òèêîâ
; ja @@Err1 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
in AL,DX
in AL, DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
test AL, 80h
jnz @@WaitHDReady
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
test AL,08h
test AL, 08h
jnz @@WaitHDReady
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
cli
mov DX,[ATABasePortAddr]
mov DX, [ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
mov AL,[ATAFeatures]
out DX,AL
mov AL, [ATAFeatures]
out DX, AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
mov AL,[ATASectorCount]
out DX,AL
mov AL, [ATASectorCount]
out DX, AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
mov AL,[ATASectorNumber]
out DX,AL
mov AL, [ATASectorNumber]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
mov AX,[ATACylinder]
out DX,AL
mov AX, [ATACylinder]
out DX, AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
mov AL,AH
out DX,AL
mov AL, AH
out DX, AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
mov AL, [DiskNumber]
shl AL, 4
cmp [ATAHead], 0Fh;ïðîâåðèòü íîìåð ãîëîâêè
ja @@Err5
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
or AL, [ATAHead]
or AL, 10100000b
mov AH, [ATAAddressMode]
shl AH, 6
or AL, AH
out DX, AL
; Ïîñëàòü êîìàíäó
mov AL,[ATACommand]
mov AL, [ATACommand]
inc DX ;ðåãèñòð êîìàíä
out DX,AL
out DX, AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
mov [DevErrorCode], 0
ret
; Çàïèñàòü êîä îøèáêè
@@Err1: mov [DevErrorCode],1
@@Err1:
mov [DevErrorCode], 1
ret
@@Err2: mov [DevErrorCode],2
@@Err2:
mov [DevErrorCode], 2
ret
@@Err3: mov [DevErrorCode],3
@@Err3:
mov [DevErrorCode], 3
ret
@@Err4: mov [DevErrorCode],4
@@Err4:
mov [DevErrorCode], 4
ret
@@Err5: mov [DevErrorCode],5
@@Err5:
mov [DevErrorCode], 5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
ret
 
281,48 → 287,48
;*************************************************
ReadCD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
mov [ATAAddressMode], 0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A1h
mov [ATAFeatures], 0
mov [ATASectorCount], 0
mov [ATASectorNumber], 0
mov [ATACylinder], 0
mov [ATAHead], 0
mov [ATACommand], 0A1h
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode], 0;ïðîâåðèòü êîä îøèáêè
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,0xffff
mov DX, [ATABasePortAddr]
add DX, 7 ;ïîðò 1õ7h
mov ecx, 0xffff
@@WaitCompleet_1:
; Ïðîâåðèòü âðåì
dec ecx
; cmp ecx,0
jz @@Error1_1 ;îøèáêà òàéì-àóòà
dec ecx
; cmp ecx,0
jz @@Error1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
in AL, DX
test AL, 80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
test AL, 1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6_1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
test AL, 08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet_1
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw
mov EDI, Sector512 ;offset Sector512
mov DX, [ATABasePortAddr];ïîðò 1x0h
mov CX, 256;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw
ret
; Çàïèñàòü êîä îøèáêè
@@Error1_1:
mov [DevErrorCode],1
mov [DevErrorCode], 1
ret
@@Error6_1:
mov [DevErrorCode],6
mov [DevErrorCode], 6
@@End_1:
ret
 
335,30 → 341,30
;*************************************************
DeviceReset:
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
mov BX, [ChannelNumber]
cmp BX, 1
jb @@Err3_2
cmp BX,2
cmp BX, 2
ja @@Err3_2
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov DX,[ebx+StandardATABases]
mov [ATABasePortAddr],DX
shl BX, 1
movzx ebx, bx
mov DX, [ebx+StandardATABases]
mov [ATABasePortAddr], DX
; Âûáðàòü íóæíûé äèñê
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
add DX, 6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL, [DiskNumber]
cmp AL, 1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4_2
shl AL,4
or AL,10100000b
out DX,AL
shl AL, 4
or AL, 10100000b
out DX, AL
; Ïîñëàòü êîìàíäó "Ñáðîñ"
mov AL,08h
mov AL, 08h
inc DX ;ðåãèñòð êîìàíä
out DX,AL
mov ecx,0x80000
out DX, AL
mov ecx, 0x80000
@@WaitHDReady_1:
; Ïðîâåðèòü âðåìÿ îæèäàíè
dec ecx
365,19 → 371,22
; cmp ecx,0
je @@Err1_2 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
in AL,DX
in AL, DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
test AL, 80h
jnz @@WaitHDReady_1
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
mov [DevErrorCode], 0
ret
; Îáðàáîòêà îøèáîê
@@Err1_2: mov [DevErrorCode],1
@@Err1_2:
mov [DevErrorCode], 1
ret
@@Err3_2: mov [DevErrorCode],3
@@Err3_2:
mov [DevErrorCode], 3
ret
@@Err4_2: mov [DevErrorCode],4
@@Err4_2:
mov [DevErrorCode], 4
; Çàïèñàòü êîä îøèáêè
ret
 
/kernel/branches/net/detect/getcache.inc
7,206 → 7,206
 
$Revision$
 
pusha
pusha
 
mov eax,[pg_data.pages_free]
mov eax, [pg_data.pages_free]
; 1/32
shr eax,5
shr eax, 5
; round off up to 8 pages
shr eax,3
shl eax,3
shr eax, 3
shl eax, 3
; translate pages in butes *4096
shl eax,12
shl eax, 12
; check a upper size of the cache, no more than 1 Mb on the physical device
cmp eax,1024*1024
jbe @f
mov eax,1024*1024
jmp .continue
cmp eax, 1024*1024
jbe @f
mov eax, 1024*1024
jmp .continue
@@:
; check a lower size of the cache, not less than 128 Kb on the physical device
cmp eax,128*1024
jae @f
mov eax,128*1024
cmp eax, 128*1024
jae @f
mov eax, 128*1024
@@:
.continue:
mov [cache_ide0_size],eax
mov [cache_ide1_size],eax
mov [cache_ide2_size],eax
mov [cache_ide3_size],eax
xor eax,eax
mov [hdd_appl_data],1 ;al
mov [cd_appl_data],1
mov [cache_ide0_size], eax
mov [cache_ide1_size], eax
mov [cache_ide2_size], eax
mov [cache_ide3_size], eax
xor eax, eax
mov [hdd_appl_data], 1;al
mov [cd_appl_data], 1
mov ch,[DRIVE_DATA+1]
mov cl,ch
and cl,11b
je .ide2
mov esi,cache_ide3
call get_cache_ide
mov ch, [DRIVE_DATA+1]
mov cl, ch
and cl, 11b
je .ide2
mov esi, cache_ide3
call get_cache_ide
.ide2:
mov cl,ch
shr cl,2
and cl,11b
je .ide1
mov esi,cache_ide2
call get_cache_ide
mov cl, ch
shr cl, 2
and cl, 11b
je .ide1
mov esi, cache_ide2
call get_cache_ide
.ide1:
mov cl,ch
shr cl,4
and cl,11b
je .ide0
mov esi,cache_ide1
call get_cache_ide
mov cl, ch
shr cl, 4
and cl, 11b
je .ide0
mov esi, cache_ide1
call get_cache_ide
.ide0:
mov cl,ch
shr cl,6
and cl,11b
je @f
mov esi,cache_ide0
call get_cache_ide
mov cl, ch
shr cl, 6
and cl, 11b
je @f
mov esi, cache_ide0
call get_cache_ide
@@:
xor ecx,ecx
cmp [NumBiosDisks],ecx
jz .endbd
mov esi,BiosDiskCaches
xor ecx, ecx
cmp [NumBiosDisks], ecx
jz .endbd
mov esi, BiosDiskCaches
.loopbd:
push ecx
movsx ecx,byte [BiosDisksData+ecx*4+2]
inc ecx
jz .getbd
add ecx,ecx
movzx eax,byte [DRIVE_DATA+1]
shl eax,cl
and ah,3
cmp ah,1
jz .contbd
pop ecx
mov byte [BiosDisksData+ecx*4+2], -1
push ecx
push ecx
movsx ecx, byte [BiosDisksData+ecx*4+2]
inc ecx
jz .getbd
add ecx, ecx
movzx eax, byte [DRIVE_DATA+1]
shl eax, cl
and ah, 3
cmp ah, 1
jz .contbd
pop ecx
mov byte [BiosDisksData+ecx*4+2], -1
push ecx
.getbd:
mov eax,[cache_ide0_size]
mov [esi+cache_ide0_size-cache_ide0],eax
mov cl,1
call get_cache_ide
mov eax, [cache_ide0_size]
mov [esi+cache_ide0_size-cache_ide0], eax
mov cl, 1
call get_cache_ide
.contbd:
pop ecx
add esi,cache_ide1-cache_ide0
inc ecx
cmp ecx,[NumBiosDisks]
jb .loopbd
pop ecx
add esi, cache_ide1-cache_ide0
inc ecx
cmp ecx, [NumBiosDisks]
jb .loopbd
.endbd:
jmp end_get_cache
jmp end_get_cache
 
get_cache_ide:
and [esi+cache_ide0_search_start-cache_ide0],0
and [esi+cache_ide0_appl_search_start-cache_ide0],0
push ecx
stdcall kernel_alloc,[esi+cache_ide0_size-cache_ide0]
mov [esi+cache_ide0_pointer-cache_ide0],eax
pop ecx
mov edx,eax
mov eax,[esi+cache_ide0_size-cache_ide0]
shr eax,3
mov [esi+cache_ide0_system_data_size-cache_ide0],eax
mov ebx,eax
imul eax,7
mov [esi+cache_ide0_appl_data_size-cache_ide0],eax
add ebx,edx
mov [esi+cache_ide0_data_pointer-cache_ide0],ebx
and [esi+cache_ide0_search_start-cache_ide0], 0
and [esi+cache_ide0_appl_search_start-cache_ide0], 0
push ecx
stdcall kernel_alloc, [esi+cache_ide0_size-cache_ide0]
mov [esi+cache_ide0_pointer-cache_ide0], eax
pop ecx
mov edx, eax
mov eax, [esi+cache_ide0_size-cache_ide0]
shr eax, 3
mov [esi+cache_ide0_system_data_size-cache_ide0], eax
mov ebx, eax
imul eax, 7
mov [esi+cache_ide0_appl_data_size-cache_ide0], eax
add ebx, edx
mov [esi+cache_ide0_data_pointer-cache_ide0], ebx
 
cmp cl,10b
je .cd
push ecx
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_hd
add eax,[esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0],eax
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
cmp cl, 10b
je .cd
push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_hd
add eax, [esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx
 
push edi
mov edi,[esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
push edi
mov edi, [esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_hd
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0],eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_hd
add eax, [esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx
 
push edi
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
push edi
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
pop ecx
ret
.cd:
push ecx
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_cd
add eax,[esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0],eax
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
push ecx
mov eax, [esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_cd
add eax, [esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0], eax
mov [esi+cache_ide0_system_sad_size-cache_ide0], ecx
 
push edi
mov edi,[esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
push edi
mov edi, [esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_cd
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0],eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
mov eax, [esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_cd
add eax, [esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0], eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0], ecx
 
push edi
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
push edi
mov edi, [esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
pop ecx
ret
 
calculate_for_hd:
push eax
mov ebx,eax
shr eax,9
shl eax,3
sub ebx,eax
shr ebx,9
mov ecx,ebx
shl ebx,9
pop eax
sub eax,ebx
dec ecx
ret
push eax
mov ebx, eax
shr eax, 9
shl eax, 3
sub ebx, eax
shr ebx, 9
mov ecx, ebx
shl ebx, 9
pop eax
sub eax, ebx
dec ecx
ret
 
calculate_for_cd:
push eax
mov ebx,eax
shr eax,11
shl eax,3
sub ebx,eax
shr ebx,11
mov ecx,ebx
shl ebx,11
pop eax
sub eax,ebx
dec ecx
ret
push eax
mov ebx, eax
shr eax, 11
shl eax, 3
sub ebx, eax
shr ebx, 11
mov ecx, ebx
shl ebx, 11
pop eax
sub eax, ebx
dec ecx
ret
 
clear_ide_cache:
push eax
shl ecx,1
xor eax,eax
cld
rep stosd
pop eax
ret
push eax
shl ecx, 1
xor eax, eax
cld
rep stosd
pop eax
ret
 
end_get_cache:
; mov [cache_ide0_pointer],HD_CACHE
; mov [cache_ide0_system_data],HD_CACHE+65536
; mov [cache_ide0_system_sad_size],1919
popa
popa
/kernel/branches/net/detect/sear_par.inc
13,74 → 13,94
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
; àâòîð Mario79
;****************************************************
mov [transfer_adress],DRIVE_DATA+0xa
mov [transfer_adress], DRIVE_DATA+0xa
search_partitions_ide0:
test [DRIVE_DATA+1],byte 0x40
jz search_partitions_ide1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],1
test [DRIVE_DATA+1], byte 0x40
jz search_partitions_ide1
mov [hdbase], 0x1f0
mov [hdid], 0x0
mov [hdpos], 1
mov [known_part], 1
search_partitions_ide0_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide1
inc byte [DRIVE_DATA+2]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide0_1
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide1 ; not found part
test [problem_partition], 1
jnz @F ; not found known_part
;cmp [problem_partition],0
;jne search_partitions_ide1
inc byte [DRIVE_DATA+2]
call partition_data_transfer
add [transfer_adress], 100
@@:
inc [known_part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
test [DRIVE_DATA+1],byte 0x10
jz search_partitions_ide2
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],1
test [DRIVE_DATA+1], byte 0x10
jz search_partitions_ide2
mov [hdbase], 0x1f0
mov [hdid], 0x10
mov [hdpos], 2
mov [known_part], 1
search_partitions_ide1_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide2
inc byte [DRIVE_DATA+3]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide1_1
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide2
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide2
inc byte [DRIVE_DATA+3]
call partition_data_transfer
add [transfer_adress], 100
@@:
inc [known_part]
jmp search_partitions_ide1_1
 
search_partitions_ide2:
test [DRIVE_DATA+1],byte 0x4
jz search_partitions_ide3
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],1
test [DRIVE_DATA+1], byte 0x4
jz search_partitions_ide3
mov [hdbase], 0x170
mov [hdid], 0x0
mov [hdpos], 3
mov [known_part], 1
search_partitions_ide2_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide3
inc byte [DRIVE_DATA+4]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide2_1
call set_PARTITION_variables
test [problem_partition], 2
jnz search_partitions_ide3
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide3
inc byte [DRIVE_DATA+4]
call partition_data_transfer
add [transfer_adress], 100
@@:
inc [known_part]
jmp search_partitions_ide2_1
 
search_partitions_ide3:
test [DRIVE_DATA+1],byte 0x1
jz end_search_partitions_ide
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],1
test [DRIVE_DATA+1], byte 0x1
jz end_search_partitions_ide
mov [hdbase], 0x170
mov [hdid], 0x10
mov [hdpos], 4
mov [known_part], 1
search_partitions_ide3_1:
call set_FAT32_variables
cmp [problem_partition],0
jne end_search_partitions_ide
inc byte [DRIVE_DATA+5]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide3_1
call set_PARTITION_variables
test [problem_partition], 2
jnz end_search_partitions_ide
test [problem_partition], 1
jnz @F
;cmp [problem_partition],0
;jne end_search_partitions_ide
inc byte [DRIVE_DATA+5]
call partition_data_transfer
add [transfer_adress], 100
@@:
inc [known_part]
jmp search_partitions_ide3_1
 
end_search_partitions_ide:
mov [hdpos], 80h
91,16 → 111,21
push ecx
mov eax, [hdpos]
and [BiosDiskPartitions+(eax-80h)*4], 0
mov [fat32part], 1
mov [known_part], 1
search_partitions_bd:
call set_FAT32_variables
cmp [problem_partition], 0
jne end_search_partitions_bd
call set_PARTITION_variables
test [problem_partition], 2
jnz end_search_partitions_bd
test [problem_partition], 1
jnz @F
;cmp [problem_partition], 0
;jne end_search_partitions_bd
mov eax, [hdpos]
inc [BiosDiskPartitions+(eax-80h)*4]
call partition_data_transfer
add [transfer_adress], 100
inc [fat32part]
@@:
inc [known_part]
jmp search_partitions_bd
end_search_partitions_bd:
pop ecx
109,45 → 134,24
jmp end_search_partitions
 
partition_data_transfer:
mov edi,[transfer_adress]
mov esi,PARTITION_START
mov ecx,(file_system_data_size+3)/4
rep movsd
ret
mov edi, [transfer_adress]
mov esi, PARTITION_START ;start of file_system_data
mov ecx, (file_system_data_size+3)/4
rep movsd
ret
uglobal
transfer_adress dd 0
endg
partition_data_transfer_1:
; cli
push edi
mov edi,PARTITION_START
mov esi,[transfer_adress]
mov ecx,(file_system_data_size+3)/4
rep movsd
pop edi
push edi
mov edi, PARTITION_START
mov esi, [transfer_adress]
mov ecx, (file_system_data_size+3)/4
rep movsd
pop edi
; sti
ret
ret
 
end_search_partitions:
 
;PARTITION_START dd 0x3f
;PARTITION_END dd 0
;SECTORS_PER_FAT dd 0x1f3a
;NUMBER_OF_FATS dd 0x2
;SECTORS_PER_CLUSTER dd 0x8
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
;ROOT_CLUSTER dd 2 ; first rootdir cluster
;FAT_START dd 0 ; start of fat table
;ROOT_START dd 0 ; start of rootdir (only fat16)
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
;DATA_START dd 0 ; start of data area (=first cluster 2)
;LAST_CLUSTER dd 0 ; last availabe cluster
;ADR_FSINFO dd 0 ; used only by fat32
;
;fatRESERVED dd 0x0FFFFFF6
;fatBAD dd 0x0FFFFFF7
;fatEND dd 0x0FFFFFF8
;fatMASK dd 0x0FFFFFFF
;
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32
 
/kernel/branches/net/fdo.inc
49,8 → 49,8
 
macro DEBUGS_N _sign,_num,[_str] {
common
pushf
pushad
pushf
pushad
local ..str,..label,is_str
is_str = 0
forward
59,43 → 59,41
end if
common
if is_str = 1
jmp ..label
jmp ..label
..str db _str,0
..label:
; add esp,4*8+4
mov edx, ..str
else
esp equ esp+4*8+4
mov edx,..str
mov edx, _str
esp equ _esp
; 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
mov esi, _num
else if ~_num eq esi
movzx esi,_num
movzx esi, _num
end if
else if _num eqtype 0
mov esi,_num
mov esi, _num
else
local tp
tp equ 0
match [_arg],_num \{
mov esi,dword[_arg]
mov esi, dword[_arg]
tp equ 1
\}
match =0 =dword[_arg],tp _num \{
mov esi,dword[_arg]
mov esi, dword[_arg]
tp equ 1
\}
match =0 =word[_arg],tp _num \{
movzx esi,word[_arg]
movzx esi, word[_arg]
tp equ 1
\}
match =0 =byte[_arg],tp _num \{
movzx esi,byte[_arg]
movzx esi, byte[_arg]
tp equ 1
\}
match =0,tp \{
103,11 → 101,11
\}
end if
else
mov esi,0x7FFFFFFF
mov esi, 0x7FFFFFFF
end if
call fdo_debug_outstr
popad
popf
call fdo_debug_outstr
popad
popf
}
 
macro DEBUGD _sign,_dec {
123,8 → 121,8
}
 
macro DEBUGD_N _sign,_num,_dec {
pushf
pushad
pushf
pushad
if (~_num eq)
if (_dec eqtype eax | _dec eqtype 0)
'Error: precision allowed only for in-memory variables'
139,43 → 137,43
end if
if _dec eqtype eax
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp>
mov eax,_dec
mov eax, _dec
else if ~_dec eq eax
if _sign = 1
movsx eax,_dec
movsx eax, _dec
else
movzx eax,_dec
movzx eax, _dec
end if
end if
else if _dec eqtype 0
mov eax,_dec
mov eax, _dec
else
; add esp,4*8+4
esp equ esp+4*8+4
if _num eq
mov eax,dword _dec
mov eax, dword _dec
else if _num = 1
if _sign = 1
movsx eax,byte _dec
movsx eax, byte _dec
else
movzx eax,byte _dec
movzx eax, byte _dec
end if
else if _num = 2
if _sign = 1
movsx eax,word _dec
movsx eax, word _dec
else
movzx eax,word _dec
movzx eax, word _dec
end if
else
mov eax,dword _dec
mov eax, dword _dec
end if
esp equ _esp
; sub esp,4*8+4
end if
mov cl,_sign
call fdo_debug_outdec
popad
popf
mov cl, _sign
call fdo_debug_outdec
popad
popf
}
 
macro DEBUGH _sign,_hex {
191,8 → 189,8
}
 
macro DEBUGH_N _sign,_num,_hex {
pushf
pushad
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
199,43 → 197,43
if _hex eqtype eax
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
if ~_hex eq eax
mov eax,_hex
mov eax, _hex
end if
mov edx,8
mov edx, 8
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
if ~_hex eq ax
movzx eax,_hex
movzx eax, _hex
end if
if (_num eq)
mov edx,4
mov edx, 4
end if
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
if ~_hex eq al
movzx eax,_hex
movzx eax, _hex
end if
if (_num eq)
mov edx,2
mov edx, 2
end if
end if
else if _hex eqtype 0
mov eax,_hex
mov eax, _hex
else
; add esp,4*8+4
esp equ esp+4*8+4
mov eax,dword _hex
mov eax, dword _hex
esp equ _esp
; sub esp,4*8+4
end if
if ~_num eq
mov edx,_num
mov edx, _num
else
if ~_hex eqtype eax
mov edx,8
mov edx, 8
end if
end if
call fdo_debug_outhex
popad
popf
call fdo_debug_outhex
popad
popf
}
 
;-----------------------------------------------------------------------------
243,9 → 241,9
debug_func fdo_debug_outchar
debug_beginf
pushad
movzx ebx,al
mov eax,1
mov ecx,sys_msg_board
movzx ebx, al
mov eax, 1
mov ecx, sys_msg_board
call ecx ; sys_msg_board
popad
ret
253,58 → 251,65
 
debug_func fdo_debug_outstr
debug_beginf
mov eax,1
.l1: dec esi
mov eax, 1
.l1:
dec esi
js .l2
movzx ebx,byte[edx]
or bl,bl
movzx ebx, byte[edx]
or bl, bl
jz .l2
mov ecx,sys_msg_board
mov ecx, sys_msg_board
call ecx ; sys_msg_board
inc edx
jmp .l1
.l2: ret
.l2:
ret
debug_endf
 
debug_func fdo_debug_outdec
debug_beginf
or cl,cl
or cl, cl
jz @f
or eax,eax
or eax, eax
jns @f
neg eax
push eax
mov al,'-'
mov al, '-'
call fdo_debug_outchar
pop eax
@@: push 10
@@:
push 10
pop ecx
push -'0'
.l1: xor edx,edx
.l1:
xor edx, edx
div ecx
push edx
test eax,eax
test eax, eax
jnz .l1
.l2: pop eax
add al,'0'
.l2:
pop eax
add al, '0'
jz .l3
call fdo_debug_outchar
jmp .l2
.l3: ret
.l3:
ret
debug_endf
 
debug_func fdo_debug_outhex
__fdo_hexdigits db '0123456789ABCDEF'
debug_beginf
mov cl,dl
mov cl, dl
neg cl
add cl,8
shl cl,2
rol eax,cl
.l1: rol eax,4
add cl, 8
shl cl, 2
rol eax, cl
.l1:
rol eax, 4
push eax
and eax,0x0000000F
mov al,[__fdo_hexdigits+eax]
and eax, 0x0000000F
mov al, [__fdo_hexdigits+eax]
call fdo_debug_outchar
pop eax
dec edx
/kernel/branches/net/fs/ext2.inc
0,0 → 1,1318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2381 $
 
EXT2_BAD_INO = 1
EXT2_ROOT_INO = 2
EXT2_ACL_IDX_INO = 3
EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO= 5
EXT2_UNDEL_DIR_INO = 6
 
;type inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
;user inode right's
EXT2_S_IRUSR = 0x0100
EXT2_S_IWUSR = 0x0080
EXT2_S_IXUSR = 0x0040
;group inode right's
EXT2_S_IRGRP = 0x0020
EXT2_S_IWGRP = 0x0010
EXT2_S_IXGRP = 0x0008
;other inode right's
EXT2_S_IROTH = 0x0004
EXT2_S_IWOTH = 0x0002
EXT2_S_IXOTH = 0x0001
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
 
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
 
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
 
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
EXT2_filename rb 256
EXT2_parent_name rb 256
EXT2_name_len dd ?
endg
 
struct EXT2_INODE_STRUC
i_mode dw ?
i_uid dw ?
i_size dd ?
i_atime dd ?
i_ctime dd ?
i_mtime dd ?
i_dtime dd ?
i_gid dw ?
i_links_count dw ?
i_blocks dd ?
i_flags dd ?
i_osd1 dd ?
i_block rd 15
i_generation dd ?
i_file_acl dd ?
i_dir_acl dd ?
i_faddr dd ?
i_osd2 dd ? ; 1..12
ends
 
struct EXT2_DIR_STRUC
inode dd ?
rec_len dw ?
name_len db ?
file_type db ?
name db ? ; 0..255
ends
 
struct EXT2_BLOCK_GROUP_DESC
block_bitmap dd ?
inode_bitmap dd ?
inode_table dd ?
free_blocks_count dw ?
free_inodes_count dw ?
used_dirs_count dw ?
ends
 
struct EXT2_SB_STRUC
inodes_count dd ? ;+0
blocks_count dd ? ;+4
r_block_count dd ? ;+8
free_block_count dd ? ;+12
free_inodes_count dd ? ;+16
first_data_block dd ? ;+20
log_block_size dd ? ;+24
log_frag_size dd ? ;+28
blocks_per_group dd ? ;+32
frags_per_group dd ? ;+36
inodes_per_group dd ? ;+40
mtime dd ? ;+44
wtime dd ? ;+48
mnt_count dw ? ;+52
max_mnt_count dw ? ;+54
magic dw ? ;+56
state dw ? ;+58
errors dw ? ;+60
minor_rev_level dw ? ;+62
lastcheck dd ? ;+64
check_intervals dd ? ;+68
creator_os dd ? ;+72
rev_level dd ? ;+76
def_resuid dw ? ;+80
def_resgid dw ? ;+82
first_ino dd ? ;+84
inode_size dw ? ;+88
block_group_nr dw ? ;+90
feature_compat dd ? ;+92
feature_incompat dd ? ;+96
feature_ro_compat dd ? ;+100
uuid rb 16 ;+104
volume_name rb 16 ;+120
last_mounted rb 64 ;+136
algo_bitmap dd ? ;+200
prealloc_blocks db ? ;+204
preallock_dir_blocks db ? ;+205
dw ? ;+206 alignment
journal_uuid rb 16 ;+208
journal_inum dd ? ;+224
journal_dev dd ? ;+228
last_orphan dd ? ;+232
hash_seed rd 4 ;+236
def_hash_version db ? ;+252
rb 3 ;+253 reserved
default_mount_options dd ? ;+256
first_meta_bg dd ? ;+260
ends
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
 
mov eax, [PARTITION_START]
add eax, 2 ;superblock start at 1024b
call hd_read
 
cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3
ja .no
cmp word [ebx+56], 0xEF53 ;s_magic
jne .no
cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1)
jne .no
mov eax, [ebx+96]
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
jnz .no
 
; OK, this is correct EXT2 superblock
clc
ret
.no:
; No, this superblock isn't EXT2
stc
ret
 
ext2_setup:
mov [fs_type], 2
 
push 512
call kernel_alloc ; mem for superblock
mov esi, ebx
mov edi, eax
mov ecx, 512/4
rep movsd ; copy sb to reserved mem
mov ebx, eax
mov [ext2_data.sb], eax
 
mov eax, [ebx + EXT2_SB_STRUC.blocks_count]
sub eax, [ebx + EXT2_SB_STRUC.first_data_block]
dec eax
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ext2_data.groups_count], eax
 
mov ecx, [ebx+24]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ext2_data.count_block_in_block], eax
 
shl eax, 7
mov [ext2_data.count_pointer_in_block], eax
mov edx, eax ; потом еще квадрат найдем
 
shl eax, 2
mov [ext2_data.block_size], eax
 
push eax eax ; 2 kernel_alloc
 
mov eax, edx
mul edx
mov [ext2_data.count_pointer_in_block_square], eax
 
call kernel_alloc
mov [ext2_data.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx+88]
mov ecx, [ebx+32]
mov edx, [ebx+40]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
mov [ext2_data.inodes_per_group], edx
 
push ebp ebp ebp ;3 kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_save_inode], eax
call kernel_alloc
mov [ext2_data.ext2_temp_inode], eax
call kernel_alloc
mov [ext2_data.root_inode], eax
 
mov ebx, eax
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
jmp return_from_part_set
 
;==================================================================
;in: eax = i_block
; ebx = pointer to return memory
ext2_get_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_read
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
;===================================================================
; in: ecx = номер блока в inode (0..)
; ebp = адрес inode
; out: ecx = адрес очередного блока
ext2_get_inode_block:
cmp ecx, 12 ; 0..11 - direct block address
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
cmp ecx, [ext2_data.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
;.get_triple_indirect_block:
push eax edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
xor edx, edx
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
 
;eax - номер в полученном блоке edx - номер дальше
mov eax, [ebx + eax*4]
call ext2_get_block
 
mov eax, edx
jmp @F
 
.get_double_indirect_block:
push eax edx ebx
 
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
mov ecx, [ebx + edx*4]
 
pop ebx edx eax
ret
 
.get_indirect_block:
push eax ebx
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov ecx, [ebx + ecx*4]
pop ebx eax
ret
 
.get_direct_block:
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
ret
 
;===================================================================
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
ext2_get_inode:
 
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
div [ext2_data.inodes_per_group]
 
push edx ;locale num in group
 
mov edx, 32
mul edx ; address block_group in global_desc_table
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
 
div [ext2_data.block_size]
mov ecx, [ext2_data.sb]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx+8] ; номер блока - в терминах ext2
 
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; прибавим локальный адрес inode-а
pop eax ; index
mov ecx, [ext2_data.inode_size]
mul ecx ; (index * inode_size)
mov ebp, 512
div ebp ;поделим на размер блока
 
add eax, esi ;нашли адрес блока для чтения
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
; mov ecx, [ext2_data.inode_size]
rep movsb ;копируем inode
popad
ret
 
;----------------------------------------------------------------
; in: esi -> children
; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed
; ebx -> dir_rec of inode children or trash
ext2_test_block_by_name:
push eax ecx edx edi
 
mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
 
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
mov edi, EXT2_filename
lea esi, [ebx + EXT2_DIR_STRUC.name]
 
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
 
mov edi, EXT2_filename
mov esi, [esp]
@@:
jecxz .test_find
dec ecx
 
lodsb
call char_toupper
 
mov ah, [edi]
inc edi
xchg al, ah
call char_toupper
cmp al, ah
je @B
@@: ;не подошло
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
jb .start_rec
jmp .ret
 
.test_find:
cmp byte [esi], 0
je .find ;нашли конец
cmp byte [esi], '/'
jne @B
inc esi
.find:
pop eax ;удаляем из стека сохраненое значение
.ret:
pop edi edx ecx eax
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdReadFolder:
cmp byte [esi], 0
jz .doit
 
push ecx ebx
call ext2_find_lfn
jnc .doit2
pop ebx
.not_found:
pop ecx
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
push ecx
jmp @F
.doit2:
pop ebx
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .not_found
@@:
xor eax, eax
mov edi, edx
mov ecx, 32/4
rep stosd ; fill header zero
pop edi ; edi = число блоков для чтения
push edx ebx
 
;--------------------------------------------- final step
and [EXT2_read_in_folder], 0
and [EXT2_files_in_folder], 0
 
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax
 
add edx, 32 ; (header pointer in stack) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку
 
.new_block_folder: ;reserved label
mov ecx, esi ; получим номер блока
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
 
mov eax, ebx ; eax = current dir record
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx ; запомним конец очередного блока
 
pop ecx
mov ecx, [ecx] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc [EXT2_files_in_folder]
dec ecx
@@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx ; к следующей записи
cmp eax, [EXT2_end_block] ; проверяем "конец"
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетили из цикла
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jbe .end_dir
 
inc esi ;получаем новый блок
push ecx
mov ecx, esi
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
ret ; опять в цикл
 
.wanted_end:
loop .find_wanted_cycle ; ecx = -1
 
.find_wanted_end:
mov ecx, edi
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc [EXT2_files_in_folder]
inc [EXT2_read_in_folder]
 
mov edi, edx
push eax ecx
xor eax, eax
mov ecx, 40 / 4
rep stosd
pop ecx eax
 
push eax esi edx ;получим inode
mov eax, [eax + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_temp_inode]
call ext2_get_inode
 
lea edi, [edx + 8]
 
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат
xor edx, edx
add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
pop edx ; пока достаем только буфер
test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер
jnz @F ; не возвращаем
 
mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size
stosd
mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size
stosd
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
pop esi eax
 
or dword [edx+4], FS_FT_ASCII ; symbol type in name
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push eax ecx esi
movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [eax + EXT2_DIR_STRUC.name]
call utf8toansi_str
pop esi ecx eax
and byte [edi], 0
 
cmp byte [edx + 40], '.'
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx
cmp eax, [EXT2_end_block]
jb .wanted_start
 
push .wanted_start ; дошли до конца очередного блока
jmp .end_block
 
.end_dir:
pop eax ; мусор (адрес возврата в цикл)
.end_error:
pop edx
mov ebx, [EXT2_read_in_folder]
mov ecx, [EXT2_files_in_folder]
mov dword [edx], 1 ;version
xor eax, eax
mov [edx+4], ebx
mov [edx+8], ecx
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
ret
;====================== end ext2_HdReadFolder
utf8toansi_str:
; convert UTF-8 string to ASCII-string (codepage 866)
; in: ecx=length source, esi->source, edi->buffer
; destroys: eax,esi,edi
jecxz .ret
.start:
lodsw
cmp al, 0x80
jb .ascii
 
xchg al, ah ; big-endian
cmp ax, 0xd080
jz .yo1
cmp ax, 0xd191
jz .yo2
cmp ax, 0xd090
jb .unk
cmp ax, 0xd180
jb .rus1
cmp ax, 0xd190
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xf0 ; Ё capital
jmp .doit
.yo2:
mov al, 0xf1 ; ё small
jmp .doit
.rus1:
sub ax, 0xd090 - 0x80
jmp .doit
.rus2:
sub ax, 0xd18f - 0xEF
.doit:
stosb
sub ecx, 2
ja .start
ret
 
.ascii:
stosb
dec esi
dec ecx
jnz .start
.ret:
ret
 
;----------------------------------------------------------------
;
; ext2_HdRead - read hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdRead:
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ecx ebx
call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
jz .this_is_nofile
 
;-----------------------------------------------------------------------------final step
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
 
;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; а если равно, то не важно куда
 
.size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт)
jmp @F
 
.size_great_great:
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
 
@@:
push ecx ;save for return
test esi, esi
jz .zero_start
 
;пока делаем п..ц криво =)
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
 
mov [EXT2_counter_blocks], eax ;номер блока запоминаем
 
push ecx
mov ecx, eax
call ext2_get_inode_block
mov ebx, [ext2_data.ext2_save_block]
mov eax, ecx
call ext2_get_block
pop ecx
add ebx, edx
 
neg edx
add edx, [ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
cmp ecx, edx
jbe .only_one_block
 
mov eax, ecx
sub eax, edx
mov ecx, edx
 
mov esi, ebx
rep movsb ;кусок 1-го блока
jmp @F
 
.zero_start:
mov eax, ecx
;теперь в eax кол-во оставшихся байт для чтения
@@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
jz .finish_block
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block
add ebx, [ext2_data.block_size]
 
dec edi
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
 
mov ecx, [EXT2_counter_blocks]
inc ecx
call ext2_get_inode_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
mov ecx, edx
 
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
.end_read:
pop ebx
cmp [EXT2_files_in_folder], 0
jz @F
 
mov eax, ERROR_END_OF_FILE
ret
@@:
xor eax, eax
ret
;========================
;in : esi -> name not save: eax ebx ecx
;out: ebp -> inode cf=0
; ebp -> trash cf=1
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
.next_folder:
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков
add eax, [ext2_data.count_block_in_block]
mov [EXT2_end_block], eax
.next_block_folder:
mov eax, [ext2_data.count_block_in_block]
sub [EXT2_end_block], eax
jz .not_found
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
 
mov eax, esi
call ext2_test_block_by_name
cmp eax, esi ;нашли имя?
jz .next_block_folder
 
cmp byte [esi], 0
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
jne .not_found ;нашли, но это не папка
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
mov ebp, ebx
jmp .next_folder
 
.not_found:
stc
ret
.get_inode_ret:
mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
clc
ret
 
 
;========================
 
ext2_HdGetFileInfo:
cmp byte [esi], 0
jz .doit
 
call ext2_find_lfn
jnc .doit2
;.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov ebx, .doit ;неважно что лишь бы этому адресу не '.'
jmp @F
.doit2:
mov ebx, [EXT2_end_block]
add ebx, EXT2_DIR_STRUC.name
@@:
xor eax, eax
mov edi, edx
mov ecx, 40/4
rep stosd ; fill zero
 
cmp byte [ebx], '.'
jnz @F
or dword [edx], FS_FT_HIDDEN
@@:
 
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jnz @F
mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size
mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size
mov dword [edx+32], eax
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
xor eax, eax
ret
 
ext2_HdRewrite:
ext2_HdWrite:
ext2_HdSetFileEnd:
ext2_HdSetFileInfo:
ext2_HdDelete:
ext2_HdCreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
;----------------------------------------------------------------
;
; ext2_HdCreateFolder - create new folder
;
; esi points to filename
;
; ret eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
cmp byte [esi], 0
jz .not_found
cmp byte [esi], '/'
jz .not_found
 
mov ebx, esi ; save source pointer
xor edi, edi ; slah pointer
@@:
lodsb
cmp al, 0
jz .zero
cmp al, '/'
jz .slash
jmp @B
 
.slash:
lodsb
cmp al, 0
jz .zero ; уберем слеш из имени
cmp al, '/'
jz .not_found
mov edi, esi ; edi -> next symbol after '/'
dec edi
jmp @B
 
.zero:
dec esi
test edi, edi
jz .doit
 
;слеш был
mov eax, esi
sub eax, edi
mov [EXT2_name_len], eax
 
mov ecx, edi
sub ecx, ebx
dec ecx ;выкинули '/' из имени ролителя
mov esi, ebx
mov edi, EXT2_parent_name
rep movsb
; esi - pointer to last slash
 
mov edx, esi
mov esi, EXT2_parent_name
call ext2_find_lfn
jnc .doit2
.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov edx, ebx ; имя создаваемой папки
sub esi, ebx
mov [EXT2_name_len], esi
.doit2:
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name
; стратегия выбора группы для нового inode: (так делает линукс)
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
 
 
 
 
call ext2_balloc
jmp ext2_HdDelete
 
push ebx
push ebp
 
mov ecx, [ext2_data.sb]
cmp [ecx + EXT2_SB_STRUC.free_inodes_count], 0 ; есть ли место для inode
jz .no_space
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
cmp eax, 2 ; и как минимум на 2 блока
jb .no_space
 
mov ecx, [ext2_data.groups_count]
mov esi, [ext2_data.global_desc_table]
mov edi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group_dir:
jecxz .end_find_group_dir
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
cmp eax, edx
jbe @F
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
jz @F
mov edi, esi
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
@@:
dec ecx
add esi, 32 ;размер структуры
jmp .find_group_dir
.end_find_group_dir:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту inode-ов (найдем locale number)
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov esi, ebx
mov ecx, [ext2_data.inodes_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ; всего сохраним в ebp
or eax, -1 ; ищем первый свободный inode (!= -1)
repne scasd
jnz .test_last_dword ;нашли или нет
mov eax, [esi-4]
 
sub ebp, ecx
dec ebp
shl ebp, 5 ; глобальный номер локального номера
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; locale num of inode
 
mov eax, [esi-4]
;устанавливаем в eax крайний справа нулевой бит в 1
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1)
mov [esi-4], eax
mov ebx, [ext2_data.ext2_save_block]
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
call ext2_set_block
;считаем таблицу inode
sub edi, [ext2_data.global_desc_table]
shr edi, 5
 
mov eax, edi
mul [ext2_data.inodes_per_group]
add eax, ebp
inc eax ; теперь в eax (ebp) номер inode-а
mov ebp, eax
;call ext2_get_inode_address
 
mov ebx, [ext2_data.ext2_save_block]
call hd_read
add edx, ebx ; в edx адрес нужного inode
 
;забьем 0 для начала
mov edi, edx
mov ecx, [ext2_data.inode_size]
shr ecx, 2
xor eax, eax
rep stosd
 
mov edi, edx
mov eax, EXT2_S_IFDIR or EXT2_777_MODE
stosd ; i_mode
xor eax, eax
stosd ; i_uid
mov eax, [ext2_data.block_size]
stosd ; i_size
xor eax, eax
stosd ; i_atime
stosd ; i_ctime
stosd ; i_mtime
stosd ; i_dtime
stosd ; i_gid
inc eax
stosd ; i_links_count
mov eax, [ext2_data.count_block_in_block]
stosd ; i_blocks
 
 
 
 
.test_last_dword:
 
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
 
 
.no_space:
or ebx, -1
mov eax, ERROR_DISK_FULL
ret
 
;выделяет новый блок, если это можно
;иначе возвращает eax=0
ext2_balloc:
mov ecx, [ext2_data.sb]
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
jbe .no_space
 
mov ecx, [ext2_data.groups_count]
mov edi, [ext2_data.global_desc_table]
;mov esi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group:
jecxz .end_find_group
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
cmp eax, edx
jbe @F
mov esi, edi
mov edx, eax
@@:
dec ecx
add edi, 32 ;размер структуры
jmp .find_group
.end_find_group:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту block-ов
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov edi, ebx
mov ecx, [ext2_data.blocks_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ;всего сохраним в ebp
or eax, -1 ;ищем первый свободный inode (!= -1)
repe scasd
jz .test_last_dword ;нашли или нет
 
mov eax, [edi-4]
sub ebp, ecx
dec ebp
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; ebp = номер блока в группе
 
mov eax, [edi-4]
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
mov [edi-4], eax
 
mov ebx, [ext2_data.ext2_save_block]
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
; call ext2_set_block ; и пишем на hdd новую битовую маску
 
;============== тут получаем номер блока
mov eax, [ext2_data.blocks_per_group]
sub esi, [ext2_data.global_desc_table]
shr esi, 5 ;esi - номер группы
mul esi
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе
mov eax, [ext2_data.sb]
add ebp, [eax + EXT2_SB_STRUC.first_data_block]
 
;теперь поправим глобальную дескрипторную таблицу и суперблок
mov ebx, [ext2_data.sb]
dec [ebx + EXT2_SB_STRUC.free_block_count]
mov eax, 2
add eax, [PARTITION_START]
call hd_write
mov eax, [ebx + EXT2_SB_STRUC.first_data_block]
inc eax
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
call ext2_set_block
 
mov eax, ebx
ret
 
.test_last_dword:
lodsd
mov ecx, [ext2_data.blocks_per_group]
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит
mov edx, ecx
mov ebx, 1
@@:
jecxz .no_space
mov edx, ebx
or edx, eax ; тестируем очередной бит
shl ebx, 1
jmp @B
@@:
sub edx, ecx
dec edx ;номер в последнем блоке
 
 
.no_space:
xor eax, eax
ret
 
;in: eax = i_block
; ebx = pointer to memory
ext2_set_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_write
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
 
/kernel/branches/net/fs/fat12.inc
26,24 → 26,24
 
reserve_flp:
 
cli
cmp [flp_status],0
je reserve_flp_ok
cli
cmp [flp_status], 0
je reserve_flp_ok
 
sti
call change_task
jmp reserve_flp
sti
call change_task
jmp reserve_flp
 
reserve_flp_ok:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status],eax
pop eax
sti
ret
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status], eax
pop eax
sti
ret
 
 
floppy_fileread:
63,455 → 63,455
; 10 = access denied
;--------------------------------------------------------------
 
mov [save_flag],0
mov [path_pointer_flp],edi
test esi,esi ; return ramdisk root
jnz fr_noroot_1
cmp ebx,224/16
jbe fr_do_1
mov eax,5
xor ebx,ebx
mov [flp_status],ebx
ret
mov [save_flag], 0
mov [path_pointer_flp], edi
test esi, esi ; return ramdisk root
jnz fr_noroot_1
cmp ebx, 224/16
jbe fr_do_1
mov eax, 5
xor ebx, ebx
mov [flp_status], ebx
ret
 
fr_do_1:
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status],0
jne fdc_status_error_1
mov edi,edx
dec ebx
shl ebx,9
mov esi,FLOPPY_BUFF
add esi,ebx
shl ecx,9
cld
rep movsb
xor eax,eax
xor ebx,ebx
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status], 0
jne fdc_status_error_1
mov edi, edx
dec ebx
shl ebx, 9
mov esi, FLOPPY_BUFF
add esi, ebx
shl ecx, 9
cld
rep movsb
xor eax, eax
xor ebx, ebx
; mov eax,0 ; ok read
; mov ebx,0
mov [flp_status],eax
ret
mov [flp_status], eax
ret
fdc_status_error_1:
xor eax,eax
mov [flp_status],eax
mov eax,10
or ebx,-1
ret
xor eax, eax
mov [flp_status], eax
mov eax, 10
or ebx, -1
ret
 
fr_noroot_1:
sub esp,32
call expand_filename
sub esp, 32
call expand_filename
frfloppy_1:
test ebx,ebx
jnz frfl5_1
mov ebx,1
test ebx, ebx
jnz frfl5_1
mov ebx, 1
frfl5_1:
test ecx,ecx
jnz frfl6_1
mov ecx,1
test ecx, ecx
jnz frfl6_1
mov ecx, 1
frfl6_1:
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status], 0
jne fdc_status_error_3_1
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
call SeekTrack
mov dh, 14
l.20_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov dl,16
mov edi,FDD_BUFF
inc [FDD_Sector]
call ReadSectWithRetr
cmp [FDC_Status], 0
jne fdc_status_error_3_1
mov dl, 16
mov edi, FDD_BUFF
inc [FDD_Sector]
l.21_1:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
test dl,dl
jnz l.21_1
dec dh
test dh,dh
jnz l.20_1
mov esi, eax ;Name of file we want
mov ecx, 11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx, 21
add edi, ecx ;Advance to next entry
dec dl
test dl, dl
jnz l.21_1
dec dh
test dh, dh
jnz l.20_1
fdc_status_error_3:
mov eax,5 ; file not found ?
or ebx,-1
add esp,32+28
mov [flp_status],0
ret
mov eax, 5 ; file not found ?
or ebx, -1
add esp, 32+28
mov [flp_status], 0
ret
fdc_status_error_3_2:
cmp [FDC_Status],0
je fdc_status_error_3
cmp [FDC_Status], 0
je fdc_status_error_3
fdc_status_error_3_1:
add esp,32+28
jmp fdc_status_error_1
add esp, 32+28
jmp fdc_status_error_1
 
fifound_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifound_2
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx,[ebx-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
jmp fifound_3
mov eax, [path_pointer_flp]
cmp [eax+36], byte 0
je fifound_2
add edi, 0xf
mov eax, [edi]
and eax, 65535
mov ebx, [path_pointer_flp]
add ebx, 36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx, [ebx-11+28] ;file size
mov [esp+20], ebx
mov [esp+24], ebx
jmp fifound_3
fifound_2:
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
mov eax,[edi]
mov ebx, [edi-11+28] ;file size
mov [esp+20], ebx
mov [esp+24], ebx
add edi, 0xf
mov eax, [edi]
fifound_3:
and eax,65535
mov [n_sector],eax ;eax=cluster
and eax, 65535
mov [n_sector], eax ;eax=cluster
frnew_1:
add eax,31 ;bootsector+2*fat+filenames
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_5
mov edi,[esp+8]
call give_back_application_data_1
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12],dword 0
je frnoread_1
jmp frfl8_1
add eax, 31 ;bootsector+2*fat+filenames
cmp [esp+16], dword 0; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status], 0
jne fdc_status_error_5
mov edi, [esp+8]
call give_back_application_data_1
add [esp+8], dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12], dword 0
je frnoread_1
jmp frfl8_1
frfl7_1:
dec dword [esp+16]
dec dword [esp+16]
frfl8_1:
mov edi,[n_sector]
shl edi,1 ;find next cluster from FAT
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
mov edi,eax
mov [n_sector],edi
cmp edi,4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24],dword 512 ;eof - size
jb frnoread_1
sub [esp+24],dword 512
jmp frnew_1
mov edi, [n_sector]
shl edi, 1 ;find next cluster from FAT
add edi, FLOPPY_FAT
mov eax, [edi]
and eax, 4095
mov edi, eax
mov [n_sector], edi
cmp edi, 4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24], dword 512;eof - size
jb frnoread_1
sub [esp+24], dword 512
jmp frnew_1
 
read_chs_sector:
call calculate_chs
call ReadSectWithRetr
ret
call calculate_chs
call ReadSectWithRetr
ret
 
frnoread2_1:
cmp [esp+16],dword 0 ; eof without read ?
je frnoread_1
mov [fdc_irq_func],fdc_null
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
mov [flp_status],0
ret
cmp [esp+16], dword 0; eof without read ?
je frnoread_1
mov [fdc_irq_func], fdc_null
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
mov eax, 6; end of file
mov [flp_status], 0
ret
 
frnoread_1:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax
mov [flp_status],eax
ret
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
xor eax, eax
mov [flp_status], eax
ret
 
fdc_status_error_5:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
jmp fdc_status_error_1
pop edi esi edx ecx
add esp, 4
pop ebx; ebx <- eax : size of file
add esp, 36
jmp fdc_status_error_1
 
read_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_read
cmp [root_read],1
je unnecessary_root_read
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_root_read
cmp [root_read], 1
je unnecessary_root_read
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov edi, FLOPPY_BUFF
call SeekTrack
read_flp_root_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],16
jne read_flp_root_1
mov [root_read],1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi, 512
inc [FDD_Sector]
cmp [FDD_Sector], 16
jne read_flp_root_1
mov [root_read], 1
unnecessary_root_read:
popa
ret
popa
ret
 
 
read_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat
cmp [flp_fat],1
je unnecessary_flp_fat
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_flp_fat
cmp [flp_fat], 1
je unnecessary_flp_fat
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov edi, FLOPPY_BUFF
call SeekTrack
read_flp_fat_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],19
jne read_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read],0
mov [flp_fat],1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi, 512
inc [FDD_Sector]
cmp [FDD_Sector], 19
jne read_flp_fat_1
mov [FDD_Sector], 1
mov [FDD_Head], 1
call ReadSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read], 0
mov [flp_fat], 1
unnecessary_flp_fat:
popa
ret
popa
ret
 
calculatefatchain_flp:
pushad
pushad
 
mov esi,FLOPPY_BUFF
mov edi,FLOPPY_FAT
mov esi, FLOPPY_BUFF
mov edi, FLOPPY_FAT
 
fcnew_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
add edi,4
mov dword [edi],ebx
add edi,4
mov dword [edi],ecx
add edi,4
mov dword [edi],edx
add edi,4
add esi,12
mov eax, dword [esi]
mov ebx, dword [esi+4]
mov ecx, dword [esi+8]
mov edx, ecx
shr edx, 4;8 ok
shr dx, 4;7 ok
xor ch, ch
shld ecx, ebx, 20;6 ok
shr cx, 4;5 ok
shld ebx, eax, 12
and ebx, 0x0fffffff;4 ok
shr bx, 4;3 ok
shl eax, 4
and eax, 0x0fffffff;2 ok
shr ax, 4;1 ok
mov dword [edi], eax
add edi, 4
mov dword [edi], ebx
add edi, 4
mov dword [edi], ecx
add edi, 4
mov dword [edi], edx
add edi, 4
add esi, 12
 
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters
jnz fcnew_1
cmp edi, FLOPPY_FAT+2856*2;2849 clusters
jnz fcnew_1
 
popad
ret
popad
ret
 
check_label:
pushad
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status],0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status],0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error
mov esi,flp_label
mov edi,FDD_BUFF+39
mov ecx,15
cld
rep cmpsb
je same_label
mov [root_read],0
mov [flp_fat],0
pushad
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 1; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status], 0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status], 0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status], 0
jne fdc_status_error
mov esi, flp_label
mov edi, FDD_BUFF+39
mov ecx, 15
cld
rep cmpsb
je same_label
mov [root_read], 0
mov [flp_fat], 0
same_label:
mov esi,FDD_BUFF+39
mov edi,flp_label
mov ecx,15
cld
rep movsb
popad
ret
mov esi, FDD_BUFF+39
mov edi, flp_label
mov ecx, 15
cld
rep movsb
popad
ret
fdc_status_error:
popad
ret
popad
ret
 
save_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_save
cmp [root_read],0
je unnecessary_root_save
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_root_save
cmp [root_read], 0
je unnecessary_root_save
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 1; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov esi, FLOPPY_BUFF
call SeekTrack
save_flp_root_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector],16
jne save_flp_root_1
push esi
call take_data_from_application_1
pop esi
add esi, 512
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector], 16
jne save_flp_root_1
unnecessary_root_save:
mov [fdc_irq_func],fdc_null
popa
ret
mov [fdc_irq_func], fdc_null
popa
ret
 
save_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
cmp [flp_fat],0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
pusha
call check_label
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
cmp [flp_fat], 0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track], 0; Öèëèíäð
mov [FDD_Head], 0; Ñòîðîíà
mov [FDD_Sector], 2; Ñåêòîð
mov esi, FLOPPY_BUFF
call SeekTrack
save_flp_fat_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
mov [root_read],0
push esi
call take_data_from_application_1
pop esi
add esi, 512
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector], 19
jne save_flp_fat_1
mov [FDD_Sector], 1
mov [FDD_Head], 1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status], 0
jne unnecessary_flp_fat_save
mov [root_read], 0
unnecessary_flp_fat_save:
mov [fdc_irq_func],fdc_null
popa
ret
mov [fdc_irq_func], fdc_null
popa
ret
 
 
restorefatchain_flp: ; restore fat chain
pushad
pushad
 
mov esi,FLOPPY_FAT
mov edi,FLOPPY_BUFF
mov esi, FLOPPY_FAT
mov edi, FLOPPY_BUFF
 
fcnew2_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
add edi,4
mov word [edi],bx
add edi,2
add esi,8
mov eax, dword [esi]
mov ebx, dword [esi+4]
shl ax, 4
shl eax, 4
shl bx, 4
shr ebx, 4
shrd eax, ebx, 8
shr ebx, 8
mov dword [edi], eax
add edi, 4
mov word [edi], bx
add edi, 2
add esi, 8
 
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
cmp edi, FLOPPY_BUFF+0x1200;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,FLOPPY_BUFF ; duplicate fat chain
mov edi,FLOPPY_BUFF+0x1200
mov ecx,0x1200/4
cld
rep movsd
mov esi, FLOPPY_BUFF ; duplicate fat chain
mov edi, FLOPPY_BUFF+0x1200
mov ecx, 0x1200/4
cld
rep movsd
 
popad
ret
popad
ret
 
 
save_chs_sector:
call calculate_chs
call WriteSectWithRetr
ret
call calculate_chs
call WriteSectWithRetr
ret
 
calculate_chs:
mov bl,[FDD_Track]
mov [old_track],bl
mov ebx,18
xor edx,edx
div ebx
inc edx
mov [FDD_Sector],dl
xor edx,edx
mov ebx,2
div ebx
mov [FDD_Track],al
mov [FDD_Head],0
test edx,edx
jz no_head_2
inc [FDD_Head]
mov bl, [FDD_Track]
mov [old_track], bl
mov ebx, 18
xor edx, edx
div ebx
inc edx
mov [FDD_Sector], dl
xor edx, edx
mov ebx, 2
div ebx
mov [FDD_Track], al
mov [FDD_Head], 0
test edx, edx
jz no_head_2
inc [FDD_Head]
no_head_2:
mov dl,[old_track]
cmp dl,[FDD_Track]
je no_seek_track_1
call SeekTrack
mov dl, [old_track]
cmp dl, [FDD_Track]
je no_seek_track_1
call SeekTrack
no_seek_track_1:
ret
ret
 
 
get_cluster_of_a_path_flp:
525,40 → 525,40
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
 
push edx
mov edx,ebx
push edx
mov edx, ebx
 
search_end_of_path_flp:
cmp [save_flag],0
jne search_end_of_path_flp_1
cmp byte [edx],0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
cmp [save_flag], 0
jne search_end_of_path_flp_1
cmp byte [edx], 0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
search_end_of_path_flp_1:
cmp byte [edx+12],0
je found_end_of_path_flp
cmp byte [edx+12], 0
je found_end_of_path_flp
search_end_of_path_flp_2:
inc edx ; '/'
call analyze_directory_flp
jc directory_not_found_flp
inc edx; '/'
call analyze_directory_flp
jc directory_not_found_flp
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,0xfff ;[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
mov eax, [ebx+20-2] ; read the HIGH 16bit cluster field
mov ax, [ebx+26] ; read the LOW 16bit cluster field
and eax, 0xfff ;[fatMASK]
add edx, 11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
 
found_end_of_path_flp:
inc edx
mov [pointer_file_name_flp],edx
pop edx
clc ; no errors
ret
inc edx
mov [pointer_file_name_flp], edx
pop edx
clc ; no errors
ret
 
directory_not_found_flp:
pop edx
stc ; errors occour
ret
pop edx
stc ; errors occour
ret
 
analyze_directory_flp:
;--------------------------------
570,62 → 570,62
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
push ebx ;[esp+16]
push ecx
push edx
push esi
push edi
push ebx;[esp+16]
push ecx
push edx
push esi
push edi
 
 
adr56_flp:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne not_found_file_analyze_flp
mov [clust_tmp_flp], eax
add eax, 31
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jne not_found_file_analyze_flp
 
mov ecx,512/32
mov ebx,FDD_BUFF
mov ecx, 512/32
mov ebx, FDD_BUFF
 
adr1_analyze_flp:
mov esi,edx ;[esp+16]
mov edi,ebx
cld
push ecx
mov ecx,11
rep cmpsb
pop ecx
je found_file_analyze_flp
mov esi, edx;[esp+16]
mov edi, ebx
cld
push ecx
mov ecx, 11
rep cmpsb
pop ecx
je found_file_analyze_flp
 
add ebx,32
loop adr1_analyze_flp
add ebx, 32
loop adr1_analyze_flp
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,FLOPPY_FAT
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr56_flp
mov eax, [clust_tmp_flp]
shl eax, 1 ;find next cluster from FAT
add eax, FLOPPY_FAT
mov eax, [eax]
and eax, 4095
cmp eax, 0x0ff8
jb adr56_flp
not_found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
stc ;file not found
ret
pop edi
pop esi
pop edx
pop ecx
add esp, 4
stc ;file not found
ret
 
found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
clc ;file found
ret
pop edi
pop esi
pop edx
pop ecx
add esp, 4
clc ;file found
ret
 
 
; \begin{diamond}
789,7 → 789,7
xor eax, eax
mov edi, FLOPPY_FAT
mov ecx, 2849
repnz scasw
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, FLOPPY_FAT
802,7 → 802,7
xor eax, eax
mov edi, FDD_BUFF
mov ecx, 128
rep stosd
rep stosd
popa
call flp_notroot_end_write
mov edi, FDD_BUFF
1007,7 → 1007,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
1282,7 → 1282,7
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
1307,7 → 1307,7
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
1433,7 → 1433,7
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
1470,14 → 1470,14
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
repnz scasw
mov al, ERROR_DISK_FULL
jnz .ret
dec edi
dec edi
 
mov eax, edi
sub eax, FLOPPY_FAT
mov eax, edi
sub eax, FLOPPY_FAT
 
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
1502,7 → 1502,7
cmp byte [esp+24+28+28], 0
jnz .writedir
push ecx
rep movsb
rep movsb
pop ecx
.writedircont:
push ecx
1510,7 → 1510,7
neg ecx
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
add eax, 31
pusha
1561,7 → 1561,7
push ecx
mov ecx, 32/4
push ecx esi
rep movsd
rep movsd
pop esi ecx
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
1569,7 → 1569,7
mov byte [edi-32+11], 10h
mov word [edi-32+26], ax
push esi
rep movsd
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
1749,7 → 1749,7
jbe @f
mov edi, FDD_BUFF
add edi, [esp+4+12]
rep stosb
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
1757,7 → 1757,7
jbe @f
mov edi, FDD_BUFF
add edi, esi
rep stosb
rep stosb
@@:
pop edi ecx eax
; copy new data
1850,7 → 1850,7
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
2003,7 → 2003,7
add edi, [esp+8]
xor eax, eax
mov [esp+8], eax
rep stosb
rep stosb
pop edi
lea eax, [edi+31]
pusha
2083,7 → 2083,7
sub ecx, edi
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
pusha
call save_chs_sector
/kernel/branches/net/fs/fat32.inc
60,6 → 60,7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
93,10 → 94,13
 
uglobal
align 4
fat_cache: times 512 db 0
fat_cache:
times 512 db 0
Sector512: ; label for dev_hdcd.inc
buffer: times 512 db 0
fsinfo_buffer: times 512 db 0
buffer:
times 512 db 0
fsinfo_buffer:
times 512 db 0
endg
 
uglobal
106,24 → 110,24
 
reserve_hd1:
 
cli
cmp [hd1_status],0
je reserve_ok1
cli
cmp [hd1_status], 0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status],eax
pop eax
sti
ret
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status], eax
pop eax
sti
ret
;********************************************
 
uglobal
135,22 → 139,22
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1],0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2],0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
168,8 → 172,8
mov [hd_in_cache], al
call clear_hd_cache
@@:
pop eax
sti
pop eax
sti
.ret:
ret
 
177,15 → 181,15
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
mov [IDE_Channel_1], 0
.ret:
ret
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
mov [IDE_Channel_2], 0
ret
;********************************************
problem_partition db 0 ; used for partitions search
 
197,67 → 201,67
; EDX = value to save
; output : EDX = old value
;--------------------------------
push eax ebx esi
push eax ebx esi
 
cmp eax,2
jb sfc_error
cmp eax,[LAST_CLUSTER]
ja sfc_error
cmp [fs_type],16
je sfc_1
add eax,eax
cmp eax, 2
jb sfc_error
cmp eax, [LAST_CLUSTER]
ja sfc_error
cmp [fs_type], 16
je sfc_1
add eax, eax
sfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je sfc_in_cache ; yes
cmp eax, [fat_in_cache]; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [fat_change],0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne sfc_error
cmp [fat_change], 0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne sfc_error
 
sfc_no_change:
mov [fat_in_cache],eax ; save fat sector
call hd_read
cmp [hd_error],0
jne sfc_error
mov [fat_in_cache], eax; save fat sector
call hd_read
cmp [hd_error], 0
jne sfc_error
 
 
sfc_in_cache:
cmp [fs_type],16
jne sfc_test32
cmp [fs_type], 16
jne sfc_test32
 
sfc_set16:
xchg [ebx+esi],dx ; save new value and get old value
jmp sfc_write
xchg [ebx+esi], dx ; save new value and get old value
jmp sfc_write
 
sfc_test32:
mov eax,[fatMASK]
mov eax, [fatMASK]
 
sfc_set32:
and edx,eax
xor eax,-1 ; mask for high bits
and eax,[ebx+esi] ; get high 4 bits
or eax,edx
mov edx,[ebx+esi] ; get old value
mov [ebx+esi],eax ; save new value
and edx, eax
xor eax, -1 ; mask for high bits
and eax, [ebx+esi] ; get high 4 bits
or eax, edx
mov edx, [ebx+esi] ; get old value
mov [ebx+esi], eax ; save new value
 
sfc_write:
mov [fat_change],1 ; fat has changed
mov [fat_change], 1 ; fat has changed
 
sfc_nonzero:
and edx,[fatMASK]
and edx, [fatMASK]
 
sfc_error:
pop esi ebx eax
ret
pop esi ebx eax
ret
 
 
get_FAT:
265,40 → 269,40
; input : EAX = cluster
; output : EAX = next cluster
;--------------------------------
push ebx esi
push ebx esi
 
cmp [fs_type],16
je gfc_1
add eax,eax
cmp [fs_type], 16
je gfc_1
add eax, eax
gfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
add eax, eax
mov esi, 511
and esi, eax ; esi = position in fat sector
shr eax, 9 ; eax = fat sector
add eax, [FAT_START]
mov ebx, fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je gfc_in_cache
cmp eax, [fat_in_cache]; is fat sector already in memory?
je gfc_in_cache
 
cmp [fat_change],0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne hd_error_01
cmp [fat_change], 0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector; yes. write it into disk
cmp [hd_error], 0
jne hd_error_01
 
gfc_no_change:
mov [fat_in_cache],eax
call hd_read
cmp [hd_error],0
jne hd_error_01
mov [fat_in_cache], eax
call hd_read
cmp [hd_error], 0
jne hd_error_01
 
gfc_in_cache:
mov eax,[ebx+esi]
and eax,[fatMASK]
mov eax, [ebx+esi]
and eax, [fatMASK]
hd_error_01:
pop esi ebx
ret
pop esi ebx
ret
 
 
get_free_FAT:
307,45 → 311,45
; if CARRY=1 disk full
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx,[LAST_CLUSTER] ; counter for full disk
sub ecx,2
mov eax,[fatStartScan]
cmp eax,2
jb gff_reset
push ecx
mov ecx, [LAST_CLUSTER]; counter for full disk
sub ecx, 2
mov eax, [fatStartScan]
cmp eax, 2
jb gff_reset
 
gff_test:
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
jbe gff_in_range
cmp eax, [LAST_CLUSTER]; if above last cluster start at cluster 2
jbe gff_in_range
gff_reset:
mov eax,2
mov eax, 2
 
gff_in_range:
push eax
call get_FAT ; get cluster state
cmp [hd_error],0
jne gff_not_found_1
push eax
call get_FAT ; get cluster state
cmp [hd_error], 0
jne gff_not_found_1
 
test eax,eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
test eax, eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
 
gff_not_found_1:
add esp,4
add esp, 4
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
pop ecx ; yes. disk is full
stc
ret
 
gff_found:
lea ecx,[eax+1]
mov [fatStartScan],ecx
pop ecx
clc
ret
lea ecx, [eax+1]
mov [fatStartScan], ecx
pop ecx
clc
ret
 
 
write_fat_sector:
352,27 → 356,27
;-----------------------------------------------------------
; write changed fat to disk
;-----------------------------------------------------------
push eax ebx ecx
push eax ebx ecx
 
mov [fat_change],0
mov eax,[fat_in_cache]
cmp eax,-1
jz write_fat_not_used
mov ebx,fat_cache
mov ecx,[NUMBER_OF_FATS]
mov [fat_change], 0
mov eax, [fat_in_cache]
cmp eax, -1
jz write_fat_not_used
mov ebx, fat_cache
mov ecx, [NUMBER_OF_FATS]
 
write_next_fat:
call hd_write
cmp [hd_error],0
jne write_fat_not_used
call hd_write
cmp [hd_error], 0
jne write_fat_not_used
 
add eax,[SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
add eax, [SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
write_fat_not_used:
pop ecx ebx eax
ret
pop ecx ebx eax
ret
 
 
analyze_directory:
387,91 → 391,91
; Note : if cluster=0 it's changed to read rootdir
; save 2 previous directory sectors in longname_sec
;-----------------------------------------------------------
push ecx edx esi edi ebx ; ebx = [esp+0]
mov [longname_sec1],0
mov [longname_sec2],0
push ecx edx esi edi ebx; ebx = [esp+0]
mov [longname_sec1], 0
mov [longname_sec2], 0
 
adr_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adr_data_cluster
mov [cluster_tmp], eax
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax, 2
jnb adr_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne adr_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adr_new_sector
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne adr_data_cluster
mov eax, [ROOT_START]
mov edx, [ROOT_SECTORS]
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp adr_new_sector
 
adr_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
sub eax, 2
mov edx, [SECTORS_PER_CLUSTER]
imul eax, edx
add eax, [DATA_START]
 
adr_new_sector:
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne adr_not_found
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jne adr_not_found
 
mov ecx,512/32 ; count of dir entrys per sector = 16
mov ecx, 512/32 ; count of dir entrys per sector = 16
 
adr_analyze:
mov edi,[ebx+11] ; file attribute
and edi,0xf
cmp edi,0xf
je adr_long_filename
test edi,0x8 ; skip over volume label
jne adr_long_filename ; Note: label can be same name as file/dir
mov edi, [ebx+11] ; file attribute
and edi, 0xf
cmp edi, 0xf
je adr_long_filename
test edi, 0x8 ; skip over volume label
jne adr_long_filename; Note: label can be same name as file/dir
 
mov esi,[esp+0] ; filename need to be uppercase
mov edi,ebx
push ecx
mov ecx,11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
mov esi, [esp+0] ; filename need to be uppercase
mov edi, ebx
push ecx
mov ecx, 11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
 
adr_long_filename:
add ebx,32 ; position of next dir entry
dec ecx
jnz adr_analyze
add ebx, 32 ; position of next dir entry
dec ecx
jnz adr_analyze
 
mov ecx,[longname_sec1] ; save 2 previous directory sectors
mov [longname_sec1],eax ; for delete long filename
mov [longname_sec2],ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adr_not_found
mov ecx, [longname_sec1]; save 2 previous directory sectors
mov [longname_sec1], eax; for delete long filename
mov [longname_sec2], ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root], 1 ; end of fat16 rootdir
je adr_not_found
 
adr_next_cluster:
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error],0
jne adr_not_found
mov eax, [cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error], 0
jne adr_not_found
 
cmp eax,2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adr_new_cluster ; no. analyse it
cmp eax, 2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax, [fatRESERVED]; is it end of directory?
jb adr_new_cluster ; no. analyse it
 
adr_not_found:
pop edi edi esi edx ecx ; first edi will remove ebx
stc ; file not found
ret
pop edi edi esi edx ecx; first edi will remove ebx
stc ; file not found
ret
 
adr_found:
pop edi edi esi edx ecx ; first edi will remove ebx
clc ; file found
ret
pop edi edi esi edx ecx; first edi will remove ebx
clc ; file found
ret
 
 
get_data_cluster:
484,59 → 488,59
; if CARRY=1 cluster out of range
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push eax ecx
push eax ecx
 
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax,2
jnb gdc_cluster
mov [fat16_root], 0
cmp eax, [LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax, 2
jnb gdc_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne gdc_cluster
mov eax,[ROOT_START]
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
mov [fat16_root],1 ; flag for fat16 rootdir
jmp gdc_read
mov eax, [ROOT_CLUSTER]; if cluster < 2 then read rootdir
cmp [fs_type], 16
jne gdc_cluster
mov eax, [ROOT_START]
mov ecx, [ROOT_SECTORS]; Note: not cluster size
mov [fat16_root], 1 ; flag for fat16 rootdir
jmp gdc_read
 
gdc_cluster:
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
sub eax, 2
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
 
gdc_read:
test esi,esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
test esi, esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
 
gdcl1:
call hd_read
cmp [hd_error],0
jne gdc_error
call hd_read
cmp [hd_error], 0
jne gdc_error
 
add ebx,512 ; update pointer
dec edx
add ebx, 512 ; update pointer
dec edx
 
gdcl2:
test edx,edx ; is all read?
je out_of_read
test edx, edx ; is all read?
je out_of_read
 
inc eax ; next sector
dec ecx
jnz gdc_read
inc eax ; next sector
dec ecx
jnz gdc_read
 
out_of_read:
pop ecx eax
clc
ret
pop ecx eax
clc
ret
 
gdc_error:
pop ecx eax
stc
ret
pop ecx eax
stc
ret
 
 
get_cluster_of_a_path:
549,35 → 553,35
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx edx
push ebx edx
 
mov eax,[ROOT_CLUSTER]
mov edx,ebx
mov eax, [ROOT_CLUSTER]
mov edx, ebx
 
search_end_of_path:
cmp byte [edx],0
je found_end_of_path
cmp byte [edx], 0
je found_end_of_path
 
inc edx ; '/'
mov ebx,edx
call analyze_directory
jc directory_not_found
inc edx; '/'
mov ebx, edx
call analyze_directory
jc directory_not_found
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path
mov eax, [ebx+20-2] ; read the HIGH 16bit cluster field
mov ax, [ebx+26] ; read the LOW 16bit cluster field
and eax, [fatMASK]
add edx, 11 ; 8+3 (name+extension)
jmp search_end_of_path
 
found_end_of_path:
pop edx ebx
clc ; no errors
ret
pop edx ebx
clc ; no errors
ret
 
directory_not_found:
pop edx ebx
stc ; errors occour
ret
pop edx ebx
stc ; errors occour
ret
 
 
bcd2bin:
586,11 → 590,11
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
xor ah,ah
shl ax,4
shr al,4
aad
ret
xor ah, ah
shl ax, 4
shr al, 4
aad
ret
 
 
get_date_for_file:
600,26 → 604,26
; 5..8 : month of year 1..12
; 9..15 : count of years from 1980
;-----------------------------------------------------
mov al,0x7 ;day
out 0x70,al
in al,0x71
call bcd2bin
ror eax,5
mov al, 0x7 ;day
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 5
 
mov al,0x8 ;month
out 0x70,al
in al,0x71
call bcd2bin
ror eax,4
mov al, 0x8 ;month
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 4
 
mov al,0x9 ;year
out 0x70,al
in al,0x71
call bcd2bin
add ax,20 ;because CMOS return only the two last
mov al, 0x9 ;year
out 0x70, al
in al, 0x71
call bcd2bin
add ax, 20 ;because CMOS return only the two last
;digit (eg. 2000 -> 00 , 2001 -> 01) and we
rol eax,9 ;need the difference with 1980 (eg. 2001-1980)
ret
rol eax, 9 ;need the difference with 1980 (eg. 2001-1980)
ret
 
 
get_time_for_file:
629,24 → 633,24
; 5..10 : minute 0..59
; 11..15 : hour 0..23
;-----------------------------------------------------
mov al,0x0 ;second
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
mov al, 0x0 ;second
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 6
 
mov al,0x2 ;minute
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
mov al, 0x2 ;minute
out 0x70, al
in al, 0x71
call bcd2bin
ror eax, 6
 
mov al,0x4 ;hour
out 0x70,al
in al,0x71
call bcd2bin
rol eax,11
ret
mov al, 0x4 ;hour
out 0x70, al
in al, 0x71
call bcd2bin
rol eax, 11
ret
 
 
set_current_time_for_entry:
654,13 → 658,13
; Set current time/date for file entry
; input : ebx = file entry pointer
;-----------------------------------------------------
push eax
call get_time_for_file ; update files date/time
mov [ebx+22],ax
call get_date_for_file
mov [ebx+24],ax
pop eax
ret
push eax
call get_time_for_file; update files date/time
mov [ebx+22], ax
call get_date_for_file
mov [ebx+24], ax
pop eax
ret
 
 
 
670,33 → 674,33
; Note : negative = remove clusters from free space
; positive = add clusters to free space
;-----------------------------------------------------
test ecx,ecx ; no change
je add_dfs_no
cmp [fs_type],32 ; free disk space only used by fat32
jne add_dfs_no
test ecx, ecx ; no change
je add_dfs_no
cmp [fs_type], 32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
mov eax,[ADR_FSINFO]
mov ebx,fsinfo_buffer
call hd_read
cmp [hd_error],0
jne add_not_fs
push eax ebx
mov eax, [ADR_FSINFO]
mov ebx, fsinfo_buffer
call hd_read
cmp [hd_error], 0
jne add_not_fs
 
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id
jne add_not_fs
cmp dword [ebx+0x1fc], 0xaa550000; check sector id
jne add_not_fs
 
add [ebx+0x1e8],ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
add [ebx+0x1e8], ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
pop ebx eax
 
add_dfs_no:
ret
ret
 
 
file_read:
723,113 → 727,113
jz fat_ok_for_reading
cmp [fs_type], 32
jz fat_ok_for_reading
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
xor ebx, ebx
mov eax, ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
 
fat_ok_for_reading:
; call reserve_hd1
 
pushad
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_read_not_found
mov ebx, edx
call get_cluster_of_a_path
jc file_to_read_not_found
 
test edi,edi ; read rootdir
jne no_read_root
test edi, edi ; read rootdir
jne no_read_root
 
xor eax,eax
call get_dir_size ; return rootdir size
cmp [hd_error],0
jne file_access_denied
xor eax, eax
call get_dir_size ; return rootdir size
cmp [hd_error], 0
jne file_access_denied
 
mov [file_size],eax
mov eax,[ROOT_CLUSTER]
jmp file_read_start
mov [file_size], eax
mov eax, [ROOT_CLUSTER]
jmp file_read_start
 
no_read_root:
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
mov ebx, PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
 
mov eax,[ebx+28] ; file size
test byte [ebx+11],0x10 ; is it directory?
jz read_set_size ; no
mov eax, [ebx+28] ; file size
test byte [ebx+11], 0x10; is it directory?
jz read_set_size ; no
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
call get_dir_size
cmp [hd_error],0
jne file_access_denied
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
call get_dir_size
cmp [hd_error], 0
jne file_access_denied
 
read_set_size:
mov [file_size],eax
mov [file_size], eax
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
mov eax, [ebx+20-2] ; FAT entry
mov ax, [ebx+26]
and eax, [fatMASK]
 
file_read_start:
mov ebx,PUSHAD_ECX ; pointer to buffer
mov edx,PUSHAD_EBX ; file blocks to read
mov esi,PUSHAD_ESI ; first 512 block to read
mov ebx, PUSHAD_ECX ; pointer to buffer
mov edx, PUSHAD_EBX ; file blocks to read
mov esi, PUSHAD_ESI ; first 512 block to read
 
file_read_new_cluster:
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
 
test edx,edx ; is all read?
je file_read_OK ; yes
test edx, edx ; is all read?
je file_read_OK ; yes
 
call get_FAT ; get next cluster
cmp [hd_error],0
jne file_access_denied
call get_FAT ; get next cluster
cmp [hd_error], 0
jne file_access_denied
 
cmp eax,[fatRESERVED] ; end of file
jnb file_read_eof
cmp eax,2 ; incorrect fat chain
jnb file_read_new_cluster
cmp eax, [fatRESERVED]; end of file
jnb file_read_eof
cmp eax, 2 ; incorrect fat chain
jnb file_read_new_cluster
 
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_FAT_TABLE
ret
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_FAT_TABLE
ret
 
file_read_eof:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_END_OF_FILE
ret
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
mov ebx, [file_size]
mov eax, ERROR_END_OF_FILE
ret
 
file_read_OK:
popad
mov [hd1_status],0
mov ebx,[file_size]
xor eax,eax
ret
popad
mov [hd1_status], 0
mov ebx, [file_size]
xor eax, eax
ret
 
file_to_read_not_found:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
cmp [hd_error], 0
jne file_access_denied
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_FILE_NOT_FOUND
ret
 
file_access_denied:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_ACCESS_DENIED
ret
popad
mov [hd1_status], 0
xor ebx, ebx
mov eax, ERROR_ACCESS_DENIED
ret
 
get_dir_size:
;-----------------------------------------------------
836,36 → 840,36
; input : eax = first cluster (0=rootdir)
; output : eax = directory size in bytes
;-----------------------------------------------------
push edx
xor edx,edx ; count of directory clusters
test eax,eax
jnz dir_size_next
push edx
xor edx, edx ; count of directory clusters
test eax, eax
jnz dir_size_next
 
mov eax,[ROOT_SECTORS]
shl eax,9 ; fat16 rootdir size in bytes
cmp [fs_type],16
je dir_size_ret
mov eax,[ROOT_CLUSTER]
mov eax, [ROOT_SECTORS]
shl eax, 9 ; fat16 rootdir size in bytes
cmp [fs_type], 16
je dir_size_ret
mov eax, [ROOT_CLUSTER]
 
dir_size_next:
cmp eax,2 ; incorrect fat chain
jb dir_size_end
cmp eax,[fatRESERVED] ; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error],0
jne dir_size_ret
cmp eax, 2 ; incorrect fat chain
jb dir_size_end
cmp eax, [fatRESERVED]; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error], 0
jne dir_size_ret
 
inc edx
jmp dir_size_next
inc edx
jmp dir_size_next
 
dir_size_end:
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
imul eax,edx
imul eax, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
imul eax, edx
 
dir_size_ret:
pop edx
ret
pop edx
ret
 
 
clear_cluster_chain:
872,31 → 876,31
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
push eax ecx edx
xor ecx,ecx ; cluster count
push eax ecx edx
xor ecx, ecx ; cluster count
 
clean_new_chain:
cmp eax,[LAST_CLUSTER] ; end of file
ja delete_OK
cmp eax,2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz delete_OK
cmp eax, [LAST_CLUSTER]; end of file
ja delete_OK
cmp eax, 2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax, [ROOT_CLUSTER]; don't remove root cluster
jz delete_OK
 
xor edx,edx
call set_FAT ; clear fat entry
cmp [hd_error],0
jne access_denied_01
xor edx, edx
call set_FAT ; clear fat entry
cmp [hd_error], 0
jne access_denied_01
 
inc ecx ; update cluster count
mov eax,edx ; old cluster
jmp clean_new_chain
inc ecx ; update cluster count
mov eax, edx ; old cluster
jmp clean_new_chain
 
delete_OK:
call add_disk_free_space ; add clusters to free disk space
call add_disk_free_space; add clusters to free disk space
access_denied_01:
pop edx ecx eax
ret
pop edx ecx eax
ret
 
 
get_hd_info:
912,65 → 916,65
jz info_fat_ok
cmp [fs_type], 32
jz info_fat_ok
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_UNKNOWN_FS
ret
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_UNKNOWN_FS
ret
 
info_fat_ok:
; call reserve_hd1
 
xor ecx,ecx ; count of free clusters
mov eax,2
mov ebx,[LAST_CLUSTER]
xor ecx, ecx ; count of free clusters
mov eax, 2
mov ebx, [LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
cmp [hd_error],0
jne info_access_denied
push eax
call get_FAT ; get cluster info
cmp [hd_error], 0
jne info_access_denied
 
test eax,eax ; is it free?
jnz info_used ; no
inc ecx
test eax, eax ; is it free?
jnz info_used ; no
inc ecx
 
info_used:
pop eax
inc eax
cmp eax,ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
pop eax
inc eax
cmp eax, ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
mov [hd1_status],0
xor eax,eax
ret
dec ebx ; cluster count
imul edx, [SECTORS_PER_CLUSTER], 512; cluster size in bytes
mov [hd1_status], 0
xor eax, eax
ret
 
info_access_denied:
add esp,4
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_ACCESS_DENIED
ret
add esp, 4
xor edx, edx
xor ebx, ebx
xor ecx, ecx
mov eax, ERROR_ACCESS_DENIED
ret
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [fat_change],0 ; is fat changed?
je upd_no_change
cmp [fat_change], 0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
cmp [hd_error],0
jne update_disk_acces_denied
call write_fat_sector
cmp [hd_error], 0
jne update_disk_acces_denied
 
upd_no_change:
 
call write_cache
call write_cache
update_disk_acces_denied:
ret
ret
 
 
; \begin{diamond}
1049,44 → 1053,46
jz @f
cmp [fs_type], 1
jz ntfs_HdRead
cmp [fs_type], 2
jz ext2_HdRead
or ebx, -1
mov eax, ERROR_UNKNOWN_FS
ret
@@:
push edi
cmp byte [esi], 0
jnz @f
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
test byte [edi+11], 0x10 ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
test byte [edi+11], 0x10; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6
pop edi
ret
mov eax, 6
pop edi
ret
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
push ecx edx
push 0
1098,74 → 1104,74
mov ecx, eax
mov byte [esp], 6
@@:
mov eax, [edi+20-2]
mov ax, [edi+26]
mov eax, [edi+20-2]
mov ax, [edi+26]
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_cluster:
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
.new_sector:
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
; we may read directly to given buffer
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error],0
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error], 0
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
.force_buf:
; we must read sector to temporary buffer and then copy it to destination
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error],0
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
mov ecx, 512
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error], 0
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
mov ecx, 512
@@:
sub ecx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
pop eax
xor ebx, ebx
sub ecx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
pop eax
xor ebx, ebx
.skip:
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error],0
jne .noaccess_1
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error], 0
jne .noaccess_1
 
jmp .new_cluster
jmp .new_cluster
.noaccess_3:
pop eax
.noaccess_1:
1200,6 → 1206,8
fs_HdReadFolder:
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
1241,7 → 1249,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
1520,7 → 1528,7
mov edi, buffer
push edi
xor eax, eax
rep stosd
rep stosd
pop edi
pop ecx
mov eax, [esp+4]
1586,6 → 1594,8
.common:
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
1758,7 → 1768,7
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
1783,7 → 1793,7
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
1914,7 → 1924,7
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
1989,13 → 1999,13
push ecx
mov edi, buffer
mov ebx, edi
rep movsb
rep movsb
.writedircont:
mov ecx, buffer+0x200
sub ecx, edi
push eax
xor eax, eax
rep stosb
rep stosb
pop eax
pop ecx
.writecommon:
2068,7 → 2078,7
dec dword [esp+16]
push esi
mov ecx, 32/4
rep movsd
rep movsd
pop esi
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
2076,7 → 2086,7
mov byte [edi-32+11], 10h
push esi
mov ecx, 32/4
rep movsd
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
2120,6 → 2130,8
fs_HdWrite:
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2286,7 → 2298,7
jbe @f
mov edi, buffer
add edi, [esp+4+12]
rep stosb
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
2294,7 → 2306,7
jbe @f
mov edi, buffer
add edi, esi
rep stosb
rep stosb
@@:
pop edi ecx
; copy new data
2336,7 → 2348,8
sub dword [esp], 0x200
jae @f
and dword [esp], 0
@@: jmp .write_loop
@@:
jmp .write_loop
 
hd_extend_file.zero_size:
xor eax, eax
2445,7 → 2458,8
cmp [hd_error], 0
jz @f
mov al, 11
@@: stc
@@:
stc
ret
 
;----------------------------------------------------------------
2463,6 → 2477,8
fs_HdSetFileEnd:
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2578,7 → 2594,7
push eax
xor eax, eax
mov [esp+12], eax
rep stosb
rep stosb
pop eax
pop edi
call hd_write
2678,7 → 2694,7
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
rep stosb
pop eax
call hd_write
pop ebx
2695,6 → 2711,8
fs_HdGetFileInfo:
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2723,6 → 2741,8
fs_HdSetFileInfo:
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
2773,6 → 2793,8
fs_HdDelete:
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 2
jz ext2_HdDelete
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
/kernel/branches/net/fs/fs.inc
21,12 → 21,14
 
 
iglobal
dir0: db 'HARDDISK '
dir0:
db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
 
dir1: db 'FIRST '
dir1:
db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
34,7 → 36,8
 
not_select_IDE db 0
 
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10
hd_address_table:
dd 0x1f0,0x00,0x1f0,0x10
dd 0x170,0x00,0x170,0x10
endg
 
89,178 → 92,178
; Extract parameters
; add eax, std_application_base_address ; abs start of info block
 
cmp dword [eax+0],15 ; GET_DISK_INFO
je fs_info
cmp dword [eax+0], 15; GET_DISK_INFO
je fs_info
 
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx,eax
cmp dword [eax+0],1
jnz .usual_check
mov ebx,[eax+12]
cmp dword [CURRENT_TASK], 1; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx, eax
cmp dword [eax+0], 1
jnz .usual_check
mov ebx, [eax+12]
; add ebx,std_application_base_address
mov ecx,[eax+8]
call check_region
test eax,eax
jnz area_in_app_mem
mov ecx, [eax+8]
call check_region
test eax, eax
jnz area_in_app_mem
 
.error_output:
mov esi,buffer_failed
call sys_msg_board_str
mov esi, buffer_failed
call sys_msg_board_str
; mov eax,7
mov dword [esp+36],7
ret
mov dword [esp+36], 7
ret
iglobal
buffer_failed db 'K : Buffer check failed',13,10,0
endg
.usual_check:
cmp dword [eax+0],0
mov ecx,512
jnz .small_size
mov ecx,[eax+8]
shl ecx,9
cmp dword [eax+0], 0
mov ecx, 512
jnz .small_size
mov ecx, [eax+8]
shl ecx, 9
.small_size:
mov ebx,[eax+12]
mov ebx, [eax+12]
; add ebx,std_application_base_address
call check_region
test eax,eax
jz .error_output
call check_region
test eax, eax
jz .error_output
area_in_app_mem:
mov eax,edx
mov eax, edx
no_checks_for_kernel:
 
fs_read:
 
mov ebx,[eax+20] ; program wants root directory ?
test bl,bl
je fs_getroot
test bh,bh
jne fs_noroot
mov ebx, [eax+20] ; program wants root directory ?
test bl, bl
je fs_getroot
test bh, bh
jne fs_noroot
fs_getroot:
; \begin{diamond}[18.03.2006]
; root - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
.read_root:
; \end{diamond}[18.03.2006]
mov esi,dir0
mov edi,[eax+12]
mov esi, dir0
mov edi, [eax+12]
; add edi,std_application_base_address
mov ecx,11
push ecx
mov ecx, 11
push ecx
; cld ; already is
rep movsb
mov al,0x10
stosb
add edi,32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*2 ; size of root
ret
rep movsb
mov al, 0x10
stosb
add edi, 32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36], 0; ok read
mov dword [esp+24], 32*2; size of root
ret
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21],byte 'h'
je fs_info_h
cmp [eax+21],byte 'H'
je fs_info_h
cmp [eax+21],byte 'r'
je fs_info_r
cmp [eax+21],byte 'R'
je fs_info_r
mov eax,3 ;if unknown disk
xor ebx,ebx
xor ecx,ecx
xor edx,edx
jmp fs_info1
push eax
cmp [eax+21], byte 'h'
je fs_info_h
cmp [eax+21], byte 'H'
je fs_info_h
cmp [eax+21], byte 'r'
je fs_info_r
cmp [eax+21], byte 'R'
je fs_info_r
mov eax, 3 ;if unknown disk
xor ebx, ebx
xor ecx, ecx
xor edx, edx
jmp fs_info1
fs_info_r:
call ramdisk_free_space ;if ramdisk
mov ecx,edi ;free space in ecx
shr ecx,9 ;free clusters
mov ebx,2847 ;total clusters
mov edx,512 ;cluster size
xor eax,eax ;always 0
jmp fs_info1
call ramdisk_free_space;if ramdisk
mov ecx, edi ;free space in ecx
shr ecx, 9 ;free clusters
mov ebx, 2847 ;total clusters
mov edx, 512 ;cluster size
xor eax, eax ;always 0
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
call get_hd_info
fs_info1:
pop edi
mov [esp+36],eax
mov [esp+24],ebx ; total clusters on disk
mov [esp+32],ecx ; free clusters on disk
mov [edi],edx ; cluster size in bytes
ret ;end of code - Mihasik
pop edi
mov [esp+36], eax
mov [esp+24], ebx ; total clusters on disk
mov [esp+32], ecx ; free clusters on disk
mov [edi], edx ; cluster size in bytes
ret ;end of code - Mihasik
 
fs_noroot:
 
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx,[eax+12]
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx, [eax+12]
; add ebx,std_application_base_address
push ebx ; abs start of return/save area
push ebx ; abs start of return/save area
 
lea esi,[eax+20] ; abs start of dir + filename
mov edi,[eax+16]
lea esi, [eax+20] ; abs start of dir + filename
mov edi, [eax+16]
; add edi,std_application_base_address ; abs start of work area
 
call expand_pathz
call expand_pathz
 
push edi ; dir start
push ebx ; name of file start
push edi ; dir start
push ebx ; name of file start
 
mov eax,[edi+1]
cmp eax,'RD '
je fs_yesramdisk
cmp eax,'RAMD'
jne fs_noramdisk
mov eax, [edi+1]
cmp eax, 'RD '
je fs_yesramdisk
cmp eax, 'RAMD'
jne fs_noramdisk
 
fs_yesramdisk:
 
cmp byte [edi+1+11],0
je fs_give_dir1
cmp byte [edi+1+11], 0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesramdisk_first
cmp eax,'FIRS'
jne fs_noramdisk
mov eax, [edi+1+12]
cmp eax, '1 '
je fs_yesramdisk_first
cmp eax, 'FIRS'
jne fs_noramdisk
 
fs_yesramdisk_first:
 
cmp dword [esp+20],8 ; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
cmp dword [esp+20], 8; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
 
mov eax,[esp+16] ; LBA block to read
mov ecx,[esp+8] ; abs pointer to return area
mov eax, [esp+16] ; LBA block to read
mov ecx, [esp+8] ; abs pointer to return area
 
call LBA_read_ramdisk
jmp file_system_return
call LBA_read_ramdisk
jmp file_system_return
 
 
fs_no_LBA_read_ramdisk:
 
cmp dword [esp+20],0 ; READ
jne fs_noramdisk_read
cmp dword [esp+20], 0; READ
jne fs_noramdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call fileread
mov eax, [esp+4] ; fname
add eax, 2*12+1
mov ebx, [esp+16] ; block start
inc ebx
mov ecx, [esp+12] ; block count
mov edx, [esp+8] ; return
mov esi, [esp+0]
sub esi, eax
add esi, 12+1 ; file name length
call fileread
 
jmp file_system_return
jmp file_system_return
 
 
fs_noramdisk_read:
267,50 → 270,50
fs_noramdisk:
 
;********************************************************************
mov eax,[edi+1]
cmp eax,'FD '
je fs_yesflpdisk
cmp eax,'FLOP'
jne fs_noflpdisk
mov eax, [edi+1]
cmp eax, 'FD '
je fs_yesflpdisk
cmp eax, 'FLOP'
jne fs_noflpdisk
 
fs_yesflpdisk:
call reserve_flp
call reserve_flp
 
cmp byte [edi+1+11],0
je fs_give_dir1
cmp byte [edi+1+11], 0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesflpdisk_first
cmp eax,'FIRS'
je fs_yesflpdisk_first
cmp eax,'2 '
je fs_yesflpdisk_second
cmp eax,'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
mov eax, [edi+1+12]
cmp eax, '1 '
je fs_yesflpdisk_first
cmp eax, 'FIRS'
je fs_yesflpdisk_first
cmp eax, '2 '
je fs_yesflpdisk_second
cmp eax, 'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
 
fs_yesflpdisk_first:
mov [flp_number],1
jmp fs_yesflpdisk_start
mov [flp_number], 1
jmp fs_yesflpdisk_start
fs_yesflpdisk_second:
mov [flp_number],2
mov [flp_number], 2
fs_yesflpdisk_start:
cmp dword [esp+20],0 ; READ
jne fs_noflpdisk_read
cmp dword [esp+20], 0; READ
jne fs_noflpdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call floppy_fileread
mov eax, [esp+4] ; fname
add eax, 2*12+1
mov ebx, [esp+16] ; block start
inc ebx
mov ecx, [esp+12] ; block count
mov edx, [esp+8] ; return
mov esi, [esp+0]
sub esi, eax
add esi, 12+1 ; file name length
call floppy_fileread
 
jmp file_system_return
jmp file_system_return
 
 
fs_noflpdisk_read:
317,166 → 320,166
fs_noflpdisk:
;*****************************************************************
 
mov eax,[edi+1]
cmp eax,'HD0 '
je fs_yesharddisk_IDE0
cmp eax,'HD1 '
je fs_yesharddisk_IDE1
cmp eax,'HD2 '
je fs_yesharddisk_IDE2
cmp eax,'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
mov eax, [edi+1]
cmp eax, 'HD0 '
je fs_yesharddisk_IDE0
cmp eax, 'HD1 '
je fs_yesharddisk_IDE1
cmp eax, 'HD2 '
je fs_yesharddisk_IDE2
cmp eax, 'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
fs_yesharddisk_IDE0:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
jmp fs_yesharddisk_partition
call reserve_hd1
mov [hdbase], 0x1f0
mov [hdid], 0x0
mov [hdpos], 1
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE1:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
jmp fs_yesharddisk_partition
call reserve_hd1
mov [hdbase], 0x1f0
mov [hdid], 0x10
mov [hdpos], 2
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE2:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
jmp fs_yesharddisk_partition
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x0
mov [hdpos], 3
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE3:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
mov [hdpos], 4
fs_yesharddisk_partition:
call reserve_hd_channel
; call choice_necessity_partition
; jmp fs_yesharddisk_all
jmp fs_for_new_semantic
jmp fs_for_new_semantic
 
choice_necessity_partition:
mov eax,[edi+1+12]
call StringToNumber
mov [fat32part],eax
mov eax, [edi+1+12]
call StringToNumber
mov [fat32part], eax
choice_necessity_partition_1:
mov ecx,[hdpos]
xor eax,eax
mov [hd_entries], eax ; entries in hd cache
mov edx,DRIVE_DATA+2
cmp ecx,0x80
jb search_partition_array
mov ecx,4
mov ecx, [hdpos]
xor eax, eax
mov [hd_entries], eax; entries in hd cache
mov edx, DRIVE_DATA+2
cmp ecx, 0x80
jb search_partition_array
mov ecx, 4
search_partition_array:
mov bl,[edx]
movzx ebx,bl
add eax,ebx
inc edx
loop search_partition_array
mov ecx,[hdpos]
mov edx,BiosDiskPartitions
sub ecx,0x80
jb .s
je .f
mov bl, [edx]
movzx ebx, bl
add eax, ebx
inc edx
loop search_partition_array
mov ecx, [hdpos]
mov edx, BiosDiskPartitions
sub ecx, 0x80
jb .s
je .f
@@:
mov ebx,[edx]
add edx,4
add eax,ebx
loop @b
jmp .f
mov ebx, [edx]
add edx, 4
add eax, ebx
loop @b
jmp .f
.s:
sub eax,ebx
sub eax, ebx
.f:
add eax,[fat32part]
dec eax
xor edx,edx
imul eax,100
add eax,DRIVE_DATA+0xa
mov [transfer_adress],eax
call partition_data_transfer_1
ret
add eax, [known_part]; add eax,[fat32part]
dec eax
xor edx, edx
imul eax, 100
add eax, DRIVE_DATA+0xa
mov [transfer_adress], eax
call partition_data_transfer_1
ret
 
old_path_harddisk:
mov eax,[edi+1]
cmp eax,'HD '
je fs_yesharddisk
cmp eax,'HARD'
jne fs_noharddisk
mov eax, [edi+1]
cmp eax, 'HD '
je fs_yesharddisk
cmp eax, 'HARD'
jne fs_noharddisk
 
fs_yesharddisk:
cmp dword [esp+20],8 ; LBA read
jne fs_no_LBA_read
mov eax,[esp+16] ; LBA block to read
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx,[esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
cmp dword [esp+20], 8; LBA read
jne fs_no_LBA_read
mov eax, [esp+16] ; LBA block to read
lea ebx, [edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx, [esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
 
fs_no_LBA_read:
 
cmp byte [edi+1+11],0 ; directory read
je fs_give_dir1
call reserve_hd1
cmp byte [edi+1+11], 0; directory read
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
mov ebx, [esp+24+24]
cmp [hdpos],0 ; is hd base set?
jz hd_err_return
cmp [fat32part],0 ; is partition set?
jnz @f
mov eax, 1
mov ebx, [esp+24+24]
cmp [hdpos], 0 ; is hd base set?
jz hd_err_return
cmp [fat32part], 0 ; is partition set?
jnz @f
hd_err_return:
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
@@:
 
cmp dword [esp+20],0 ; READ
jne fs_noharddisk_read
cmp dword [esp+20], 0; READ
jne fs_noharddisk_read
 
mov eax,[esp+0] ; /fname
lea edi,[eax+12]
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov eax, [esp+0] ; /fname
lea edi, [eax+12]
mov byte [eax], 0 ; path to asciiz
inc eax ; filename start
 
mov ebx,[esp+12] ; count to read
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; dir start
sub edi,edx ; path length
mov esi,[esp+16] ; blocks to read
mov ebx, [esp+12] ; count to read
mov ecx, [esp+8] ; buffer
mov edx, [esp+4]
add edx, 12*2 ; dir start
sub edi, edx ; path length
mov esi, [esp+16] ; blocks to read
 
call file_read
call file_read
 
mov edi,[esp+0]
mov byte [edi],'/'
mov edi, [esp+0]
mov byte [edi], '/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
 
call free_hd_channel
and [hd1_status], 0
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
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:
 
add esp,24
add esp, 24
 
mov [esp+36],eax
mov [esp+24],ebx
ret
mov [esp+36], eax
mov [esp+24], ebx
ret
 
 
fs_give_dir1:
485,72 → 488,72
; /RD,/FD,/HD - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
.read:
; \end{diamond}[18.03.2006]
mov al,0x10
mov ebx,1
mov edi,[esp+8]
mov esi,dir1
mov al, 0x10
mov ebx, 1
mov edi, [esp+8]
mov esi, dir1
fs_d1_new:
mov ecx,11
mov ecx, 11
; cld
rep movsb
stosb
add edi,32-11-1
dec ebx
jne fs_d1_new
rep movsb
stosb
add edi, 32-11-1
dec ebx
jne fs_d1_new
 
add esp,24
add esp, 24
 
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*1 ; dir/data size
ret
and dword [esp+36], 0; ok read
mov dword [esp+24], 32*1; dir/data size
ret
 
 
 
LBA_read_ramdisk:
 
cmp [lba_read_enabled],1
je lbarrl1
cmp [lba_read_enabled], 1
je lbarrl1
 
xor ebx,ebx
mov eax,2
ret
xor ebx, ebx
mov eax, 2
ret
 
lbarrl1:
 
cmp eax,18*2*80
jb lbarrl2
xor ebx,ebx
mov eax,3
ret
cmp eax, 18*2*80
jb lbarrl2
xor ebx, ebx
mov eax, 3
ret
 
lbarrl2:
 
pushad
pushad
 
call restorefatchain
call restorefatchain
 
mov edi,ecx
mov esi,eax
mov edi, ecx
mov esi, eax
 
shl esi,9
add esi,RAMDISK
mov ecx,512/4
shl esi, 9
add esi, RAMDISK
mov ecx, 512/4
; cld
rep movsd
rep movsd
 
popad
popad
 
xor ebx,ebx
xor eax,eax
ret
xor ebx, ebx
xor eax, eax
ret
 
LBA_read:
 
560,106 → 563,106
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
; ecx = abs pointer to return area
 
cmp [lba_read_enabled],1
je lbarl1
mov eax,2
ret
cmp [lba_read_enabled], 1
je lbarl1
mov eax, 2
ret
 
lbarl1:
 
call reserve_hd1
call reserve_hd1
 
push eax
push ecx
push eax
push ecx
 
mov edi,hd_address_table
mov esi,dir1
mov eax,[ebx]
mov edx,'1 '
mov ecx,4
mov edi, hd_address_table
mov esi, dir1
mov eax, [ebx]
mov edx, '1 '
mov ecx, 4
blar0:
cmp eax,[esi]
je blar2
cmp eax,edx
je blar2
inc edx
add edi,8
add esi,11
dec ecx
jnz blar0
cmp eax, [esi]
je blar2
cmp eax, edx
je blar2
inc edx
add edi, 8
add esi, 11
dec ecx
jnz blar0
 
mov eax,1
mov ebx,1
jmp LBA_read_ret
mov eax, 1
mov ebx, 1
jmp LBA_read_ret
 
blar2:
mov eax,[edi+0]
mov ebx,[edi+4]
mov eax, [edi+0]
mov ebx, [edi+4]
 
mov [hdbase],eax
mov [hdid],ebx
mov [hdbase], eax
mov [hdid], ebx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_lba_error
call wait_for_hd_idle
cmp [hd_error], 0
jne hd_lba_error
 
; eax = hd port
; ebx = set for primary (0x00) or slave (0x10)
 
cli
cli
 
mov edx,eax
inc edx
xor eax,eax
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esp+4]
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,bl
add al,128+64+32
out dx,al
mov edx, eax
inc edx
xor eax, eax
out dx, al
inc edx
inc eax
out dx, al
inc edx
mov eax, [esp+4]
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
and al, 1+2+4+8
add al, bl
add al, 128+64+32
out dx, al
 
inc edx
mov al,20h
out dx,al
inc edx
mov al, 20h
out dx, al
 
sti
sti
 
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_lba_error
call wait_for_sector_buffer
cmp [hd_error], 0
jne hd_lba_error
 
cli
cli
 
mov edi,[esp+0]
mov ecx,256
sub edx,7
cld
rep insw
mov edi, [esp+0]
mov ecx, 256
sub edx, 7
cld
rep insw
 
sti
sti
 
xor eax,eax
xor ebx,ebx
xor eax, eax
xor ebx, ebx
 
LBA_read_ret:
mov [hd_error],0
mov [hd1_status],0
add esp,2*4
mov [hd_error], 0
mov [hd1_status], 0
add esp, 2*4
 
ret
ret
 
 
expand_pathz:
671,66 → 674,66
; ebx = /file name - zero terminated
; esi = pointer after source
 
push eax
push ecx
push edi ;[esp+0]
push eax
push ecx
push edi;[esp+0]
 
pathz_start:
mov byte [edi],'/'
inc edi
mov al,32
mov ecx,11
cld
rep stosb ; clear filename area
sub edi,11
mov ebx,edi ; start of dir/file name
mov byte [edi], '/'
inc edi
mov al, 32
mov ecx, 11
cld
rep stosb ; clear filename area
sub edi, 11
mov ebx, edi ; start of dir/file name
 
pathz_new_char:
mov al,[esi]
inc esi
cmp al,0
je pathz_end
mov al, [esi]
inc esi
cmp al, 0
je pathz_end
 
cmp al,'/'
jne pathz_not_path
cmp edi,ebx ; skip first '/'
jz pathz_new_char
lea edi,[ebx+11] ; start of next directory
jmp pathz_start
cmp al, '/'
jne pathz_not_path
cmp edi, ebx ; skip first '/'
jz pathz_new_char
lea edi, [ebx+11] ; start of next directory
jmp pathz_start
 
pathz_not_path:
cmp al,'.'
jne pathz_not_ext
lea edi,[ebx+8] ; start of extension
jmp pathz_new_char
cmp al, '.'
jne pathz_not_ext
lea edi, [ebx+8] ; start of extension
jmp pathz_new_char
 
pathz_not_ext:
cmp al,'a'
jb pathz_not_low
cmp al,'z'
ja pathz_not_low
sub al,0x20 ; char to uppercase
cmp al, 'a'
jb pathz_not_low
cmp al, 'z'
ja pathz_not_low
sub al, 0x20 ; char to uppercase
 
pathz_not_low:
mov [edi],al
inc edi
mov eax,[esp+0] ; start_of_dest_path
add eax,512 ; keep maximum path under 512 bytes
cmp edi,eax
jb pathz_new_char
mov [edi], al
inc edi
mov eax, [esp+0] ; start_of_dest_path
add eax, 512 ; keep maximum path under 512 bytes
cmp edi, eax
jb pathz_new_char
 
pathz_end:
cmp ebx,edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx,12
cmp ebx, edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx, 12
 
pathz_put_zero:
mov byte [ebx+11],0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
mov byte [ebx+11], 0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
 
;*******************************************
;* string to number
747,51 → 750,52
; 1 - îøèáêà
; Åñëè CF=0, òî AX - ÷èñëî.
 
push bx
push cx
push dx
push edi
mov [partition_string],eax
mov edi,partition_string
xor cx,cx
push bx
push cx
push dx
push edi
mov [partition_string], eax
mov edi, partition_string
xor cx, cx
i1:
mov al,[edi]
cmp al,32 ;13
je i_exit
mov al, [edi]
cmp al, 32;13
je i_exit
; cmp al,'0'
; jb err
; cmp al,'9'
; ja err
sub al,48
shl cx,1
jc error
mov bx,cx
shl cx,1
jc error
shl cx,1
jc error
add cx,bx
jc error
cbw
add cx,ax
jc error
sub al, 48
shl cx, 1
jc error
mov bx, cx
shl cx, 1
jc error
shl cx, 1
jc error
add cx, bx
jc error
cbw
add cx, ax
jc error
i3:
inc edi
jmp i1
inc edi
jmp i1
i_exit:
mov ax,cx
clc
mov ax, cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
movzx eax, ax
pop edi
pop dx
pop cx
pop bx
ret
 
error:
stc
jmp i4
stc
jmp i4
 
partition_string: dd 0
partition_string:
dd 0
db 32
/kernel/branches/net/fs/fs_lfn.inc
8,8 → 8,8
$Revision$
 
 
image_of_eax EQU esp+36
image_of_ebx EQU esp+24
image_of_eax EQU esp+32
image_of_ebx EQU esp+20
 
; System function 70 - files with long names (LFN)
; diamond, 2006
17,81 → 17,81
iglobal
; in this table names must be in lowercase
rootdirs:
db 2,'rd'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 7,'ramdisk'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 2,'fd'
dd fs_OnFloppy
dd fs_NextFloppy
db 10,'floppydisk'
dd fs_OnFloppy
dd fs_NextFloppy
db 3,'hd0'
dd fs_OnHd0
dd fs_NextHd0
db 3,'hd1'
dd fs_OnHd1
dd fs_NextHd1
db 3,'hd2'
dd fs_OnHd2
dd fs_NextHd2
db 3,'hd3'
dd fs_OnHd3
dd fs_NextHd3
db 2,'rd'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 7,'ramdisk'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 2,'fd'
dd fs_OnFloppy
dd fs_NextFloppy
db 10,'floppydisk'
dd fs_OnFloppy
dd fs_NextFloppy
db 3,'hd0'
dd fs_OnHd0
dd fs_NextHd0
db 3,'hd1'
dd fs_OnHd1
dd fs_NextHd1
db 3,'hd2'
dd fs_OnHd2
dd fs_NextHd2
db 3,'hd3'
dd fs_OnHd3
dd fs_NextHd3
;**********************************************
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
;***********************************************
db 0
db 0
 
 
virtual_root_query:
dd fs_HasRamdisk
db 'rd',0
dd fs_HasFloppy
db 'fd',0
dd fs_HasHd0
db 'hd0',0
dd fs_HasHd1
db 'hd1',0
dd fs_HasHd2
db 'hd2',0
dd fs_HasHd3
db 'hd3',0
dd fs_HasRamdisk
db 'rd',0
dd fs_HasFloppy
db 'fd',0
dd fs_HasHd0
db 'hd0',0
dd fs_HasHd1
db 'hd1',0
dd fs_HasHd2
db 'hd2',0
dd fs_HasHd3
db 'hd3',0
;**********************************************
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
;**********************************************
dd 0
dd 0
 
fs_additional_handlers:
dd biosdisk_handler, biosdisk_enum_root
dd dyndisk_handler, dyndisk_enum_root
; add new handlers here
dd 0
 
endg
 
file_system_lfn:
; in: eax->fileinfo block
; in: ebx->fileinfo block
; operation codes:
; 0 : read file
; 1 : read folder
105,211 → 105,210
; 9 : create directory
 
; parse file name
xchg ebx, eax
lea esi, [ebx+20]
lodsb
test al, al
jnz @f
mov esi, [esi]
lodsb
lea esi, [ebx+20]
lodsb
test al, al
jnz @f
mov esi, [esi]
lodsb
@@:
cmp al, '/'
jz .notcurdir
dec esi
mov ebp, esi
test al, al
jnz @f
xor ebp, ebp
cmp al, '/'
jz .notcurdir
dec esi
mov ebp, esi
test al, al
jnz @f
xor ebp, ebp
@@:
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
jmp .parse_normal
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
jmp .parse_normal
.notcurdir:
cmp byte [esi], 0
jz .rootdir
call process_replace_file_name
cmp byte [esi], 0
jz .rootdir
call process_replace_file_name
.parse_normal:
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
call fs_execute ; esi+ebp, ebx, edx
mov [image_of_eax], eax
ret
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
call fs_execute; esi+ebp, ebx, edx
mov [image_of_eax], eax
ret
@@:
mov edi, rootdirs-8
xor ecx, ecx
push esi
mov edi, rootdirs-8
xor ecx, ecx
push esi
.scan1:
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
test cl, cl
jz .notfound_try
inc edi
push esi
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
test cl, cl
jz .notfound_try
inc edi
push esi
@@:
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
; directory /xxx
.maindir:
mov esi, [edi+4]
mov esi, [edi+4]
.maindir_noesi:
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12]
mov edx, [ebx+16]
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12] ;количество блоков для считывания
mov edx, [ebx+16] ;куда записывать рузельтат
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
mov edi, edx
push ecx
mov ecx, 32/4
rep stosd
pop ecx
mov byte [edx], 1 ; version
mov edi, edx
push ecx
mov ecx, 32/4
rep stosd
pop ecx
mov byte [edx], 1 ; version
.maindir_loop:
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
push ecx
mov ecx, 40/4-2
rep stosd
pop ecx
pop eax
push eax edx
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
push ecx
mov ecx, 40/4-2
rep stosd
pop ecx
pop eax
push eax edx
; convert number in eax to decimal UNICODE string
push edi
push ecx
push -'0'
mov ecx, 10
push edi
push ecx
push -'0'
mov ecx, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
.ansi2:
test al, al
jnz @b
mov byte [edi-1], 0
pop ecx
pop edi
test al, al
jnz @b
mov byte [edi-1], 0
pop ecx
pop edi
; UNICODE name length is 520 bytes, ANSI - 264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
@@:
pop edx eax
jmp .maindir_loop
pop edx eax
jmp .maindir_loop
.maindir_done:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
; directory /
.rootdir:
cmp dword [ebx], 1 ; read folder?
jz .readroot
cmp dword [ebx], 1 ; read folder?
jz .readroot
.access_denied:
mov dword [image_of_eax], 10 ; access denied
ret
mov dword [image_of_eax], 10 ; access denied
ret
 
.readroot:
; virtual root folder - special handler
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
.readroot_loop:
cmp dword [esi], eax
jz .readroot_done_static
call dword [esi]
add esi, 4
test eax, eax
jnz @f
cmp dword [esi], eax
jz .readroot_done_static
call dword [esi]
add esi, 4
test eax, eax
jnz @f
.readroot_next:
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
@@:
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
@@:
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
.ansi:
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
.readroot_done_static:
mov esi, fs_additional_handlers-8
sub esp, 16
337,7 → 336,7
mov dword [edi+4], ebx
add edi, 8
mov ecx, 40/4-2
rep stosd
rep stosd
push esi edi
lea esi, [esp+12]
@@:
358,16 → 357,16
jmp .readroot_ah_loop2
.readroot_done:
add esp, 16
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.notfound_try:
mov edi, fs_additional_handlers
@@:
378,52 → 377,53
scasd
jmp @b
.notfound:
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
and dword [image_of_ebx], 0
ret
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
and dword [image_of_ebx], 0
ret
 
.notfounda:
cmp edi, esp
jnz .notfound
add esp, 8
call dword [edi+4]
add esp, 16
jmp .notfound
 
.found1:
pop eax
cmp byte [esi], 0
jz .maindir
pop eax
cmp byte [esi], 0
jz .maindir
.found2:
; read partition number
xor ecx, ecx
xor eax, eax
xor ecx, ecx
xor eax, eax
@@:
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfounda
lea ecx, [ecx*5]
lea ecx, [ecx*2+eax]
jmp @b
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfounda
lea ecx, [ecx*5]
lea ecx, [ecx*2+eax]
jmp @b
.done1:
jecxz .notfounda
test al, al
jnz @f
dec esi
jecxz .notfounda
test al, al
jnz @f
dec esi
@@:
cmp byte [esi], 0
jnz @f
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
cmp byte [esi], 0
jnz @f
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
@@:
; now [edi] contains handler address, ecx - partition number,
; esi points to ASCIIZ string - rest of name
jmp dword [edi]
jmp dword [edi]
 
; handlers for devices
; in: ecx = 0 => query virtual directory /xxx
434,287 → 434,287
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
 
fs_OnRamdisk:
cmp ecx, 1
jnz file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumRamdiskServices
jae .not_impl
mov ecx, [ebx+12]
mov edx, [ebx+16]
cmp ecx, 1
jnz file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumRamdiskServices
jae .not_impl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_RamdiskServices + eax*4]
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
add ebx, 4
call dword [fs_RamdiskServices + eax*4]
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
mov dword [image_of_eax], 2 ; not implemented
ret
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_NotImplemented:
mov eax, 2
ret
mov eax, 2
ret
 
fs_RamdiskServices:
dd fs_RamdiskRead
dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
dd fs_RamdiskWrite
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd 0
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
dd fs_RamdiskRead
dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
dd fs_RamdiskWrite
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd 0
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
 
fs_OnFloppy:
cmp ecx, 2
ja file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumFloppyServices
jae fs_OnRamdisk.not_impl
call reserve_flp
mov [flp_number], cl
mov ecx, [ebx+12]
mov edx, [ebx+16]
cmp ecx, 2
ja file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumFloppyServices
jae fs_OnRamdisk.not_impl
call reserve_flp
mov [flp_number], cl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_FloppyServices + eax*4]
and [flp_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
add ebx, 4
call dword [fs_FloppyServices + eax*4]
and [flp_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
 
fs_FloppyServices:
dd fs_FloppyRead
dd fs_FloppyReadFolder
dd fs_FloppyRewrite
dd fs_FloppyWrite
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd 0
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
dd fs_FloppyRead
dd fs_FloppyReadFolder
dd fs_FloppyRewrite
dd fs_FloppyWrite
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd 0
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
 
fs_OnHd0:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
push 4
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
push 4
fs_OnHd:
call reserve_hd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae fs_OnHdAndBd.nf
cmp cl, [DRIVE_DATA+1+eax]
call reserve_hd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae fs_OnHdAndBd.nf
cmp cl, [DRIVE_DATA+1+eax]
fs_OnHdAndBd:
jbe @f
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
mov [known_part], ecx ; mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax, fs_NumHdServices
jae .not_impl
add ebx, 4
call dword [fs_HdServices + eax*4]
call free_hd_channel
and [hd1_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov eax, [ebx]
cmp eax, fs_NumHdServices
jae .not_impl
add ebx, 4
call dword [fs_HdServices + eax*4]
call free_hd_channel
and [hd1_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_HdServices:
dd fs_HdRead
dd fs_HdReadFolder
dd fs_HdRewrite
dd fs_HdWrite
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd 0
dd fs_HdDelete
dd fs_HdCreateFolder
dd fs_HdRead
dd fs_HdReadFolder
dd fs_HdRewrite
dd fs_HdWrite
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd 0
dd fs_HdDelete
dd fs_HdCreateFolder
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
push 1
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 0
push 6
push 1
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
push 2
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 1
mov [DiskNumber], 1
push 4
push 2
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
push 3
jmp fs_OnCd
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 0
push 2
push 3
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
push 4
call reserve_cd
mov [ChannelNumber], 2
mov [DiskNumber], 1
push 0
push 4
fs_OnCd:
call reserve_cd_channel
pop eax
mov [cdpos], eax
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl,al
mov bl,[DRIVE_DATA+1]
shr bl,cl
test bl,2
pop ebx ecx
call reserve_cd_channel
pop eax
mov [cdpos], eax
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl, al
mov bl, [DRIVE_DATA+1]
shr bl, cl
test bl, 2
pop ebx ecx
 
jnz @f
jnz @f
.nf:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 5 ; not found
ret
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax,fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
mov eax, [ebx]
cmp eax, fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd 0
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd 0
dd fs_NotImplemented
dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4
 
;*******************************************************
 
fs_HasRamdisk:
mov al, 1 ; we always have ramdisk
ret
mov al, 1 ; we always have ramdisk
ret
 
fs_HasFloppy:
cmp byte [DRIVE_DATA], 0
setnz al
ret
cmp byte [DRIVE_DATA], 0
setnz al
ret
 
fs_HasHd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
 
;*******************************************************
fs_HasCd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
;*******************************************************
 
; fs_NextXXX functions:
724,65 → 724,65
 
fs_NextRamdisk:
; we always have /rd/1
test eax, eax
stc
jnz @f
mov al, 1
clc
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
ret
 
fs_NextFloppy:
; 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
test byte [DRIVE_DATA], 0xF0
jz .no1
test eax, eax
jnz .no1
inc eax
ret ; CF cleared
.no1:
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
mov al, 2
clc
ret
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
mov al, 2
clc
ret
.no2:
stc
ret
stc
ret
 
; on hdx, we have partitions from 1 to [0x40002+x]
fs_NextHd0:
push 0
jmp fs_NextHd
push 0
jmp fs_NextHd
fs_NextHd1:
push 1
jmp fs_NextHd
push 1
jmp fs_NextHd
fs_NextHd2:
push 2
jmp fs_NextHd
push 2
jmp fs_NextHd
fs_NextHd3:
push 3
push 3
fs_NextHd:
pop ecx
movzx ecx, byte [DRIVE_DATA+2+ecx]
cmp eax, ecx
jae fs_NextFloppy.no2
inc eax
clc
ret
pop 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
test eax, eax
stc
jnz @f
mov al, 1
clc
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
ret
;*******************************************************
 
; Additional FS handlers.
852,6 → 852,8
jmp file_system_lfn.maindir_noesi
@@:
push ecx
push ecx
push biosdisk_cleanup
push fs_OnBd
mov edi, esp
jmp file_system_lfn.found2
858,19 → 860,20
 
fs_BdNext:
cmp eax, [BiosDiskPartitions+ecx*4]
inc eax
cmc
ret
inc eax
cmc
biosdisk_cleanup:
ret
 
fs_OnBd:
pop edx edx
pop edx edx edx edx
; edx = disk number, ecx = partition number
; esi+ebp = name
call reserve_hd1
add edx, 0x80
mov [hdpos], edx
cmp ecx, [BiosDiskPartitions+(edx-0x80)*4]
jmp fs_OnHdAndBd
call reserve_hd1
add edx, 0x80
mov [hdpos], edx
cmp ecx, [BiosDiskPartitions+(edx-0x80)*4]
jmp fs_OnHdAndBd
 
; This handler is called when virtual root is enumerated
; and must return all items which can be handled by this.
904,7 → 907,7
xor eax, eax
ret
.big:
push ecx
push ecx edx
push -'0'
mov ecx, 10
@@:
919,227 → 922,229
add al, '0'
stosb
jnz @b
pop ecx
pop edx ecx
pop eax
inc eax
ret
 
process_replace_file_name:
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
.loop:
cmp edi, ebp
jb .notfound
push esi edi
cmp edi, ebp
jb .notfound
push esi edi
@@:
cmp byte [edi], 0
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
scasb
jz @b
jmp .cont
cmp byte [edi], 0
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
scasb
jz @b
jmp .cont
.dest_done:
cmp byte [esi], 0
jz .found
cmp byte [esi], '/'
jnz .cont
inc esi
jmp .found
cmp byte [esi], 0
jz .found
cmp byte [esi], '/'
jnz .cont
inc esi
jmp .found
.cont:
pop edi esi
sub edi, 128
jmp .loop
pop edi esi
sub edi, 128
jmp .loop
.found:
pop edi eax
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
jnz .ret
pop edi eax
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
jnz .ret
.notfound:
xor ebp, ebp
xor ebp, ebp
.ret:
ret
ret
 
sys_current_directory:
; mov esi, [current_slot]
; mov esi, [esi+APPDATA.cur_dir]
; mov edx, esi
; mov esi, [current_slot]
; mov esi, [esi+APPDATA.cur_dir]
; mov edx, esi
 
;get length string of appdata.cur_dir
mov eax, [current_slot]
mov edi, [eax+APPDATA.cur_dir]
mov eax, [current_slot]
mov edi, [eax+APPDATA.cur_dir]
 
dec ebx
jz .set
dec ebx
jz .get
ret
dec ebx
jz .set
dec ebx
jz .get
ret
.get:
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
; for our code: ebx->buffer,ecx=len
max_cur_dir equ 0x1000
max_cur_dir equ 0x1000
 
mov ebx,edi
mov ebx, edi
 
push ecx
push edi
push ecx
push edi
 
xor eax,eax
mov ecx,max_cur_dir
xor eax, eax
mov ecx, max_cur_dir
 
repne scasb ;find zerro at and string
jnz .error ; no zero in cur_dir: internal error, should not happen
repne scasb ;find zerro at and string
jnz .error ; no zero in cur_dir: internal error, should not happen
 
sub edi,ebx ;lenght for copy
inc edi
mov [esp+32+8],edi ;return in eax
sub edi, ebx ;lenght for copy
inc edi
mov [esp+32+8], edi ;return in eax
 
cmp edx, edi
jbe @f
mov edx, edi
cmp edx, edi
jbe @f
mov edx, edi
@@:
;source string
pop esi
pop esi
;destination string
pop edi
cmp edx, 1
jbe .ret
pop edi
cmp edx, 1
jbe .ret
 
mov al,'/' ;start string with '/'
stosb
mov ecx,edx
rep movsb ;copy string
.ret: ret
mov al, '/' ;start string with '/'
stosb
mov ecx, edx
rep movsb ;copy string
.ret:
ret
 
.error: add esp,8
or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir]
ret
.error:
add esp, 8
or dword [esp+32], -1 ;error not found zerro at string ->[eax+APPDATA.cur_dir]
ret
.set:
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
; for our code: ebx->string to set
; use generic resolver with APPDATA.cur_dir as destination
push max_cur_dir ;0x1000
push edi ;destination
mov ebx,ecx
call get_full_file_name
ret
push max_cur_dir ;0x1000
push edi ;destination
mov ebx, ecx
call get_full_file_name
ret
 
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
; destroys all registers except ebp,esp
get_full_file_name:
push ebp
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov edx, esi
push ebp
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov edx, esi
@@:
inc esi
cmp byte [esi-1], 0
jnz @b
dec esi
cmp byte [ebx], '/'
jz .set_absolute
inc esi
cmp byte [esi-1], 0
jnz @b
dec esi
cmp byte [ebx], '/'
jz .set_absolute
; string gives relative path
mov edi, [esp+8] ; destination
mov edi, [esp+8] ; destination
.relative:
cmp byte [ebx], 0
jz .set_ok
cmp word [ebx], '.'
jz .set_ok
cmp word [ebx], './'
jnz @f
add ebx, 2
jmp .relative
cmp byte [ebx], 0
jz .set_ok
cmp word [ebx], '.'
jz .set_ok
cmp word [ebx], './'
jnz @f
add ebx, 2
jmp .relative
@@:
cmp word [ebx], '..'
jnz .doset_relative
cmp byte [ebx+2], 0
jz @f
cmp byte [ebx+2], '/'
jnz .doset_relative
cmp word [ebx], '..'
jnz .doset_relative
cmp byte [ebx+2], 0
jz @f
cmp byte [ebx+2], '/'
jnz .doset_relative
@@:
dec esi
cmp byte [esi], '/'
jnz @b
add ebx, 3
jmp .relative
dec esi
cmp byte [esi], '/'
jnz @b
add ebx, 3
jmp .relative
.set_ok:
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
jz .set_ok.cur_dir
sub esi, edx
cmp esi, [esp+12]
jb .set_ok.copy
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
jz .set_ok.cur_dir
sub esi, edx
cmp esi, [esp+12]
jb .set_ok.copy
.fail:
mov byte [edi], 0
xor eax, eax ; fail
pop ebp
ret 8
mov byte [edi], 0
xor eax, eax ; fail
pop ebp
ret 8
.set_ok.copy:
mov ecx, esi
mov esi, edx
rep movsb
mov byte [edi], 0
mov ecx, esi
mov esi, edx
rep movsb
mov byte [edi], 0
.ret.ok:
mov al, 1 ; ok
pop ebp
ret 8
mov al, 1 ; ok
pop ebp
ret 8
.set_ok.cur_dir:
mov byte [esi], 0
jmp .ret.ok
mov byte [esi], 0
jmp .ret.ok
.doset_relative:
cmp edx, edi
jz .doset_relative.cur_dir
sub esi, edx
cmp esi, [esp+12]
jae .fail
mov ecx, esi
mov esi, edx
mov edx, edi
rep movsb
jmp .doset_relative.copy
cmp edx, edi
jz .doset_relative.cur_dir
sub esi, edx
cmp esi, [esp+12]
jae .fail
mov ecx, esi
mov esi, edx
mov edx, edi
rep movsb
jmp .doset_relative.copy
.doset_relative.cur_dir:
mov edi, esi
mov edi, esi
.doset_relative.copy:
add edx, [esp+12]
mov byte [edi], '/'
inc edi
cmp edi, edx
jae .overflow
add edx, [esp+12]
mov byte [edi], '/'
inc edi
cmp edi, edx
jae .overflow
@@:
mov al, [ebx]
inc ebx
stosb
test al, al
jz .ret.ok
cmp edi, edx
jb @b
mov al, [ebx]
inc ebx
stosb
test al, al
jz .ret.ok
cmp edi, edx
jb @b
.overflow:
dec edi
jmp .fail
dec edi
jmp .fail
.set_absolute:
lea esi, [ebx+1]
call process_replace_file_name
mov edi, [esp+8]
mov edx, [esp+12]
add edx, edi
lea esi, [ebx+1]
call process_replace_file_name
mov edi, [esp+8]
mov edx, [esp+12]
add edx, edi
.set_copy:
lodsb
stosb
test al, al
jz .set_part2
lodsb
stosb
test al, al
jz .set_part2
.set_copy_cont:
cmp edi, edx
jb .set_copy
jmp .overflow
cmp edi, edx
jb .set_copy
jmp .overflow
.set_part2:
mov esi, ebp
xor ebp, ebp
test esi, esi
jz .ret.ok
mov byte [edi-1], '/'
jmp .set_copy_cont
mov esi, ebp
xor ebp, ebp
test esi, esi
jz .ret.ok
mov byte [edi-1], '/'
jmp .set_copy_cont
/kernel/branches/net/fs/iso9660.inc
5,72 → 5,76
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision:1322 $
$Revision$
 
 
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
 
reserve_cd:
 
cli
cmp [cd_status],0
je reserve_ok2
cli
cmp [cd_status], 0
je reserve_ok2
 
sti
call change_task
jmp reserve_cd
sti
call change_task
jmp reserve_cd
 
reserve_ok2:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status],eax
pop eax
sti
ret
push eax
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status], eax
pop eax
sti
ret
 
reserve_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1],0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
cli
cmp [IDE_Channel_1], 0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2],0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_1
cli
cmp [IDE_Channel_2], 0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1],1
ret
mov [IDE_Channel_1], 1
sti
ret
.reserve_ok_2:
mov [IDE_Channel_2],1
ret
mov [IDE_Channel_2], 1
sti
ret
 
free_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
cmp [ChannelNumber], 1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
ret
mov [IDE_Channel_1], 0
sti
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
mov [IDE_Channel_2], 0
sti
ret
 
uglobal
cd_status dd 0
91,113 → 95,113
;
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
pop eax edx ecx edi
jmp .noaccess_2
 
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; end of file
pop edi
ret
mov eax, 6; end of file
pop edi
ret
@@:
mov ebx, [ebx]
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax,[edi+2]
mov [CDSectorAddress],eax
mov eax, [edi+2]
mov [CDSectorAddress], eax
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer],edx
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
mov [CDDataBuf_pointer], edx
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode], 0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
.next:
inc dword [CDSectorAddress]
jmp .new_sector
inc dword [CDSectorAddress]
jmp .new_sector
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode], 0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
@@:
sub ecx, ebx
push edi esi ecx
mov edi,edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
sub ecx, ebx
push edi esi ecx
mov edi, edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
 
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
215,242 → 219,242
;
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
or ebx, -1
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
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
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
; äèðåêòîðèÿ çàêîí÷èëàñü?
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
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]
ret
pop ecx edi
mov ebx, [edx+4]
ret
 
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
push eax esi edi edx
mov [cd_current_pointer_of_input_2], CDDataBuf
push eax esi edi edx
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax,[cd_counter_block]
cmp [ebx],eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi,[cd_counter_block]
mov [edx+4],edi
dec ecx
mov esi,ebp
mov edi,[cd_mem_location]
add edi,40
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax, [cd_counter_block]
cmp [ebx], eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi, [cd_counter_block]
mov [edx+4], edi
dec ecx
mov esi, ebp
mov edi, [cd_mem_location]
add edi, 40
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
.ansi:
cmp [cd_counter_block],2
jbe .ansi_parent_directory
cld
lodsw
xchg ah,al
call uni2ansi_char
cld
stosb
cmp [cd_counter_block], 2
jbe .ansi_parent_directory
cld
lodsw
xchg ah, al
call uni2ansi_char
cld
stosb
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
mov ax, [esi]
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_1
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .ansi
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .ansi
.cd_get_parameters_of_file_1:
mov [edi],byte 0
call cd_get_parameters_of_file
add [cd_mem_location],304
jmp .get_names_from_buffer_1
mov [edi], byte 0
call cd_get_parameters_of_file
add [cd_mem_location], 304
jmp .get_names_from_buffer_1
 
.ansi_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
cmp [cd_counter_block], 2
je @f
mov [edi], byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
@@:
mov [edi],word '..'
add edi,2
jmp .cd_get_parameters_of_file_1
mov [edi], word '..'
add edi, 2
jmp .cd_get_parameters_of_file_1
 
.unicode:
cmp [cd_counter_block],2
jbe .unicode_parent_directory
cld
movsw
cmp [cd_counter_block], 2
jbe .unicode_parent_directory
cld
movsw
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
mov ax, [esi]
cmp ax, word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_2
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp esi, eax
je .cd_get_parameters_of_file_2
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .unicode
movzx eax, byte [ebp-1]
add eax, ebp
cmp esi, eax
jb .unicode
.cd_get_parameters_of_file_2:
mov [edi],word 0
call cd_get_parameters_of_file
add [cd_mem_location],560
jmp .get_names_from_buffer_1
mov [edi], word 0
call cd_get_parameters_of_file
add [cd_mem_location], 560
jmp .get_names_from_buffer_1
 
.unicode_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],word 2E00h ; '.'
add edi,2
jmp .cd_get_parameters_of_file_2
cmp [cd_counter_block], 2
je @f
mov [edi], word 2E00h; '.'
add edi, 2
jmp .cd_get_parameters_of_file_2
@@:
mov [edi],dword 2E002E00h ; '..'
add edi,4
jmp .cd_get_parameters_of_file_2
mov [edi], dword 2E002E00h; '..'
add edi, 4
jmp .cd_get_parameters_of_file_2
 
.end_buffer:
pop edx edi esi eax
ret
pop edx edi esi eax
ret
 
cd_get_parameters_of_file:
mov edi,[cd_mem_location]
mov edi, [cd_mem_location]
cd_get_parameters_of_file_1:
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
xor eax, eax
; ôàéë íå àðõèâèðîâàëñÿ
inc eax
shl eax,1
inc eax
shl eax, 1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc eax
test [ebp-8], byte 2
jz .file
inc eax
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
shl eax, 3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc eax
test [ebp-8], byte 1
jz .hidden
inc eax
.hidden:
shl eax,1
shl eax, 1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc eax
mov [edi],eax
inc eax
mov [edi], eax
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
;÷àñ
movzx eax,byte [ebp-12]
shl eax,8
movzx eax, byte [ebp-12]
shl eax, 8
;ìèíóòà
mov al,[ebp-11]
shl eax,8
mov al, [ebp-11]
shl eax, 8
;ñåêóíäà
mov al,[ebp-10]
mov al, [ebp-10]
;âðåìÿ ñîçäàíèÿ ôàéëà
mov [edi+8],eax
mov [edi+8], eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+16],eax
mov [edi+16], eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+24],eax
mov [edi+24], eax
; ïîëó÷àåì äàòó äëÿ ôàéëà
;ãîä
movzx eax,byte [ebp-15]
add eax,1900
shl eax,8
movzx eax, byte [ebp-15]
add eax, 1900
shl eax, 8
;ìåñÿö
mov al,[ebp-14]
shl eax,8
mov al, [ebp-14]
shl eax, 8
;äåíü
mov al,[ebp-13]
mov al, [ebp-13]
;äàòà ñîçäàíèÿ ôàéëà
mov [edi+12],eax
mov [edi+12], eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+20],eax
mov [edi+20], eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+28],eax
mov [edi+28], eax
; ïîëó÷àåì òèï äàííûõ èìåíè
xor eax,eax
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4],eax
jmp @f
xor eax, eax
test dword [ebx+4], 1; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4], eax
jmp @f
.unicode_1:
inc eax
mov [edi+4],eax
inc eax
mov [edi+4], eax
@@:
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
xor eax,eax
mov [edi+32+4],eax
mov eax,[ebp-23]
mov [edi+32],eax
ret
xor eax, eax
mov [edi+32+4], eax
mov eax, [ebp-23]
mov [edi+32], eax
ret
 
;----------------------------------------------------------------
;
459,186 → 463,186
;
;----------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
 
mov edi, edx
push ebp
mov ebp, [cd_current_pointer_of_input]
add ebp, 33
call cd_get_parameters_of_file_1
pop ebp
and dword [edi+4], 0
pop edi
xor eax, eax
ret
mov edi, edx
push ebp
mov ebp, [cd_current_pointer_of_input]
add ebp, 33
call cd_get_parameters_of_file_1
pop ebp
and dword [edi+4], 0
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data],0
mov [cd_appl_data], 0
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
 
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
 
call prevent_medium_removal
call prevent_medium_removal
; òåñòîâîå ÷òåíèå
mov [CDSectorAddress],dword 16
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
mov [CDSectorAddress], dword 16
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr;_1
cmp [DevErrorCode], 0
jne .access_denied
 
; âû÷èñëåíèå ïîñëåäíåé ñåññèè
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
call Read_TOC
mov ah,[CDDataBuf+4+4]
mov al,[CDDataBuf+4+5]
shl eax,16
mov ah,[CDDataBuf+4+6]
mov al,[CDDataBuf+4+7]
add eax,15
mov [CDSectorAddress],eax
call WaitUnitReady
cmp [DevErrorCode], 0
jne .access_denied
call Read_TOC
mov ah, [CDDataBuf+4+4]
mov al, [CDDataBuf+4+5]
shl eax, 16
mov ah, [CDDataBuf+4+6]
mov al, [CDDataBuf+4+7]
add eax, 15
mov [CDSectorAddress], eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer],CDDataBuf
mov [CDDataBuf_pointer], CDDataBuf
 
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
inc dword [CDSectorAddress]
call ReadCDWRetr;_1
cmp [DevErrorCode], 0
jne .access_denied
 
.start_check:
; ïðîâåðêà íà âøèâîñòü
cmp [CDDataBuf+1],dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5],byte '1'
jne .access_denied
cmp [CDDataBuf+1], dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5], byte '1'
jne .access_denied
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
cmp [CDDataBuf],byte 0xff
je .access_denied
cmp [CDDataBuf], byte 0xff
je .access_denied
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf],byte 0x2
jne .start
cmp [CDDataBuf], byte 0x2
jne .start
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf+6],byte 0x1
jne .start
cmp [CDDataBuf+6], byte 0x1
jne .start
 
; ïàðàìåòðû root äèðåêòðîðèè
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress],eax
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
jmp .done
mov eax, [CDDataBuf+0x9c+2]; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress], eax
mov eax, [CDDataBuf+0x9c+10]; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input], CDDataBuf+0x9c
jmp .done
@@:
; íà÷èíàåì ïîèñê
.mainloop:
dec dword [CDSectorAddress]
dec dword [CDSectorAddress]
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax,2048
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax, 2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
cmp eax, 0
ja .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
mov [cd_appl_data],1
stc
ret
pop esi eax
mov [cd_appl_data], 1
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi-1], 0
jz .done
cmp byte [esi-1], 0
jz .done
.nested:
mov eax,[cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
mov eax, [cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax, [eax+2+8]; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
@@:
pop esi eax
mov [cd_appl_data],1
clc
ret
pop esi eax
mov [cd_appl_data], 1
clc
ret
 
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
mov [cd_current_pointer_of_input_2], CDDataBuf
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
.found:
clc
ret
clc
ret
.not_found:
stc
ret
stc
ret
 
cd_get_name:
push eax
mov ebp,[cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input],ebp
mov eax,[ebp]
test eax,eax ; âõîäû çàêîí÷èëèñü?
jz .next_sector
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
push eax
mov ebp, [cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input], ebp
mov eax, [ebp]
test eax, eax ; âõîäû çàêîí÷èëèñü?
jz .next_sector
cmp ebp, CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2], eax; ñëåäóþùèé âõîä êàòàëîãà
add ebp, 33; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
.next_sector:
pop eax
stc
ret
pop eax
stc
ret
 
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
646,112 → 650,112
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push esi eax edi
mov edi,ebp
push esi eax edi
mov edi, ebp
.loop:
cld
lodsb
push eax
call char_todown
call ansi2uni_char
xchg ah,al
scasw
pop eax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah,al
sub edi,2
scasw
jne .name_not_coincide
cld
lodsb
push eax
call char_todown
call ansi2uni_char
xchg ah, al
scasw
pop eax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah, al
sub edi, 2
scasw
jne .name_not_coincide
.coincides:
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
cmp [esi], byte '/'; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi], byte 0; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
.name_not_coincide:
pop edi eax esi
stc
ret
pop edi eax esi
stc
ret
.done:
; ïðîâåðêà êîíöà ôàéëà
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
cmp [edi], word 3B00h; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp edi,eax
je .done_1
movzx eax, byte [ebp-33]
add eax, ebp
sub eax, 34
cmp edi, eax
je .done_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp edi,eax
jne .name_not_coincide
movzx eax, byte [ebp-1]
add eax, ebp
cmp edi, eax
jne .name_not_coincide
.done_1:
pop edi eax
add esp,4
inc esi
clc
ret
pop edi eax
add esp, 4
inc esi
clc
ret
 
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 'à'-''
add al, 'à'-''
.ret:
ret
ret
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
add al, 0x20
ret
 
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
add al, 0xA0
.ascii:
.doit:
ret
ret
/kernel/branches/net/fs/ntfs.inc
8,7 → 8,7
$Revision$
 
 
ntfs_test_bootsec:
ntfs_test_bootsec:
; in: ebx->buffer, edx=size of partition
; out: CF set <=> invalid
; 1. Name=='NTFS '
95,8 → 95,8
 
ntfs_setup: ; CODE XREF: part_set.inc
; By given bootsector, initialize some NTFS variables
call ntfs_test_bootsec
jc problem_fat_dec_count
; call ntfs_test_bootsec ; checking boot sector was already
; jc problem_fat_dec_count
movzx eax, byte [ebx+13]
mov [ntfs_data.sectors_per_cluster], eax
mov eax, [ebx+0x28]
256,7 → 256,7
mov edi, eax
mov ecx, [ntfs_data.mft_retrieval_size]
add ecx, ecx
rep movsd
rep movsd
push [ntfs_data.mft_retrieval]
mov [ntfs_data.mft_retrieval], eax
call kernel_free
639,7 → 639,7
mov edi, ntfs_attrlist_mft_buf
@@:
mov ecx, 0x200/4
rep movsd
rep movsd
mov eax, edi
pop edi esi
sub esi, 0x200
915,7 → 915,7
cmp ecx, 8
ja .end
push ecx
rep movsb
rep movsb
pop ecx
sub ecx, 8
neg ecx
923,13 → 923,13
jae .end
push eax
xor eax, eax
rep stosb
rep stosb
pop ecx
shr ecx, 4
cmp ecx, 8
ja .end
push ecx
rep movsb
rep movsb
pop ecx
sub ecx, 8
neg ecx
936,12 → 936,24
cmp byte [esi-1], 80h
cmc
sbb eax, eax
rep stosb
rep stosb
stc
.end:
pop edi ecx eax
ret
 
unichar_toupper:
push eax
call uni2ansi_char
cmp al, '_'
jz .unk
add esp, 4
call char_toupper
jmp ansi2uni_char
.unk:
pop eax
ret
 
ntfs_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
1007,7 → 1019,7
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
1030,8 → 1042,7
push edi
@@:
lodsw
call uni2ansi_char
call char_toupper
call unichar_toupper
push eax
mov al, [edi]
inc edi
1038,7 → 1049,8
cmp al, '/'
jz .slash
call char_toupper
cmp al, [esp]
call ansi2uni_char
cmp ax, [esp]
pop eax
loopz @b
jz .found
1187,7 → 1199,7
@@:
mov [esp+10h+4], ecx
mov edi, edx
rep movsb
rep movsb
mov edx, edi
pop ecx
sub ecx, [esp+10h]
1241,7 → 1253,7
mov edi, edx
mov esi, ntfs_bitmap_buf
add [esp+10h+4], ecx
rep movsb
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ntfs_cur_read]
1358,7 → 1370,7
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
1376,7 → 1388,7
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
rep stosd
mov byte [edx], 1 ; version
mov ecx, [esp+4+18h]
push edx
1410,7 → 1422,7
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
rep stosd
mov [ntfs_cur_attr], 0xB0 ; $BITMAP
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
1466,7 → 1478,7
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
rep stosd
pop edi ecx
pop eax
push [ntfs_cur_offs]
1528,7 → 1540,7
lea ecx, [esi+1]
test byte [edi-0x24], 1
jz @f
rep stosw
rep stosw
pop ecx
xor eax, eax
stosw
1536,7 → 1548,7
add edi, 520
ret
@@:
rep stosb
rep stosb
pop ecx
xor eax, eax
stosb
1568,9 → 1580,9
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
rep movsd
rep movsd
adc ecx, ecx
rep movsw
rep movsw
and word [edi], 0
pop edi
add edi, 520
1641,6 → 1653,7
xchg eax, [esp]
div [_10000000]
pop edx
.sec:
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
1813,3 → 1826,4
pop edi esi
xor eax, eax
ret
 
/kernel/branches/net/fs/parse_fn.inc
38,66 → 38,66
; use bx_from_load and init system directory /sys
proc Parser_params
locals
buff db 4 dup(?) ; for test cd
buff db 4 dup(?) ; for test cd
endl
mov eax,[OS_BASE+0x10000+bx_from_load]
mov ecx,sysdir_path
mov [ecx-64],dword 'sys'
cmp al,'r' ; if ram disk
jnz @f
mov [ecx],dword 'RD/?'
mov [ecx+3],byte ah
mov [ecx+4],byte 0
ret
mov eax, [OS_BASE+0x10000+bx_from_load]
mov ecx, sysdir_path
mov [ecx-64], dword 'sys'
cmp al, 'r'; if ram disk
jnz @f
mov [ecx], dword 'RD/?'
mov [ecx+3], byte ah
mov [ecx+4], byte 0
ret
@@:
cmp al,'m' ; if ram disk
jnz @f
mov [ecx],dword 'CD?/' ; if cd disk {m}
mov [ecx+4],byte '1'
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
cmp al, 'm'; if ram disk
jnz @f
mov [ecx], dword 'CD?/'; if cd disk {m}
mov [ecx+4], byte '1'
mov [ecx+5], dword '/KOL'
mov [ecx+9], dword 'IBRI'
mov [ecx+13], byte 0
.next_cd:
mov [ecx+2],byte ah
inc ah
cmp ah,'5'
je .not_found_cd
lea edx,[buff]
pushad
stdcall read_file,read_firstapp,edx,0,4
popad
cmp [edx],dword 'MENU'
jne .next_cd
jmp .ok
mov [ecx+2], byte ah
inc ah
cmp ah, '5'
je .not_found_cd
lea edx, [buff]
pushad
stdcall read_file, read_firstapp, edx, 0, 4
popad
cmp [edx], dword 'MENU'
jne .next_cd
jmp .ok
@@:
sub al,49
mov [ecx],dword 'HD?/' ; if hard disk
mov [ecx+2],byte al
mov [ecx+4],byte ah
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
sub al, 49
mov [ecx], dword 'HD?/'; if hard disk
mov [ecx+2], byte al
mov [ecx+4], byte ah
mov [ecx+5], dword '/KOL'
mov [ecx+9], dword 'IBRI'
mov [ecx+13], byte 0
.ok:
.not_found_cd:
ret
ret
endp
 
proc load_file_parse_table
stdcall kernel_alloc,0x1000
mov [tmp_file_name_table],eax
mov edi,eax
mov esi,sysdir_name
mov ecx,128/4
rep movsd
stdcall kernel_alloc, 0x1000
mov [tmp_file_name_table], eax
mov edi, eax
mov esi, sysdir_name
mov ecx, 128/4
rep movsd
 
invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key
invoke ini.enum_keys, conf_fname, conf_path_sect, get_every_key
 
mov eax,[tmp_file_name_table]
mov [full_file_name_table],eax
mov eax,[tmp_file_name_size]
mov [full_file_name_table.size],eax
ret
mov eax, [tmp_file_name_table]
mov [full_file_name_table], eax
mov eax, [tmp_file_name_size]
mov [full_file_name_table.size], eax
ret
endp
 
uglobal
129,7 → 129,7
@@:
stosb
 
invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1
invoke ini.get_str, [f_name], [sec_name], ecx, ebx, 64, def_val_1
 
cmp byte [ebx], '/'
jnz @f
136,7 → 136,7
lea esi, [ebx+1]
mov edi, ebx
mov ecx, 63
rep movsb
rep movsb
@@:
push ebp
mov ebp, [tmp_file_name_table]
/kernel/branches/net/fs/part_set.inc
9,6 → 9,7
 
 
;*************************************************************
;* 13.02.2010 Find all partition and check supported FS
;* 12.07.2007 Check all 4 entry of MBR and EMBR
;* 29.04.2006 Elimination of hangup after the
;* expiration hd_wait_timeout - Mario79
26,7 → 27,7
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
align 4
 
fs_dependent_data_start:
54,7 → 55,8
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
ERROR: sizeof(file system data) too big!
ERROR:
sizeof(file system data) too big!
end if
 
virtual at fs_dependent_data_start
74,10 → 76,36
.cur_index_size dd ?
.cur_index_buf dd ?
if $ > fs_dependent_data_end
ERROR: increase sizeof(fs_dependent_data)!
ERROR:
increase sizeof(fs_dependent_data)!
end if
end virtual
 
virtual at fs_dependent_data_start
; EXT2 data
ext2_data:
.log_block_size dd ?
.block_size dd ?
.count_block_in_block dd ?
.blocks_per_group dd ?
.inodes_per_group dd ?
.global_desc_table dd ?
.root_inode dd ? ; pointer to root inode in memory
.inode_size dd ?
.count_pointer_in_block dd ? ; block_size / 4
.count_pointer_in_block_square dd ? ; (block_size / 4)**2
.ext2_save_block dd ? ; ¡«®ª ­  £«®¡ «ì­ãî 1 ¯à®æ¥¤ãàã
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.ext2_save_inode dd ? ; inode ­  £«®¡ «ì­ãî ¯à®æ¥¤ãàã
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.sb dd ? ; superblock
.groups_count dd ?
if $ > fs_dependent_data_end
ERROR:
increase sizeof(fs_dependent_data)!
end if
end virtual
 
;***************************************************************************
; End place
; Mario79
105,6 → 133,7
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
db 0x07 ; NTFS
db 0x27 ; NTFS, hidden
db 0x83 ; Linux native file system (ext2fs)
partition_types_end:
 
 
118,233 → 147,249
endg
 
; Partition chain used:
; MBR ; PARTITION2 ; PARTITION3 ; PARTITION4
;==========================================================
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
; extended --+ extended --+ extended --+ extended --+
; 0 0 0 0
; 0 0 0 0
; Notes:
; - extended partition need to be in second entry on table
; - it will skip over removed partitions
; MBR <---------------------
; | |
; |-> PARTITION1 |
; |-> EXTENDED PARTITION - ;not need be second partition
; |-> PARTITION3
; |-> PARTITION4
 
set_FAT32_variables:
mov [problem_partition],0
call reserve_hd1
call reserve_hd_channel
set_PARTITION_variables:
set_FAT32_variables: ;deprecated
and [problem_partition], 0
call reserve_hd1
call reserve_hd_channel
 
pushad
pushad
 
cmp dword [hdpos],0
je problem_hd
cmp dword [hdpos], 0
je problem_hd
 
xor ecx,ecx ; partition count
mov edx,-1 ; flag for partition
xor eax,eax ; read MBR
xor ebp,ebp ; extended partition start
xor ecx, ecx ; partition count
;or edx,-1 ; flag for partition
xor eax, eax ; address MBR
xor ebp, ebp ; extended partition start
 
new_partition:
test ebp,ebp ; is there extended partition?
jnz extended_already_set ; yes
xchg ebp,eax ; no. set it now
new_mbr:
test ebp, ebp ; is there extended partition? (MBR or EMBR)
jnz extended_already_set; yes
xchg ebp, eax ; no. set it now
 
extended_already_set:
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne problem_hd
add eax, ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jne problem_hd
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz end_partition_chain
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
; jz next_partition
jnz .next_primary_partition
cmp dword [ebx+0x1be+0xc+16],0
jnz next_primary_partition
cmp dword [ebx+0x1be+0xc+16+16],0
jnz next_primary_partition_1
cmp dword [ebx+0x1be+0xc+16+16+16],0
jnz next_primary_partition_2
jmp next_partition
.next_primary_partition:
push eax
mov al,[ebx+0x1be+4] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition ; no. skip over
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
jnz end_partition_chain
push eax ; push only one time
cmp dword [ebx+0x1be+0xc], 0; skip over empty partition
jnz test_primary_partition_0
cmp dword [ebx+0x1be+0xc+16], 0
jnz test_primary_partition_1
cmp dword [ebx+0x1be+0xc+16+16], 0
jnz test_primary_partition_2
cmp dword [ebx+0x1be+0xc+16+16+16], 0
jnz test_primary_partition_3
pop eax
jmp end_partition_chain
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition ; no
test_primary_partition_0:
mov al, [ebx+0x1be+4]; get primary partition type
call scan_partition_types
jnz test_primary_partition_1; no. skip over
 
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
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_1; no
 
pop eax
;mov edx, eax ; start sector
add eax, [ebx+0x1be+8] ; add relative start
;mov [PARTITON_START],edx
;push edx
mov edx, [ebx+0x1be+12] ; length
;add edx, eax ; 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
mov cl, [ebx+0x1be+4] ; fs_type
;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
;pop edx
jmp hd_and_partition_ok
 
next_primary_partition:
push eax
mov al,[ebx+0x1be+4+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_1 ; no. skip over
test_primary_partition_1:
mov al, [ebx+0x1be+4+16]; get primary partition type
call scan_partition_types
jnz test_primary_partition_2 ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_1 ; no
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_2 ; no
 
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
pop eax
add eax, [ebx+0x1be+8+16]
mov edx, [ebx+0x1be+12+16]
mov cl, [ebx+0x1be+4+16]
jmp hd_and_partition_ok
 
next_primary_partition_1:
push eax
mov al,[ebx+0x1be+4+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_2 ; no. skip over
;mov edx, eax
;add edx, [ebx+0x1be+8+16]
;push edx
;add edx, [ebx+0x1be+12+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16]
;mov [fs_type], dl
;pop edx
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_2 ; no
test_primary_partition_2:
mov al, [ebx+0x1be+4+16+16]; get primary partition type
call scan_partition_types
jnz test_primary_partition_3 ; no. skip over
 
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
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_primary_partition_3 ; no
 
next_primary_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_partition ; no. skip over
pop eax
add eax, [ebx+0x1be+8+16+16]
mov edx, [ebx+0x1be+12+16+16]
mov cl, [ebx+0x1be+4+16+16]
jmp hd_and_partition_ok
;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 al, [ebx+0x1be+4+16+16]
;mov [fs_type], dl
;pop edx
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
test_primary_partition_3:
mov al, [ebx+0x1be+4+16+16+16]; get primary partition type
call scan_partition_types
jnz test_ext_partition_0 ; no. skip over
 
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
inc ecx
cmp ecx, [known_part]; is it wanted partition?
jnz test_ext_partition_0; no
 
next_partition:
push eax
mov al,[ebx+0x1be+4] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_1
pop eax
add eax, [ebx+0x1be+8+16+16+16]
mov edx, [ebx+0x1be+12+16+16+16]
mov cl, [ebx+0x1be+4+16+16+16]
jmp hd_and_partition_ok
 
mov eax,[ebx+0x1be+8] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
;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 al, [ebx+0x1be+4+16+16+16]
;mov [fs_type], dl
;pop edx
 
next_partition_1:
push eax
mov al,[ebx+0x1be+4+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_2
test_ext_partition_0:
pop eax ; ¯à®áâ® ¢ëª¨¤ë¢ ¥¬ ¨§ á⥪ 
mov al, [ebx+0x1be+4]; get extended partition type
call scan_extended_types
jnz test_ext_partition_1
 
mov eax,[ebx+0x1be+8+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
mov eax, [ebx+0x1be+8]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
next_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_3
test_ext_partition_1:
mov al, [ebx+0x1be+4+16]; get extended partition type
call scan_extended_types
jnz test_ext_partition_2
 
mov eax,[ebx+0x1be+8+16+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_3:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz end_partition_chain ; no. end chain
mov eax, [ebx+0x1be+8+16]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
test_ext_partition_2:
mov al, [ebx+0x1be+4+16+16]; get extended partition type
call scan_extended_types
jnz test_ext_partition_3
 
mov eax, [ebx+0x1be+8+16+16]; add relative start
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
test_ext_partition_3:
mov al, [ebx+0x1be+4+16+16+16]; get extended partition type
call scan_extended_types
jnz end_partition_chain; no. end chain
 
mov eax, [ebx+0x1be+8+16+16+16]; get start of extended partition
test eax, eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
end_partition_chain:
mov [partition_count],ecx
;mov [partition_count],ecx
 
cmp edx,-1 ; found wanted partition?
jnz hd_and_partition_ok ; yes. install it
jmp problem_partition_or_fat
;cmp edx,-1 ; found wanted partition?
;jnz hd_and_partition_ok ; yes. install it
;jmp problem_partition_or_fat
problem_hd:
or [problem_partition], 2
jmp return_from_part_set
 
 
scan_partition_types:
push ecx
mov edi,partition_types
mov ecx,partition_types_end-partition_types
cld
repne scasb ; is partition type ok?
pop ecx
ret
push ecx
mov edi, partition_types
mov ecx, partition_types_end-partition_types
cld
repne scasb ; is partition type ok?
pop ecx
ret
 
scan_extended_types:
push ecx
mov edi,extended_types
mov ecx,extended_types_end-extended_types
cld
repne scasb ; is it extended partition?
pop ecx
ret
push ecx
mov edi, extended_types
mov ecx, extended_types_end-extended_types
cld
repne scasb ; is it extended partition?
pop ecx
ret
 
problem_fat_dec_count: ; bootsector is missing or another problem
dec [partition_count] ; remove it from partition_count
; dec [partition_count] ; remove it from partition_count
 
problem_partition_or_fat:
problem_hd:
popad
or [problem_partition], 1
 
mov [fs_type],0
call free_hd_channel
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
return_from_part_set:
popad
;mov [fs_type],0
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
mov edx, [PARTITION_END]
sub edx, eax
inc edx ; edx = length of partition
 
;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type
mov [fs_type], cl
;mov eax,edx
mov [PARTITION_START], eax
add edx, eax
dec edx
mov [PARTITION_END], edx
 
; mov edx, [PARTITION_END]
; sub edx, eax
; inc edx ; edx = length of partition § ç¥¬ ®­® ­ ¬??
 
; mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
mov ebx, buffer
call hd_read ; read boot sector of partition
cmp [hd_error], 0
jz boot_read_ok
cmp [fs_type], 7
366,116 → 411,124
add eax, [PARTITION_START]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count ; ­¥ áã¤ì¡ ...
jnz problem_fat_dec_count ; no chance...
boot_read_ok:
; mov [hd_setup], 0
 
; if we are running on NTFS, check bootsector
; cmp [fs_type], 7
; jz ntfs_setup
call ntfs_test_bootsec
 
call ntfs_test_bootsec ; test ntfs
jnc ntfs_setup
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
call ext2_test_superblock ; test ext2fs
jnc ext2_setup
 
movzx eax,word [ebx+0xe] ; sectors reserved
add eax,[PARTITION_START]
mov [FAT_START],eax ; fat_start = partition_start + reserved
mov eax, [PARTITION_START] ;ext2 test changes [buffer]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count
 
movzx eax,byte [ebx+0xd] ; sectors per cluster
test eax,eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER],eax
cmp word [ebx+0x1fe], 0xaa55; is it valid boot sector?
jnz problem_fat_dec_count
 
movzx ecx,word [ebx+0xb] ; bytes per sector
cmp ecx,0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR],ecx
movzx eax, word [ebx+0xe]; sectors reserved
add eax, [PARTITION_START]
mov [FAT_START], eax; fat_start = partition_start + reserved
 
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
mov edx,32
mul edx
dec ecx
add eax,ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS],eax ; count of rootdir sectors
movzx eax, byte [ebx+0xd]; sectors per cluster
test eax, eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER], eax
 
movzx eax,word [ebx+0x16] ; sectors per fat <65536
test eax,eax
jnz fat16_fatsize
mov eax,[ebx+0x24] ; sectors per fat
movzx ecx, word [ebx+0xb]; bytes per sector
cmp ecx, 0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR], ecx
 
movzx eax, word [ebx+0x11]; count of rootdir entries (=0 fat32)
mov edx, 32
mul edx
dec ecx
add eax, ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS], eax; count of rootdir sectors
 
movzx eax, word [ebx+0x16]; sectors per fat <65536
test eax, eax
jnz fat16_fatsize
mov eax, [ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT],eax
mov [SECTORS_PER_FAT], eax
 
movzx eax,byte [ebx+0x10] ; number of fats
test eax,eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS],eax
imul eax,[SECTORS_PER_FAT]
add eax,[FAT_START]
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [DATA_START],eax ; data area = rootdir + rootdir_size
movzx eax, byte [ebx+0x10]; number of fats
test eax, eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS], eax
imul eax, [SECTORS_PER_FAT]
add eax, [FAT_START]
mov [ROOT_START], eax; rootdir = fat_start + fat_size * fat_count
add eax, [ROOT_SECTORS]; rootdir sectors should be 0 on fat32
mov [DATA_START], eax; data area = rootdir + rootdir_size
 
movzx eax,word [ebx+0x13] ; total sector count <65536
test eax,eax
jnz fat16_total
mov eax,[ebx+0x20] ; total sector count
movzx eax, word [ebx+0x13]; total sector count <65536
test eax, eax
jnz fat16_total
mov eax, [ebx+0x20] ; total sector count
fat16_total:
add eax,[PARTITION_START]
dec eax
mov [PARTITION_END],eax
inc eax
sub eax,[DATA_START] ; eax = count of data sectors
xor edx,edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER],eax
dec eax ; cluster count
mov [fatStartScan],2
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
inc eax
sub eax, [DATA_START]; eax = count of data sectors
xor edx, edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER], eax
dec eax ; cluster count
mov [fatStartScan], 2
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax,4085 ; 0xff5
jb problem_fat_dec_count ; fat12 not supported
cmp eax,65525 ; 0xfff5
jb fat16_partition
cmp eax, 4085 ; 0xff5
jb problem_fat_dec_count; fat12 not supported
cmp eax, 65525 ; 0xfff5
jb fat16_partition
 
fat32_partition:
mov eax,[ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER],eax
movzx eax,word [ebx+0x30] ; fs info sector
add eax,[PARTITION_START]
mov [ADR_FSINFO],eax
call hd_read
mov eax,[ebx+0x1ec]
cmp eax,-1
jz @f
mov [fatStartScan],eax
mov eax, [ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER], eax
movzx eax, word [ebx+0x30]; fs info sector
add eax, [PARTITION_START]
mov [ADR_FSINFO], eax
call hd_read
mov eax, [ebx+0x1ec]
cmp eax, -1
jz @f
mov [fatStartScan], eax
@@:
 
popad
popad
 
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fs_type],32 ; Fat32
call free_hd_channel
mov [hd1_status],0 ; free
ret
mov [fatRESERVED], 0x0FFFFFF6
mov [fatBAD], 0x0FFFFFF7
mov [fatEND], 0x0FFFFFF8
mov [fatMASK], 0x0FFFFFFF
mov [fs_type], 32 ; Fat32
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
fat16_partition:
xor eax,eax
mov [ROOT_CLUSTER],eax
xor eax, eax
mov [ROOT_CLUSTER], eax
 
popad
popad
 
mov [fatRESERVED],0x0000FFF6
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fs_type],16 ; Fat16
call free_hd_channel
mov [hd1_status],0 ; free
ret
mov [fatRESERVED], 0x0000FFF6
mov [fatBAD], 0x0000FFF7
mov [fatEND], 0x0000FFF8
mov [fatMASK], 0x0000FFFF
mov [fs_type], 16 ; Fat16
call free_hd_channel
mov [hd1_status], 0 ; free
ret
 
/kernel/branches/net/gui/button.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
8,14 → 8,12
 
$Revision$
 
 
button._.MAX_BUTTONS = 4095
 
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
button.MAX_BUTTONS = 4095
 
struc SYS_BUTTON
{
.pslot dw ?
25,6 → 23,7
.top dw ?
.height dw ?
.id_hi dw ?
dw ?
.sizeof:
}
virtual at 0
31,13 → 30,6
SYS_BUTTON SYS_BUTTON
end virtual
 
iglobal
mx dw 0x0 ; keeps the x mouse's position when it was clicked
my dw 0x0 ; keeps the y mouse's position when it was clicked
bPressedMouseXY_B db 0x0
btn_down_determ db 0x0
endg
 
align 4
;------------------------------------------------------------------------------
syscall_button: ;///// system function 8 //////////////////////////////////////
66,7 → 58,7
; do we have free button slots available?
mov edi, [BTN_ADDR]
mov eax, [edi]
cmp eax, button._.MAX_BUTTONS
cmp eax, button.MAX_BUTTONS
jge .exit
 
; does it have positive size? (otherwise it doesn't have sense)
139,7 → 131,8
call button._.incecx2
 
; set button height counter
@@: mov edx, edi
@@:
mov edx, edi
 
.next_line:
call button._.button_dececx
227,6 → 220,7
add esi, edi
xor ecx, ecx
add ecx, -SYS_BUTTON.sizeof
add esi, SYS_BUTTON.sizeof
 
.next_button:
dec ebx
262,201 → 256,123
 
align 4
;------------------------------------------------------------------------------
check_buttons: ;///////////////////////////////////////////////////////////////
sys_button_activate_handler: ;/////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
cmp byte[BTN_DOWN], 0 ; mouse buttons pressed
jnz @f
mov [bPressedMouseXY_B], 0
ret
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
call button._.find_button
or eax, eax
jz .exit
 
@@: pushad
xor esi, esi
mov edi, [BTN_ADDR]
mov edx, [edi]
test edx, edx
jne @f
popad
ret
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2]
call button._.negative_button
 
;here i catch the coordinates when the mouse's button is clicked
@@: push ax
cmp [bPressedMouseXY_B], 0 ; FALSE
jnz @f
mov [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
mov ax, [MOUSE_X]
mov [mx], ax
mov ax, [MOUSE_Y]
mov [my], ax
@@: pop ax
;and it is only refreshed after the mouse's button release
 
push esi
inc edx
push edx
 
.buttonnewcheck:
pop edx
pop esi
inc esi
cmp edx, esi
jge .bch
 
popad
.exit:
ret
 
.bch:
push esi
push edx
mov eax, esi
shl eax, 4
add eax, edi
align 4
;------------------------------------------------------------------------------
sys_button_deactivate_handler: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
call button._.find_button
or eax, eax
jz .exit
 
; check that button is at top of windowing stack
movzx ebx, [eax + SYS_BUTTON.pslot]
movzx ecx, word[WIN_STACK + ebx * 2]
cmp ecx, [TASK_COUNT]
jne .buttonnewcheck
 
; check that button start is inside window x/y end
shl ebx, 5
 
test [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .buttonnewcheck
 
movzx edx, [eax + SYS_BUTTON.left]
cmp edx, [window_data + ebx + WDATA.box.width] ;ecx
jge .buttonnewcheck
 
movzx edx, [eax + SYS_BUTTON.top]
cmp edx, [window_data + ebx + WDATA.box.height] ;ecx
jge .buttonnewcheck
 
; check coordinates
 
; mouse x >= button x ?
add ebx, window_data
mov ecx, [ebx + WDATA.box.left]
movzx edx, [eax + SYS_BUTTON.left]
add edx, ecx
mov cx, [mx] ;mov cx,[MOUSE_X]
cmp edx, ecx
jg .buttonnewcheck
 
movzx ebx, [eax + SYS_BUTTON.width]
add edx, ebx
cmp ecx, edx
jg .buttonnewcheck
 
; mouse y >= button y ?
movzx ebx, [eax + SYS_BUTTON.pslot]
shl ebx, 5
add ebx, window_data
mov ecx, [ebx + WDATA.box.top]
movzx edx, [eax + SYS_BUTTON.top]
add edx, ecx
mov cx, [my] ;mov cx,[MOUSE_Y]
cmp edx, ecx
jg .buttonnewcheck
 
movzx ebx, [eax + SYS_BUTTON.height]
add edx, ebx
cmp ecx, edx
jg .buttonnewcheck
 
; mouse on button
 
pop edx
pop esi
 
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2] ; button id : bits 16-31
mov bx, [eax + SYS_BUTTON.id_lo] ; button id : bits 00-16
push ebx
 
mov byte[MOUSE_DOWN], 1 ; no mouse down checks
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2]
call button._.negative_button
 
pushad
push eax
mov al, [BTN_DOWN]
mov byte[btn_down_determ], al
pop eax
.exit:
ret
 
.cbwaitmouseup:
call checkidle
call [draw_pointer]
align 4
;------------------------------------------------------------------------------
sys_button_perform_handler: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
shl eax, 8
mov al, cl
movzx ebx, byte[BTN_COUNT]
mov [BTN_BUFF + ebx * 4], eax
inc bl
mov [BTN_COUNT], bl
ret
 
pushad
call stack_handler
popad
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
cmp byte[BTN_DOWN], 0 ; mouse buttons pressed ?
jnz .cbwaitmouseup
popad
;------------------------------------------------------------------------------
button._.find_button: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system button by specified process slot, id and coordinates
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)] or 0
;> ebx = pack[16(button x coord), 16(button y coord)]
;------------------------------------------------------------------------------
;< eax = pointer to SYS_BUTTON struct or 0
;------------------------------------------------------------------------------
push ecx edx esi edi
 
call button._.negative_button
mov byte[MOUSE_BACKGROUND], 0 ; no mouse background
mov byte[DONT_DRAW_MOUSE], 0 ; draw mouse
mov edx, eax
shr edx, 24
and eax, 0x0ffffff
 
; check coordinates
pusha
mov edi, [BTN_ADDR]
mov ecx, [edi]
imul esi, ecx, SYS_BUTTON.sizeof
add esi, edi
inc ecx
add esi, SYS_BUTTON.sizeof
 
; mouse x >= button x ?
movzx ebx, [eax + SYS_BUTTON.pslot]
shl ebx, 5
add ebx, window_data
mov ecx, [ebx + WDATA.box.left]
movzx edx, [eax + SYS_BUTTON.left]
add edx, ecx
mov cx, [MOUSE_X]
cmp edx, ecx
jg .no_on_button ;if we release the pointer out of the button area
.next_button:
dec ecx
jz .not_found
 
movzx ebx, [eax + SYS_BUTTON.width]
add edx, ebx
cmp ecx, edx
jg .no_on_button
add esi, -SYS_BUTTON.sizeof
 
; mouse y >= button y ?
movzx ebx, [eax + SYS_BUTTON.pslot]
shl ebx, 5
add ebx, window_data
mov ecx, [ebx + WDATA.box.top]
movzx edx, [eax + SYS_BUTTON.top]
add edx, ecx
mov cx, [MOUSE_Y]
cmp edx, ecx
jg .no_on_button
; does it belong to our process?
cmp dx, [esi + SYS_BUTTON.pslot]
jne .next_button
 
movzx ebx, [eax + SYS_BUTTON.height]
add edx, ebx
cmp ecx, edx
jg .no_on_button
; does id match?
mov edi, dword[esi + SYS_BUTTON.id_hi - 2]
mov di, [esi + SYS_BUTTON.id_lo]
and edi, 0x0ffffff
cmp eax, edi
jne .next_button
 
popa
; does coordinates match?
mov edi, dword[esi + SYS_BUTTON.left - 2]
mov di, [esi + SYS_BUTTON.top]
cmp ebx, edi
jne .next_button
 
mov byte[BTN_COUNT], 1 ; no of buttons in buffer
pop ebx
mov [BTN_BUFF], ebx ; lets put the button id in buffer
push ebx
pusha
jmp .yes_on_button
; okay, return it
mov eax, esi
jmp .exit
 
.no_on_button:
mov byte[BTN_COUNT], 0 ; no of buttons in buffer
.not_found:
xor eax, eax
 
.yes_on_button:
mov byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
popa
pop ebx
popa
.exit:
pop edi esi edx ecx
ret
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
;------------------------------------------------------------------------------
button._.dececx: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
465,14 → 381,17
sub cl, 0x20
jnc @f
xor cl, cl
@@: sub ch, 0x20
@@:
sub ch, 0x20
jnc @f
xor ch, ch
@@: rol ecx, 16
@@:
rol ecx, 16
sub cl, 0x20
jnc @f
xor cl, cl
@@: rol ecx, 16
@@:
rol ecx, 16
ret
 
;------------------------------------------------------------------------------
483,14 → 402,17
add cl, 0x20
jnc @f
or cl, -1
@@: add ch, 0x20
@@:
add ch, 0x20
jnc @f
or ch, -1
@@: rol ecx, 16
@@:
rol ecx, 16
add cl, 0x20
jnc @f
or cl, -1
@@: rol ecx, 16
@@:
rol ecx, 16
ret
 
;------------------------------------------------------------------------------
501,14 → 423,17
add cl, 0x14
jnc @f
or cl, -1
@@: add ch, 0x14
@@:
add ch, 0x14
jnc @f
or ch, -1
@@: rol ecx, 16
@@:
rol ecx, 16
add cl, 0x14
jnc @f
or cl, -1
@@: rol ecx, 16
@@:
rol ecx, 16
ret
 
;------------------------------------------------------------------------------
525,17 → 450,21
jg @f
mov al, 2
 
@@: sub cl, al
@@:
sub cl, al
jnc @f
xor cl, cl
@@: sub ch, al
@@:
sub ch, al
jnc @f
xor ch, ch
@@: rol ecx, 16
@@:
rol ecx, 16
sub cl, al
jnc @f
xor cl, cl
@@: rol ecx, 16
@@:
rol ecx, 16
 
pop eax
 
545,7 → 474,7
;------------------------------------------------------------------------------
button._.negative_button: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;? Invert system button border
;------------------------------------------------------------------------------
; if requested, do not display button border on press.
test ebx, 0x20000000
/kernel/branches/net/gui/event.inc
7,6 → 7,13
 
$Revision$
 
WINDOW_MOVE_AND_RESIZE_FLAGS = \
mouse.WINDOW_RESIZE_N_FLAG + \
mouse.WINDOW_RESIZE_W_FLAG + \
mouse.WINDOW_RESIZE_S_FLAG + \
mouse.WINDOW_RESIZE_E_FLAG + \
mouse.WINDOW_MOVE_FLAG
 
uglobal
align 4
event_start dd ?
18,22 → 25,24
; FreeEvents.fd=event_start è FreeEvents.bk=event_end
align 4
init_events: ;; used from kernel.asm
stdcall kernel_alloc,EV_SPACE*EVENT.size
or eax,eax
stdcall kernel_alloc, EV_SPACE*EVENT.size
or eax, eax
jz .fail
; eax - current event, ebx - previos event below
mov ecx,EV_SPACE ; current - in allocated space
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà
mov ecx, EV_SPACE ; current - in allocated space
mov ebx, FreeEvents ; previos - íà÷àëî ñïèñêà
push ebx ; îíî æå è êîíåö ïîòîì áóäåò
@@: mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
mov ebx,eax ; previos <- current
add eax,EVENT.size ; new current
@@:
mov [ebx+EVENT.fd], eax
mov [eax+EVENT.bk], ebx
mov ebx, eax ; previos <- current
add eax, EVENT.size ; new current
loop @b
pop eax ; âîò îíî êîíöîì è ñòàëî
mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
.fail: ret
mov [ebx+EVENT.fd], eax
mov [eax+EVENT.bk], ebx
.fail:
ret
 
EVENT_WATCHED equ 0x10000000 ;áèò 28
EVENT_SIGNALED equ 0x20000000 ;áèò 29
52,10 → 61,10
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
mov edx,[TASK_BASE]
mov edx,[edx+TASKDATA.pid]
mov ebx, [current_slot]
add ebx, APP_OBJ_OFFSET
mov edx, [TASK_BASE]
mov edx, [edx+TASKDATA.pid]
pushfd
cli
 
73,26 → 82,27
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov eax,FreeEvents
cmp eax,[eax+EVENT.fd]
mov eax, FreeEvents
cmp eax, [eax+EVENT.fd]
jne @f ; not empty ???
pushad
call init_events
popad
jz RemoveEventTo.break ; POPF+RET
@@: mov eax,[eax+EVENT.fd]
mov [eax+EVENT.magic],'EVNT'
mov [eax+EVENT.destroy],destroy_event.internal
mov [eax+EVENT.state],ecx
mov [eax+EVENT.pid],edx
@@:
mov eax, [eax+EVENT.fd]
mov [eax+EVENT.magic], 'EVNT'
mov [eax+EVENT.destroy], destroy_event.internal
mov [eax+EVENT.state], ecx
mov [eax+EVENT.pid], edx
inc [event_uid]
Mov [eax+EVENT.id],edx,[event_uid]
or esi,esi
or esi, esi
jz RemoveEventTo
lea edi,[eax+EVENT.code]
mov ecx,EVENT.codesize/4
lea edi, [eax+EVENT.code]
mov ecx, EVENT.codesize/4
cld
rep movsd
rep movsd
 
RemoveEventTo: ;; INTERNAL use !!! don't use for Call
;param:
99,16 → 109,17
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì
;scratched: ebx,ecx
mov ecx,eax ; ecx=eax=Self, ebx=NewLeft
xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight
cmp eax,ecx ; ñòîï, ñåáå äóìàþ...
mov ecx, eax ; ecx=eax=Self, ebx=NewLeft
xchg ecx, [ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight
cmp eax, ecx ; ñòîï, ñåáå äóìàþ...
je .break ; - à íå äóðàê ëè ÿ?
mov [ecx+EVENT.bk],eax ; NewRight.bk=Self
xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft
.break: popfd
mov [ecx+EVENT.bk], eax ; NewRight.bk=Self
xchg ebx, [eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft
xchg ecx, [eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight
mov [ebx+EVENT.fd], ecx ; OldLeft.fd=OldRight
mov [ecx+EVENT.bk], ebx ; OldRight.bk=OldLeft
.break:
popfd
ret
 
align 4
115,8 → 126,8
NotDummyTest: ;; INTERNAL use (not returned for fail !!!)
pop edi
call DummyTest ; not returned for fail !!!
mov ebx,eax
mov eax,[ebx+EVENT.pid]
mov ebx, eax
mov eax, [ebx+EVENT.pid]
push edi
.small: ; êðèâî êàê-òî...
pop edi
123,7 → 134,7
pushfd
cli
call pid_to_slot ; saved all registers (eax - retval)
shl eax,8
shl eax, 8
jz RemoveEventTo.break ; POPF+RET
jmp edi ; øòàòíûé âîçâðàò
 
141,23 → 152,23
; esi - event data (=0 => skip)
;scratched: ebx,ecx,esi,edi
call NotDummyTest ; not returned for fail !!!
or esi,esi
or esi, esi
jz @f
lea edi,[ebx+EVENT.code]
mov ecx,EVENT.codesize/4
lea edi, [ebx+EVENT.code]
mov ecx, EVENT.codesize/4
cld
rep movsd
rep movsd
@@:
test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
jnz RemoveEventTo.break ; POPF+RET
bt edx, 28 ;EVENT_WATCHED
jnc @f
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24
jz RemoveEventTo.break ; POPF+RET
@@:
or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
add eax,SLOT_BASE+APP_EV_OFFSET
xchg eax,ebx
add eax, SLOT_BASE+APP_EV_OFFSET
xchg eax, ebx
jmp RemoveEventTo
 
align 4
169,9 → 180,9
; ebx - uid (for Dummy testing)
;scratched: ebx,ecx
call NotDummyTest ; not returned for fail !!!
add eax,SLOT_BASE+APP_OBJ_OFFSET
add eax, SLOT_BASE+APP_OBJ_OFFSET
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
xchg eax,ebx
xchg eax, ebx
jmp RemoveEventTo
 
align 4
191,10 → 202,10
; mov eax,[esp+4]
; but not as STDCALL :(
;scratched: ebx,ecx,esi,edi
mov edx,eax
mov edx, eax
call NotDummyTest.small ; not returned for fail !!!
lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET]
mov ecx,EVENT_SIGNALED
lea ebx, [eax+SLOT_BASE+APP_EV_OFFSET]
mov ecx, EVENT_SIGNALED
jmp set_event
 
align 4
202,18 → 213,20
;param:
; eax - event
; ebx - uid (for Dummy testing)
cmp [eax+EVENT.magic],'EVNT'
cmp [eax+EVENT.magic], 'EVNT'
jne @f
cmp [eax+EVENT.id],ebx
cmp [eax+EVENT.id], ebx
je .ret
@@: pop eax
xor eax,eax
.ret: ret
@@:
pop eax
xor eax, eax
.ret:
ret
 
 
align 4
Wait_events:
or ebx,-1 ; infinite timeout
or ebx, -1; infinite timeout
Wait_events_ex:
;info:
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ.
228,26 → 241,27
;retval:
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout)
;scratched: esi
mov esi,[current_slot]
mov [esi+APPDATA.wait_param],ecx
mov esi, [current_slot]
mov [esi+APPDATA.wait_param], ecx
pushad
mov ebx,esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
mov ebx, esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call edx
popfd
mov [esp+28],eax
mov [esp+28], eax
popad
or eax,eax
or eax, eax
jnz @f ;RET
mov [esi+APPDATA.wait_test],edx
mov [esi+APPDATA.wait_timeout],ebx
mov [esi+APPDATA.wait_test], edx
mov [esi+APPDATA.wait_timeout], ebx
Mov [esi+APPDATA.wait_begin],eax,[timer_ticks]
mov eax,[TASK_BASE]
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], 5
call change_task
mov eax,[esi+APPDATA.wait_param]
@@: ret
mov eax, [esi+APPDATA.wait_param]
@@:
ret
 
align 4
wait_event: ;; EXPORT use
263,7 → 277,7
; ebx - uid (for Dummy testing)
;scratched: ecx,edx,esi
call DummyTest
mov ecx,eax ; wait_param
mov ecx, eax ; wait_param
mov edx, get_event_alone ; wait_test
call Wait_events ; timeout ignored
jmp wait_finish
284,11 → 298,11
;scratched: ebx,ecx,edx,esi,edi
mov edx, get_event_queue ; wait_test
call Wait_events ; timeout ignored
lea esi,[eax+EVENT.code]
mov ecx,EVENT.codesize/4
lea esi, [eax+EVENT.code]
mov ecx, EVENT.codesize/4
cld
rep movsd
mov [edi-EVENT.codesize+2],cl ;clear priority field
rep movsd
mov [edi-EVENT.codesize+2], cl;clear priority field
wait_finish:
test byte[eax+EVENT.state+3], MANUAL_RESET shr 24
jnz get_event_queue.ret ; RET
295,8 → 309,8
and byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24
jz destroy_event.internal
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
mov ebx, [current_slot]
add ebx, APP_OBJ_OFFSET
pushfd
cli
jmp RemoveEventTo
313,14 → 327,14
;scratched: ebx,ecx
call DummyTest ; not returned for fail !!!
.internal:
xor ecx,ecx ; clear common header
xor ecx, ecx ; clear common header
pushfd
cli
mov [eax+EVENT.magic],ecx
mov [eax+EVENT.destroy],ecx
mov [eax+EVENT.pid],ecx
mov [eax+EVENT.id],ecx
mov ebx,FreeEvents
mov [eax+EVENT.magic], ecx
mov [eax+EVENT.destroy], ecx
mov [eax+EVENT.pid], ecx
mov [eax+EVENT.id], ecx
mov ebx, FreeEvents
jmp RemoveEventTo
 
align 4
335,11 → 349,12
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
add ebx,APP_EV_OFFSET
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO
cmp eax,ebx ; empty ???
add ebx, APP_EV_OFFSET
mov eax, [ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO
cmp eax, ebx ; empty ???
je get_event_alone.ret0
.ret: ret
.ret:
ret
 
align 4
get_event_alone:
353,12 → 368,14
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
mov eax,[ebx+APPDATA.wait_param]
mov eax, [ebx+APPDATA.wait_param]
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24
jnz .ret
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24
.ret0: xor eax,eax ; NO event!!!
.ret: ret
.ret0:
xor eax, eax; NO event!!!
.ret:
ret
 
align 4
sys_sendwindowmsg: ;; f72
366,43 → 383,46
jnz .ret ;subfunction==1 ?
;pushfd ;à íàôèãà?
cli
sub ecx,2
sub ecx, 2
je .sendkey
loop .retf
dec ecx
jnz .retf
.sendbtn:
cmp byte[BTN_COUNT],1
cmp byte[BTN_COUNT], 1
jae .result ;overflow
inc byte[BTN_COUNT]
mov [BTN_BUFF],edx
shl edx, 8
mov [BTN_BUFF], edx
jmp .result
.sendkey:
movzx eax,byte[KEY_COUNT]
cmp al,120
movzx eax, byte[KEY_COUNT]
cmp al, 120
jae .result ;overflow
inc byte[KEY_COUNT]
mov [KEY_COUNT+1+eax],dl
mov [KEY_COUNT+1+eax], dl
.result:
setae byte[esp+32] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32]==72
.retf: ;popfd
.ret: ret
.ret:
ret
 
align 4
sys_getevent: ;; f11
mov ebx,[current_slot] ;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
mov ebx, [current_slot];ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call get_event_for_app
popfd
mov [esp+32],eax
mov [esp+32], eax
ret
 
align 4
sys_waitforevent: ;; f10
or ebx,-1 ; infinite timeout
or ebx, -1; infinite timeout
sys_wait_event_timeout: ;; f23
mov edx,get_event_for_app ; wait_test
mov edx, get_event_for_app; wait_test
call Wait_events_ex ; ebx - timeout
mov [esp+32],eax
mov [esp+32], eax
ret
 
align 4
417,70 → 437,73
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - íîìåð ñîáûòèÿ (=0 => no events)
movzx edi,bh ; bh is assumed as [CURRENT_TASK]
shl edi,5
add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE]
mov ecx,[edi+TASKDATA.event_mask]
movzx edi, bh ; bh is assumed as [CURRENT_TASK]
shl edi, 5
add edi, CURRENT_TASK ; edi is assumed as [TASK_BASE]
mov ecx, [edi+TASKDATA.event_mask]
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè
bsr eax,ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0)
bsr eax, ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0)
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ???
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè
btr ecx, eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà
cmp eax,16
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15
cmp eax,9
jae .loop ; eax=[9..15], ignored
cmp eax,3
cmp eax, 9
jae .loop ; eax=[9..31], ignored
cmp eax, 3
je .loop ; eax=3, ignored
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1
cmp eax,1
cmp eax, 1
jae .BtKy ; eax=[1,2], retvals=eax+1
.WndRedraw: ; eax=0, retval WndRedraw=1
cmp [edi-twdw+WDATA.fl_redraw],al ;al==0
cmp [edi-twdw+WDATA.fl_redraw], al;al==0
jne .result
jmp .loop
.no_events:
xor eax,eax
xor eax, eax
ret
.IRQ:
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug)
mov edx,[irq_owner+eax*4-64] ; eax==16+irq
cmp edx,[edi+TASKDATA.pid]
jne .loop
mov edx,eax
shl edx,12
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000
je .loop ; empty ???
ret ; retval = eax
 
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9
btr [ebx+APPDATA.event_mask],eax
cmp eax, 5; Mouse 5+1=6
jne @f
push eax
; If the window is captured and moved by the user, then no mouse events!!!
mov al, [mouse.active_sys_window.action]
and al, WINDOW_MOVE_AND_RESIZE_FLAGS
test al, al
pop eax
jnz .loop
@@:
btr [ebx+APPDATA.event_mask], eax
jnc .loop
.result: ; retval = eax+1
inc eax
ret
.BtKy:
movzx edx,bh
movzx edx, bh
movzx edx, word[WIN_STACK+edx*2]
je .Keys ; eax=1, retval Keys=2
.Buttons: ; eax=2, retval Buttons=3
cmp byte[BTN_COUNT],0
cmp byte[BTN_COUNT], 0
je .loop ; empty ???
cmp edx,[TASK_COUNT]
cmp edx, [TASK_COUNT]
jne .loop ; not Top ???
cmp dword[BTN_BUFF],0xFFFF ;-ID for Minimize-Button of Form
mov edx, [BTN_BUFF]
shr edx, 8
cmp edx, 0xFFFF ;-ID for Minimize-Button of Form
jne .result
mov [window_minimize],1
mov [window_minimize], 1
dec byte[BTN_COUNT]
jmp .loop
.Keys: ; eax==1
cmp edx,[TASK_COUNT]
cmp edx, [TASK_COUNT]
jne @f ; not Top ???
cmp [KEY_COUNT],al ; al==1
cmp [KEY_COUNT], al; al==1
jae .result ; not empty ???
@@: mov edx, hotkey_buffer
@@: cmp [edx],bh ; bh - slot for testing
@@:
mov edx, hotkey_buffer
@@:
cmp [edx], bh ; bh - slot for testing
je .result
add edx,8
add edx, 8
cmp edx, hotkey_buffer+120*8
jb @b
jmp .loop
/kernel/branches/net/gui/font.inc
10,10 → 10,10
; // Alver 22.06.2008 // {
align 4
dtext_asciiz_esi: ; for skins title out
push eax
xor eax, eax
inc eax
jmp dtext.1
push eax
xor eax, eax
inc eax
jmp dtext.1
; } \\ Alver \\
 
align 4
28,7 → 28,7
; edi 1 force
 
; // Alver 22.06.2008 // {
push eax
push eax
xor eax, eax
.1:
; } \\ Alver \\
51,10 → 51,10
cmp byte [edx], 0
jz .end
; // Alver 22.06.2008 // {
cmp byte [esp+28], 1
jne @f
cmp byte [esp+28], 1
jne @f
dec esi
js .end
js .end
; } \\ Alver \\
@@:
inc edx
128,5 → 128,5
jmp .loop
.end:
popad
pop eax ; << // Alver 22.06.2008 // <<
pop eax ; << // Alver 22.06.2008 // <<
ret
/kernel/branches/net/gui/mouse.inc
1,250 → 1,715
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Copyright (C) KolibriOS team 2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
include 'mousepointer.inc'
 
iglobal
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
mouse.LEFT_BUTTON_FLAG = 0001b
mouse.RIGHT_BUTTON_FLAG = 0010b
mouse.MIDDLE_BUTTON_FLAG = 0100b
 
mouse.BUTTONS_MASK = \
mouse.LEFT_BUTTON_FLAG or \
mouse.RIGHT_BUTTON_FLAG or \
mouse.MIDDLE_BUTTON_FLAG
 
mouse.WINDOW_RESIZE_N_FLAG = 000001b
mouse.WINDOW_RESIZE_W_FLAG = 000010b
mouse.WINDOW_RESIZE_S_FLAG = 000100b
mouse.WINDOW_RESIZE_E_FLAG = 001000b
mouse.WINDOW_MOVE_FLAG = 010000b
 
mouse.WINDOW_RESIZE_SW_FLAG = \
mouse.WINDOW_RESIZE_S_FLAG or \
mouse.WINDOW_RESIZE_W_FLAG
mouse.WINDOW_RESIZE_SE_FLAG = \
mouse.WINDOW_RESIZE_S_FLAG or \
mouse.WINDOW_RESIZE_E_FLAG
 
align 4
mousepointer:
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80
;------------------------------------------------------------------------------
mouse_check_events: ;//////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if mouse buttons state or cursor position has changed and call
;? appropriate handlers
;------------------------------------------------------------------------------
push eax ebx
 
mousepointer1:
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00
mov al, [BTN_DOWN]
mov bl, [mouse.state.buttons]
and al, mouse.BUTTONS_MASK
mov cl, al
xchg cl, [mouse.state.buttons]
xor bl, al
push eax ebx
 
; did any mouse button changed its state?
or bl, bl
jz .check_position
 
; yes it did, is that the first button of all pressed down?
or cl, cl
jnz .check_buttons_released
 
; yes it is, activate window user is pointing at, if needed
call mouse._.activate_sys_window_under_cursor
 
; NOTE: this code wouldn't be necessary if we knew window did
; already redraw itself after call above
or eax, eax
jz @f
 
and [mouse.state.buttons], 0
jmp .exit
 
; is there any system button under cursor?
@@:
call mouse._.find_sys_button_under_cursor
or eax, eax
jz .check_buttons_released
 
; yes there is, activate it and exit
mov [mouse.active_sys_button.pbid], eax
mov [mouse.active_sys_button.coord], ebx
mov cl, [mouse.state.buttons]
mov [mouse.active_sys_button.buttons], cl
call sys_button_activate_handler
jmp .exit
 
.check_buttons_released:
cmp [mouse.state.buttons], 0
jnz .buttons_changed
 
; did we press some button earlier?
cmp [mouse.active_sys_button.pbid], 0
je .buttons_changed
 
; yes we did, deactivate it
xor eax, eax
xchg eax, [mouse.active_sys_button.pbid]
mov ebx, [mouse.active_sys_button.coord]
mov cl, [mouse.active_sys_button.buttons]
push eax ebx
call sys_button_deactivate_handler
pop edx ecx
 
; is the button under cursor the one we deactivated?
call mouse._.find_sys_button_under_cursor
cmp eax, ecx
jne .exit
cmp ebx, edx
jne .exit
 
; yes it is, perform associated action
mov cl, [mouse.active_sys_button.buttons]
call sys_button_perform_handler
jmp .exit
 
.buttons_changed:
test byte[esp], mouse.LEFT_BUTTON_FLAG
jz @f
mov eax, [esp + 4]
call .call_left_button_handler
 
@@:
test byte[esp], mouse.RIGHT_BUTTON_FLAG
jz @f
mov eax, [esp + 4]
call .call_right_button_handler
 
@@:
test byte[esp], mouse.MIDDLE_BUTTON_FLAG
jz .check_position
mov eax, [esp + 4]
call .call_middle_button_handler
 
.check_position:
movzx eax, word[MOUSE_X]
movzx ebx, word[MOUSE_Y]
cmp eax, [mouse.state.pos.x]
jne .position_changed
cmp ebx, [mouse.state.pos.y]
je .exit
 
.position_changed:
xchg eax, [mouse.state.pos.x]
xchg ebx, [mouse.state.pos.y]
 
call mouse._.move_handler
 
.exit:
add esp, 8
pop ebx eax
ret
 
.call_left_button_handler:
test eax, mouse.LEFT_BUTTON_FLAG
jnz mouse._.left_button_press_handler
jmp mouse._.left_button_release_handler
 
.call_right_button_handler:
test eax, mouse.RIGHT_BUTTON_FLAG
jnz mouse._.right_button_press_handler
jmp mouse._.right_button_release_handler
 
.call_middle_button_handler:
test eax, mouse.MIDDLE_BUTTON_FLAG
jnz mouse._.middle_button_press_handler
jmp mouse._.middle_button_release_handler
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
uglobal
mouse.state:
.pos POINT
.buttons db ?
 
; NOTE: since there's no unique and lifetime-constant button identifiers,
; we're using two dwords to identify each of them:
; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack
; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack
align 4
mouse.active_sys_button:
.pbid dd ?
.coord dd ?
.buttons db ?
 
align 4
mouse.active_sys_window:
.pslot dd ?
.old_box BOX
.new_box BOX
.delta POINT
.last_ticks dd ?
.action db ?
endg
 
align 4
;------------------------------------------------------------------------------
mouse._.left_button_press_handler: ;///////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when left mouse button has been pressed down
;------------------------------------------------------------------------------
test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG
jnz .exit
 
call mouse._.find_sys_window_under_cursor
call mouse._.check_sys_window_actions
mov [mouse.active_sys_window.action], al
or eax, eax
jz .exit
 
xchg eax, edx
test dl, mouse.WINDOW_MOVE_FLAG
jz @f
 
mov eax, [timer_ticks]
mov ebx, eax
xchg ebx, [mouse.active_sys_window.last_ticks]
sub eax, ebx
cmp eax, 50
jg @f
 
mov [mouse.active_sys_window.last_ticks], 0
call sys_window_maximize_handler
jmp .exit
 
@@:
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
mov [mouse.active_sys_window.pslot], esi
lea eax, [edi + WDATA.box]
mov ebx, mouse.active_sys_window.old_box
mov ecx, sizeof.BOX
call memmove
mov ebx, mouse.active_sys_window.new_box
call memmove
test edx, mouse.WINDOW_MOVE_FLAG
jz @f
 
call .calculate_n_delta
call .calculate_w_delta
jmp .call_window_handler
 
@@:
test dl, mouse.WINDOW_RESIZE_W_FLAG
jz @f
call .calculate_w_delta
 
@@:
test dl, mouse.WINDOW_RESIZE_S_FLAG
jz @f
call .calculate_s_delta
 
@@:
test dl, mouse.WINDOW_RESIZE_E_FLAG
jz .call_window_handler
call .calculate_e_delta
 
.call_window_handler:
mov eax, mouse.active_sys_window.old_box
call sys_window_start_moving_handler
 
.exit:
ret
 
.calculate_n_delta:
mov eax, [mouse.state.pos.y]
sub eax, [mouse.active_sys_window.old_box.top]
mov [mouse.active_sys_window.delta.y], eax
ret
 
.calculate_w_delta:
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.old_box.left]
mov [mouse.active_sys_window.delta.x], eax
ret
 
.calculate_s_delta:
mov eax, [mouse.active_sys_window.old_box.top]
add eax, [mouse.active_sys_window.old_box.height]
sub eax, [mouse.state.pos.y]
mov [mouse.active_sys_window.delta.y], eax
ret
 
.calculate_e_delta:
mov eax, [mouse.active_sys_window.old_box.left]
add eax, [mouse.active_sys_window.old_box.width]
sub eax, [mouse.state.pos.x]
mov [mouse.active_sys_window.delta.x], eax
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.left_button_release_handler: ;/////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when left mouse button has been released
;------------------------------------------------------------------------------
xor esi, esi
xchg esi, [mouse.active_sys_window.pslot]
or esi, esi
jz .exit
 
mov eax, esi
shl eax, 5
add eax, window_data + WDATA.box
mov ebx, mouse.active_sys_window.old_box
mov ecx, sizeof.BOX
call memmove
 
mov eax, mouse.active_sys_window.old_box
mov ebx, mouse.active_sys_window.new_box
call sys_window_end_moving_handler
 
.exit:
and [mouse.active_sys_window.action], 0
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.right_button_press_handler: ;//////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when right mouse button has been pressed down
;------------------------------------------------------------------------------
test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG
jnz .exit
 
call mouse._.find_sys_window_under_cursor
call mouse._.check_sys_window_actions
test al, mouse.WINDOW_MOVE_FLAG
jz .exit
 
call sys_window_rollup_handler
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.right_button_release_handler: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when right mouse button has been released
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.middle_button_press_handler: ;/////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when middle mouse button has been pressed down
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.middle_button_release_handler: ;///////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when middle mouse button has been released
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.move_handler: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when cursor has been moved
;------------------------------------------------------------------------------
;> eax = old x coord
;> ebx = old y coord
;------------------------------------------------------------------------------
cmp [mouse.active_sys_button.pbid], 0
jnz .exit
 
mov esi, [mouse.active_sys_window.pslot]
or esi, esi
jz .exit
 
mov eax, mouse.active_sys_window.new_box
mov ebx, mouse.active_sys_window.old_box
mov ecx, sizeof.BOX
call memmove
 
mov dl, [mouse.active_sys_window.action]
test dl, mouse.WINDOW_MOVE_FLAG
jz .check_resize_w
 
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.delta.x]
mov [mouse.active_sys_window.new_box.left], eax
mov eax, [mouse.state.pos.y]
sub eax, [mouse.active_sys_window.delta.y]
mov [mouse.active_sys_window.new_box.top], eax
 
mov eax, [mouse.active_sys_window.new_box.left]
or eax, eax
jge @f
xor eax, eax
mov [mouse.active_sys_window.new_box.left], eax
@@:
add eax, [mouse.active_sys_window.new_box.width]
cmp eax, [Screen_Max_X]
jl @f
sub eax, [Screen_Max_X]
sub [mouse.active_sys_window.new_box.left], eax
@@:
mov eax, [mouse.active_sys_window.new_box.top]
or eax, eax
jge @f
xor eax, eax
mov [mouse.active_sys_window.new_box.top], eax
@@:
add eax, [mouse.active_sys_window.new_box.height]
cmp eax, [Screen_Max_Y]
jle .call_window_handler
sub eax, [Screen_Max_Y]
sub [mouse.active_sys_window.new_box.top], eax
jmp .call_window_handler
 
.check_resize_w:
test dl, mouse.WINDOW_RESIZE_W_FLAG
jz .check_resize_s
 
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.delta.x]
mov [mouse.active_sys_window.new_box.left], eax
sub eax, [mouse.active_sys_window.old_box.left]
sub [mouse.active_sys_window.new_box.width], eax
 
mov eax, [mouse.active_sys_window.new_box.width]
sub eax, 127
jge @f
add [mouse.active_sys_window.new_box.left], eax
mov [mouse.active_sys_window.new_box.width], 127
@@:
mov eax, [mouse.active_sys_window.new_box.left]
or eax, eax
jge .check_resize_s
add [mouse.active_sys_window.new_box.width], eax
xor eax, eax
mov [mouse.active_sys_window.new_box.left], eax
 
.check_resize_s:
test dl, mouse.WINDOW_RESIZE_S_FLAG
jz .check_resize_e
 
mov eax, [mouse.state.pos.y]
add eax, [mouse.active_sys_window.delta.y]
sub eax, [mouse.active_sys_window.old_box.top]
mov [mouse.active_sys_window.new_box.height], eax
 
push eax
mov edi, esi
shl edi, 5
add edi, window_data
call window._.get_rolledup_height
mov ecx, eax
pop eax
mov eax, [mouse.active_sys_window.new_box.height]
cmp eax, ecx
jge @f
mov eax, ecx
mov [mouse.active_sys_window.new_box.height], eax
@@:
add eax, [mouse.active_sys_window.new_box.top]
cmp eax, [Screen_Max_Y]
jle .check_resize_e
sub eax, [Screen_Max_Y]
neg eax
add [mouse.active_sys_window.new_box.height], eax
mov ecx, [Screen_Max_Y]
cmp ecx, eax
jge .check_resize_e
mov [mouse.active_sys_window.new_box.height], ecx
 
.check_resize_e:
test dl, mouse.WINDOW_RESIZE_E_FLAG
jz .call_window_handler
 
mov eax, [mouse.state.pos.x]
add eax, [mouse.active_sys_window.delta.x]
sub eax, [mouse.active_sys_window.old_box.left]
mov [mouse.active_sys_window.new_box.width], eax
 
mov eax, [mouse.active_sys_window.new_box.width]
cmp eax, 127
jge @f
mov eax, 127
mov [mouse.active_sys_window.new_box.width], eax
@@:
add eax, [mouse.active_sys_window.new_box.left]
cmp eax, [Screen_Max_X]
jle .call_window_handler
sub eax, [Screen_Max_X]
neg eax
add [mouse.active_sys_window.new_box.width], eax
mov ecx, [Screen_Max_X]
cmp ecx, eax
jge .call_window_handler
mov [mouse.active_sys_window.new_box.width], ecx
 
.call_window_handler:
mov eax, mouse.active_sys_window.old_box
mov ebx, mouse.active_sys_window.new_box
 
push esi
mov esi, mouse.active_sys_window.old_box
mov edi, mouse.active_sys_window.new_box
mov ecx, sizeof.BOX / 4
repe
cmpsd
pop esi
je .exit
 
mov [mouse.active_sys_window.last_ticks], 0
call sys_window_moving_handler
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.find_sys_window_under_cursor: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system window object which is currently visible on screen and has
;? mouse cursor within its bounds
;------------------------------------------------------------------------------
;< esi = process slot
;< edi = pointer to WDATA struct
;------------------------------------------------------------------------------
mov esi, [Screen_Max_X]
inc esi
imul esi, [mouse.state.pos.y]
add esi, [_WinMapAddress]
add esi, [mouse.state.pos.x]
movzx esi, byte[esi]
mov edi, esi
shl edi, 5
add edi, window_data
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.activate_sys_window_under_cursor: ;////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; activate and redraw window under cursor (if necessary)
call mouse._.find_sys_window_under_cursor
movzx esi, word[WIN_STACK + esi * 2]
lea esi, [WIN_POS + esi * 2]
jmp waredraw
 
align 4
;------------------------------------------------------------------------------
mouse._.find_sys_button_under_cursor: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system button object which is currently visible on screen and has
;? mouse cursor within its bounds
;------------------------------------------------------------------------------
;< eax = pack[8(process slot), 24(button id)] or 0
;< ebx = pack[16(button x coord), 16(button y coord)]
;------------------------------------------------------------------------------
push ecx edx esi edi
 
call mouse._.find_sys_window_under_cursor
mov edx, esi
 
; check if any process button contains cursor
mov eax, [BTN_ADDR]
mov ecx, [eax]
imul esi, ecx, SYS_BUTTON.sizeof
add esi, eax
inc ecx
add esi, SYS_BUTTON.sizeof
 
.next_button:
dec ecx
jz .not_found
 
add esi, -SYS_BUTTON.sizeof
 
; does it belong to our process?
cmp dx, [esi + SYS_BUTTON.pslot]
jne .next_button
 
; does it contain cursor coordinates?
mov eax, [mouse.state.pos.x]
sub eax, [edi + WDATA.box.left]
sub ax, [esi + SYS_BUTTON.left]
jl .next_button
sub ax, [esi + SYS_BUTTON.width]
jge .next_button
mov eax, [mouse.state.pos.y]
sub eax, [edi + WDATA.box.top]
sub ax, [esi + SYS_BUTTON.top]
jl .next_button
sub ax, [esi + SYS_BUTTON.height]
jge .next_button
 
; okay, return it
shl edx, 24
mov eax, dword[esi + SYS_BUTTON.id_hi - 2]
mov ax, [esi + SYS_BUTTON.id_lo]
and eax, 0x0ffffff
or eax, edx
mov ebx, dword[esi + SYS_BUTTON.left - 2]
mov bx, [esi + SYS_BUTTON.top]
jmp .exit
 
.not_found:
xor eax, eax
xor ebx, ebx
 
.exit:
pop edi esi edx ecx
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.check_sys_window_actions: ;////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;< eax = action flags or 0
;------------------------------------------------------------------------------
; is window movable?
test byte[edi + WDATA.cl_titlebar + 3], 0x01
jnz .no_action
 
mov eax, [mouse.state.pos.x]
mov ebx, [mouse.state.pos.y]
sub eax, [edi + WDATA.box.left]
sub ebx, [edi + WDATA.box.top]
 
; is there a window titlebar under cursor?
push eax
call window._.get_titlebar_height
cmp ebx, eax
pop eax
jl .move_action
 
; no there isn't, can it be resized then?
mov dl, [edi + WDATA.fl_wstyle]
and dl, 0x0f
; NOTE: dangerous optimization, revise if window types changed;
; this currently implies only types 2 and 3 could be resized
test dl, 2
jz .no_action
 
mov ecx, [edi + WDATA.box.width]
add ecx, -window.BORDER_SIZE
mov edx, [edi + WDATA.box.height]
add edx, -window.BORDER_SIZE
 
; is it rolled up?
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .resize_w_or_e_action
 
cmp eax, window.BORDER_SIZE
jl .resize_w_action
cmp eax, ecx
jg .resize_e_action
cmp ebx, edx
jle .no_action
 
.resize_s_action:
cmp eax, window.BORDER_SIZE + 10
jl .resize_sw_action
add ecx, -10
cmp eax, ecx
jge .resize_se_action
mov eax, mouse.WINDOW_RESIZE_S_FLAG
jmp .exit
 
.resize_w_or_e_action:
cmp eax, window.BORDER_SIZE + 10
jl .resize_w_action.direct
add ecx, -10
cmp eax, ecx
jg .resize_e_action.direct
jmp .no_action
 
.resize_w_action:
add edx, -10
cmp ebx, edx
jge .resize_sw_action
.resize_w_action.direct:
mov eax, mouse.WINDOW_RESIZE_W_FLAG
jmp .exit
 
.resize_e_action:
add edx, -10
cmp ebx, edx
jge .resize_se_action
.resize_e_action.direct:
mov eax, mouse.WINDOW_RESIZE_E_FLAG
jmp .exit
 
.resize_sw_action:
mov eax, mouse.WINDOW_RESIZE_SW_FLAG
jmp .exit
 
.resize_se_action:
mov eax, mouse.WINDOW_RESIZE_SE_FLAG
jmp .exit
 
.move_action:
mov eax, mouse.WINDOW_MOVE_FLAG
jmp .exit
 
.no_action:
xor eax, eax
 
.exit:
ret
/kernel/branches/net/gui/mousepointer.inc
0,0 → 1,250
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 2288 $
 
 
iglobal
 
align 4
mousepointer:
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80
 
mousepointer1:
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00
 
endg
/kernel/branches/net/gui/skincode.inc
13,273 → 13,279
;skin_data = 0x00778000
 
read_skin_file:
stdcall load_file, ebx
test eax, eax
jz .notfound
cmp dword [eax], 'SKIN'
jnz .noskin
cmp ebx, 32*1024
jb @f
mov ebx, 32*1024
stdcall load_file, ebx
test eax, eax
jz .notfound
cmp dword [eax], 'SKIN'
jnz .noskin
cmp ebx, 32*1024
jb @f
mov ebx, 32*1024
@@:
lea ecx, [ebx+3]
shr ecx, 2
mov esi, eax
mov edi, skin_data
rep movsd
stdcall kernel_free, eax
lea ecx, [ebx+3]
shr ecx, 2
mov esi, eax
mov edi, skin_data
rep movsd
stdcall kernel_free, eax
 
call parse_skin_data
xor eax, eax
ret
call parse_skin_data
xor eax, eax
ret
.notfound:
xor eax, eax
inc eax
ret
xor eax, eax
inc eax
ret
.noskin:
stdcall kernel_free, eax
push 2
pop eax
ret
stdcall kernel_free, eax
push 2
pop eax
ret
 
struct SKIN_HEADER
ident dd ?
version dd ?
params dd ?
buttons dd ?
bitmaps dd ?
struct SKIN_HEADER
ident dd ?
version dd ?
params dd ?
buttons dd ?
bitmaps dd ?
ends
 
struct SKIN_PARAMS
skin_height dd ?
margin.right dw ?
margin.left dw ?
margin.bottom dw ?
margin.top dw ?
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
colors_1.inner dd ?
colors_1.outer dd ?
colors_1.frame dd ?
dtp.size dd ?
dtp.data rb 40
struct SKIN_PARAMS
skin_height dd ?
margin.right dw ?
margin.left dw ?
margin.bottom dw ?
margin.top dw ?
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
colors_1.inner dd ?
colors_1.outer dd ?
colors_1.frame dd ?
dtp.size dd ?
dtp.data rb 40
ends
 
struct SKIN_BUTTONS
type dd ?
; pos:
left dw ?
top dw ?
; size:
width dw ?
height dw ?
struct SKIN_BUTTONS
type dd ?
; position
left dw ?
top dw ?
; size
width dw ?
height dw ?
ends
 
struct SKIN_BITMAPS
kind dw ?
type dw ?
data dd ?
struct SKIN_BITMAPS
kind dw ?
type dw ?
data dd ?
ends
 
load_default_skin:
mov [_skinh],22
mov ebx,_skin_file_default
call read_skin_file
ret
mov [_skinh], 22
mov ebx, _skin_file_default
call read_skin_file
ret
 
parse_skin_data:
mov ebp,skin_data
cmp [ebp+SKIN_HEADER.ident],'SKIN'
jne .exit
mov ebp, skin_data
cmp [ebp+SKIN_HEADER.ident], 'SKIN'
jne .exit
 
mov edi,skin_udata
mov ecx,(skin_udata.end-skin_udata)/4
xor eax,eax
cld
rep stosd
mov edi, skin_udata
mov ecx, (skin_udata.end-skin_udata)/4
xor eax, eax
cld
rep stosd
 
mov ebx,[ebp+SKIN_HEADER.params]
add ebx,skin_data
mov eax,[ebx+SKIN_PARAMS.skin_height]
mov [_skinh],eax
mov eax,[ebx+SKIN_PARAMS.colors.inner]
mov [skin_active.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors.outer]
mov [skin_active.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors.frame]
mov [skin_active.colors.frame],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.inner]
mov [skin_inactive.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.outer]
mov [skin_inactive.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.frame]
mov [skin_inactive.colors.frame],eax
lea esi,[ebx+SKIN_PARAMS.dtp.data]
mov edi,common_colours
mov ecx,[ebx+SKIN_PARAMS.dtp.size]
and ecx,127
rep movsb
mov eax,dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0],eax
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom]
mov dword[_skinmargins+4],eax
mov ebx, [ebp+SKIN_HEADER.params]
add ebx, skin_data
mov eax, [ebx+SKIN_PARAMS.skin_height]
mov [_skinh], eax
mov eax, [ebx+SKIN_PARAMS.colors.inner]
mov [skin_active.colors.inner], eax
mov eax, [ebx+SKIN_PARAMS.colors.outer]
mov [skin_active.colors.outer], eax
mov eax, [ebx+SKIN_PARAMS.colors.frame]
mov [skin_active.colors.frame], eax
mov eax, [ebx+SKIN_PARAMS.colors_1.inner]
mov [skin_inactive.colors.inner], eax
mov eax, [ebx+SKIN_PARAMS.colors_1.outer]
mov [skin_inactive.colors.outer], eax
mov eax, [ebx+SKIN_PARAMS.colors_1.frame]
mov [skin_inactive.colors.frame], eax
lea esi, [ebx+SKIN_PARAMS.dtp.data]
mov edi, common_colours
mov ecx, [ebx+SKIN_PARAMS.dtp.size]
and ecx, 127
rep movsb
mov eax, dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0], eax
mov eax, dword[ebx+SKIN_PARAMS.margin.bottom]
mov dword[_skinmargins+4], eax
 
mov ebx,[ebp+SKIN_HEADER.bitmaps]
add ebx,skin_data
.lp1: cmp dword[ebx],0
je .end_bitmaps
movzx eax,[ebx+SKIN_BITMAPS.kind]
movzx ecx,[ebx+SKIN_BITMAPS.type]
dec eax
jnz .not_left
xor eax,eax
mov edx,skin_active.left.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.left.data
@@: jmp .next_bitmap
mov ebx, [ebp+SKIN_HEADER.bitmaps]
add ebx, skin_data
.lp1:
cmp dword[ebx], 0
je .end_bitmaps
movzx eax, [ebx+SKIN_BITMAPS.kind]
movzx ecx, [ebx+SKIN_BITMAPS.type]
dec eax
jnz .not_left
xor eax, eax
mov edx, skin_active.left.data
or ecx, ecx
jnz @f
mov edx, skin_inactive.left.data
@@:
jmp .next_bitmap
.not_left:
dec eax
jnz .not_oper
mov esi,[ebx+SKIN_BITMAPS.data]
add esi,skin_data
mov eax,[esi+0]
neg eax
mov edx,skin_active.oper.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.oper.data
@@: jmp .next_bitmap
dec eax
jnz .not_oper
mov esi, [ebx+SKIN_BITMAPS.data]
add esi, skin_data
mov eax, [esi+0]
neg eax
mov edx, skin_active.oper.data
or ecx, ecx
jnz @f
mov edx, skin_inactive.oper.data
@@:
jmp .next_bitmap
.not_oper:
dec eax
jnz .not_base
mov eax,[skin_active.left.width]
mov edx,skin_active.base.data
or ecx,ecx
jnz @f
mov eax,[skin_inactive.left.width]
mov edx,skin_inactive.base.data
@@: jmp .next_bitmap
dec eax
jnz .not_base
mov eax, [skin_active.left.width]
mov edx, skin_active.base.data
or ecx, ecx
jnz @f
mov eax, [skin_inactive.left.width]
mov edx, skin_inactive.base.data
@@:
jmp .next_bitmap
.not_base:
add ebx,8
jmp .lp1
add ebx, 8
jmp .lp1
.next_bitmap:
mov ecx,[ebx+SKIN_BITMAPS.data]
add ecx,skin_data
mov [edx+4],eax
mov eax,[ecx+0]
mov [edx+8],eax
add ecx,8
mov [edx+0],ecx
add ebx,8
jmp .lp1
mov ecx, [ebx+SKIN_BITMAPS.data]
add ecx, skin_data
mov [edx+4], eax
mov eax, [ecx+0]
mov [edx+8], eax
add ecx, 8
mov [edx+0], ecx
add ebx, 8
jmp .lp1
.end_bitmaps:
 
mov ebx,[ebp+SKIN_HEADER.buttons]
add ebx,skin_data
.lp2: cmp dword[ebx],0
je .end_buttons
mov eax,[ebx+SKIN_BUTTONS.type]
dec eax
jnz .not_close
mov edx,skin_btn_close
jmp .next_button
mov ebx, [ebp+SKIN_HEADER.buttons]
add ebx, skin_data
.lp2:
cmp dword[ebx], 0
je .end_buttons
mov eax, [ebx+SKIN_BUTTONS.type]
dec eax
jnz .not_close
mov edx, skin_btn_close
jmp .next_button
.not_close:
dec eax
jnz .not_minimize
mov edx,skin_btn_minimize
jmp .next_button
dec eax
jnz .not_minimize
mov edx, skin_btn_minimize
jmp .next_button
.not_minimize:
add ebx,12
jmp .lp2
add ebx, 12
jmp .lp2
.next_button:
movsx eax,[ebx+SKIN_BUTTONS.left]
mov [edx+SKIN_BUTTON.left],eax
movsx eax,[ebx+SKIN_BUTTONS.top]
mov [edx+SKIN_BUTTON.top],eax
movsx eax,[ebx+SKIN_BUTTONS.width]
mov [edx+SKIN_BUTTON.width],eax
movsx eax,[ebx+SKIN_BUTTONS.height]
mov [edx+SKIN_BUTTON.height],eax
add ebx,12
jmp .lp2
movsx eax, [ebx+SKIN_BUTTONS.left]
mov [edx+SKIN_BUTTON.left], eax
movsx eax, [ebx+SKIN_BUTTONS.top]
mov [edx+SKIN_BUTTON.top], eax
movsx eax, [ebx+SKIN_BUTTONS.width]
mov [edx+SKIN_BUTTON.width], eax
movsx eax, [ebx+SKIN_BUTTONS.height]
mov [edx+SKIN_BUTTON.height], eax
add ebx, 12
jmp .lp2
.end_buttons:
 
.exit:
ret
ret
 
sys_putimage_with_check:
or ebx,ebx
jz @f
call sys_putimage.forced
@@: ret
or ebx, ebx
jz @f
call sys_putimage.forced
@@:
ret
 
drawwindow_IV_caption:
 
mov ebp,skin_active
or al,al
jnz @f
mov ebp,skin_inactive
mov ebp, skin_active
or al, al
jnz @f
mov ebp, skin_inactive
@@:
 
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width] ; window width
mov edx,[ebp+SKIN_DATA.left.left]
shl edx,16
mov ecx,[ebp+SKIN_DATA.left.width]
shl ecx,16
add ecx,[_skinh]
mov esi, [esp+4]
mov eax, [esi+WDATA.box.width] ; window width
mov edx, [ebp+SKIN_DATA.left.left]
shl edx, 16
mov ecx, [ebp+SKIN_DATA.left.width]
shl ecx, 16
add ecx, [_skinh]
 
mov ebx, [ebp+SKIN_DATA.left.data]
call sys_putimage_with_check
mov ebx, [ebp+SKIN_DATA.left.data]
call sys_putimage_with_check
 
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width]
sub eax,[ebp+SKIN_DATA.left.width]
sub eax,[ebp+SKIN_DATA.oper.width]
cmp eax,[ebp+SKIN_DATA.base.left]
jng .non_base
xor edx,edx
mov ecx,[ebp+SKIN_DATA.base.width]
jecxz .non_base
div ecx
mov esi, [esp+4]
mov eax, [esi+WDATA.box.width]
sub eax, [ebp+SKIN_DATA.left.width]
sub eax, [ebp+SKIN_DATA.oper.width]
cmp eax, [ebp+SKIN_DATA.base.left]
jng .non_base
xor edx, edx
mov ecx, [ebp+SKIN_DATA.base.width]
jecxz .non_base
div ecx
 
inc eax
inc eax
 
mov ebx,[ebp+SKIN_DATA.base.data]
mov ecx,[ebp+SKIN_DATA.base.width]
shl ecx,16
add ecx,[_skinh]
mov edx,[ebp+SKIN_DATA.base.left]
sub edx,[ebp+SKIN_DATA.base.width]
shl edx,16
mov ebx, [ebp+SKIN_DATA.base.data]
mov ecx, [ebp+SKIN_DATA.base.width]
shl ecx, 16
add ecx, [_skinh]
mov edx, [ebp+SKIN_DATA.base.left]
sub edx, [ebp+SKIN_DATA.base.width]
shl edx, 16
.baseskinloop:
shr edx,16
add edx,[ebp+SKIN_DATA.base.width]
shl edx,16
shr edx, 16
add edx, [ebp+SKIN_DATA.base.width]
shl edx, 16
 
push eax ebx ecx edx
call sys_putimage_with_check
pop edx ecx ebx eax
push eax ebx ecx edx
call sys_putimage_with_check
pop edx ecx ebx eax
 
dec eax
jnz .baseskinloop
dec eax
jnz .baseskinloop
.non_base:
 
mov esi,[esp+4]
mov edx,[esi+WDATA.box.width]
sub edx,[ebp+SKIN_DATA.oper.width]
inc edx
shl edx,16
mov ebx,[ebp+SKIN_DATA.oper.data]
mov esi, [esp+4]
mov edx, [esi+WDATA.box.width]
sub edx, [ebp+SKIN_DATA.oper.width]
inc edx
shl edx, 16
mov ebx, [ebp+SKIN_DATA.oper.data]
 
mov ecx,[ebp+SKIN_DATA.oper.width]
shl ecx,16
add ecx,[_skinh]
call sys_putimage_with_check
mov ecx, [ebp+SKIN_DATA.oper.width]
shl ecx, 16
add ecx, [_skinh]
call sys_putimage_with_check
 
ret
ret
 
;//mike.dld, 2006-08-02 ]
 
287,174 → 293,174
drawwindow_IV:
;param1 - aw_yes
 
pusha
pusha
 
push edx
push edx
 
mov edi,edx
mov edi, edx
 
mov ebp,skin_active
cmp byte [esp+32+4+4],0
jne @f
mov ebp,skin_inactive
mov ebp, skin_active
cmp byte [esp+32+4+4], 0
jne @f
mov ebp, skin_inactive
@@:
 
mov eax,[edi+WDATA.box.left]
shl eax,16
mov ax,word [edi+WDATA.box.left]
add ax,word [edi+WDATA.box.width]
mov ebx,[edi+WDATA.box.top]
shl ebx,16
mov bx,word [edi+WDATA.box.top]
add bx,word [edi+WDATA.box.height]
mov eax, [edi+WDATA.box.left]
shl eax, 16
mov ax, word [edi+WDATA.box.left]
add ax, word [edi+WDATA.box.width]
mov ebx, [edi+WDATA.box.top]
shl ebx, 16
mov bx, word [edi+WDATA.box.top]
add bx, word [edi+WDATA.box.height]
; mov esi,[edi+24]
; shr esi,1
; and esi,0x007f7f7f
mov esi,[ebp+SKIN_DATA.colors.outer]
call draw_rectangle
mov ecx,3
mov esi, [ebp+SKIN_DATA.colors.outer]
call draw_rectangle
mov ecx, 3
_dw3l:
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24]
call draw_rectangle
dec ecx
jnz _dw3l
mov esi,[ebp+SKIN_DATA.colors.inner]
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
call draw_rectangle
add eax, 1*65536-1
add ebx, 1*65536-1
test ax, ax
js no_skin_add_button
test bx, bx
js no_skin_add_button
mov esi, [ebp+SKIN_DATA.colors.frame];[edi+24]
call draw_rectangle
dec ecx
jnz _dw3l
mov esi, [ebp+SKIN_DATA.colors.inner]
add eax, 1*65536-1
add ebx, 1*65536-1
test ax, ax
js no_skin_add_button
test bx, bx
js no_skin_add_button
call draw_rectangle
 
cmp dword[skin_data],'SKIN'
je @f
xor eax,eax
xor ebx,ebx
mov esi,[esp]
mov ecx,[esi+WDATA.box.width]
inc ecx
mov edx,[_skinh]
mov edi,[common_colours+4] ; standard grab color
call [drawbar]
jmp draw_clientbar
cmp dword[skin_data], 'SKIN'
je @f
xor eax, eax
xor ebx, ebx
mov esi, [esp]
mov ecx, [esi+WDATA.box.width]
inc ecx
mov edx, [_skinh]
mov edi, [common_colours+4]; standard grab color
call [drawbar]
jmp draw_clientbar
@@:
 
mov al,[esp+32+4+4]
call drawwindow_IV_caption
mov al, [esp+32+4+4]
call drawwindow_IV_caption
 
draw_clientbar:
 
mov esi,[esp]
mov esi, [esp]
 
mov edx,[esi+WDATA.box.top] ; WORK AREA
add edx,21+5
mov ebx,[esi+WDATA.box.top]
add ebx,[esi+WDATA.box.height]
cmp edx,ebx
jg _noinside2
mov eax,5
mov ebx,[_skinh]
mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height]
sub ecx,4
sub edx,4
mov edi,[esi+WDATA.cl_workarea]
test edi,0x40000000
jnz _noinside2
call [drawbar]
mov edx, [esi+WDATA.box.top] ; WORK AREA
add edx, 21+5
mov ebx, [esi+WDATA.box.top]
add ebx, [esi+WDATA.box.height]
cmp edx, ebx
jg _noinside2
mov eax, 5
mov ebx, [_skinh]
mov ecx, [esi+WDATA.box.width]
mov edx, [esi+WDATA.box.height]
sub ecx, 4
sub edx, 4
mov edi, [esi+WDATA.cl_workarea]
test edi, 0x40000000
jnz _noinside2
call [drawbar]
_noinside2:
 
cmp dword[skin_data],'SKIN'
jne no_skin_add_button
cmp dword[skin_data], 'SKIN'
jne no_skin_add_button
 
;* close button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
mov edi, [BTN_ADDR]
movzx eax, word [edi]
cmp eax, 1000
jge no_skin_add_button
inc eax
mov [edi], ax
 
shl eax,4
add eax,edi
shl eax, 4
add eax, edi
 
mov bx,[CURRENT_TASK]
mov [eax],bx
mov bx, [CURRENT_TASK]
mov [eax], bx
 
add eax,2 ; save button id number
mov bx,1
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_close.left],0
jge _bCx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
add eax, 2 ; save button id number
mov bx, 1
mov [eax], bx
add eax, 2 ; x start
xor ebx, ebx
cmp [skin_btn_close.left], 0
jge _bCx_at_right
mov ebx, [esp]
mov ebx, [ebx+WDATA.box.width]
inc ebx
_bCx_at_right:
add ebx,[skin_btn_close.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_close.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_close.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_close.height]
dec ebx
mov [eax],bx
add ebx, [skin_btn_close.left]
mov [eax], bx
add eax, 2 ; x size
mov ebx, [skin_btn_close.width]
dec ebx
mov [eax], bx
add eax, 2 ; y start
mov ebx, [skin_btn_close.top]
mov [eax], bx
add eax, 2 ; y size
mov ebx, [skin_btn_close.height]
dec ebx
mov [eax], bx
 
;* minimize button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
mov edi, [BTN_ADDR]
movzx eax, word [edi]
cmp eax, 1000
jge no_skin_add_button
inc eax
mov [edi], ax
 
shl eax,4
add eax,edi
shl eax, 4
add eax, edi
 
mov bx,[CURRENT_TASK]
mov [eax],bx
mov bx, [CURRENT_TASK]
mov [eax], bx
 
add eax,2 ; save button id number
mov bx,65535 ;999
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_minimize.left],0
jge _bMx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
add eax, 2 ; save button id number
mov bx, 65535;999
mov [eax], bx
add eax, 2 ; x start
xor ebx, ebx
cmp [skin_btn_minimize.left], 0
jge _bMx_at_right
mov ebx, [esp]
mov ebx, [ebx+WDATA.box.width]
inc ebx
_bMx_at_right:
add ebx,[skin_btn_minimize.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_minimize.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_minimize.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_minimize.height]
dec ebx
mov [eax],bx
add ebx, [skin_btn_minimize.left]
mov [eax], bx
add eax, 2 ; x size
mov ebx, [skin_btn_minimize.width]
dec ebx
mov [eax], bx
add eax, 2 ; y start
mov ebx, [skin_btn_minimize.top]
mov [eax], bx
add eax, 2 ; y size
mov ebx, [skin_btn_minimize.height]
dec ebx
mov [eax], bx
 
no_skin_add_button:
pop edi
popa
pop edi
popa
 
ret 4
ret 4
 
/kernel/branches/net/gui/skindata.inc
16,26 → 16,26
_skin_file_default db '/sys/DEFAULT.SKN',0
endg
 
struct SKIN_DATA
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
left.data dd ?
left.left dd ?
left.width dd ?
oper.data dd ?
oper.left dd ?
oper.width dd ?
base.data dd ?
base.left dd ?
base.width dd ?
struct SKIN_DATA
colors.inner dd ?
colors.outer dd ?
colors.frame dd ?
left.data dd ?
left.left dd ?
left.width dd ?
oper.data dd ?
oper.left dd ?
oper.width dd ?
base.data dd ?
base.left dd ?
base.width dd ?
ends
 
struct SKIN_BUTTON
left dd ?
top dd ?
width dd ?
height dd ?
struct SKIN_BUTTON
left dd ?
top dd ?
width dd ?
height dd ?
ends
 
uglobal
43,18 → 43,18
align 4
 
skin_udata:
_skinh dd ?
_skinh dd ?
 
_skinmargins: ; rw 4
.right dw ?
.left dw ?
.bottom dw ?
.top dw ?
.right dw ?
.left dw ?
.bottom dw ?
.top dw ?
 
skin_btn_close SKIN_BUTTON
skin_btn_minimize SKIN_BUTTON
 
skin_active SKIN_DATA
skin_active SKIN_DATA
skin_inactive SKIN_DATA
 
align 4
/kernel/branches/net/gui/window.inc
1,1846 → 1,2217
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
macro FuncTable name, [label]
{
common
align 4
\label name#.ftable dword
forward
dd name#.#label
common
name#.sizeof.ftable = $ - name#.ftable
}
 
iglobal
FuncTable syscall_display_settings, \
00, 01, 02, 03, 04, 05, 06, 07, 08
endg
 
uglobal
common_colours rd 32
new_window_starting dd ?
latest_window_touch dd ?
latest_window_touch_delta dd ?
old_window_pos BOX
new_window_pos BOX
draw_limits RECT
bPressedMouseXY_W db ?
do_resize db ?
do_resize_from_corner db ?
reposition db ?
endg
 
align 4
;------------------------------------------------------------------------------
syscall_display_settings: ;///// system function 48 ///////////////////////////
;------------------------------------------------------------------------------
;; Redraw screen:
;< ebx = 0
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set button style:
;< ebx = 1
;< ecx = 0 (flat) or 1 (with gradient)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set system color palette:
;< ebx = 2
;< ecx = pointer to color table
;< edx = size of color table
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get system color palette:
;< ebx = 3
;< ecx = pointer to color table buffer
;< edx = size of color table buffer
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skinned caption height:
;< ebx = 4
;> eax = height in pixels
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get screen working area:
;< ebx = 5
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set screen working area:
;< ebx = 6
;< ecx = pack[16(left), 16(right)]
;< edx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skin margins:
;< ebx = 7
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set skin:
;< ebx = 8
;< ecx = pointer to FileInfoBlock struct
;> eax = FS error code
;------------------------------------------------------------------------------
cmp ebx, .sizeof.ftable / 4
ja @f
jmp [.ftable + ebx * 4]
@@: ret
 
 
align 4
syscall_display_settings.00:
xor eax, eax
inc ebx
cmp [windowtypechanged], ebx
jne .exit
mov [windowtypechanged], eax
 
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.01:
and ecx, 1
cmp ecx, [buttontype]
je .exit
mov [buttontype], ecx
mov [windowtypechanged], ebx
 
.exit:
ret
 
align 4
syscall_display_settings.02:
dec ebx
mov esi, ecx
and edx, 127
mov edi, common_colours
mov ecx, edx
rep movsb
mov [windowtypechanged], ebx
ret
 
align 4
syscall_display_settings.03:
mov edi, ecx
and edx, 127
mov esi, common_colours
mov ecx, edx
rep movsb
ret
 
align 4
syscall_display_settings.04:
mov eax, [_skinh]
mov [esp + 32], eax
ret
 
align 4
syscall_display_settings.05:
mov eax, [screen_workarea.left - 2]
mov ax, word[screen_workarea.right]
mov [esp + 32], eax
mov eax, [screen_workarea.top - 2]
mov ax, word[screen_workarea.bottom]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.06:
xor esi, esi
 
mov edi, [Screen_Max_X]
mov eax, ecx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_horizontal
inc esi
or eax, eax
jge @f
xor eax, eax
@@: mov [screen_workarea.left], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@: mov [screen_workarea.right], ebx
 
.check_horizontal:
mov edi, [Screen_Max_Y]
mov eax, edx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_if_redraw_needed
inc esi
or eax, eax
jge @f
xor eax, eax
@@: mov [screen_workarea.top], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@: mov [screen_workarea.bottom], ebx
 
.check_if_redraw_needed:
or esi, esi
jz .exit
 
call repos_windows
jmp syscall_display_settings._.calculate_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.07:
mov eax, [_skinmargins + 0]
mov [esp + 32], eax
mov eax, [_skinmargins + 4]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.08:
mov ebx, ecx
call read_skin_file
mov [esp + 32], eax
test eax, eax
jnz .exit
 
call syscall_display_settings._.calculate_whole_screen
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
syscall_display_settings._.calculate_whole_screen:
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
jmp calculatescreen
 
syscall_display_settings._.redraw_whole_screen:
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [Screen_Max_X]
mov [draw_limits.right], eax
mov eax, [Screen_Max_Y]
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
 
align 4
;------------------------------------------------------------------------------
syscall_set_window_shape: ;///// system function 50 ///////////////////////////
;------------------------------------------------------------------------------
;; Set window shape address:
;> ebx = 0
;> ecx = shape data address
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set window shape scale:
;> ebx = 1
;> ecx = scale power (resulting scale is 2^ebx)
;------------------------------------------------------------------------------
mov edi, [current_slot]
 
test ebx, ebx
jne .shape_scale
mov [edi + APPDATA.wnd_shape], ecx
 
.shape_scale:
dec ebx
jnz .exit
mov [edi + APPDATA.wnd_shape_scale], ecx
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
set_window_defaults: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
push eax ecx
xor eax, eax
mov ecx, WIN_STACK
@@: inc eax
add ecx, 2
; process no
mov [ecx + 0x000], ax
; positions in stack
mov [ecx + 0x400], ax
cmp ecx, WIN_POS - 2
jne @b
pop ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
calculatescreen: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Scan all windows from bottom to top, calling `setscreen` for each one
;? intersecting given screen area
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;------------------------------------------------------------------------------
push esi
pushfd
cli
 
mov esi, 1
call window._.set_screen
 
push ebp
 
mov ebp, [TASK_COUNT]
cmp ebp, 1
jbe .exit
 
push edx ecx ebx eax
 
.next_window:
movzx edi, word[WIN_POS + esi * 2]
shl edi, 5
 
cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE
je .skip_window
 
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_window
 
mov eax, [edi + WDATA.box.left]
cmp eax, [esp + RECT.right]
jg .skip_window
mov ebx, [edi + WDATA.box.top]
cmp ebx, [esp + RECT.bottom]
jg .skip_window
mov ecx, [edi + WDATA.box.width]
add ecx, eax
cmp ecx, [esp + RECT.left]
jl .skip_window
mov edx, [edi + WDATA.box.height]
add edx, ebx
cmp edx, [esp + RECT.top]
jl .skip_window
 
cmp eax, [esp + RECT.left]
jae @f
mov eax, [esp + RECT.left]
@@: cmp ebx, [esp + RECT.top]
jae @f
mov ebx, [esp + RECT.top]
@@: cmp ecx, [esp + RECT.right]
jbe @f
mov ecx, [esp + RECT.right]
@@: cmp edx, [esp + RECT.bottom]
jbe @f
mov edx, [esp + RECT.bottom]
 
@@: push esi
movzx esi, word[WIN_POS + esi * 2]
call window._.set_screen
pop esi
 
.skip_window:
inc esi
dec ebp
jnz .next_window
 
pop eax ebx ecx edx
 
.exit:
pop ebp
popfd
pop esi
ret
 
align 4
;------------------------------------------------------------------------------
repos_windows: ;///////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [TASK_COUNT]
mov edi, window_data + WDATA.sizeof * 2
call force_redraw_background
dec ecx
jle .exit
 
.next_window:
mov [edi + WDATA.fl_redraw], 1
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .fix_maximized
 
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [Screen_Max_X]
cmp eax, ebx
jle .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jle @f
mov [edi + WDATA.box.width], ebx
@@: sub ebx, [edi + WDATA.box.width]
mov [edi + WDATA.box.left], ebx
 
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [Screen_Max_Y]
cmp eax, ebx
jle .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jle @f
mov [edi + WDATA.box.height], ebx
@@: sub ebx, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], ebx
jmp .fix_client_box
 
.fix_maximized:
mov eax, [screen_workarea.left]
mov [edi + WDATA.box.left], eax
sub eax, [screen_workarea.right]
neg eax
mov [edi + WDATA.box.width], eax
mov eax, [screen_workarea.top]
mov [edi + WDATA.box.top], eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .fix_client_box
sub eax, [screen_workarea.bottom]
neg eax
mov [edi + WDATA.box.height], eax
 
.fix_client_box:
call set_window_clientbox
 
add edi, WDATA.sizeof
loop .next_window
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
check_window_position: ;///////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is inside screen area
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
push eax ebx ecx edx esi
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
 
mov esi, [Screen_Max_X]
cmp ecx, esi
ja .fix_width
 
.check_left:
or eax, eax
jl .fix_left_low
add eax, ecx
cmp eax, esi
jg .fix_left_high
 
.check_height:
mov esi, [Screen_Max_Y]
cmp edx, esi
ja .fix_height
 
.check_top:
or ebx, ebx
jl .fix_top_low
add ebx, edx
cmp ebx, esi
jg .fix_top_high
 
.exit:
pop esi edx ecx ebx eax
ret
 
.fix_width:
mov ecx, esi
mov [edi + WDATA.box.width], esi
jmp .check_left
 
.fix_left_low:
xor eax, eax
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_left_high:
mov eax, esi
sub eax, ecx
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_height:
mov edx, esi
mov [edi + WDATA.box.height], esi
jmp .check_top
 
.fix_top_low:
xor ebx, ebx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
.fix_top_high:
mov ebx, esi
sub ebx, edx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
align 4
;------------------------------------------------------------------------------
sys_window_mouse: ;////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
push eax
 
mov eax, [timer_ticks]
cmp [new_window_starting], eax
jb .exit
 
mov byte[MOUSE_BACKGROUND], 0
mov byte[DONT_DRAW_MOUSE], 0
 
mov [new_window_starting], eax
 
.exit:
pop eax
ret
 
align 4
;------------------------------------------------------------------------------
draw_rectangle: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
;> esi = color
;------------------------------------------------------------------------------
push eax ebx ecx edi
 
xor edi, edi
 
.flags_set:
push ebx
 
; set line color
mov ecx, esi
 
; draw top border
rol ebx, 16
push ebx
rol ebx, 16
pop bx
call [draw_line]
 
; draw bottom border
mov ebx, [esp - 2]
pop bx
call [draw_line]
 
pop ebx
add ebx, 1 * 65536 - 1
 
; draw left border
rol eax, 16
push eax
rol eax, 16
pop ax
call [draw_line]
 
; draw right border
mov eax, [esp - 2]
pop ax
call [draw_line]
 
pop edi ecx ebx eax
ret
 
.forced:
push eax ebx ecx edi
xor edi, edi
inc edi
jmp .flags_set
 
align 4
;------------------------------------------------------------------------------
drawwindow_I_caption: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
push [edx + WDATA.cl_titlebar]
mov esi, edx
 
mov edx, [esi + WDATA.box.top]
mov eax, edx
lea ebx, [edx + 21]
inc edx
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jbe @f
mov ebx, eax
@@: push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
inc eax
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
dec eax
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
mov [esi + WDATA.cl_titlebar], ecx
@@: and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_I: ;////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
call draw_rectangle
 
; window caption
 
call drawwindow_I_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 1
mov ebx, 21
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III_caption: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [edx + WDATA.cl_titlebar]
push ecx
mov esi, edx
mov edx, [esi + WDATA.box.top]
add edx, 4
mov ebx, [esi + WDATA.box.top]
add ebx, 20
mov eax, [esi + WDATA.box.top]
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jb @f
mov ebx, eax
@@: push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
add eax, 4 * 65536 - 4
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x40000000
jz @f
add ecx, 0x00040404
@@: test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
@@: mov [esi + WDATA.cl_titlebar], ecx
and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
shr esi, 1
and esi, 0x007f7f7f
call draw_rectangle
 
push esi
mov ecx, 3
mov esi, [edx + WDATA.cl_frames]
 
.next_frame:
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
dec ecx
jnz .next_frame
 
pop esi
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
 
; window caption
 
call drawwindow_III_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 5
mov ebx, 20
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
sub ecx, 4
sub edx, 4
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
waredraw: ;////////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window, redrawing if necessary
;------------------------------------------------------------------------------
; is it overlapped by another window now?
push ecx
call window._.check_window_draw
test ecx, ecx
pop ecx
jz .do_not_draw
 
; yes it is, activate and update screen buffer
mov byte[MOUSE_DOWN], 1
call window._.window_activate
 
pushad
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
shl esi, 5
add esi, window_data
 
mov eax, [esi + WDATA.box.left]
mov ebx, [esi + WDATA.box.top]
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
 
add ecx, eax
add edx, ebx
 
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
call window._.set_screen
popad
 
; tell application to redraw itself
mov [edi + WDATA.fl_redraw], 1
mov byte[MOUSE_DOWN], 0
ret
 
.do_not_draw:
; no it's not, just activate the window
call window._.window_activate
mov byte[MOUSE_DOWN], 0
mov byte[MOUSE_BACKGROUND], 0
mov byte[DONT_DRAW_MOUSE], 0
ret
 
align 4
;------------------------------------------------------------------------------
minimize_window: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
push edi
pushfd
cli
 
; is it already minimized?
movzx edi, word[WIN_POS + eax * 2]
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .exit
 
push eax ebx ecx edx esi
 
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
add ecx, [edi + WDATA.box.width]
mov [draw_limits.right], ecx
mov ebx, [edi + WDATA.box.top]
mov [draw_limits.top], ebx
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
call calculatescreen
xor esi, esi
xor eax, eax
call redrawscreen
 
pop esi edx ecx ebx eax
 
.exit:
popfd
pop edi
ret
 
align 4
;------------------------------------------------------------------------------
restore_minimized_window: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
pushad
pushfd
cli
 
; is it already restored?
movzx esi, word[WIN_POS + eax * 2]
mov edi, esi
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jz .exit
 
; no it's not, let's do that
mov [edi + WDATA.fl_redraw], 1
and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
mov ebp, window._.set_screen
cmp eax, [TASK_COUNT]
jz @f
mov ebp, calculatescreen
@@: mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call ebp
 
mov byte[MOUSE_BACKGROUND], 0
 
.exit:
popfd
popad
ret
 
align 4
;------------------------------------------------------------------------------
checkwindows: ;////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check for user-initiated window operations
;------------------------------------------------------------------------------
pushad
 
; do we have window minimize/restore request?
cmp [window_minimize], 0
je .check_for_mouse_buttons_state
 
; okay, minimize or restore top-most window and exit
mov eax, [TASK_COUNT]
mov bl, 0
xchg [window_minimize], bl
dec bl
jnz @f
call minimize_window
jmp .check_for_mouse_buttons_state
@@: call restore_minimized_window
 
.check_for_mouse_buttons_state:
; do we have any mouse buttons pressed?
cmp byte[BTN_DOWN], 0
jne .mouse_buttons_pressed
 
mov [bPressedMouseXY_W], 0
jmp .exit
 
.mouse_buttons_pressed:
; yes we do, iterate and ...
mov esi, [TASK_COUNT]
inc esi
 
cmp [bPressedMouseXY_W], 1
ja .next_window
inc [bPressedMouseXY_W]
jnc .next_window
push dword[MOUSE_X]
pop dword[mx]
 
.next_window:
cmp esi, 2
jb .exit
 
dec esi
 
; is that window not minimized?
movzx edi, word[WIN_POS + esi * 2]
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .next_window
 
movzx eax, [mx]
movzx ebx, [my]
 
; is the cursor inside screen bounds of that window?
mov ecx, [edi + WDATA.box.left]
mov edx, [edi + WDATA.box.top]
cmp eax, ecx
jl .next_window
cmp ebx, edx
jl .next_window
add ecx, [edi + WDATA.box.width]
add edx, [edi + WDATA.box.height]
cmp eax, ecx
jge .next_window
cmp ebx, edx
jge .next_window
 
; is that a top-most (which means active) window?
cmp esi, [TASK_COUNT]
je .check_for_moving_or_resizing
 
; no it's not, did we just press mouse button down above it or was it
; already pressed before?
cmp [bPressedMouseXY_W], 1
ja .exit
 
; okay, we just pressed the button, activate this window and exit
lea esi, [WIN_POS + esi * 2]
call waredraw
jmp .exit
 
.check_for_moving_or_resizing:
; is that window movable?
test byte[edi + WDATA.cl_titlebar + 3], 0x01
jnz .exit
 
; yes it is, is it rolled up?
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .check_for_cursor_on_caption
 
; no it's not, can it be resized then?
mov [do_resize_from_corner], 0
mov dl, [edi + WDATA.fl_wstyle]
and dl, 0x0f
cmp dl, 0x00
je .check_for_cursor_on_caption
cmp dl, 0x01
je .check_for_cursor_on_caption
cmp dl, 0x04
je .check_for_cursor_on_caption
 
; are we going to resize it?
mov edx, [edi + WDATA.box.top]
add edx, [edi + WDATA.box.height]
sub edx, 6
cmp ebx, edx
jl .check_for_cursor_on_caption
 
; yes we do, remember that
mov [do_resize_from_corner], 1
jmp .set_move_resize_flag
 
.check_for_cursor_on_caption:
; is the cursor inside window titlebar?
push eax
call window._.get_titlebar_height
add eax, [edi + WDATA.box.top]
cmp ebx, eax
pop eax
jge .exit
 
; calculate duration between two clicks
mov ecx, [timer_ticks]
mov edx, ecx
sub edx, [latest_window_touch]
mov [latest_window_touch], ecx
mov [latest_window_touch_delta], edx
 
.set_move_resize_flag:
mov cl, [BTN_DOWN]
mov [do_resize], cl
 
mov ecx, [edi + WDATA.box.left]
mov edx, [edi + WDATA.box.top]
 
push ecx edx
mov [draw_limits.left], ecx
mov [draw_limits.top], edx
add ecx, [edi + WDATA.box.width]
add edx, [edi + WDATA.box.height]
mov [draw_limits.right], ecx
mov [draw_limits.bottom], edx
pop edx ecx
 
; calculate window-relative cursor coordinates
sub eax, ecx
sub ebx, edx
 
push dword[MOUSE_X]
pop dword[WIN_TEMP_XY]
 
; save old window coordinates
push eax
mov eax, [edi + WDATA.box.left]
mov [old_window_pos.left], eax
mov [new_window_pos.left], eax
mov eax, [edi + WDATA.box.top]
mov [old_window_pos.top], eax
mov [new_window_pos.top], eax
mov eax, [edi + WDATA.box.width]
mov [old_window_pos.width], eax
mov [new_window_pos.width], eax
mov eax, [edi + WDATA.box.height]
mov [old_window_pos.height], eax
mov [new_window_pos.height], eax
pop eax
 
; draw negative moving/sizing frame
call window._.draw_window_frames
 
mov [reposition], 0
mov byte[MOUSE_DOWN], 1
 
.next_mouse_state_check:
; process OS events
mov byte[DONT_DRAW_MOUSE], 1
call checkidle
call checkVga_N13
mov byte[MOUSE_BACKGROUND], 0
call [draw_pointer]
pushad
call stack_handler
popad
 
; did cursor position change?
mov esi, [WIN_TEMP_XY]
cmp esi, [MOUSE_X]
je .check_for_new_mouse_buttons_state
 
; yes it did, calculate window-relative cursor coordinates
movzx ecx, word[MOUSE_X]
movzx edx, word[MOUSE_Y]
sub ecx, eax
sub edx, ebx
 
push eax ebx
 
; we're going to draw new frame, erasing the old one
call window._.draw_window_frames
 
; are we moving it right now?
cmp [do_resize_from_corner], 0
jne .resize_window
 
; yes we do, check if it's inside the screen area
mov eax, [Screen_Max_X]
mov ebx, [Screen_Max_Y]
 
mov [new_window_pos.left], 0
or ecx, ecx
jle .check_for_new_vert_cursor_pos
mov [reposition], 1
sub eax, [new_window_pos.width]
mov [new_window_pos.left], eax
cmp ecx, eax
jge .check_for_new_vert_cursor_pos
mov [new_window_pos.left], ecx
 
.check_for_new_vert_cursor_pos:
mov [new_window_pos.top], 0
or edx, edx
jle .draw_new_window_frame
mov [reposition], 1
sub ebx, [new_window_pos.height]
mov [new_window_pos.top], ebx
cmp edx, ebx
jge .draw_new_window_frame
mov [new_window_pos.top], edx
jmp .draw_new_window_frame
 
.resize_window:
push eax ebx edx
 
mov edx, edi
sub edx, window_data
lea edx, [SLOT_BASE + edx * 8]
 
movzx eax, word[MOUSE_X]
cmp eax, [edi + WDATA.box.left]
jb .fix_new_vert_size
sub eax, [edi + WDATA.box.left]
cmp eax, 32
jge @f
mov eax, 32
@@: mov [new_window_pos.width], eax
 
.fix_new_vert_size:
call window._.get_rolledup_height
mov ebx, eax
movzx eax, word[MOUSE_Y]
cmp eax, [edi + WDATA.box.top]
jb .set_reposition_flag
sub eax, [edi + WDATA.box.top]
cmp eax, ebx
jge @f
mov eax, ebx
@@: mov [new_window_pos.height], eax
 
.set_reposition_flag:
mov [reposition], 1
 
pop edx ebx eax
 
.draw_new_window_frame:
pop ebx eax
 
; draw new window moving/sizing frame
call window._.draw_window_frames
 
mov esi, [MOUSE_X]
mov [WIN_TEMP_XY], esi
 
.check_for_new_mouse_buttons_state:
; did user release mouse button(s)?
cmp byte[BTN_DOWN], 0
jne .next_mouse_state_check
 
; yes he did, moving/sizing is over
mov byte[DONT_DRAW_MOUSE], 1
mov cl, 0
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .check_other_actions
 
mov cl, [reposition]
 
; draw negative frame once again to hide it
call window._.draw_window_frames
 
; save new window bounds
mov eax, [new_window_pos.left]
mov [edi + WDATA.box.left], eax
mov eax, [new_window_pos.top]
mov [edi + WDATA.box.top], eax
mov eax, [new_window_pos.width]
mov [edi + WDATA.box.width], eax
mov eax, [new_window_pos.height]
mov [edi + WDATA.box.height], eax
call set_window_clientbox
 
cmp cl, 1
jne .check_other_actions
push esi edi ecx
mov esi, edi
mov ecx, 2
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED
jnz @f
add ecx, 2
@@: sub edi, window_data
shr edi, 5
shl edi, 8
add edi, SLOT_BASE + APPDATA.saved_box
cld
rep movsd
pop ecx edi esi
 
.check_other_actions:
mov [reposition], cl
 
pushad
 
mov dl, [edi + WDATA.fl_wstyle]
and dl, 0x0f
cmp dl, 0x00
je .check_if_window_fits_screen
cmp dl, 0x01
je .check_if_window_fits_screen
 
cmp cl, 1
je .no_window_sizing
mov edx, edi
sub edx, window_data
shr edx, 5
shl edx, 8
add edx, SLOT_BASE
 
; did we right-click on titlebar?
cmp [do_resize], 2
jne .check_maximization_request
 
; yes we did, toggle normal/rolled up window state
xor [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
mov [reposition], 1
 
; calculate and set appropriate window height
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jz @f
call window._.get_rolledup_height
jmp .set_new_window_height
@@: mov eax, [edx + APPDATA.saved_box.height]
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jz .set_new_window_height
mov eax, [screen_workarea.bottom]
sub eax, [screen_workarea.top]
 
.set_new_window_height:
mov [edi + WDATA.box.height], eax
add eax, [edi + WDATA.box.top]
cmp eax, [Screen_Max_Y]
jbe @f
mov eax, [Screen_Max_Y]
sub eax, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], eax
@@: call check_window_position
call set_window_clientbox
 
.check_maximization_request:
; can window change its height?
push edx
mov dl, [edi + WDATA.fl_wstyle]
and dl, 0x0f
cmp dl, 0x04
pop edx
je .check_if_window_fits_screen
 
; was it really a maximize/restore request?
cmp [do_resize], 1
jne .check_if_window_fits_screen
cmp [do_resize_from_corner], 0
jne .check_if_window_fits_screen
cmp [latest_window_touch_delta], 50
jg .check_if_window_fits_screen
 
; yes is was, toggle normal/maximized window state
xor [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
mov [reposition], 1
 
; calculate and set appropriate window bounds
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jz .restore_normal_window_size
mov eax, [screen_workarea.left]
mov [edi + WDATA.box.left], eax
sub eax, [screen_workarea.right]
neg eax
mov [edi + WDATA.box.width], eax
mov eax, [screen_workarea.top]
mov [edi + WDATA.box.top], eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .calculate_window_client_area
sub eax, [screen_workarea.bottom]
neg eax
mov [edi + WDATA.box.height], eax
jmp .calculate_window_client_area
 
.restore_normal_window_size:
push [edi + WDATA.box.height]
push edi
lea esi, [edx + APPDATA.saved_box]
mov ecx, 4
cld
rep movsd
pop edi
pop eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jz .calculate_window_client_area
mov [edi + WDATA.box.height], eax
 
.calculate_window_client_area:
call set_window_clientbox
 
.check_if_window_fits_screen:
; does window fit into screen area?
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
cmp eax, [Screen_Max_Y]
jbe .no_window_sizing
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
cmp eax, [Screen_Max_X]
jbe .no_window_sizing
 
; no it doesn't, fix that
mov eax, [Screen_Max_X]
sub eax, [edi + WDATA.box.width]
mov [edi + WDATA.box.left], eax
mov eax, [Screen_Max_Y]
sub eax, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], eax
call set_window_clientbox
 
.no_window_sizing:
popad
 
; did somethins actually change its place?
cmp [reposition], 0
je .reset_vars
 
mov byte[DONT_DRAW_MOUSE], 1
 
push eax ebx ecx edx
 
; recalculate screen buffer at new position
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call calculatescreen
 
; recalculate screen buffer at old position
mov eax, [old_window_pos.left]
mov ebx, [old_window_pos.top]
mov ecx, [old_window_pos.width]
mov edx, [old_window_pos.height]
add ecx, eax
add edx, ebx
call calculatescreen
 
pop edx ecx ebx eax
 
mov eax, edi
call redrawscreen
 
; tell window to redraw itself
mov [edi + WDATA.fl_redraw], 1
 
; wait a bit for window to redraw itself
mov ecx, 100
 
.next_idle_cycle:
mov byte[DONT_DRAW_MOUSE], 1
call checkidle
cmp [edi + WDATA.fl_redraw], 0
jz .reset_vars
loop .next_idle_cycle
 
.reset_vars:
mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
mov byte[MOUSE_BACKGROUND], 0 ; no mouse under
mov byte[MOUSE_DOWN], 0 ; react to mouse up/down
 
.exit:
popad
ret
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
align 4
;------------------------------------------------------------------------------
window._.get_titlebar_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jne @f
mov eax, [_skinh]
ret
@@: mov eax, 21
ret
 
align 4
;------------------------------------------------------------------------------
window._.get_rolledup_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jb @f
mov eax, [_skinh]
add eax, 3
ret
@@: or al, al
jnz @f
mov eax, 21
ret
@@: mov eax, 21 + 2
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_screen: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Reserve window area in screen buffer
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
;------------------------------------------------------------------------------
virtual at esp
ff_x dd ?
ff_y dd ?
ff_width dd ?
ff_xsz dd ?
ff_ysz dd ?
ff_scale dd ?
end virtual
 
pushad
 
cmp esi, 1
jz .check_for_shaped_window
mov edi, esi
shl edi, 5
cmp [window_data + edi + WDATA.box.width], 0
jnz .check_for_shaped_window
cmp [window_data + edi + WDATA.box.height], 0
jz .exit
 
.check_for_shaped_window:
mov edi, esi
shl edi, 8
add edi, SLOT_BASE
cmp [edi + APPDATA.wnd_shape], 0
jne .shaped_window
 
; get x&y size
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
; get WinMap start
push esi
mov edi, [Screen_Max_X]
inc edi
mov esi, edi
imul edi, ebx
add edi, eax
add edi, [_WinMapAddress]
pop eax
mov ah, al
push ax
shl eax, 16
pop ax
 
.next_line:
push ecx
shr ecx, 2
rep stosd
mov ecx, [esp]
and ecx, 3
rep stosb
pop ecx
add edi, esi
sub edi, ecx
dec edx
jnz .next_line
 
jmp .exit
 
.shaped_window:
; for (y=0; y <= x_size; y++)
; for (x=0; x <= x_size; x++)
; if (shape[coord(x,y,scale)]==1)
; set_pixel(x, y, process_number);
 
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop
 
; get WinMap start -> ebp
push eax
mov eax, [Screen_Max_X] ; screen_sx
inc eax
imul eax, ebx
add eax, [esp]
add eax, [_WinMapAddress]
mov ebp, eax
 
mov edi, [edi + APPDATA.wnd_shape]
pop eax
 
; eax = x_start
; ebx = y_start
; ecx = x_size
; edx = y_size
; esi = process_number
; edi = &shape
; [scale]
push edx ecx ; for loop - x,y size
 
mov ecx, esi
shl ecx, 5
mov edx, [window_data + ecx + WDATA.box.top]
push [window_data + ecx + WDATA.box.width] ; for loop - width
mov ecx, [window_data + ecx + WDATA.box.left]
sub ebx, edx
sub eax, ecx
push ebx eax ; for loop - x,y
 
add [ff_xsz], eax
add [ff_ysz], ebx
 
mov ebx, [ff_y]
 
.ff_new_y:
mov edx, [ff_x]
 
.ff_new_x:
; -- body --
mov ecx, [ff_scale]
mov eax, [ff_width]
inc eax
shr eax, cl
push ebx edx
shr ebx, cl
shr edx, cl
imul eax, ebx
add eax, edx
pop edx ebx
add eax, edi
call .read_byte
test al,al
jz @f
mov eax, esi
mov [ebp], al
; -- end body --
@@: inc ebp
inc edx
cmp edx, [ff_xsz]
jb .ff_new_x
 
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [Screen_Max_X] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]
jb .ff_new_y
 
add esp, 24
 
.exit:
popad
ret
 
.read_byte:
; eax - address
; esi - slot
push eax ecx edx esi
xchg eax, esi
lea ecx, [esp + 12]
mov edx, 1
call read_process_memory
pop esi edx ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.window_activate: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window
;------------------------------------------------------------------------------
;> esi = pointer to WIN_POS+ window data
;------------------------------------------------------------------------------
push eax ebx
 
; if type of current active window is 3 or 4, it must be redrawn
mov ebx, [TASK_COUNT]
movzx ebx, word[WIN_POS + ebx * 2]
shl ebx, 5
add eax, window_data
mov al, [window_data + ebx + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
je .set_window_redraw_flag
cmp al, 0x04
jne .move_others_down
 
.set_window_redraw_flag:
mov [window_data + ebx + WDATA.fl_redraw], 1
 
.move_others_down:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
 
; drop others
xor eax, eax
 
.next_stack_window:
cmp eax, [TASK_COUNT]
jae .move_self_up
inc eax
cmp [WIN_STACK + eax * 2], bx
jbe .next_stack_window
dec word[WIN_STACK + eax * 2]
jmp .next_stack_window
 
.move_self_up:
movzx ebx, word[esi]
; number of processes
mov ax, [TASK_COUNT]
; this is the last (and the upper)
mov [WIN_STACK + ebx * 2], ax
 
; update on screen - window stack
xor eax, eax
 
.next_window_pos:
cmp eax, [TASK_COUNT]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
 
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
 
pop ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.check_window_draw: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is necessary to draw
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov cl, [edi + WDATA.fl_wstyle]
and cl, 0x0f
cmp cl, 0x03
je .exit.redraw ; window type 3
cmp cl, 0x04
je .exit.redraw ; window type 4
 
push eax ebx edx esi
 
mov eax, edi
sub eax, window_data
shr eax, 5
 
; esi = process number
 
movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400
 
.next_window:
add esi, 2
 
mov eax, [TASK_COUNT]
lea eax, word[WIN_POS + eax * 2] ; number of the upper window
 
cmp esi, eax
ja .exit.no_redraw
 
movzx edx, word[esi]
shl edx, 5
cmp [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
je .next_window
 
mov eax, [edi + WDATA.box.top]
mov ebx, [edi + WDATA.box.height]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.top]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.height]
cmp eax, ecx
jge .next_window
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.width]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.left]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.width]
cmp eax, ecx
jge .next_window
 
pop esi edx ebx eax
 
.exit.redraw:
xor ecx, ecx
inc ecx
ret
 
.exit.no_redraw:
pop esi edx ebx eax
xor ecx, ecx
ret
 
align 4
;------------------------------------------------------------------------------
window._.draw_window_frames: ;/////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw negative window frames
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
push eax
cli
 
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
mov eax, [new_window_pos.left]
cmp eax, [edi + WDATA.box.left]
jnz .draw
mov eax, [new_window_pos.width]
cmp eax, [edi + WDATA.box.width]
jnz .draw
mov eax, [new_window_pos.top]
cmp eax, [edi + WDATA.box.top]
jnz .draw
mov eax, [new_window_pos.height]
cmp eax, [edi + WDATA.box.height]
jnz .draw
xor [edi + WDATA.fl_wdrawn], 2
 
.draw:
push ebx esi
mov eax, [new_window_pos.left - 2]
mov ax, word[new_window_pos.left]
add ax, word[new_window_pos.width]
mov ebx, [new_window_pos.top - 2]
mov bx, word[new_window_pos.top]
add bx, word[new_window_pos.height]
mov esi, 0x01000000
call draw_rectangle.forced
pop esi ebx
 
.exit:
sti
pop eax
ret
 
.forced:
push eax
cli
jmp .draw
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
window.BORDER_SIZE = 5
 
macro FuncTable name, table_name, [label]
{
common
align 4
\label name#.#table_name dword
forward
dd name#.#label
common
name#.sizeof.#table_name = $ - name#.#table_name
}
 
uglobal
common_colours rd 32
draw_limits RECT
endg
 
align 4
;------------------------------------------------------------------------------
syscall_draw_window: ;///// system function 0 /////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov eax, edx
shr eax, 24
and al, 0x0f
cmp al, 5
jae .exit
 
push eax
inc [mouse_pause]
call [_display.disable_mouse]
call window._.sys_set_window
call [_display.disable_mouse]
pop eax
 
or al, al
jnz @f
 
; type I - original style
call drawwindow_I
jmp window._.draw_window_caption.2
 
@@:
dec al
jnz @f
 
; type II - only reserve area, no draw
call sys_window_mouse
dec [mouse_pause]
call [draw_pointer]
jmp .exit
 
@@:
dec al
jnz @f
 
; type III - new style
call drawwindow_III
jmp window._.draw_window_caption.2
 
; type IV & V - skinned window (resizable & not)
@@:
mov eax, [TASK_COUNT]
movzx eax, word[WIN_POS + eax * 2]
cmp eax, [CURRENT_TASK]
setz al
movzx eax, al
push eax
call drawwindow_IV
jmp window._.draw_window_caption.2
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_display_settings: ;///// system function 48 ///////////////////////////
;------------------------------------------------------------------------------
;; Redraw screen:
;< ebx = 0
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set button style:
;< ebx = 1
;< ecx = 0 (flat) or 1 (with gradient)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set system color palette:
;< ebx = 2
;< ecx = pointer to color table
;< edx = size of color table
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get system color palette:
;< ebx = 3
;< ecx = pointer to color table buffer
;< edx = size of color table buffer
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skinned caption height:
;< ebx = 4
;> eax = height in pixels
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get screen working area:
;< ebx = 5
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set screen working area:
;< ebx = 6
;< ecx = pack[16(left), 16(right)]
;< edx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skin margins:
;< ebx = 7
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set skin:
;< ebx = 8
;< ecx = pointer to FileInfoBlock struct
;> eax = FS error code
;------------------------------------------------------------------------------
cmp ebx, .sizeof.ftable / 4
ja @f
jmp [.ftable + ebx * 4]
@@:
ret
 
 
align 4
syscall_display_settings.00:
xor eax, eax
inc ebx
cmp [windowtypechanged], ebx
jne .exit
mov [windowtypechanged], eax
 
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.01:
and ecx, 1
cmp ecx, [buttontype]
je .exit
mov [buttontype], ecx
mov [windowtypechanged], ebx
 
.exit:
ret
 
align 4
syscall_display_settings.02:
dec ebx
mov esi, ecx
and edx, 127
mov edi, common_colours
mov ecx, edx
rep movsb
mov [windowtypechanged], ebx
ret
 
align 4
syscall_display_settings.03:
mov edi, ecx
and edx, 127
mov esi, common_colours
mov ecx, edx
rep movsb
ret
 
align 4
syscall_display_settings.04:
mov eax, [_skinh]
mov [esp + 32], eax
ret
 
align 4
syscall_display_settings.05:
mov eax, [screen_workarea.left - 2]
mov ax, word[screen_workarea.right]
mov [esp + 32], eax
mov eax, [screen_workarea.top - 2]
mov ax, word[screen_workarea.bottom]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.06:
xor esi, esi
 
mov edi, [Screen_Max_X]
mov eax, ecx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_horizontal
inc esi
or eax, eax
jge @f
xor eax, eax
@@:
mov [screen_workarea.left], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@:
mov [screen_workarea.right], ebx
 
.check_horizontal:
mov edi, [Screen_Max_Y]
mov eax, edx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_if_redraw_needed
inc esi
or eax, eax
jge @f
xor eax, eax
@@:
mov [screen_workarea.top], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@:
mov [screen_workarea.bottom], ebx
 
.check_if_redraw_needed:
or esi, esi
jz .exit
 
call repos_windows
jmp syscall_display_settings._.calculate_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.07:
mov eax, [_skinmargins + 0]
mov [esp + 32], eax
mov eax, [_skinmargins + 4]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.08:
mov ebx, ecx
call read_skin_file
mov [esp + 32], eax
test eax, eax
jnz .exit
 
call syscall_display_settings._.calculate_whole_screen
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
syscall_display_settings._.calculate_whole_screen:
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
jmp calculatescreen
 
syscall_display_settings._.redraw_whole_screen:
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [Screen_Max_X]
mov [draw_limits.right], eax
mov eax, [Screen_Max_Y]
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
 
align 4
;------------------------------------------------------------------------------
syscall_set_window_shape: ;///// system function 50 ///////////////////////////
;------------------------------------------------------------------------------
;; Set window shape address:
;> ebx = 0
;> ecx = shape data address
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set window shape scale:
;> ebx = 1
;> ecx = scale power (resulting scale is 2^ebx)
;------------------------------------------------------------------------------
mov edi, [current_slot]
 
test ebx, ebx
jne .shape_scale
mov [edi + APPDATA.wnd_shape], ecx
 
.shape_scale:
dec ebx
jnz .exit
mov [edi + APPDATA.wnd_shape_scale], ecx
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_move_window: ;///// system function 67 ////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov edi, [CURRENT_TASK]
shl edi, 5
add edi, window_data
 
test [edi + WDATA.fl_wdrawn], 1
jz .exit
 
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
 
cmp ebx, -1
jne @f
mov ebx, [edi + WDATA.box.left]
@@:
cmp ecx, -1
jne @f
mov ecx, [edi + WDATA.box.top]
@@:
cmp edx, -1
jne @f
mov edx, [edi + WDATA.box.width]
@@:
cmp esi, -1
jne @f
mov esi, [edi + WDATA.box.height]
 
@@:
push esi edx ecx ebx
mov eax, esp
mov bl, [edi + WDATA.fl_wstate]
call window._.set_window_box
add esp, sizeof.BOX
 
; NOTE: do we really need this? to be reworked
; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under
; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down
 
; NOTE: do we really need this? to be reworked
; call [draw_pointer]
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_window_settings: ;///// system function 71 /////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
dec ebx ; subfunction #1 - set window caption
jnz .exit_fail
 
; NOTE: only window owner thread can set its caption,
; so there's no parameter for PID/TID
 
mov edi, [CURRENT_TASK]
shl edi, 5
 
mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx
or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
 
call window._.draw_window_caption
 
xor eax, eax ; eax = 0 (success)
ret
 
; .get_window_caption:
; dec eax ; subfunction #2 - get window caption
; jnz .exit_fail
 
; not implemented yet
 
.exit_fail:
xor eax, eax
inc eax ; eax = 1 (fail)
ret
 
align 4
;------------------------------------------------------------------------------
set_window_defaults: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable
push eax ecx
xor eax, eax
mov ecx, WIN_STACK
@@:
inc eax
add ecx, 2
; process no
mov [ecx + 0x000], ax
; positions in stack
mov [ecx + 0x400], ax
cmp ecx, WIN_POS - 2
jne @b
pop ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
calculatescreen: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Scan all windows from bottom to top, calling `setscreen` for each one
;? intersecting given screen area
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;------------------------------------------------------------------------------
push esi
pushfd
cli
 
mov esi, 1
call window._.set_screen
 
push ebp
 
mov ebp, [TASK_COUNT]
cmp ebp, 1
jbe .exit
 
push edx ecx ebx eax
 
.next_window:
movzx edi, word[WIN_POS + esi * 2]
shl edi, 5
 
cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE
je .skip_window
 
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_window
 
mov eax, [edi + WDATA.box.left]
cmp eax, [esp + RECT.right]
jg .skip_window
mov ebx, [edi + WDATA.box.top]
cmp ebx, [esp + RECT.bottom]
jg .skip_window
mov ecx, [edi + WDATA.box.width]
add ecx, eax
cmp ecx, [esp + RECT.left]
jl .skip_window
mov edx, [edi + WDATA.box.height]
add edx, ebx
cmp edx, [esp + RECT.top]
jl .skip_window
 
cmp eax, [esp + RECT.left]
jae @f
mov eax, [esp + RECT.left]
@@:
cmp ebx, [esp + RECT.top]
jae @f
mov ebx, [esp + RECT.top]
@@:
cmp ecx, [esp + RECT.right]
jbe @f
mov ecx, [esp + RECT.right]
@@:
cmp edx, [esp + RECT.bottom]
jbe @f
mov edx, [esp + RECT.bottom]
 
@@:
push esi
movzx esi, word[WIN_POS + esi * 2]
call window._.set_screen
pop esi
 
.skip_window:
inc esi
dec ebp
jnz .next_window
 
pop eax ebx ecx edx
 
.exit:
pop ebp
popfd
pop esi
ret
 
align 4
;------------------------------------------------------------------------------
repos_windows: ;///////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [TASK_COUNT]
mov edi, window_data + sizeof.WDATA * 2
call force_redraw_background
dec ecx
jle .exit
 
.next_window:
mov [edi + WDATA.fl_redraw], 1
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .fix_maximized
 
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [Screen_Max_X]
cmp eax, ebx
jle .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jle @f
mov [edi + WDATA.box.width], ebx
@@:
sub ebx, [edi + WDATA.box.width]
mov [edi + WDATA.box.left], ebx
 
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [Screen_Max_Y]
cmp eax, ebx
jle .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jle @f
mov [edi + WDATA.box.height], ebx
@@:
sub ebx, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], ebx
jmp .fix_client_box
 
.fix_maximized:
mov eax, [screen_workarea.left]
mov [edi + WDATA.box.left], eax
sub eax, [screen_workarea.right]
neg eax
mov [edi + WDATA.box.width], eax
mov eax, [screen_workarea.top]
mov [edi + WDATA.box.top], eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .fix_client_box
sub eax, [screen_workarea.bottom]
neg eax
mov [edi + WDATA.box.height], eax
 
.fix_client_box:
call window._.set_window_clientbox
 
add edi, sizeof.WDATA
loop .next_window
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_mouse: ;////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; NOTE: commented out since doesn't provide necessary functionality
; anyway, to be reworked
; push eax
;
; mov eax, [timer_ticks]
; cmp [new_window_starting], eax
; jb .exit
;
; mov byte[MOUSE_BACKGROUND], 0
; mov byte[DONT_DRAW_MOUSE], 0
;
; mov [new_window_starting], eax
;
; .exit:
; pop eax
ret
 
align 4
;------------------------------------------------------------------------------
draw_rectangle: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
;> esi = color
;------------------------------------------------------------------------------
push eax ebx ecx edi
 
xor edi, edi
 
.flags_set:
push ebx
 
; set line color
mov ecx, esi
 
; draw top border
rol ebx, 16
push ebx
rol ebx, 16
pop bx
call [draw_line]
 
; draw bottom border
mov ebx, [esp - 2]
pop bx
call [draw_line]
 
pop ebx
add ebx, 1 * 65536 - 1
 
; draw left border
rol eax, 16
push eax
rol eax, 16
pop ax
call [draw_line]
 
; draw right border
mov eax, [esp - 2]
pop ax
call [draw_line]
 
pop edi ecx ebx eax
ret
 
.forced:
push eax ebx ecx edi
xor edi, edi
inc edi
jmp .flags_set
 
align 4
;------------------------------------------------------------------------------
drawwindow_I_caption: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
push [edx + WDATA.cl_titlebar]
mov esi, edx
 
mov edx, [esi + WDATA.box.top]
mov eax, edx
lea ebx, [edx + 21]
inc edx
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jbe @f
mov ebx, eax
@@:
push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
inc eax
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
dec eax
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
mov [esi + WDATA.cl_titlebar], ecx
@@:
and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_I: ;////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
call draw_rectangle
 
; window caption
 
call drawwindow_I_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 1
mov ebx, 21
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III_caption: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [edx + WDATA.cl_titlebar]
push ecx
mov esi, edx
mov edx, [esi + WDATA.box.top]
add edx, 4
mov ebx, [esi + WDATA.box.top]
add ebx, 20
mov eax, [esi + WDATA.box.top]
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jb @f
mov ebx, eax
@@:
push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
add eax, 4 * 65536 - 4
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x40000000
jz @f
add ecx, 0x00040404
@@:
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
@@:
mov [esi + WDATA.cl_titlebar], ecx
and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
shr esi, 1
and esi, 0x007f7f7f
call draw_rectangle
 
push esi
mov ecx, 3
mov esi, [edx + WDATA.cl_frames]
 
.next_frame:
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
dec ecx
jnz .next_frame
 
pop esi
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
 
; window caption
 
call drawwindow_III_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 5
mov ebx, 20
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
sub ecx, 4
sub edx, 4
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
waredraw: ;////////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window, redrawing if necessary
;------------------------------------------------------------------------------
push -1
mov eax, [TASK_COUNT]
lea eax, [WIN_POS + eax * 2]
cmp eax, esi
pop eax
je .exit
 
; is it overlapped by another window now?
push ecx
call window._.check_window_draw
test ecx, ecx
pop ecx
jz .do_not_draw
 
; yes it is, activate and update screen buffer
mov byte[MOUSE_DOWN], 1
call window._.window_activate
 
pushad
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
shl esi, 5
add esi, window_data
 
mov eax, [esi + WDATA.box.left]
mov ebx, [esi + WDATA.box.top]
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
 
add ecx, eax
add edx, ebx
 
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
call window._.set_screen
popad
 
; tell application to redraw itself
mov [edi + WDATA.fl_redraw], 1
xor eax, eax
jmp .exit
 
.do_not_draw:
; no it's not, just activate the window
call window._.window_activate
xor eax, eax
mov byte[MOUSE_BACKGROUND], al
mov byte[DONT_DRAW_MOUSE], al
 
 
.exit:
mov byte[MOUSE_DOWN], 0
inc eax
ret
 
align 4
;------------------------------------------------------------------------------
minimize_window: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
push edi
pushfd
cli
 
; is it already minimized?
movzx edi, word[WIN_POS + eax * 2]
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .exit
 
push eax ebx ecx edx esi
 
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
add ecx, [edi + WDATA.box.width]
mov [draw_limits.right], ecx
mov ebx, [edi + WDATA.box.top]
mov [draw_limits.top], ebx
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
call calculatescreen
xor esi, esi
xor eax, eax
call redrawscreen
 
pop esi edx ecx ebx eax
 
.exit:
popfd
pop edi
ret
 
align 4
;------------------------------------------------------------------------------
restore_minimized_window: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
pushad
pushfd
cli
 
; is it already restored?
movzx esi, word[WIN_POS + eax * 2]
mov edi, esi
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jz .exit
 
; no it's not, let's do that
mov [edi + WDATA.fl_redraw], 1
and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
mov ebp, window._.set_screen
cmp eax, [TASK_COUNT]
jz @f
mov ebp, calculatescreen
@@:
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call ebp
 
mov byte[MOUSE_BACKGROUND], 0
 
.exit:
popfd
popad
ret
 
align 4
; TODO: remove this proc
;------------------------------------------------------------------------------
window_check_events: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; do we have window minimize/restore request?
cmp [window_minimize], 0
je .exit
 
; okay, minimize or restore top-most window and exit
mov eax, [TASK_COUNT]
mov bl, 0
xchg [window_minimize], bl
dec bl
jnz @f
call minimize_window
jmp .exit
 
@@:
call restore_minimized_window
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_maximize_handler: ;/////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, esi
shl edi, 5
add edi, window_data
 
; can window change its height?
; only types 2 and 3 can be resized
mov dl, [edi + WDATA.fl_wstyle]
test dl, 2
jz .exit
 
; toggle normal/maximized window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_MAXIMIZED
 
; calculate and set appropriate window bounds
test bl, WSTATE_MAXIMIZED
jz .restore_size
 
mov eax, [screen_workarea.left]
mov ecx, [screen_workarea.top]
push [screen_workarea.bottom] \
[screen_workarea.right] \
ecx \
eax
sub [esp + BOX.width], eax
sub [esp + BOX.height], ecx
mov eax, esp
jmp .set_box
 
.restore_size:
mov eax, esi
shl eax, 8
add eax, SLOT_BASE + APPDATA.saved_box
push [eax + BOX.height] \
[eax + BOX.width] \
[eax + BOX.top] \
[eax + BOX.left]
mov eax, esp
 
.set_box:
test bl, WSTATE_ROLLEDUP
jz @f
 
xchg eax, ecx
call window._.get_rolledup_height
mov [ecx + BOX.height], eax
xchg eax, ecx
 
@@:
call window._.set_window_box
add esp, sizeof.BOX
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_rollup_handler: ;///////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> esi = process slot
;------------------------------------------------------------------------------
mov edx, esi
shl edx, 8
add edx, SLOT_BASE
 
; toggle normal/rolled up window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_ROLLEDUP
 
; calculate and set appropriate window bounds
test bl, WSTATE_ROLLEDUP
jz .restore_size
 
call window._.get_rolledup_height
push eax \
[edi + WDATA.box.width] \
[edi + WDATA.box.top] \
[edi + WDATA.box.left]
mov eax, esp
jmp .set_box
 
.restore_size:
test bl, WSTATE_MAXIMIZED
jnz @f
add esp, -sizeof.BOX
lea eax, [edx + APPDATA.saved_box]
jmp .set_box
 
@@:
mov eax, [screen_workarea.top]
push [screen_workarea.bottom] \
[edi + WDATA.box.width] \
eax \
[edi + WDATA.box.left]
sub [esp + BOX.height], eax
mov eax, esp
 
.set_box:
call window._.set_window_box
add esp, sizeof.BOX
 
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_start_moving_handler: ;/////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, eax
call window._.draw_negative_box
 
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_end_moving_handler: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> ebx = new (final) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, ebx
call window._.end_moving__box
 
mov edi, esi
shl edi, 5
add edi, window_data
 
mov eax, ebx
mov bl, [edi + WDATA.fl_wstate]
call window._.set_window_box
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_moving_handler: ;///////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (from previous call) window box
;> ebx = new (current) window box
;> esi = process_slot
;------------------------------------------------------------------------------
mov edi, eax
call window._.draw_negative_box
mov edi, ebx
call window._.draw_negative_box
ret
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
iglobal
FuncTable syscall_display_settings, ftable, \
00, 01, 02, 03, 04, 05, 06, 07, 08
 
align 4
window_topleft dd \
1, 21, \ ;type 0
0, 0, \ ;type 1
5, 20, \ ;type 2
5, ?, \ ;type 3 {set by skin}
5, ? ;type 4 {set by skin}
endg
 
;uglobal
; NOTE: commented out since doesn't provide necessary functionality anyway,
; to be reworked
; new_window_starting dd ?
;endg
 
align 4
;------------------------------------------------------------------------------
window._.invalidate_screen: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> ebx = new (final) window box
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ebx
 
; TODO: do we really need `draw_limits`?
; Yes, they are used by background drawing code.
mov ecx, [eax + BOX.left]
mov edx, [ebx + BOX.left]
cmp ecx, edx
jle @f
mov ecx, edx
@@:
mov [draw_limits.left], ecx
mov ecx, [eax + BOX.left]
add ecx, [eax + BOX.width]
add edx, [ebx + BOX.width]
cmp ecx, edx
jae @f
mov ecx, edx
@@:
mov [draw_limits.right], ecx
mov ecx, [eax + BOX.top]
mov edx, [ebx + BOX.top]
cmp ecx, edx
jle @f
mov ecx, edx
@@:
mov [draw_limits.top], ecx
mov ecx, [eax + BOX.top]
add ecx, [eax + BOX.height]
add edx, [ebx + BOX.height]
cmp ecx, edx
jae @f
mov ecx, edx
@@:
mov [draw_limits.bottom], ecx
 
; recalculate screen buffer at old position
push ebx
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
pop eax
 
; recalculate screen buffer at new position
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
 
mov eax, edi
call redrawscreen
 
; tell window to redraw itself
mov [edi + WDATA.fl_redraw], 1
 
pop ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_window_box: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pointer to BOX struct
;> bl = new window state flags
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ebx esi
 
; don't do anything if the new box is identical to the old
cmp bl, [edi + WDATA.fl_wstate]
jnz @f
mov esi, eax
push edi
if WDATA.box
add edi, WDATA.box
end if
mov ecx, 4
repz cmpsd
pop edi
jz .exit
@@:
 
add esp, -sizeof.BOX
 
mov ebx, esp
if WDATA.box
lea esi, [edi + WDATA.box]
else
mov esi, edi ; optimization for WDATA.box = 0
end if
xchg eax, esi
mov ecx, sizeof.BOX
call memmove
xchg eax, esi
xchg ebx, esi
call memmove
mov eax, ebx
mov ebx, esi
 
call window._.check_window_position
call window._.set_window_clientbox
call window._.invalidate_screen
 
add esp, sizeof.BOX
 
mov cl, [esp + 4]
mov ch, cl
xchg cl, [edi + WDATA.fl_wstate]
 
or cl, ch
test cl, WSTATE_MAXIMIZED
jnz .exit
 
mov eax, edi
sub eax, window_data
shl eax, 3
add eax, SLOT_BASE
 
lea ebx, [edi + WDATA.box]
xchg esp, ebx
 
pop [eax + APPDATA.saved_box.left] \
[eax + APPDATA.saved_box.top] \
[eax + APPDATA.saved_box.width] \
edx
 
xchg esp, ebx
 
test ch, WSTATE_ROLLEDUP
jnz .exit
 
mov [eax + APPDATA.saved_box.height], edx
 
.exit:
pop esi ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_window_clientbox: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ecx edi
 
mov eax, [_skinh]
mov [window_topleft + 8 * 3 + 4], eax
mov [window_topleft + 8 * 4 + 4], eax
 
mov ecx, edi
sub edi, window_data
shl edi, 3
test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE
jz .whole_window
 
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
mov eax, [eax * 8 + window_topleft + 0]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
shl eax, 1
neg eax
add eax, [ecx + WDATA.box.width]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
 
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
push [eax * 8 + window_topleft + 0]
mov eax, [eax * 8 + window_topleft + 4]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
neg eax
sub eax, [esp]
add eax, [ecx + WDATA.box.height]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
add esp, 4
jmp .exit
 
.whole_window:
xor eax, eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
mov eax, [ecx + WDATA.box.width]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
mov eax, [ecx + WDATA.box.height]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
 
.exit:
pop edi ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.sys_set_window: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;< edx = pointer to WDATA struct
;------------------------------------------------------------------------------
mov eax, [CURRENT_TASK]
shl eax, 5
add eax, window_data
 
; save window colors
mov [eax + WDATA.cl_workarea], edx
mov [eax + WDATA.cl_titlebar], esi
mov [eax + WDATA.cl_frames], edi
 
mov edi, eax
 
; was it already defined before?
test [edi + WDATA.fl_wdrawn], 1
jnz .set_client_box
or [edi + WDATA.fl_wdrawn], 1
 
; NOTE: commented out since doesn't provide necessary functionality
; anyway, to be reworked
; mov eax, [timer_ticks] ; [0xfdf0]
; add eax, 100
; mov [new_window_starting], eax
 
; no it wasn't, performing initial window definition
movzx eax, bx
mov [edi + WDATA.box.width], eax
movzx eax, cx
mov [edi + WDATA.box.height], eax
sar ebx, 16
sar ecx, 16
mov [edi + WDATA.box.left], ebx
mov [edi + WDATA.box.top], ecx
 
call window._.check_window_position
 
push ecx edi
 
mov cl, [edi + WDATA.fl_wstyle]
mov eax, [edi + WDATA.cl_frames]
 
sub edi, window_data
shl edi, 3
add edi, SLOT_BASE
 
and cl, 0x0F
cmp cl, 3
je @f
cmp cl, 4
je @f
 
xor eax, eax
 
@@:
mov [edi + APPDATA.wnd_caption], eax
 
mov esi, [esp]
add edi, APPDATA.saved_box
movsd
movsd
movsd
movsd
 
pop edi ecx
 
mov esi, [CURRENT_TASK]
movzx esi, word[WIN_STACK + esi * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call calculatescreen
 
mov byte[KEY_COUNT], 0 ; empty keyboard buffer
mov byte[BTN_COUNT], 0 ; empty button buffer
 
.set_client_box:
; update window client box coordinates
call window._.set_window_clientbox
 
; reset window redraw flag and exit
mov [edi + WDATA.fl_redraw], 0
mov edx, edi
ret
 
align 4
;------------------------------------------------------------------------------
window._.check_window_position: ;//////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is inside screen area
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
push eax ebx ecx edx esi
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
 
mov esi, [Screen_Max_X]
cmp ecx, esi
ja .fix_width_high
 
.check_left:
or eax, eax
jl .fix_left_low
add eax, ecx
cmp eax, esi
jg .fix_left_high
 
.check_height:
mov esi, [Screen_Max_Y]
cmp edx, esi
ja .fix_height_high
 
.check_top:
or ebx, ebx
jl .fix_top_low
add ebx, edx
cmp ebx, esi
jg .fix_top_high
 
.exit:
pop esi edx ecx ebx eax
ret
 
.fix_width_high:
mov ecx, esi
mov [edi + WDATA.box.width], esi
jmp .check_left
 
.fix_left_low:
xor eax, eax
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_left_high:
mov eax, esi
sub eax, ecx
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_height_high:
mov edx, esi
mov [edi + WDATA.box.height], esi
jmp .check_top
 
.fix_top_low:
xor ebx, ebx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
.fix_top_high:
mov ebx, esi
sub ebx, edx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
align 4
;------------------------------------------------------------------------------
window._.get_titlebar_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jne @f
mov eax, [_skinh]
ret
@@:
mov eax, 21
ret
 
align 4
;------------------------------------------------------------------------------
window._.get_rolledup_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jb @f
mov eax, [_skinh]
add eax, 3
ret
@@:
or al, al
jnz @f
mov eax, 21
ret
@@:
mov eax, 21 + 2
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_screen: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Reserve window area in screen buffer
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
;------------------------------------------------------------------------------
virtual at esp
ff_x dd ?
ff_y dd ?
ff_width dd ?
ff_xsz dd ?
ff_ysz dd ?
ff_scale dd ?
end virtual
 
pushad
 
cmp esi, 1
jz .check_for_shaped_window
mov edi, esi
shl edi, 5
cmp [window_data + edi + WDATA.box.width], 0
jnz .check_for_shaped_window
cmp [window_data + edi + WDATA.box.height], 0
jz .exit
 
.check_for_shaped_window:
mov edi, esi
shl edi, 8
add edi, SLOT_BASE
cmp [edi + APPDATA.wnd_shape], 0
jne .shaped_window
 
; get x&y size
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
; get WinMap start
push esi
mov edi, [Screen_Max_X]
inc edi
mov esi, edi
imul edi, ebx
add edi, eax
add edi, [_WinMapAddress]
pop eax
mov ah, al
push ax
shl eax, 16
pop ax
 
.next_line:
push ecx
shr ecx, 2
rep stosd
mov ecx, [esp]
and ecx, 3
rep stosb
pop ecx
add edi, esi
sub edi, ecx
dec edx
jnz .next_line
 
jmp .exit
 
.shaped_window:
; for (y=0; y <= x_size; y++)
; for (x=0; x <= x_size; x++)
; if (shape[coord(x,y,scale)]==1)
; set_pixel(x, y, process_number);
 
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop
 
; get WinMap start -> ebp
push eax
mov eax, [Screen_Max_X] ; screen_sx
inc eax
imul eax, ebx
add eax, [esp]
add eax, [_WinMapAddress]
mov ebp, eax
 
mov edi, [edi + APPDATA.wnd_shape]
pop eax
 
; eax = x_start
; ebx = y_start
; ecx = x_size
; edx = y_size
; esi = process_number
; edi = &shape
; [scale]
push edx ecx ; for loop - x,y size
 
mov ecx, esi
shl ecx, 5
mov edx, [window_data + ecx + WDATA.box.top]
push [window_data + ecx + WDATA.box.width] ; for loop - width
mov ecx, [window_data + ecx + WDATA.box.left]
sub ebx, edx
sub eax, ecx
push ebx eax ; for loop - x,y
 
add [ff_xsz], eax
add [ff_ysz], ebx
 
mov ebx, [ff_y]
 
.ff_new_y:
mov edx, [ff_x]
 
.ff_new_x:
; -- body --
mov ecx, [ff_scale]
mov eax, [ff_width]
inc eax
shr eax, cl
push ebx edx
shr ebx, cl
shr edx, cl
imul eax, ebx
add eax, edx
pop edx ebx
add eax, edi
call .read_byte
test al, al
jz @f
mov eax, esi
mov [ebp], al
; -- end body --
@@:
inc ebp
inc edx
cmp edx, [ff_xsz]
jb .ff_new_x
 
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [Screen_Max_X] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]
jb .ff_new_y
 
add esp, 24
 
.exit:
popad
ret
 
.read_byte:
; eax - address
; esi - slot
push eax ecx edx esi
xchg eax, esi
lea ecx, [esp + 12]
mov edx, 1
call read_process_memory
pop esi edx ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.window_activate: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window
;------------------------------------------------------------------------------
;> esi = pointer to WIN_POS+ window data
;------------------------------------------------------------------------------
push eax ebx
 
; if type of current active window is 3 or 4, it must be redrawn
mov ebx, [TASK_COUNT]
; DEBUGF 1, "K : TASK_COUNT (0x%x)\n", ebx
movzx ebx, word[WIN_POS + ebx * 2]
shl ebx, 5
add eax, window_data
mov al, [window_data + ebx + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
je .set_window_redraw_flag
cmp al, 0x04
jne .move_others_down
 
.set_window_redraw_flag:
mov [window_data + ebx + WDATA.fl_redraw], 1
 
.move_others_down:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
 
; drop others
xor eax, eax
 
.next_stack_window:
cmp eax, [TASK_COUNT]
jae .move_self_up
inc eax
; push ebx
; xor ebx,ebx
; mov bx,[WIN_STACK + eax * 2]
; DEBUGF 1, "K : DEC WIN_STACK (0x%x)\n",ebx
; pop ebx
cmp [WIN_STACK + eax * 2], bx
jbe .next_stack_window
dec word[WIN_STACK + eax * 2]
jmp .next_stack_window
 
.move_self_up:
movzx ebx, word[esi]
; number of processes
mov ax, [TASK_COUNT]
; this is the last (and the upper)
mov [WIN_STACK + ebx * 2], ax
 
; update on screen - window stack
xor eax, eax
 
.next_window_pos:
cmp eax, [TASK_COUNT]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
 
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
 
pop ebx eax
ret
 
;------------------------------------------------------------------------------
window._.window_deactivate: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Deactivate window
;------------------------------------------------------------------------------
;> esi = pointer to WIN_POS+ window data
;------------------------------------------------------------------------------
push eax ebx
;------------------------------------------------------------------------------
.move_others_up:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
; up others
xor eax, eax
.next_stack_window:
cmp eax, [TASK_COUNT]
jae .move_self_down
inc eax
cmp [WIN_STACK + eax * 2], bx
jae .next_stack_window
inc word[WIN_STACK + eax * 2]
jmp .next_stack_window
;----------------------------------------------
.move_self_down:
movzx ebx, word[esi]
; this is the last (and the low)
mov [WIN_STACK + ebx * 2], word 1
; update on screen - window stack
xor eax, eax
.next_window_pos:
cmp eax, [TASK_COUNT]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
;-----------------------------------------------
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
pop ebx eax
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
window._.check_window_draw: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is necessary to draw
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov cl, [edi + WDATA.fl_wstyle]
and cl, 0x0f
cmp cl, 3
je .exit.redraw ; window type 3
cmp cl, 4
je .exit.redraw ; window type 4
 
push eax ebx edx esi
 
mov eax, edi
sub eax, window_data
shr eax, 5
 
movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400
 
.next_window:
add esi, 2
 
mov eax, [TASK_COUNT]
lea eax, word[WIN_POS + eax * 2] ; number of the upper window
 
cmp esi, eax
ja .exit.no_redraw
 
movzx edx, word[esi]
shl edx, 5
cmp [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
je .next_window
 
mov eax, [edi + WDATA.box.top]
mov ebx, [edi + WDATA.box.height]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.top]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.height]
cmp eax, ecx
jge .next_window
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.width]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.left]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.width]
cmp eax, ecx
jge .next_window
 
pop esi edx ebx eax
 
.exit.redraw:
xor ecx, ecx
inc ecx
ret
 
.exit.no_redraw:
pop esi edx ebx eax
xor ecx, ecx
ret
 
align 4
;------------------------------------------------------------------------------
window._.draw_window_caption: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
inc [mouse_pause]
call [_display.disable_mouse]
 
xor eax, eax
mov edx, [TASK_COUNT]
movzx edx, word[WIN_POS + edx * 2]
cmp edx, [CURRENT_TASK]
jne @f
inc eax
@@:
mov edx, [CURRENT_TASK]
shl edx, 5
add edx, window_data
movzx ebx, [edx + WDATA.fl_wstyle]
and bl, 0x0F
cmp bl, 3
je .draw_caption_style_3
cmp bl, 4
je .draw_caption_style_3
 
jmp .not_style_3
 
.draw_caption_style_3:
push edx
call drawwindow_IV_caption
add esp, 4
jmp .2
 
.not_style_3:
cmp bl, 2
jne .not_style_2
 
call drawwindow_III_caption
jmp .2
 
.not_style_2:
cmp bl, 0
jne .2
 
call drawwindow_I_caption
 
.2:
mov edi, [CURRENT_TASK]
shl edi, 5
test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
jz .exit
mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption]
or edx, edx
jz .exit
 
movzx eax, [edi + window_data + WDATA.fl_wstyle]
and al, 0x0F
cmp al, 3
je .skinned
cmp al, 4
je .skinned
 
jmp .not_skinned
 
.skinned:
mov ebp, [edi + window_data + WDATA.box.left - 2]
mov bp, word[edi + window_data + WDATA.box.top]
movzx eax, word[edi + window_data + WDATA.box.width]
sub ax, [_skinmargins.left]
sub ax, [_skinmargins.right]
push edx
cwde
cdq
mov ebx, 6
idiv ebx
pop edx
or eax, eax
js .exit
 
mov esi, eax
mov ebx, dword[_skinmargins.left - 2]
mov bx, word[_skinh]
sub bx, [_skinmargins.bottom]
sub bx, [_skinmargins.top]
sar bx, 1
adc bx, 0
add bx, [_skinmargins.top]
add bx, -3
add ebx, ebp
jmp .dodraw
 
.not_skinned:
cmp al, 1
je .exit
 
mov ebp, [edi + window_data + WDATA.box.left - 2]
mov bp, word[edi + window_data + WDATA.box.top]
movzx eax, word[edi + window_data + WDATA.box.width]
sub eax, 16
push edx
cwde
cdq
mov ebx, 6
idiv ebx
pop edx
or eax, eax
js .exit
 
mov esi, eax
mov ebx, 0x00080007
add ebx, ebp
 
.dodraw:
mov ecx, [common_colours + 16]
or ecx, 0x80000000
xor edi, edi
call dtext_asciiz_esi
 
.exit:
dec [mouse_pause]
call [draw_pointer]
ret
 
align 4
;------------------------------------------------------------------------------
window._.draw_negative_box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw negative box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
mov esi, 0x01000000
.1:
mov eax, [edi + BOX.left - 2]
mov ax, word[edi + BOX.left]
add ax, word[edi + BOX.width]
mov ebx, [edi + BOX.top - 2]
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
call draw_rectangle.forced
pop esi ebx eax
ret
;------------------------------------------------------------------------------
window._.end_moving__box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw positive box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
xor esi, esi
jmp window._.draw_negative_box.1
 
 
;------------------------------------------------------------------------------
window._.get_rect: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description> void __fastcall get_window_rect(struct RECT* rc);
;------------------------------------------------------------------------------
;> ecx = pointer to RECT
;------------------------------------------------------------------------------
mov eax, [TASK_BASE]
 
mov edx, [eax-twdw + WDATA.box.left]
mov [ecx+RECT.left], edx
 
add edx, [eax-twdw + WDATA.box.width]
mov [ecx+RECT.right], edx
 
mov edx, [eax-twdw + WDATA.box.top]
mov [ecx+RECT.top], edx
 
add edx, [eax-twdw + WDATA.box.height]
mov [ecx+RECT.bottom], edx
 
ret
 
/kernel/branches/net/hid/keyboard.inc
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8,8 → 8,6
$Revision$
 
 
;// mike.dld [
 
VKEY_LSHIFT = 0000000000000001b
VKEY_RSHIFT = 0000000000000010b
VKEY_LCONTROL = 0000000000000100b
26,318 → 24,384
 
uglobal
align 4
kb_state dd 0
ext_code db 0
kb_state dd 0
ext_code db 0
 
keyboard_mode db 0
keyboard_data db 0
 
altmouseb db 0
ctrl_alt_del db 0
altmouseb db 0
ctrl_alt_del db 0
 
kb_lights db 0
kb_lights db 0
 
align 4
hotkey_scancodes rd 256 ; we have 256 scancodes
hotkey_list rd 256*4 ; max 256 defined hotkeys
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys
hotkey_scancodes rd 256 ; we have 256 scancodes
hotkey_list rd 256*4 ; max 256 defined hotkeys
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys
endg
 
iglobal
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
dd hotkey_test3
dd hotkey_test4
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
dd hotkey_test3
dd hotkey_test4
hotkey_tests_num = 5
endg
 
;---------------------------------------------------------------------
hotkey_test0:
test al, al
setz al
ret
test al, al
setz al
ret
;---------------------------------------------------------------------
hotkey_test1:
test al, al
setnp al
ret
test al, al
setnp al
ret
;---------------------------------------------------------------------
hotkey_test2:
cmp al, 3
setz al
ret
cmp al, 3
setz al
ret
;---------------------------------------------------------------------
hotkey_test3:
cmp al, 1
setz al
ret
cmp al, 1
setz al
ret
;---------------------------------------------------------------------
hotkey_test4:
cmp al, 2
setz al
ret
 
cmp al, 2
setz al
ret
;---------------------------------------------------------------------
hotkey_do_test:
push eax
mov edx, [kb_state]
shr edx, cl
add cl, cl
mov eax, [eax+4]
shr eax, cl
and eax, 15
cmp al, hotkey_tests_num
jae .fail
xchg eax, edx
and al, 3
call [hotkey_tests + edx*4]
cmp al, 1
pop eax
ret
push eax
mov edx, [kb_state]
shr edx, cl
add cl, cl
mov eax, [eax+4]
shr eax, cl
and eax, 15
cmp al, hotkey_tests_num
jae .fail
xchg eax, edx
and al, 3
call [hotkey_tests + edx*4]
cmp al, 1
pop eax
ret
;--------------------------------------
.fail:
stc
pop eax
ret
 
stc
pop eax
ret
;---------------------------------------------------------------------
align 4
set_keyboard_data:
movzx eax, word[TASK_COUNT]; top window process
movzx eax, word[WIN_POS+eax*2]
shl eax, 8
mov al, [SLOT_BASE+eax+APPDATA.keyboard_mode]
mov [keyboard_mode], al
mov eax, ecx
push ebx esi edi ebp
call send_scancode
pop ebp edi esi ebx
ret
;---------------------------------------------------------------------
align 4
irq1:
; save_ring3_context
; mov ax, os_data
; mov ds, ax
; mov es, ax
 
movzx eax,word[TASK_COUNT] ; top window process
movzx eax,word[WIN_POS+eax*2]
shl eax,8
mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode]
mov [keyboard_mode],al
 
in al,0x60
mov [keyboard_data],al
 
movzx eax, word[TASK_COUNT]; top window process
movzx eax, word[WIN_POS+eax*2]
shl eax, 8
mov al, [SLOT_BASE+eax+APPDATA.keyboard_mode]
mov [keyboard_mode], al
in al, 0x60
;--------------------------------------
send_scancode:
mov [keyboard_data], al
; ch = scancode
; cl = ext_code
; bh = 0 - normal key
; bh = 1 - modifier (Shift/Ctrl/Alt)
; bh = 2 - extended code
 
mov ch,al
cmp al,0xE0
je @f
cmp al,0xE1
jne .normal_code
@@:
mov bh, 2
mov [ext_code], al
jmp .writekey
.normal_code:
mov cl, 0
xchg cl, [ext_code]
and al,0x7F
mov bh, 1
@@: cmp al,0x2A
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_LSHIFT
jmp .modifier
@@: cmp al,0x36
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_RSHIFT
jmp .modifier
@@: cmp al,0x38
jne @f
mov eax, VKEY_LALT
test cl, cl
jz .modifier
mov al, VKEY_RALT
jmp .modifier
@@: cmp al,0x1D
jne @f
mov eax, VKEY_LCONTROL
test cl, cl
jz .modifier
mov al, VKEY_RCONTROL
cmp cl, 0xE0
jz .modifier
mov [ext_code], cl
jmp .writekey
@@: cmp al,0x3A
jne @f
mov bl,4
mov eax,VKEY_CAPSLOCK
jmp .no_key.xor
@@: cmp al,0x45
jne @f
test cl, cl
jnz .writekey
mov bl,2
mov eax,VKEY_NUMLOCK
jmp .no_key.xor
@@: cmp al,0x46
jne @f
mov bl,1
mov eax,VKEY_SCRLOCK
jmp .no_key.xor
@@:
test ch,ch
js .writekey
movzx eax,ch ; plain key
mov bl,[keymap+eax]
mov edx,[kb_state]
test dl,VKEY_CONTROL ; ctrl alt del
jz .noctrlaltdel
test dl,VKEY_ALT
jz .noctrlaltdel
cmp ch,53h
jne .noctrlaltdel
mov [ctrl_alt_del],1
.noctrlaltdel:
test dl,VKEY_CONTROL ; ctrl on ?
jz @f
sub bl,0x60
@@: test dl,VKEY_SHIFT ; shift on ?
jz @f
mov bl,[keymap_shift+eax]
@@: test dl,VKEY_ALT ; alt on ?
jz @f
mov bl,[keymap_alt+eax]
@@:
mov bh, 0
jmp .writekey
mov ch, al
cmp al, 0xE0
je @f
cmp al, 0xE1
jne .normal_code
@@:
mov bh, 2
mov [ext_code], al
jmp .writekey
;--------------------------------------
.normal_code:
mov cl, 0
xchg cl, [ext_code]
and al, 0x7F
mov bh, 1
@@:
cmp al, 0x2A
jne @f
cmp cl, 0xE0
je .writekey
mov eax, VKEY_LSHIFT
jmp .modifier
;--------------------------------------
@@:
cmp al, 0x36
jne @f
cmp cl, 0xE0
je .writekey
mov eax, VKEY_RSHIFT
jmp .modifier
;--------------------------------------
@@:
cmp al, 0x38
jne @f
mov eax, VKEY_LALT
test cl, cl
jz .modifier
mov al, VKEY_RALT
jmp .modifier
;--------------------------------------
@@:
cmp al, 0x1D
jne @f
mov eax, VKEY_LCONTROL
test cl, cl
jz .modifier
mov al, VKEY_RCONTROL
cmp cl, 0xE0
jz .modifier
mov [ext_code], cl
jmp .writekey
;--------------------------------------
@@:
cmp al, 0x3A
jne @f
mov bl, 4
mov eax, VKEY_CAPSLOCK
jmp .no_key.xor
;--------------------------------------
@@:
cmp al, 0x45
jne @f
test cl, cl
jnz .writekey
mov bl, 2
mov eax, VKEY_NUMLOCK
jmp .no_key.xor
;--------------------------------------
@@:
cmp al, 0x46
jne @f
mov bl, 1
mov eax, VKEY_SCRLOCK
jmp .no_key.xor
;--------------------------------------
@@:
xor ebx, ebx
test ch, ch
js .writekey
movzx eax, ch ; plain key
mov bl, [keymap+eax]
mov edx, [kb_state]
test dl, VKEY_CONTROL ; ctrl alt del
jz .noctrlaltdel
test dl, VKEY_ALT
jz .noctrlaltdel
cmp ch, 53h
jne .noctrlaltdel
mov [ctrl_alt_del], 1
.noctrlaltdel:
test dl, VKEY_CONTROL ; ctrl on ?
jz @f
sub bl, 0x60
@@:
test dl, VKEY_CAPSLOCK ; caps lock on ?
jz .no_caps_lock
test dl, VKEY_SHIFT ; shift on ?
jz .keymap_shif
jmp @f
;--------------------------------------
.no_caps_lock:
test dl, VKEY_SHIFT ; shift on ?
jz @f
.keymap_shif:
mov bl, [keymap_shift+eax]
@@:
test dl, VKEY_ALT ; alt on ?
jz @f
mov bl, [keymap_alt+eax]
@@:
jmp .writekey
;--------------------------------------
.modifier:
test ch, ch
js .modifier.up
or [kb_state], eax
jmp .writekey
test ch, ch
js .modifier.up
or [kb_state], eax
jmp .writekey
;--------------------------------------
.modifier.up:
not eax
and [kb_state], eax
jmp .writekey
not eax
and [kb_state], eax
jmp .writekey
;--------------------------------------
.no_key.xor:
mov bh, 0
test ch, ch
js .writekey
xor [kb_state], eax
xor [kb_lights], bl
call set_lights
 
mov bh, 0
test ch, ch
js .writekey
xor [kb_state], eax
xor [kb_lights], bl
call set_lights
.writekey:
; test for system hotkeys
movzx eax, ch
cmp bh, 1
ja .nohotkey
jb @f
xor eax, eax
movzx eax, ch
cmp bh, 1
ja .nohotkey
jb @f
xor eax, eax
@@:
mov eax, [hotkey_scancodes + eax*4]
mov eax, [hotkey_scancodes + eax*4]
.hotkey_loop:
test eax, eax
jz .nohotkey
mov cl, 0
call hotkey_do_test
jc .hotkey_cont
mov cl, 2
call hotkey_do_test
jc .hotkey_cont
mov cl, 4
call hotkey_do_test
jnc .hotkey_found
test eax, eax
jz .nohotkey
mov cl, 0
call hotkey_do_test
jc .hotkey_cont
mov cl, 2
call hotkey_do_test
jc .hotkey_cont
mov cl, 4
call hotkey_do_test
jnc .hotkey_found
.hotkey_cont:
mov eax, [eax]
jmp .hotkey_loop
mov eax, [eax]
jmp .hotkey_loop
;--------------------------------------
.hotkey_found:
mov eax, [eax+8]
mov eax, [eax+8]
; put key in buffer for process in slot eax
mov edi, hotkey_buffer
mov edi, hotkey_buffer
@@:
cmp dword [edi], 0
jz .found_free
add edi, 8
cmp edi, hotkey_buffer+120*8
jb @b
cmp dword [edi], 0
jz .found_free
add edi, 8
cmp edi, hotkey_buffer+120*8
jb @b
; no free space - replace first entry
mov edi, hotkey_buffer
mov edi, hotkey_buffer
.found_free:
mov [edi], eax
movzx eax, ch
cmp bh, 1
jnz @f
xor eax, eax
mov [edi], eax
movzx eax, ch
cmp bh, 1
jnz @f
xor eax, eax
@@:
mov [edi+4], ax
mov eax, [kb_state]
mov [edi+6], ax
jmp .exit.irq1
mov [edi+4], ax
mov eax, [kb_state]
mov [edi+6], ax
jmp .exit.irq1
;--------------------------------------
.nohotkey:
cmp [keyboard_mode],0 ; return from keymap
jne .scancode
test bh, bh
jnz .exit.irq1
test bl, bl
jz .exit.irq1
cmp [keyboard_mode], 0; return from keymap
jne .scancode
test bh, bh
jnz .exit.irq1
test bl, bl
jz .exit.irq1
 
;.........................Part1 Start.......Code by Rus, optimize by Ghost...................................
test [kb_state], VKEY_NUMLOCK
jz .dowrite
test [kb_state], VKEY_NUMLOCK
jz .dowrite
cmp cl, 0xE0
jz .dowrite
 
cmp ch, 55
jnz @f
mov bl, 0x2A ;*
jmp .dowrite
@@:
cmp ch, 71
jb .dowrite
cmp ch, 83
ja .dowrite
;push eax
movzx eax, ch
mov bl, [numlock_map + eax - 71]
;pop eax
 
;.........................Part1 End.................................................
 
jmp .dowrite
cmp ch, 55
jnz @f
mov bl, 0x2A ;*
jmp .dowrite
;--------------------------------------
@@:
cmp ch, 71
jb .dowrite
cmp ch, 83
ja .dowrite
movzx eax, ch
mov bl, [numlock_map + eax - 71]
jmp .dowrite
;--------------------------------------
.scancode:
mov bl, ch
mov bl, ch
.dowrite:
movzx eax,byte[KEY_COUNT]
cmp al,120
jae .exit.irq1
inc eax
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
 
; restore_ring3_context
; iret
ret
 
movzx eax, byte[KEY_COUNT]
cmp al, 120
jae .exit.irq1
inc eax
mov [KEY_COUNT], al
mov [KEY_COUNT+eax], bl
.exit.irq1:
mov [check_idle_semaphore], 5
ret
;---------------------------------------------------------------------
set_lights:
mov al,0xED
call kb_write
mov al,[kb_lights]
call kb_write
ret
 
;// mike.dld ]
;..........................Part2 Start.......Code by Rus.......................................
mov al, 0xED
call kb_write
mov al, [kb_lights]
call kb_write
ret
;---------------------------------------------------------------------
numlock_map:
db 0x37 ;Num 7
db 0x38 ;Num 8
db 0x39 ;Num 9
db 0x2D ;Num -
db 0x34 ;Num 4
db 0x35 ;Num 5
db 0x36 ;Num 6
db 0x2B ;Num +
db 0x31 ;Num 1
db 0x32 ;Num 2
db 0x33 ;Num 3
db 0x30 ;Num 0
db 0x2E ;Num .
;..........................Part2 End................................................
db 0x37 ;Num 7
db 0x38 ;Num 8
db 0x39 ;Num 9
db 0x2D ;Num -
db 0x34 ;Num 4
db 0x35 ;Num 5
db 0x36 ;Num 6
db 0x2B ;Num +
db 0x31 ;Num 1
db 0x32 ;Num 2
db 0x33 ;Num 3
db 0x30 ;Num 0
db 0x2E ;Num .
;---------------------------------------------------------------------
/kernel/branches/net/hid/mousedrv.inc
27,8 → 27,9
endg
 
iglobal
mouse_delay dd 10
mouse_speed_factor: dd 3
mouse_delay dd 10
mouse_speed_factor:
dd 3
mouse_timer_ticks dd 0
endg
 
49,159 → 50,159
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0
 
draw_mouse_under:
; return old picture
; return old picture
 
cmp [_display.restore_cursor], 0
je @F
cmp [_display.restore_cursor], 0
je @F
 
pushad
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
stdcall [_display.restore_cursor], eax, ebx
popad
ret
pushad
movzx eax, word [X_UNDER]
movzx ebx, word [Y_UNDER]
stdcall [_display.restore_cursor], eax, ebx
popad
ret
@@:
pushad
xor ecx,ecx
xor edx,edx
align 4
pushad
xor ecx, ecx
xor edx, edx
align 4
mres:
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
add eax,ecx
add ebx,edx
push ecx
push edx
push eax
push ebx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ecx,[eax]
pop ebx
pop eax
mov edi, 1 ;force
call [putpixel]
pop edx
pop ecx
inc ecx
cmp ecx, 16
jnz mres
xor ecx, ecx
inc edx
cmp edx, 24
jnz mres
popad
ret
movzx eax, word [X_UNDER]
movzx ebx, word [Y_UNDER]
add eax, ecx
add ebx, edx
push ecx
push edx
push eax
push ebx
mov eax, edx
shl eax, 6
shl ecx, 2
add eax, ecx
add eax, mouseunder
mov ecx, [eax]
pop ebx
pop eax
mov edi, 1;force
call [putpixel]
pop edx
pop ecx
inc ecx
cmp ecx, 16
jnz mres
xor ecx, ecx
inc edx
cmp edx, 24
jnz mres
popad
ret
 
save_draw_mouse:
 
cmp [_display.move_cursor], 0
je .no_hw_cursor
pushad
cmp [_display.move_cursor], 0
je .no_hw_cursor
pushad
 
mov [X_UNDER],ax
mov [Y_UNDER],bx
movzx eax,word [MOUSE_Y]
movzx ebx,word [MOUSE_X]
push eax
push ebx
mov [X_UNDER], ax
mov [Y_UNDER], bx
movzx eax, word [MOUSE_Y]
movzx ebx, word [MOUSE_X]
push eax
push ebx
 
mov ecx, [Screen_Max_X]
inc ecx
mul ecx
add eax, [_WinMapAddress]
movzx edx, byte [ebx+eax]
shl edx, 8
mov esi, [edx+SLOT_BASE+APPDATA.cursor]
mov ecx, [Screen_Max_X]
inc ecx
mul ecx
add eax, [_WinMapAddress]
movzx edx, byte [ebx+eax]
shl edx, 8
mov esi, [edx+SLOT_BASE+APPDATA.cursor]
 
cmp esi, [current_cursor]
je .draw
cmp esi, [current_cursor]
je .draw
 
push esi
call [_display.select_cursor]
mov [current_cursor], esi
push esi
call [_display.select_cursor]
mov [current_cursor], esi
.draw:
stdcall [_display.move_cursor], esi
popad
ret
stdcall [_display.move_cursor], esi
popad
ret
.fail:
mov ecx, [def_cursor]
mov [edx+SLOT_BASE+APPDATA.cursor], ecx
stdcall [_display.move_cursor], ecx ; stdcall: [esp]=ebx,eax
popad
ret
mov ecx, [def_cursor]
mov [edx+SLOT_BASE+APPDATA.cursor], ecx
stdcall [_display.move_cursor], ecx ; stdcall: [esp]=ebx,eax
popad
ret
 
.no_hw_cursor:
pushad
; save & draw
mov [X_UNDER],ax
mov [Y_UNDER],bx
push eax
push ebx
mov ecx,0
mov edx,0
align 4
pushad
; save & draw
mov [X_UNDER], ax
mov [Y_UNDER], bx
push eax
push ebx
mov ecx, 0
mov edx, 0
align 4
drm:
push eax
push ebx
push ecx
push edx
; helloworld
push ecx
add eax,ecx ; save picture under mouse
add ebx,edx
push ecx
call getpixel
mov [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
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
push eax
push ebx
push ecx
push edx
; helloworld
push ecx
add eax, ecx; save picture under mouse
add ebx, edx
push ecx
call getpixel
mov [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
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
 
 
combine_colors:
212,245 → 213,244
;
; out
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) )
push eax
push ebx
push edx
push ecx
xor ecx, ecx
; byte 2
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
shr ebx, 16
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+0]
mov bl, [esi+0]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 1
mov eax, 0xff
sub al, [esi+1]
mov ebx, [esp]
shr ebx, 8
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+1]
mov bl, [esi+1]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 2
mov eax, 0xff
sub al, [esi+2]
mov ebx, [esp]
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+2]
mov bl, [esi+2]
mul ebx
shr eax, 8
add ecx, eax
pop eax
pop edx
pop ebx
pop eax
ret
push eax
push ebx
push edx
push ecx
xor ecx, ecx
; byte 2
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
shr ebx, 16
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+0]
mov bl, [esi+0]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 1
mov eax, 0xff
sub al, [esi+1]
mov ebx, [esp]
shr ebx, 8
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+1]
mov bl, [esi+1]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 2
mov eax, 0xff
sub al, [esi+2]
mov ebx, [esp]
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+2]
mov bl, [esi+2]
mul ebx
shr eax, 8
add ecx, eax
pop eax
pop edx
pop ebx
pop eax
ret
 
 
__sys_disable_mouse:
cmp dword [MOUSE_VISIBLE],dword 0
je @f
ret
cmp dword [MOUSE_VISIBLE], dword 0
je @f
ret
@@:
pushad
cmp [CURRENT_TASK],dword 1
je disable_m
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[Screen_Max_X]
inc ecx
imul ecx,ebx
add ecx,eax
add ecx, [_WinMapAddress]
mov eax, [CURRENT_TASK]
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
mov ebx,[Screen_Max_X]
inc ebx
imul ebx,10
add ecx,ebx
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
jmp no_mouse_disable
pushad
cmp [CURRENT_TASK], dword 1
je disable_m
mov edx, [CURRENT_TASK]
shl edx, 5
add edx, window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx, [Screen_Max_X]
inc ecx
imul ecx, ebx
add ecx, eax
add ecx, [_WinMapAddress]
mov eax, [CURRENT_TASK]
cmp al, [ecx]
je yes_mouse_disable
cmp al, [ecx+16]
je yes_mouse_disable
add ebx, 10
cmp ebx, [Screen_Max_Y]
jae no_mouse_disable
mov ebx, [Screen_Max_X]
inc ebx
imul ebx, 10
add ecx, ebx
cmp al, [ecx]
je yes_mouse_disable
cmp al, [ecx+16]
je yes_mouse_disable
jmp no_mouse_disable
yes_mouse_disable:
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[edx+0] ; mouse inside the area ?
add eax,10
cmp eax,ecx
jb no_mouse_disable
sub eax,10
add ecx,[edx+8]
cmp eax,ecx
jg no_mouse_disable
mov ecx,[edx+4]
add ebx,14
cmp ebx,ecx
jb no_mouse_disable
sub ebx,14
add ecx,[edx+12]
cmp ebx,ecx
jg no_mouse_disable
mov edx, [CURRENT_TASK]
shl edx, 5
add edx, window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx, [edx+0]; mouse inside the area ?
add eax, 10
cmp eax, ecx
jb no_mouse_disable
sub eax, 10
add ecx, [edx+8]
cmp eax, ecx
jg no_mouse_disable
mov ecx, [edx+4]
add ebx, 14
cmp ebx, ecx
jb no_mouse_disable
sub ebx, 14
add ecx, [edx+12]
cmp ebx, ecx
jg no_mouse_disable
disable_m:
cmp dword [MOUSE_VISIBLE],dword 0
jne no_mouse_disable
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE],dword 1
cmp dword [MOUSE_VISIBLE], dword 0
jne no_mouse_disable
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE], dword 1
no_mouse_disable:
popad
ret
popad
ret
 
__sys_draw_pointer:
cmp [mouse_pause],0
je @f
ret
cmp [mouse_pause], 0
je @f
ret
@@:
push eax
mov eax,[timer_ticks]
sub eax,[MouseTickCounter]
cmp eax,1
ja @f
pop eax
ret
push eax
mov eax, [timer_ticks]
sub eax, [MouseTickCounter]
cmp eax, 1
ja @f
pop eax
ret
@@:
mov eax,[timer_ticks]
mov [MouseTickCounter],eax
pop eax
pushad
cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ?
je chms00
mov [MOUSE_VISIBLE], dword 0
movzx ebx,word [MOUSE_Y]
movzx eax,word [MOUSE_X]
pushfd
cli
call save_draw_mouse
popfd
mov eax, [timer_ticks]
mov [MouseTickCounter], eax
pop eax
pushad
cmp dword [MOUSE_VISIBLE], dword 0; mouse visible ?
je chms00
mov [MOUSE_VISIBLE], dword 0
movzx ebx, word [MOUSE_Y]
movzx eax, word [MOUSE_X]
pushfd
cli
call save_draw_mouse
popfd
nodmu2:
popad
ret
popad
ret
chms00:
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
jne redrawmouse
jmp nodmp
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
jne redrawmouse
jmp nodmp
redrawmouse:
pushfd
cli
call draw_mouse_under
call save_draw_mouse
popfd
pushfd
cli
call draw_mouse_under
call save_draw_mouse
popfd
nodmp:
popad
ret
popad
ret
 
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
 
mov eax,[BtnState]
mov [BTN_DOWN],eax
mov eax, [BtnState]
mov [BTN_DOWN], eax
 
mov eax,[XMoving]
call mouse_acceleration
add ax,[MOUSE_X] ;[XCoordinate]
cmp ax,0
jge @@M1
mov eax,0
jmp @@M2
mov eax, [XMoving]
call mouse_acceleration
add ax, [MOUSE_X];[XCoordinate]
cmp ax, 0
jge @@M1
mov eax, 0
jmp @@M2
@@M1:
cmp ax,[Screen_Max_X] ;ScreenLength
jl @@M2
mov ax,[Screen_Max_X] ;ScreenLength-1
cmp ax, [Screen_Max_X];ScreenLength
jl @@M2
mov ax, [Screen_Max_X];ScreenLength-1
 
@@M2:
mov [MOUSE_X],ax ;[XCoordinate]
mov [MOUSE_X], ax;[XCoordinate]
 
mov eax,[YMoving]
neg eax
call mouse_acceleration
mov eax, [YMoving]
neg eax
call mouse_acceleration
 
add ax,[MOUSE_Y] ;[YCoordinate]
cmp ax,0
jge @@M3
mov ax,0
jmp @@M4
add ax, [MOUSE_Y];[YCoordinate]
cmp ax, 0
jge @@M3
mov ax, 0
jmp @@M4
@@M3:
cmp ax,[Screen_Max_Y] ;ScreenHeigth
jl @@M4
mov ax,[Screen_Max_Y] ;ScreenHeigth-1
cmp ax, [Screen_Max_Y];ScreenHeigth
jl @@M4
mov ax, [Screen_Max_Y];ScreenHeigth-1
 
@@M4:
mov [MOUSE_Y],ax ;[YCoordinate]
mov [MOUSE_Y], ax;[YCoordinate]
 
mov eax,[VScroll]
add [MOUSE_SCROLL_V],ax
mov eax, [VScroll]
add [MOUSE_SCROLL_V], ax
 
mov eax,[HScroll]
add [MOUSE_SCROLL_H],ax
mov eax, [HScroll]
add [MOUSE_SCROLL_H], ax
 
mov [mouse_active],1
mov eax,[timer_ticks]
mov [mouse_timer_ticks],eax
ret
mov [mouse_active], 1
mov eax, [timer_ticks]
mov [mouse_timer_ticks], eax
ret
endp
 
mouse_acceleration:
push eax
mov eax,[timer_ticks]
sub eax,[mouse_timer_ticks]
cmp eax,[mouse_delay]
pop eax
ja @f
;push edx
imul eax,[mouse_speed_factor]
;pop edx
push eax
mov eax, [timer_ticks]
sub eax, [mouse_timer_ticks]
cmp eax, [mouse_delay]
pop eax
ja @f
;push edx
imul eax, [mouse_speed_factor]
;pop edx
@@:
ret
ret
 
/kernel/branches/net/hid/set_dtc.inc
18,186 → 18,186
; out: 0 -Ok 1 -wrong format 2 -battery low
sys_settime:
cli
mov al,0x0d
out 0x70,al
in al,0x71
bt ax,7
jnc bat_low
cmp ebx,2 ;day of week
jne nosetweek
test ecx,ecx ;test day of week
je wrongtime
cmp ecx,7
ja wrongtime
mov edx,0x70
call startstopclk
dec edx
mov al,6
out dx,al
inc edx
mov al,cl
out dx,al
jmp endsettime
cli
mov al, 0x0d
out 0x70, al
in al, 0x71
bt ax, 7
jnc bat_low
cmp ebx, 2;day of week
jne nosetweek
test ecx, ecx ;test day of week
je wrongtime
cmp ecx, 7
ja wrongtime
mov edx, 0x70
call startstopclk
dec edx
mov al, 6
out dx, al
inc edx
mov al, cl
out dx, al
jmp endsettime
nosetweek: ;set date
cmp ebx,1
jne nosetdate
cmp cl,0x99 ;test year
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
cmp ch,0x99 ;test month
ja wrongtime
shr ecx,4
test ch,ch
je wrongtime
cmp ch,0x12
ja wrongtime
shl ecx,8
bswap ecx ;ebx=00YYMMDD
test cl,cl ;test day
je wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
shr ecx,4
cmp ch,2 ;February
jne testday
cmp cl,0x29
ja wrongtime
jmp setdate
cmp ebx, 1
jne nosetdate
cmp cl, 0x99;test year
ja wrongtime
shl ecx, 4
cmp cl, 0x90
ja wrongtime
cmp ch, 0x99;test month
ja wrongtime
shr ecx, 4
test ch, ch
je wrongtime
cmp ch, 0x12
ja wrongtime
shl ecx, 8
bswap ecx ;ebx=00YYMMDD
test cl, cl ;test day
je wrongtime
shl ecx, 4
cmp cl, 0x90
ja wrongtime
shr ecx, 4
cmp ch, 2 ;February
jne testday
cmp cl, 0x29
ja wrongtime
jmp setdate
testday:
cmp ch,8
jb testday1 ;Aug-Dec
bt cx,8
jnc days31
jmp days30
cmp ch, 8
jb testday1;Aug-Dec
bt cx, 8
jnc days31
jmp days30
testday1:
bt cx,8 ;Jan-Jul ex.Feb
jnc days30
bt cx, 8 ;Jan-Jul ex.Feb
jnc days30
days31:
cmp cl,0x31
ja wrongtime
jmp setdate
cmp cl, 0x31
ja wrongtime
jmp setdate
days30:
cmp cl,0x30
ja wrongtime
cmp cl, 0x30
ja wrongtime
setdate:
mov edx,0x70
call startstopclk
dec edx
mov al,7 ;set days
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,8 ;set months
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,9 ;set years
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
jmp endsettime
mov edx, 0x70
call startstopclk
dec edx
mov al, 7 ;set days
out dx, al
inc edx
mov al, cl
out dx, al
dec edx
mov al, 8 ;set months
out dx, al
inc edx
mov al, ch
out dx, al
dec edx
mov al, 9 ;set years
out dx, al
inc edx
shr ecx, 8
mov al, ch
out dx, al
jmp endsettime
nosetdate: ;set time or alarm-clock
cmp ebx,3
ja wrongtime
cmp cl,0x23
ja wrongtime
cmp ch,0x59
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
cmp ch,0x92
ja wrongtime
shl ecx,4
bswap ecx ;00HHMMSS
cmp cl,0x59
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
shr ecx,4
cmp ebx, 3
ja wrongtime
cmp cl, 0x23
ja wrongtime
cmp ch, 0x59
ja wrongtime
shl ecx, 4
cmp cl, 0x90
ja wrongtime
cmp ch, 0x92
ja wrongtime
shl ecx, 4
bswap ecx ;00HHMMSS
cmp cl, 0x59
ja wrongtime
shl ecx, 4
cmp cl, 0x90
ja wrongtime
shr ecx, 4
 
mov edx,0x70
call startstopclk
dec edx
cmp ebx,3
mov edx, 0x70
call startstopclk
dec edx
cmp ebx, 3
je setalarm
xor eax,eax ;al=0-set seconds
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,2 ;set minutes
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,4 ;set hours
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
jmp endsettime
je setalarm
xor eax, eax;al=0-set seconds
out dx, al
inc edx
mov al, cl
out dx, al
dec edx
mov al, 2 ;set minutes
out dx, al
inc edx
mov al, ch
out dx, al
dec edx
mov al, 4 ;set hours
out dx, al
inc edx
shr ecx, 8
mov al, ch
out dx, al
jmp endsettime
setalarm:
mov al,1 ;set seconds for al.
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,3 ;set minutes for al.
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,5 ;set hours for al.
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
dec edx
mov al,0x0b ;enable irq's
out dx,al
inc dx
in al,dx
bts ax,5 ;set bit 5
out dx,al
mov al, 1;set seconds for al.
out dx, al
inc edx
mov al, cl
out dx, al
dec edx
mov al, 3;set minutes for al.
out dx, al
inc edx
mov al, ch
out dx, al
dec edx
mov al, 5;set hours for al.
out dx, al
inc edx
shr ecx, 8
mov al, ch
out dx, al
dec edx
mov al, 0x0b;enable irq's
out dx, al
inc dx
in al, dx
bts ax, 5;set bit 5
out dx, al
endsettime:
dec edx
call startstopclk
sti
and [esp+36-4],dword 0
ret
dec edx
call startstopclk
sti
and [esp+36-4], dword 0
ret
bat_low:
sti
mov [esp+36-4],dword 2
ret
sti
mov [esp+36-4], dword 2
ret
wrongtime:
sti
mov [esp+36-4],dword 1
ret
sti
mov [esp+36-4], dword 1
ret
 
startstopclk:
mov al,0x0b
out dx,al
inc dx
in al,dx
btc ax,7
out dx,al
ret
mov al, 0x0b
out dx, al
inc dx
in al, dx
btc ax, 7
out dx, al
ret
/kernel/branches/net/imports.inc
18,10 → 18,10
@IMPORT:
 
library \
libini,'libini.obj'
libini,'libini.obj'
 
import libini, \
ini.lib_init,'lib_init',\
ini.get_str,'ini.get_str',\
ini.enum_keys,'ini.enum_keys',\
ini.get_int,'ini.get_int'
import libini, \
ini.lib_init,'lib_init',\
ini.get_str,'ini.get_str',\
ini.enum_keys,'ini.enum_keys',\
ini.get_int,'ini.get_int'
/kernel/branches/net/init.inc
15,327 → 15,323
align 4
proc mem_test
; if we have BIOS with fn E820, skip the test
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0
jnz .ret
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0
jnz .ret
 
mov eax, cr0
and eax, not (CR0_CD+CR0_NW)
or eax, CR0_CD ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
mov eax, cr0
and eax, not (CR0_CD+CR0_NW)
or eax, CR0_CD ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
xor edi, edi
mov ebx, 'TEST'
xor edi, edi
mov ebx, 'TEST'
@@:
add edi, 0x100000
xchg ebx, dword [edi]
cmp dword [edi], 'TEST'
xchg ebx, dword [edi]
je @b
add edi, 0x100000
xchg ebx, dword [edi]
cmp dword [edi], 'TEST'
xchg ebx, dword [edi]
je @b
 
and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax
inc dword [BOOT_VAR-OS_BASE + 0x9100]
xor eax, eax
mov [BOOT_VAR-OS_BASE + 0x9104], eax
mov [BOOT_VAR-OS_BASE + 0x9108], eax
mov [BOOT_VAR-OS_BASE + 0x910C], edi
mov [BOOT_VAR-OS_BASE + 0x9110], eax
and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax
inc dword [BOOT_VAR-OS_BASE + 0x9100]
xor eax, eax
mov [BOOT_VAR-OS_BASE + 0x9104], eax
mov [BOOT_VAR-OS_BASE + 0x9108], eax
mov [BOOT_VAR-OS_BASE + 0x910C], edi
mov [BOOT_VAR-OS_BASE + 0x9110], eax
.ret:
ret
ret
endp
 
align 4
proc init_mem
; calculate maximum allocatable address and number of allocatable pages
mov edi, BOOT_VAR-OS_BASE + 0x9104
mov ecx, [edi-4]
xor esi, esi ; esi will hold total amount of memory
xor edx, edx ; edx will hold maximum allocatable address
mov edi, BOOT_VAR-OS_BASE + 0x9104
mov ecx, [edi-4]
xor esi, esi; esi will hold total amount of memory
xor edx, edx; edx will hold maximum allocatable address
.calcmax:
; round all to pages
mov eax, [edi]
test eax, 0xFFF
jz @f
neg eax
and eax, 0xFFF
add [edi], eax
adc dword [edi+4], 0
sub [edi+8], eax
sbb dword [edi+12], 0
jc .unusable
mov eax, [edi]
test eax, 0xFFF
jz @f
neg eax
and eax, 0xFFF
add [edi], eax
adc dword [edi+4], 0
sub [edi+8], eax
sbb dword [edi+12], 0
jc .unusable
@@:
and dword [edi+8], not 0xFFF
jz .unusable
and dword [edi+8], not 0xFFF
jz .unusable
; ignore memory after 4 Gb
cmp dword [edi+4], 0
jnz .unusable
mov eax, [edi]
cmp dword [edi+12], 0
jnz .overflow
add eax, [edi+8]
jnc @f
cmp dword [edi+4], 0
jnz .unusable
mov eax, [edi]
cmp dword [edi+12], 0
jnz .overflow
add eax, [edi+8]
jnc @f
.overflow:
mov eax, 0xFFFFF000
mov eax, 0xFFFFF000
@@:
cmp edx, eax
jae @f
mov edx, eax
cmp edx, eax
jae @f
mov edx, eax
@@:
sub eax, [edi]
mov [edi+8], eax
add esi, eax
jmp .usable
sub eax, [edi]
mov [edi+8], eax
add esi, eax
jmp .usable
.unusable:
and dword [edi+8], 0
and dword [edi+8], 0
.usable:
add edi, 20
loop .calcmax
add edi, 20
loop .calcmax
.calculated:
mov [MEM_AMOUNT-OS_BASE], esi
mov [pg_data.mem_amount-OS_BASE], esi
shr esi, 12
mov [pg_data.pages_count-OS_BASE], esi
mov [MEM_AMOUNT-OS_BASE], esi
mov [pg_data.mem_amount-OS_BASE], esi
shr esi, 12
mov [pg_data.pages_count-OS_BASE], esi
 
shr edx, 12
add edx, 31
and edx, not 31
shr edx, 3
mov [pg_data.pagemap_size-OS_BASE], edx
shr edx, 12
add edx, 31
and edx, not 31
shr edx, 3
mov [pg_data.pagemap_size-OS_BASE], edx
 
add edx, (sys_pgmap-OS_BASE)+4095
and edx, not 4095
mov [tmp_page_tabs], edx
add edx, (sys_pgmap-OS_BASE)+4095
and edx, not 4095
mov [tmp_page_tabs], edx
 
mov edx, esi
and edx, -1024
cmp edx, (OS_BASE/4096)
jbe @F
mov edx, (OS_BASE/4096)
jmp .set
mov edx, esi
and edx, -1024
cmp edx, (OS_BASE/4096)
jbe @F
mov edx, (OS_BASE/4096)
jmp .set
@@:
cmp edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
jae .set
mov edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
cmp edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
jae .set
mov edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
.set:
mov [pg_data.kernel_pages-OS_BASE], edx
shr edx, 10
mov [pg_data.kernel_tables-OS_BASE], edx
mov [pg_data.kernel_pages-OS_BASE], edx
shr edx, 10
mov [pg_data.kernel_tables-OS_BASE], edx
 
xor eax, eax
mov edi, sys_pgdir-OS_BASE
mov ecx, 4096/4
cld
rep stosd
xor eax, eax
mov edi, sys_pgdir-OS_BASE
mov ecx, 4096/4
cld
rep stosd
 
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
 
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
mov cr4, ebx
dec [pg_data.kernel_tables-OS_BASE]
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
mov cr4, ebx
dec [pg_data.kernel_tables-OS_BASE]
 
mov [edx], eax
add eax, 0x00400000
add edx, 4
mov [edx], eax
add edx, 4
 
mov eax, 0x400000+PG_SW
mov ecx, [tmp_page_tabs]
sub ecx, 0x400000
shr ecx, 12 ;ecx/=4096
jmp .map_low
mov edi, [tmp_page_tabs]
jmp .map_kernel_heap ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
.no_PSE:
mov eax, PG_SW
mov ecx, [tmp_page_tabs]
shr ecx, 12
mov eax, PG_SW
mov ecx, [tmp_page_tabs]
shr ecx, 12
.map_low:
mov edi, [tmp_page_tabs]
mov edi, [tmp_page_tabs]
@@: ;
stosd
add eax, 0x1000
dec ecx
jnz @B
stosd
add eax, 0x1000
dec ecx
jnz @B
 
mov ecx, [pg_data.kernel_tables-OS_BASE]
shl ecx, 10
xor eax, eax
rep stosd
.map_kernel_heap:
mov ecx, [pg_data.kernel_tables-OS_BASE]
shl ecx, 10
xor eax, eax
rep stosd
 
mov ecx, [pg_data.kernel_tables-OS_BASE]
mov eax, [tmp_page_tabs]
or eax, PG_SW
mov edi, edx
mov ecx, [pg_data.kernel_tables-OS_BASE]
mov eax, [tmp_page_tabs]
or eax, PG_SW
mov edi, edx
 
.map_kernel_tabs:
stosd
add eax, 0x1000
dec ecx
jnz .map_kernel_tabs
 
stosd
add eax, 0x1000
dec ecx
jnz .map_kernel_tabs
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
 
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
 
mov edi, (sys_pgdir-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)]
movsd
movsd
ret
mov edi, (sys_pgdir-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)]
movsd
movsd
ret
endp
 
align 4
proc init_page_map
; mark all memory as unavailable
mov edi, sys_pgmap-OS_BASE
mov ecx, [pg_data.pagemap_size-OS_BASE]
shr ecx, 2
xor eax, eax
cld
rep stosd
mov edi, sys_pgmap-OS_BASE
mov ecx, [pg_data.pagemap_size-OS_BASE]
shr ecx, 2
xor eax, eax
cld
rep stosd
 
; scan through memory map and mark free areas as available
mov ebx, BOOT_VAR-OS_BASE + 0x9104
mov edx, [ebx-4]
mov ebx, BOOT_VAR-OS_BASE + 0x9104
mov edx, [ebx-4]
.scanmap:
mov ecx, [ebx+8]
shr ecx, 12 ; ecx = number of pages
jz .next
mov edi, [ebx]
shr edi, 12 ; edi = first page
mov eax, edi
shr edi, 5
shl edi, 2
add edi, sys_pgmap-OS_BASE
and eax, 31
jz .startok
add ecx, eax
sub ecx, 32
jbe .onedword
push ecx
mov ecx, eax
or eax, -1
shl eax, cl
or [edi], eax
add edi, 4
pop ecx
mov ecx, [ebx+8]
shr ecx, 12; ecx = number of pages
jz .next
mov edi, [ebx]
shr edi, 12; edi = first page
mov eax, edi
shr edi, 5
shl edi, 2
add edi, sys_pgmap-OS_BASE
and eax, 31
jz .startok
add ecx, eax
sub ecx, 32
jbe .onedword
push ecx
mov ecx, eax
or eax, -1
shl eax, cl
or [edi], eax
add edi, 4
pop ecx
.startok:
push ecx
shr ecx, 5
or eax, -1
rep stosd
pop ecx
and ecx, 31
neg eax
shl eax, cl
dec eax
or [edi], eax
jmp .next
push ecx
shr ecx, 5
or eax, -1
rep stosd
pop ecx
and ecx, 31
neg eax
shl eax, cl
dec eax
or [edi], eax
jmp .next
.onedword:
add ecx, 32
sub ecx, eax
add ecx, 32
sub ecx, eax
@@:
bts [edi], eax
inc eax
loop @b
bts [edi], eax
inc eax
loop @b
.next:
add ebx, 20
dec edx
jnz .scanmap
add ebx, 20
dec edx
jnz .scanmap
 
; mark kernel memory as allocated (unavailable)
mov ecx, [tmp_page_tabs]
mov edx, [pg_data.pages_count-OS_BASE]
shr ecx, 12
add ecx, [pg_data.kernel_tables-OS_BASE]
sub edx, ecx
mov [pg_data.pages_free-OS_BASE], edx
mov ecx, [tmp_page_tabs]
mov edx, [pg_data.pages_count-OS_BASE]
shr ecx, 12
add ecx, [pg_data.kernel_tables-OS_BASE]
sub edx, ecx
mov [pg_data.pages_free-OS_BASE], edx
 
mov edi, sys_pgmap-OS_BASE
mov ebx, ecx
shr ecx, 5
xor eax, eax
rep stosd
mov edi, sys_pgmap-OS_BASE
mov ebx, ecx
shr ecx, 5
xor eax, eax
rep stosd
 
not eax
mov ecx, ebx
and ecx, 31
shl eax, cl
and [edi], eax
add edi, OS_BASE
mov [page_start-OS_BASE], edi;
not eax
mov ecx, ebx
and ecx, 31
shl eax, cl
and [edi], eax
add edi, OS_BASE
mov [page_start-OS_BASE], edi;
 
mov ebx, sys_pgmap
add ebx, [pg_data.pagemap_size-OS_BASE]
mov [page_end-OS_BASE], ebx
mov ebx, sys_pgmap
add ebx, [pg_data.pagemap_size-OS_BASE]
mov [page_end-OS_BASE], ebx
 
mov [pg_data.pg_mutex-OS_BASE], 0
ret
ret
endp
 
align 4
 
init_BIOS32:
mov edi, 0xE0000
mov edi, 0xE0000
.pcibios_nxt:
cmp dword[edi], '_32_' ; "magic" word
je .BIOS32_found
cmp dword[edi], '_32_'; "magic" word
je .BIOS32_found
.pcibios_nxt2:
add edi, 0x10
cmp edi, 0xFFFF0
je .BIOS32_not_found
jmp .pcibios_nxt
.BIOS32_found: ; magic word found, check control summ
add edi, 0x10
cmp edi, 0xFFFF0
je .BIOS32_not_found
jmp .pcibios_nxt
.BIOS32_found: ; magic word found, check control summ
 
movzx ecx, byte[edi + 9]
shl ecx, 4
mov esi, edi
xor eax, eax
cld ; paranoia
@@: lodsb
add ah, al
loop @b
jnz .pcibios_nxt2 ; control summ must be zero
movzx ecx, byte[edi + 9]
shl ecx, 4
mov esi, edi
xor eax, eax
cld ; paranoia
@@:
lodsb
add ah, al
loop @b
jnz .pcibios_nxt2; control summ must be zero
; BIOS32 service found !
mov ebp, [edi + 4]
mov [bios32_entry], ebp
mov ebp, [edi + 4]
mov [bios32_entry], ebp
; check PCI BIOS present
mov eax, '$PCI'
xor ebx, ebx
push cs ; special for 'ret far' from BIOS
call ebp
test al, al
jnz .PCI_BIOS32_not_found
mov eax, '$PCI'
xor ebx, ebx
push cs ; special for 'ret far' from BIOS
call ebp
test al, al
jnz .PCI_BIOS32_not_found
 
; çäåñü ñîçäàþòñÿ äèñêðèïòîðû äëÿ PCI BIOS
 
add ebx, OS_BASE
dec ecx
mov [(pci_code_32-OS_BASE)], cx ;limit 0-15
mov [(pci_data_32-OS_BASE)], cx ;limit 0-15
add ebx, OS_BASE
dec ecx
mov [(pci_code_32-OS_BASE)], cx ;limit 0-15
mov [(pci_data_32-OS_BASE)], cx ;limit 0-15
 
mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15
mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15
mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15
mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15
 
shr ebx, 16
mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23
mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23
shr ebx, 16
mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23
mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23
 
shr ecx, 16
and cl, 0x0F
mov ch, bh
add cx, D32
mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 &
mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31
shr ecx, 16
and cl, 0x0F
mov ch, bh
add cx, D32
mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 &
mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31
 
mov [(pci_bios_entry-OS_BASE)], edx
mov [(pci_bios_entry-OS_BASE)], edx
; jmp .end
.PCI_BIOS32_not_found:
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat
.BIOS32_not_found:
.end:
ret
ret
 
align 4
proc test_cpu
346,93 → 342,213
cpu_AMD dd ?
endl
 
xor eax, eax
mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax
xor eax, eax
mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax
 
pushfd
pop eax
mov ecx, eax
xor eax, 0x40000
push eax
popfd
pushfd
pop eax
xor eax, ecx
mov [cpu_type], CPU_386
jz .end_cpuid
push ecx
popfd
pushfd
pop eax
mov ecx, eax
xor eax, 0x40000
push eax
popfd
pushfd
pop eax
xor eax, ecx
mov [cpu_type], CPU_386
jz .end_cpuid
push ecx
popfd
 
mov [cpu_type], CPU_486
mov eax, ecx
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
je .end_cpuid
mov [cpu_id], 1
mov [cpu_type], CPU_486
mov eax, ecx
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
je .end_cpuid
mov [cpu_id], 1
 
xor eax, eax
cpuid
xor eax, eax
cpuid
 
mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx
cmp ebx, dword [intel_str-OS_BASE]
jne .check_AMD
cmp edx, dword [intel_str+4-OS_BASE]
jne .check_AMD
cmp ecx, dword [intel_str+8-OS_BASE]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx
cmp ebx, dword [intel_str-OS_BASE]
jne .check_AMD
cmp edx, dword [intel_str+4-OS_BASE]
jne .check_AMD
cmp ecx, dword [intel_str+8-OS_BASE]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
 
shr eax, 8
and eax, 0x0f
ret
shr eax, 8
and eax, 0x0f
ret
.end_cpuid:
mov eax, [cpu_type]
ret
mov eax, [cpu_type]
ret
 
.check_AMD:
cmp ebx, dword [AMD_str-OS_BASE]
jne .unknown
cmp edx, dword [AMD_str+4-OS_BASE]
jne .unknown
cmp ecx, dword [AMD_str+8-OS_BASE]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
shr eax, 8
and eax, 0x0f
ret
cmp ebx, dword [AMD_str-OS_BASE]
jne .unknown
cmp edx, dword [AMD_str+4-OS_BASE]
jne .unknown
cmp ecx, dword [AMD_str+8-OS_BASE]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
.unknown:
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
shr eax, 8
and eax, 0x0f
ret
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE], ecx
shr eax, 8
and eax, 0x0f
ret
endp
 
uglobal
align 4
acpi_rsdp rd 1
acpi_rsdt rd 1
acpi_madt rd 1
 
acpi_dev_data rd 1
acpi_dev_size rd 1
 
acpi_rsdt_base rd 1
acpi_madt_base rd 1
acpi_lapic_base rd 1
acpi_ioapic_base rd 1
endg
 
ACPI_HI_RSDP_WINDOW_START equ 0x000E0000
ACPI_HI_RSDP_WINDOW_END equ 0x00100000
ACPI_RSDP_CHECKSUM_LENGTH equ 20
ACPI_MADT_SIGN equ 0x43495041
 
 
acpi_locate:
push ebx
mov ebx, ACPI_HI_RSDP_WINDOW_START
.check:
cmp [ebx], dword 0x20445352
jne .next
cmp [ebx+4], dword 0x20525450
jne .next
 
mov edx, ebx
mov ecx, ACPI_RSDP_CHECKSUM_LENGTH
xor eax, eax
.sum:
add al, [edx]
inc edx
loop .sum
 
test al, al
jnz .next
 
mov eax, ebx
pop ebx
ret
.next:
add ebx, 16
cmp ebx, ACPI_HI_RSDP_WINDOW_END
jb .check
 
pop ebx
xor eax, eax
ret
 
align 4
rsdt_find: ;ecx= rsdt edx= SIG
push ebx
push esi
 
lea ebx, [ecx+36]
mov esi, [ecx+4]
add esi, ecx
.next:
mov eax, [ebx]
cmp [eax], edx
je .done
 
add ebx, 4
cmp ebx, esi
jb .next
 
xor eax, eax
pop esi
pop ebx
ret
 
.done:
mov eax, [ebx]
pop esi
pop ebx
ret
 
 
align 4
 
check_acpi:
 
call acpi_locate
test eax, eax
jz .done
 
mov ecx, [eax+16]
mov edx, ACPI_MADT_SIGN
mov [acpi_rsdt_base-OS_BASE], ecx
call rsdt_find
test eax, eax
jz .done
 
mov [acpi_madt_base-OS_BASE], eax
mov ecx, [eax+36]
mov [acpi_lapic_base-OS_BASE], ecx
 
lea edx, [eax+44]
mov ecx, [eax+4]
add ecx, eax
.check:
mov eax, [edx]
cmp al, 1
je .ioapic
 
.next:
movzx eax, ah
add edx, eax
cmp edx, ecx
jb .check
.done:
ret
.ioapic:
mov eax, [edx+4]
mov [acpi_ioapic_base-OS_BASE], eax
ret
/kernel/branches/net/kernel.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)
19,6 → 19,17
;; SPraid (simba)
;; Hidnplayr
;; Alexey Teplov (<Lrz>)
;; Rus
;; Nable
;; shurf
;; Alver
;; Maxis
;; Galkov
;; CleverMouse
;; tsdima
;; turbanoff
;; Asper
;; art_zh
;;
;; Data in this file was originally part of MenuetOS project which is
;; distributed under the terms of GNU GPL. It is modified and redistributed as
61,24 → 72,24
$Revision$
 
 
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices
 
; Enabling the next line will enable serial output console
debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used
;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used
 
include "proc32.inc"
include "kglobals.inc"
lang fix en
include "lang.inc"
 
include "const.inc"
max_processes equ 255
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4
max_processes equ 255
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4
 
 
os_stack equ (os_data_l-gdts) ; GDTs
os_stack equ (os_data_l-gdts) ; GDTs
os_code equ (os_code_l-gdts)
graph_data equ (3+graph_data_l-gdts)
tss0 equ (tss0_l-gdts)
tss0 equ (tss0_l-gdts)
app_code equ (3+app_code_l-gdts)
app_data equ (3+app_data_l-gdts)
app_tls equ (3+tls_data_l-gdts)
117,8 → 128,8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
use16
org 0x0
jmp start_of_code
org 0x0
jmp start_of_code
 
version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0
 
129,10 → 140,10
include "boot/booteng.inc" ; english system boot messages
else if lang eq ru
include "boot/bootru.inc" ; russian system boot messages
include "boot/ru.inc" ; Russian font
include "boot/ru.inc" ; Russian font
else if lang eq et
include "boot/bootet.inc" ; estonian system boot messages
include "boot/et.inc" ; Estonian font
include "boot/et.inc" ; Estonian font
else
include "boot/bootge.inc" ; german system boot messages
end if
150,58 → 161,61
 
; CR0 Flags - Protected mode and Paging
 
mov ecx, CR0_PE
mov ecx, CR0_PE
 
; Enabling 32 bit protected mode
 
sidt [cs:old_ints_h]
sidt [cs:old_ints_h]
 
cli ; disable all irqs
cld
mov al,255 ; mask all irqs
out 0xa1,al
out 0x21,al
l.5: in al, 0x64 ; Enable A20
test al, 2
jnz l.5
mov al, 0xD1
out 0x64, al
l.6: in al, 0x64
test al, 2
jnz l.6
mov al, 0xDF
out 0x60, al
l.7: in al, 0x64
test al, 2
jnz l.7
mov al, 0xFF
out 0x64, al
cli ; disable all irqs
cld
mov al, 255 ; mask all irqs
out 0xa1, al
out 0x21, al
l.5:
in al, 0x64 ; Enable A20
test al, 2
jnz l.5
mov al, 0xD1
out 0x64, al
l.6:
in al, 0x64
test al, 2
jnz l.6
mov al, 0xDF
out 0x60, al
l.7:
in al, 0x64
test al, 2
jnz l.7
mov al, 0xFF
out 0x64, al
 
lgdt [cs:tmp_gdt] ; Load GDT
mov eax, cr0 ; protected mode
or eax, ecx
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp pword os_code:B32 ; jmp to enable 32 bit mode
lgdt [cs:tmp_gdt] ; Load GDT
mov eax, cr0 ; protected mode
or eax, ecx
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp pword os_code:B32 ; jmp to enable 32 bit mode
 
align 8
tmp_gdt:
 
dw 23
dd tmp_gdt+0x10000
dw 0
dw 23
dd tmp_gdt+0x10000
dw 0
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
 
include "data16.inc"
 
210,65 → 224,64
 
align 4
B32:
mov ax,os_stack ; Selector for os
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x3ec00 ; Set stack
mov ax, os_stack ; Selector for os
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x006CC00 ; Set stack
 
; CLEAR 0x280000 - HEAP_BASE
 
xor eax,eax
mov edi,0x280000
mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4
cld
rep stosd
xor eax, eax
mov edi, CLEAN_ZONE
mov ecx, (HEAP_BASE-OS_BASE-CLEAN_ZONE) / 4
cld
rep stosd
 
mov edi,0x40000
mov ecx,(0x90000-0x40000)/4
rep stosd
 
; CLEAR KERNEL UNDEFINED GLOBALS
mov edi, endofcode-OS_BASE
mov ecx, (uglobals_size/4)+4
rep stosd
mov edi, endofcode-OS_BASE
mov ecx, 0x90000
sub ecx, edi
shr ecx, 2
rep stosd
 
; SAVE & CLEAR 0-0xffff
 
xor esi, esi
mov edi,0x2F0000
mov ecx,0x10000 / 4
rep movsd
mov edi,0x1000
mov ecx,0xf000 / 4
rep stosd
xor esi, esi
mov edi, (BOOT_VAR-OS_BASE)
mov ecx, 0x10000 / 4
rep movsd
mov edi, 0x1000
mov ecx, 0xf000 / 4
rep stosd
 
call test_cpu
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc
call test_cpu
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc
 
call init_BIOS32
call check_acpi
call init_BIOS32
; MEMORY MODEL
call mem_test
call init_mem
call init_page_map
call mem_test
call init_mem
call init_page_map
 
; ENABLE PAGING
 
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
 
mov eax,cr0
or eax,CR0_PG+CR0_WP
mov cr0,eax
mov eax, cr0
or eax, CR0_PG+CR0_WP
mov cr0, eax
 
lgdt [gdts]
jmp pword os_code:high_code
lgdt [gdts]
jmp pword os_code:high_code
 
align 4
bios32_entry dd ?
tmp_page_tabs dd ?
bios32_entry dd ?
tmp_page_tabs dd ?
 
use16
org $-0x10000
284,608 → 297,611
 
align 4
high_code:
mov ax, os_stack
mov bx, app_data
mov cx, app_tls
mov ss, ax
add esp, OS_BASE
mov ax, os_stack
mov bx, app_data
mov cx, app_tls
mov ss, ax
add esp, OS_BASE
 
mov ds, bx
mov es, bx
mov fs, cx
mov gs, bx
mov ds, bx
mov es, bx
mov fs, cx
mov gs, bx
 
bt [cpu_caps], CAPS_PGE
jnc @F
bt [cpu_caps], CAPS_PGE
jnc @F
 
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL
 
mov ebx, cr4
or ebx, CR4_PGE
mov cr4, ebx
mov ebx, cr4
or ebx, CR4_PGE
mov cr4, ebx
@@:
xor eax, eax
mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax
xor eax, eax
mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax
 
mov eax, cr3
mov cr3, eax ; flush TLB
mov eax, cr3
mov cr3, eax ; flush TLB
 
mov ecx, pg_data.mutex
call mutex_init
 
mov ecx, disk_list_mutex
call mutex_init
 
; SAVE REAL MODE VARIABLES
mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax
mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax
; --------------- APM ---------------------
 
; init selectors
mov ebx,[BOOT_VAR+0x9040] ; offset of APM entry point
movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of
; protected-mode 32-bit code segment
movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of
; protected-mode 16-bit code segment
movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of
; protected-mode 16-bit data segment
mov ebx, [BOOT_VAR+0x9040] ; offset of APM entry point
movzx eax, word [BOOT_VAR+0x9050]; real-mode segment base address of
; protected-mode 32-bit code segment
movzx ecx, word [BOOT_VAR+0x9052]; real-mode segment base address of
; protected-mode 16-bit code segment
movzx edx, word [BOOT_VAR+0x9054]; real-mode segment base address of
; protected-mode 16-bit data segment
 
shl eax, 4
mov [dword apm_code_32 + 2], ax
shr eax, 16
mov [dword apm_code_32 + 4], al
shl eax, 4
mov [dword apm_code_32 + 2], ax
shr eax, 16
mov [dword apm_code_32 + 4], al
 
shl ecx, 4
mov [dword apm_code_16 + 2], cx
shr ecx, 16
mov [dword apm_code_16 + 4], cl
shl ecx, 4
mov [dword apm_code_16 + 2], cx
shr ecx, 16
mov [dword apm_code_16 + 4], cl
 
shl edx, 4
mov [dword apm_data_16 + 2], dx
shr edx, 16
mov [dword apm_data_16 + 4], dl
shl edx, 4
mov [dword apm_data_16 + 2], dx
shr edx, 16
mov [dword apm_data_16 + 4], dl
 
mov dword[apm_entry], ebx
mov word [apm_entry + 4], apm_code_32 - gdts
mov dword[apm_entry], ebx
mov word [apm_entry + 4], apm_code_32 - gdts
 
mov eax, [BOOT_VAR + 0x9044] ; version & flags
mov [apm_vf], eax
mov eax, [BOOT_VAR + 0x9044]; version & flags
mov [apm_vf], eax
; -----------------------------------------
; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port
; mov [0xF604],byte 1 ;al
mov al, [BOOT_VAR+0x901F] ; DMA access
mov [allow_dma_access], al
movzx eax, byte [BOOT_VAR+0x9000] ; bpp
mov [ScreenBPP],al
mov al, [BOOT_VAR+0x901F] ; DMA access
mov [allow_dma_access], al
movzx eax, byte [BOOT_VAR+0x9000] ; bpp
mov [ScreenBPP], al
 
mov [_display.bpp], eax
mov [_display.vrefresh], 60
mov [_display.disable_mouse], __sys_disable_mouse
mov [_display.bpp], eax
mov [_display.vrefresh], 60
mov [_display.disable_mouse], __sys_disable_mouse
 
movzx eax,word [BOOT_VAR+0x900A] ; X max
mov [_display.width], eax
dec eax
mov [Screen_Max_X],eax
mov [screen_workarea.right],eax
movzx eax,word [BOOT_VAR+0x900C] ; Y max
mov [_display.height], eax
dec eax
mov [Screen_Max_Y],eax
mov [screen_workarea.bottom],eax
movzx eax,word [BOOT_VAR+0x9008] ; screen mode
mov [SCR_MODE],eax
mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add
mov [BANK_SWITCH],eax
mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine
cmp [SCR_MODE],word 0x13 ; 320x200
je @f
cmp [SCR_MODE],word 0x12 ; VGA 640x480
je @f
movzx eax, word[BOOT_VAR+0x9001] ; for other modes
mov [BytesPerScanLine],ax
mov [_display.pitch], eax
movzx eax, word [BOOT_VAR+0x900A]; X max
mov [_display.width], eax
dec eax
mov [Screen_Max_X], eax
mov [screen_workarea.right], eax
movzx eax, word [BOOT_VAR+0x900C]; Y max
mov [_display.height], eax
dec eax
mov [Screen_Max_Y], eax
mov [screen_workarea.bottom], eax
movzx eax, word [BOOT_VAR+0x9008]; screen mode
mov [SCR_MODE], eax
mov eax, [BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add
mov [BANK_SWITCH], eax
mov [BytesPerScanLine], word 640*4 ; Bytes PerScanLine
cmp [SCR_MODE], word 0x13 ; 320x200
je @f
cmp [SCR_MODE], word 0x12 ; VGA 640x480
je @f
movzx eax, word[BOOT_VAR+0x9001] ; for other modes
mov [BytesPerScanLine], ax
mov [_display.pitch], eax
@@:
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
 
mov esi, BOOT_VAR+0x9080
movzx ecx, byte [esi-1]
mov [NumBiosDisks], ecx
mov edi, BiosDisksData
rep movsd
mov esi, BOOT_VAR+0x9080
movzx ecx, byte [esi-1]
mov [NumBiosDisks], ecx
mov edi, BiosDisksData
rep movsd
 
; GRAPHICS ADDRESSES
 
and byte [BOOT_VAR+0x901e],0x0
mov eax,[BOOT_VAR+0x9018]
mov [LFBAddress],eax
and byte [BOOT_VAR+0x901e], 0x0
mov eax, [BOOT_VAR+0x9018]
mov [LFBAddress], eax
 
cmp [SCR_MODE],word 0100000000000000b
jge setvesa20
cmp [SCR_MODE],word 0x13
je v20ga32
mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2
mov [GETPIXEL],dword Vesa12_getpixel24
cmp [ScreenBPP],byte 24
jz ga24
mov [PUTPIXEL],dword Vesa12_putpixel32
mov [GETPIXEL],dword Vesa12_getpixel32
cmp [SCR_MODE], word 0100000000000000b
jge setvesa20
cmp [SCR_MODE], word 0x13
je v20ga32
mov [PUTPIXEL], dword Vesa12_putpixel24 ; Vesa 1.2
mov [GETPIXEL], dword Vesa12_getpixel24
cmp [ScreenBPP], byte 24
jz ga24
mov [PUTPIXEL], dword Vesa12_putpixel32
mov [GETPIXEL], dword Vesa12_getpixel32
ga24:
jmp v20ga24
jmp v20ga24
setvesa20:
mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0
mov [GETPIXEL],dword Vesa20_getpixel24
cmp [ScreenBPP],byte 24
jz v20ga24
mov [PUTPIXEL], dword Vesa20_putpixel24 ; Vesa 2.0
mov [GETPIXEL], dword Vesa20_getpixel24
cmp [ScreenBPP], byte 24
jz v20ga24
v20ga32:
mov [PUTPIXEL],dword Vesa20_putpixel32
mov [GETPIXEL],dword Vesa20_getpixel32
mov [PUTPIXEL], dword Vesa20_putpixel32
mov [GETPIXEL], dword Vesa20_getpixel32
v20ga24:
cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [PUTPIXEL],dword VGA_putpixel
mov [GETPIXEL],dword Vesa20_getpixel32
cmp [SCR_MODE], word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [PUTPIXEL], dword VGA_putpixel
mov [GETPIXEL], dword Vesa20_getpixel32
no_mode_0x12:
 
; -------- Fast System Call init ----------
; Intel SYSENTER/SYSEXIT (AMD CPU support it too)
bt [cpu_caps], CAPS_SEP
jnc .SEnP ; SysEnter not Present
xor edx, edx
mov ecx, MSR_SYSENTER_CS
mov eax, os_code
wrmsr
mov ecx, MSR_SYSENTER_ESP
bt [cpu_caps], CAPS_SEP
jnc .SEnP ; SysEnter not Present
xor edx, edx
mov ecx, MSR_SYSENTER_CS
mov eax, os_code
wrmsr
mov ecx, MSR_SYSENTER_ESP
; mov eax, sysenter_stack ; Check it
xor eax, eax
wrmsr
mov ecx, MSR_SYSENTER_EIP
mov eax, sysenter_entry
wrmsr
xor eax, eax
wrmsr
mov ecx, MSR_SYSENTER_EIP
mov eax, sysenter_entry
wrmsr
.SEnP:
; AMD SYSCALL/SYSRET
cmp byte[cpu_vendor], 'A'
jne .noSYSCALL
mov eax, 0x80000001
cpuid
test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support
jz .noSYSCALL
mov ecx, MSR_AMD_EFER
rdmsr
or eax, 1 ; bit_0 - System Call Extension (SCE)
wrmsr
cmp byte[cpu_vendor], 'A'
jne .noSYSCALL
mov eax, 0x80000001
cpuid
test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support
jz .noSYSCALL
mov ecx, MSR_AMD_EFER
rdmsr
or eax, 1 ; bit_0 - System Call Extension (SCE)
wrmsr
 
; !!!! It`s dirty hack, fix it !!!
; Bits of EDX :
; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
; !!!! It`s dirty hack, fix it !!!
; Bits of EDX :
; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
 
; mov edx, (os_code + 16) * 65536 + os_code
mov edx, 0x1B0008
; mov edx, (os_code + 16) * 65536 + os_code
mov edx, 0x1B0008
 
mov eax, syscall_entry
mov ecx, MSR_AMD_STAR
wrmsr
mov eax, syscall_entry
mov ecx, MSR_AMD_STAR
wrmsr
.noSYSCALL:
; -----------------------------------------
stdcall alloc_page
stdcall map_page, tss-0xF80, eax, PG_SW
stdcall alloc_page
inc eax
mov [SLOT_BASE+256+APPDATA.io_map], eax
stdcall map_page, tss+0x80, eax, PG_SW
stdcall alloc_page
inc eax
mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax
stdcall map_page, tss+0x1080, eax, PG_SW
stdcall alloc_page
stdcall map_page, tss-0xF80, eax, PG_SW
stdcall alloc_page
inc eax
mov [SLOT_BASE+256+APPDATA.io_map], eax
stdcall map_page, tss+0x80, eax, PG_SW
stdcall alloc_page
inc eax
mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax
stdcall map_page, tss+0x1080, eax, PG_SW
 
; LOAD IDT
 
call build_interrupt_table ;lidt is executed
;lidt [idtreg]
call build_interrupt_table ;lidt is executed
;lidt [idtreg]
 
call init_kernel_heap
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [os_stack_seg], eax
call init_kernel_heap
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [os_stack_seg], eax
 
lea esp, [eax+RING0_STACK_SIZE]
lea esp, [eax+RING0_STACK_SIZE]
 
mov [tss._ss0], os_stack
mov [tss._esp0], esp
mov [tss._esp], esp
mov [tss._cs],os_code
mov [tss._ss],os_stack
mov [tss._ds],app_data
mov [tss._es],app_data
mov [tss._fs],app_data
mov [tss._gs],app_data
mov [tss._io],128
mov [tss._ss0], os_stack
mov [tss._esp0], esp
mov [tss._esp], esp
mov [tss._cs], os_code
mov [tss._ss], os_stack
mov [tss._ds], app_data
mov [tss._es], app_data
mov [tss._fs], app_data
mov [tss._gs], app_data
mov [tss._io], 128
;Add IO access table - bit array of permitted ports
mov edi, tss._io_map_0
xor eax, eax
not eax
mov ecx, 8192/4
rep stosd ; access to 4096*8=65536 ports
mov edi, tss._io_map_0
xor eax, eax
not eax
mov ecx, 8192/4
rep stosd ; access to 4096*8=65536 ports
 
mov ax,tss0
ltr ax
mov ax, tss0
ltr ax
 
mov [LFBSize], 0x800000
call init_LFB
call init_fpu
call init_malloc
mov [LFBSize], 0x800000
call init_LFB
call init_fpu
call init_malloc
 
stdcall alloc_kernel_space, 0x51000
mov [default_io_map], eax
stdcall alloc_kernel_space, 0x51000
mov [default_io_map], eax
 
add eax, 0x2000
mov [ipc_tmp], eax
mov ebx, 0x1000
add eax, 0x2000
mov [ipc_tmp], eax
mov ebx, 0x1000
 
add eax, 0x40000
mov [proc_mem_map], eax
add eax, 0x40000
mov [proc_mem_map], eax
 
add eax, 0x8000
mov [proc_mem_pdir], eax
add eax, 0x8000
mov [proc_mem_pdir], eax
 
add eax, ebx
mov [proc_mem_tab], eax
add eax, ebx
mov [proc_mem_tab], eax
 
add eax, ebx
mov [tmp_task_pdir], eax
add eax, ebx
mov [tmp_task_pdir], eax
 
add eax, ebx
mov [tmp_task_ptab], eax
add eax, ebx
mov [tmp_task_ptab], eax
 
add eax, ebx
mov [ipc_pdir], eax
add eax, ebx
mov [ipc_pdir], eax
 
add eax, ebx
mov [ipc_ptab], eax
add eax, ebx
mov [ipc_ptab], eax
 
stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \
(unpack.lc+unpack.lp)))*4
stdcall kernel_alloc, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \
(unpack.lc+unpack.lp)))*4
 
mov [unpack.p], eax
mov [unpack.p], eax
 
call init_events
mov eax, srv.fd-SRV_FD_OFFSET
mov [srv.fd], eax
mov [srv.bk], eax
call init_events
mov eax, srv.fd-SRV_FD_OFFSET
mov [srv.fd], eax
mov [srv.bk], eax
 
mov edi, irq_tab
xor eax, eax
mov ecx, 16
rep stosd
 
;Set base of graphic segment to linear address of LFB
mov eax,[LFBAddress] ; set for gs
mov [graph_data_l+2],ax
shr eax,16
mov [graph_data_l+4],al
mov [graph_data_l+7],ah
mov eax, [LFBAddress] ; set for gs
mov [graph_data_l+2], ax
shr eax, 16
mov [graph_data_l+4], al
mov [graph_data_l+7], ah
 
stdcall kernel_alloc, [_WinMapSize]
mov [_WinMapAddress], eax
stdcall kernel_alloc, [_WinMapSize]
mov [_WinMapAddress], eax
 
xor eax,eax
inc eax
mov [CURRENT_TASK],eax ;dword 1
mov [TASK_COUNT],eax ;dword 1
mov [TASK_BASE],dword TASK_DATA
mov [current_slot], SLOT_BASE+256
xor eax, eax
inc eax
mov [CURRENT_TASK], eax ;dword 1
mov [TASK_COUNT], eax ;dword 1
mov [TASK_BASE], dword TASK_DATA
mov [current_slot], SLOT_BASE+256
 
; set background
 
mov [BgrDrawMode],eax
mov [BgrDataWidth],eax
mov [BgrDataHeight],eax
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
mov [BgrDrawMode], eax
mov [BgrDataWidth], eax
mov [BgrDataHeight], eax
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
 
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
 
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
 
call rerouteirqs
call init_irqs
call PIC_init
 
; Initialize system V86 machine
call init_sys_v86
call init_sys_v86
 
; TIMER SET TO 1/100 S
; Initialize system timer (IRQ0)
call PIT_init
 
mov al,0x34 ; set to 100Hz
out 0x43,al
mov al,0x9b ; lsb 1193180 / 1193
out 0x40,al
mov al,0x2e ; msb
out 0x40,al
; Try to Initialize APIC
call APIC_init
 
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; they are used: when partitions are scanned, hd_read relies on timer
; Also enable IRQ2, because in some configurations
; IRQs from slave controller are not delivered until IRQ2 on master is enabled
mov al, 0xFA
out 0x21, al
mov al, 0x3F
out 0xA1, al
call unmask_timer
stdcall enable_irq, 2 ; @#$%! PIC
stdcall enable_irq, 6 ; FDD
stdcall enable_irq, 13 ; co-processor
stdcall enable_irq, 14
stdcall enable_irq, 15
 
; Enable interrupts in IDE controller
mov al, 0
mov dx, 0x3F6
out dx, al
mov dl, 0x76
out dx, al
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'detect/disks.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
 
call Parser_params
call Parser_params
 
if ~ defined extended_primary_loader
; ramdisk image should be loaded by extended primary loader if it exists
; READ RAMDISK IMAGE FROM HD
 
;!!!!!!!!!!!!!!!!!!!!!!!
include 'boot/rdload.inc'
;!!!!!!!!!!!!!!!!!!!!!!!
end if
; mov [dma_hdd],1
; CALCULATE FAT CHAIN FOR RAMDISK
 
call calculatefatchain
call calculatefatchain
 
; LOAD VMODE DRIVER
 
;!!!!!!!!!!!!!!!!!!!!!!!
include 'vmodeld.inc'
;!!!!!!!!!!!!!!!!!!!!!!!
 
if 0
mov ax,[OS_BASE+0x10000+bx_from_load]
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba}
je no_lib_load
mov ax, [OS_BASE+0x10000+bx_from_load]
cmp ax, 'r1'; if using not ram disk, then load librares and parameters {SPraid.simba}
je no_lib_load
; LOADING LIBRARES
stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files)
call load_file_parse_table ; prepare file parse table
call set_kernel_conf ; configure devices and gui
stdcall dll.Load, @IMPORT ; loading librares for kernel (.obj files)
call load_file_parse_table ; prepare file parse table
call set_kernel_conf ; configure devices and gui
no_lib_load:
end if
 
; LOAD FONTS I and II
 
stdcall read_file, char, FONT_I, 0, 2304
stdcall read_file, char2, FONT_II, 0, 2560
stdcall read_file, char, FONT_I, 0, 2304
stdcall read_file, char2, FONT_II, 0, 2560
 
mov esi,boot_fonts
call boot_log
mov esi, boot_fonts
call boot_log
 
; Display APIC status
mov esi, boot_APIC_found
cmp [irq_mode], IRQ_APIC
je @f
mov esi, boot_APIC_nfound
@@:
 
; PRINT AMOUNT OF MEMORY
mov esi, boot_memdetect
call boot_log
mov esi, boot_memdetect
call boot_log
 
movzx ecx, word [boot_y]
or ecx, (10+29*6) shl 16 ; "Determining amount of memory"
sub ecx, 10
mov edx, 0xFFFFFF
mov ebx, [MEM_AMOUNT]
shr ebx, 20
xor edi,edi
mov eax, 0x00040000
inc edi
call display_number_force
movzx ecx, word [boot_y]
if lang eq ru
or ecx, (10+30*6) shl 16
else
or ecx, (10+29*6) shl 16
end if
sub ecx, 10
mov edx, 0xFFFFFF
mov ebx, [MEM_AMOUNT]
shr ebx, 20
xor edi, edi
mov eax, 0x00040000
inc edi
call display_number_force
 
; BUILD SCHEDULER
 
call build_scheduler ; sys32.inc
call build_scheduler; sys32.inc
 
mov esi,boot_devices
call boot_log
mov esi, boot_devices
call boot_log
 
mov [pci_access_enabled],1
mov [pci_access_enabled], 1
 
 
; SET PRELIMINARY WINDOW STACK AND POSITIONS
 
mov esi,boot_windefs
call boot_log
call set_window_defaults
mov esi, boot_windefs
call boot_log
call set_window_defaults
 
; SET BACKGROUND DEFAULTS
 
mov esi,boot_bgr
call boot_log
call init_background
call calculatebackground
mov esi, boot_bgr
call boot_log
call init_background
call calculatebackground
 
; RESERVE SYSTEM IRQ'S JA PORT'S
 
mov esi,boot_resirqports
call boot_log
call reserve_irqs_ports
mov esi, boot_resirqports
call boot_log
call reserve_irqs_ports
 
; SET PORTS FOR IRQ HANDLERS
 
mov esi,boot_setrports
call boot_log
;call setirqreadports
 
; SET UP OS TASK
 
mov esi,boot_setostask
call boot_log
mov esi, boot_setostask
call boot_log
 
xor eax, eax
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+APPDATA.except_mask], eax
xor eax, eax
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+APPDATA.except_mask], eax
 
; name for OS/IDLE process
; name for OS/IDLE process
 
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
mov edi, [os_stack_seg]
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
add edi, 0x2000-512
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case
; [SLOT_BASE+256+APPDATA.io_map] was set earlier
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
mov edi, [os_stack_seg]
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
add edi, 0x2000-512
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi; just for case
; [SLOT_BASE+256+APPDATA.io_map] was set earlier
 
mov esi, fpu_data
mov ecx, 512/4
cld
rep movsd
mov esi, fpu_data
mov ecx, 512/4
cld
rep movsd
 
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
 
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
 
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
 
; task list
mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address
inc eax
mov dword [CURRENT_TASK],eax
mov dword [TASK_COUNT],eax
mov [current_slot], SLOT_BASE+256
mov [TASK_BASE],dword TASK_DATA
mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
; task list
mov dword [TASK_DATA+TASKDATA.mem_start], eax; process base address
inc eax
mov dword [CURRENT_TASK], eax
mov dword [TASK_COUNT], eax
mov [current_slot], SLOT_BASE+256
mov [TASK_BASE], dword TASK_DATA
mov byte[TASK_DATA+TASKDATA.wnd_number], al ; on screen number
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
 
call init_display
mov eax, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor],eax
mov [SLOT_BASE+APPDATA.cursor+256],eax
call init_display
mov eax, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor], eax
mov [SLOT_BASE+APPDATA.cursor+256], eax
 
; READ TSC / SECOND
 
mov esi,boot_tsc
call boot_log
cli
rdtsc ;call _rdtsc
mov ecx,eax
mov esi,250 ; wait 1/4 a second
call delay_ms
rdtsc ;call _rdtsc
sti
sub eax,ecx
shl eax,2
mov [CPU_FREQ],eax ; save tsc / sec
mov esi, boot_tsc
call boot_log
cli
rdtsc ;call _rdtsc
mov ecx, eax
mov esi, 250 ; wait 1/4 a second
call delay_ms
rdtsc ;call _rdtsc
sti
sub eax, ecx
shl eax, 2
mov [CPU_FREQ], eax ; save tsc / sec
; mov ebx, 1000000
; div ebx
; ¢®®¡é¥-â® ¯à®¨§¢®¤¨â¥«ì­®áâì ¢ ¤ ­­®¬ ª®­ªà¥â­®¬ ¬¥áâ¥
; ᮢ¥à襭­® ­¥ªà¨â¨ç­ , ­® çâ®¡ë § âª­ãâì «î¡¨â¥«¥©
; ®¯â¨¬¨§¨àãîé¨å ª®¬¯¨«ïâ®à®¢ Ÿ‚“...
mov edx, 2251799814
mul edx
shr edx, 19
mov [stall_mcs], edx
mov edx, 2251799814
mul edx
shr edx, 19
mov [stall_mcs], edx
; PRINT CPU FREQUENCY
mov esi, boot_cpufreq
call boot_log
mov esi, boot_cpufreq
call boot_log
 
mov ebx, edx
movzx ecx, word [boot_y]
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is '
mov edx, 0xFFFFFF
xor edi,edi
mov eax, 0x00040000
inc edi
call display_number_force
mov ebx, edx
movzx ecx, word [boot_y]
if lang eq ru
add ecx, (10+19*6) shl 16 - 10 ; 'Determining amount of memory'
else
add ecx, (10+17*6) shl 16 - 10 ; 'Determining amount of memory'
end if
mov edx, 0xFFFFFF
xor edi, edi
mov eax, 0x00040000
inc edi
call display_number_force
 
; SET VARIABLES
 
call set_variables
call set_variables
 
; SET MOUSE
 
;call detect_devices
stdcall load_driver, szPS2MDriver
; stdcall load_driver, szCOM_MDriver
 
mov esi,boot_setmouse
call boot_log
call setmouse
 
 
; STACK AND FDC
 
call stack_init
call fdc_init
call stack_init
call fdc_init
 
; PALETTE FOR 320x200 and 640x480 16 col
 
cmp [SCR_MODE],word 0x12
jne no_pal_vga
mov esi,boot_pal_vga
call boot_log
call paletteVGA
cmp [SCR_MODE], word 0x12
jne no_pal_vga
mov esi, boot_pal_vga
call boot_log
call paletteVGA
no_pal_vga:
 
cmp [SCR_MODE],word 0x13
jne no_pal_ega
mov esi,boot_pal_ega
call boot_log
call palette320x200
cmp [SCR_MODE], word 0x13
jne no_pal_ega
mov esi, boot_pal_ega
call boot_log
call palette320x200
no_pal_ega:
 
; LOAD DEFAULT SKIN
 
call load_default_skin
call load_default_skin
 
;protect io permission map
 
mov esi, [default_io_map]
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP
add esi, 0x1000
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
mov esi, [default_io_map]
stdcall map_page, esi, [SLOT_BASE+256+APPDATA.io_map], PG_MAP
add esi, 0x1000
stdcall map_page, esi, [SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
stdcall map_page,tss._io_map_0,\
[SLOT_BASE+256+APPDATA.io_map], PG_MAP
stdcall map_page,tss._io_map_1,\
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
stdcall map_page, tss._io_map_0, \
[SLOT_BASE+256+APPDATA.io_map], PG_MAP
stdcall map_page, tss._io_map_1, \
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
mov ax, [OS_BASE+0x10000+bx_from_load]
 
; LOAD FIRST APPLICATION
cli
cli
 
cmp byte [BOOT_VAR+0x9030],1
jne no_load_vrr_m
; cmp byte [BOOT_VAR+0x9030],1
; jne no_load_vrr_m
 
mov ebp, vrr_m
call fs_execute_from_sysdir
; mov ebp, vrr_m
; call fs_execute_from_sysdir
;
;; cmp eax,2 ; if vrr_m app found (PID=2)
; sub eax,2
; jz first_app_found
;
;no_load_vrr_m:
 
; cmp eax,2 ; if vrr_m app found (PID=2)
sub eax,2
jz first_app_found
mov ebp, firstapp
call fs_execute_from_sysdir
 
no_load_vrr_m:
 
mov ebp, firstapp
call fs_execute_from_sysdir
 
; cmp eax,2 ; continue if a process has been loaded
sub eax,2
jz first_app_found
sub eax, 2
jz first_app_found
 
mov esi, boot_failed
call boot_log
mov esi, boot_failed
call boot_log
 
mov eax, 0xDEADBEEF ; otherwise halt
hlt
mov eax, 0xDEADBEEF ; otherwise halt
hlt
 
first_app_found:
 
cli
cli
 
;mov [TASK_COUNT],dword 2
push 1
pop dword [CURRENT_TASK] ; set OS task fisrt
;mov [TASK_COUNT],dword 2
push 1
pop dword [CURRENT_TASK] ; set OS task fisrt
 
; SET KEYBOARD PARAMETERS
mov al, 0xf6 ; reset keyboard, scan enabled
call kb_write
mov al, 0xf6 ; reset keyboard, scan enabled
call kb_write
 
; wait until 8042 is ready
xor ecx,ecx
; wait until 8042 is ready
xor ecx, ecx
@@:
in al,64h
and al,00000010b
loopnz @b
in al, 64h
and al, 00000010b
loopnz @b
 
; mov al, 0xED ; svetodiody - only for testing!
; mov al, 0xED ; Keyboard LEDs - only for testing!
; call kb_write
; call kb_read
; mov al, 111b
892,54 → 908,63
; call kb_write
; call kb_read
 
mov al, 0xF3 ; set repeat rate & delay
call kb_write
mov al, 0xF3 ; set repeat rate & delay
call kb_write
; call kb_read
mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500
call kb_write
mov al, 0; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500
call kb_write
; call kb_read
;// mike.dld [
call set_lights
call set_lights
;// mike.dld ]
stdcall attach_int_handler, 1, irq1, 0
 
; SET MOUSE
 
stdcall load_driver, szPS2MDriver
; stdcall load_driver, szCOM_MDriver
 
mov esi, boot_setmouse
call boot_log
call setmouse
 
; Setup serial output console (if enabled)
 
if defined debug_com_base
 
; enable Divisor latch
; enable Divisor latch
 
mov dx, debug_com_base+3
mov al, 1 shl 7
out dx, al
mov dx, debug_com_base+3
mov al, 1 shl 7
out dx, al
 
; Set speed to 115200 baud (max speed)
; Set speed to 115200 baud (max speed)
 
mov dx, debug_com_base
mov al, 0x01
out dx, al
mov dx, debug_com_base
mov al, 0x01
out dx, al
 
mov dx, debug_com_base+1
mov al, 0x00
out dx, al
mov dx, debug_com_base+1
mov al, 0x00
out dx, al
 
; No parity, 8bits words, one stop bit, dlab bit back to 0
; No parity, 8bits words, one stop bit, dlab bit back to 0
 
mov dx, debug_com_base+3
mov al, 3
out dx, al
mov dx, debug_com_base+3
mov al, 3
out dx, al
 
; disable interrupts
; disable interrupts
 
mov dx, debug_com_base+1
mov al, 0
out dx, al
mov dx, debug_com_base+1
mov al, 0
out dx, al
 
; clear + enable fifo (64 bits)
; clear + enable fifo (64 bits)
 
mov dx, debug_com_base+2
mov al, 0x7 + 1 shl 5
out dx, al
mov dx, debug_com_base+2
mov al, 0x7 + 1 shl 5
out dx, al
 
 
end if
946,74 → 971,50
 
; START MULTITASKING
 
; A 'All set - press ESC to start' messages if need
if preboot_blogesc
mov esi, boot_tasking
call boot_log
.bll1: in al, 0x60 ; wait for ESC key press
cmp al, 129
jne .bll1
mov esi, boot_tasking
call boot_log
.bll1:
in al, 0x60 ; wait for ESC key press
cmp al, 129
jne .bll1
end if
 
; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
mov [timer_ticks_enable], 1 ; for cd driver
 
; UNMASK ALL IRQ'S
sti
call change_task
 
mov esi,boot_allirqs
call boot_log
jmp osloop
 
cli ;guarantee forbidance of interrupts.
mov al,0 ; unmask all irq's
out 0xA1,al
out 0x21,al
 
mov ecx,32
; Fly :)
 
ready_for_irqs:
 
mov al,0x20 ; ready for irqs
out 0x20,al
out 0xa0,al
 
loop ready_for_irqs ; flush the queue
 
stdcall attach_int_handler, dword 1, irq1, dword 0
 
; mov [dma_hdd],1
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
mov [timer_ticks_enable],1 ; for cd driver
 
sti
call change_task
 
jmp osloop
 
; jmp $ ; wait here for timer to take control
 
; Fly :)
 
include 'unpacker.inc'
include 'fdo.inc'
 
align 4
boot_log:
pushad
pushad
 
mov ebx,10*65536
mov bx,word [boot_y]
add [boot_y],dword 10
mov ecx,0x80ffffff ; ASCIIZ string with white color
xor edi,edi
mov edx,esi
inc edi
call dtext
mov ebx, 10*65536
mov bx, word [boot_y]
add [boot_y], dword 10
mov ecx, 0x80ffffff; ASCIIZ string with white color
xor edi, edi
mov edx, esi
inc edi
call dtext
 
mov [novesachecksum],1000
call checkVga_N13
mov [novesachecksum], 1000
call checkVga_N13
 
popad
popad
 
ret
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
1022,17 → 1023,17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
osloop:
call [draw_pointer]
call check_buttons
call checkwindows
; call check_window_move_request
call checkmisc
call checkVga_N13
call stack_handler
call checkidle
call check_fdd_motor_status
call check_ATAPI_device_event
jmp osloop
call [draw_pointer]
call window_check_events
call mouse_check_events
call checkmisc
call checkVga_N13
call stack_handler
call checkidle
call check_fdd_motor_status
call check_ATAPI_device_event
call check_timers
jmp osloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP END ;
1040,33 → 1041,33
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
checkidle:
pushad
call change_task
jmp idle_loop_entry
pushad
call change_task
jmp idle_loop_entry
idle_loop:
cmp eax,[idlemem] ; eax == [timer_ticks]
jne idle_exit
rdtsc ;call _rdtsc
mov ecx,eax
hlt
rdtsc ;call _rdtsc
sub eax,ecx
add [idleuse],eax
cmp eax, [idlemem] ; eax == [timer_ticks]
jne idle_exit
rdtsc ;call _rdtsc
mov ecx, eax
hlt
rdtsc ;call _rdtsc
sub eax, ecx
add [idleuse], eax
idle_loop_entry:
mov eax,[timer_ticks] ; eax = [timer_ticks]
cmp [check_idle_semaphore],0
je idle_loop
dec [check_idle_semaphore]
mov eax, [timer_ticks]; eax = [timer_ticks]
cmp [check_idle_semaphore], 0
je idle_loop
dec [check_idle_semaphore]
idle_exit:
mov [idlemem],eax ; eax == [timer_ticks]
popad
ret
mov [idlemem], eax ; eax == [timer_ticks]
popad
ret
 
uglobal
idlemem dd 0x0
idleuse dd 0x0
idleusesec dd 0x0
check_idle_semaphore dd 0x0
idlemem dd 0x0
idleuse dd 0x0
idleusesec dd 0x0
check_idle_semaphore dd 0x0
endg
 
 
1089,59 → 1090,32
 
reserve_irqs_ports:
 
push eax
xor eax,eax
inc eax
mov byte [irq_owner+4*0],al ;1 ; timer
;mov [irq_owner+4*1], 1 ; keyboard
mov byte [irq_owner+4*6],al ;1 ; floppy diskette
mov byte [irq_owner+4*13],al ;1 ; math co-pros
mov byte [irq_owner+4*14],al ;1 ; ide I
mov byte [irq_owner+4*15],al ;1 ; ide II
pop eax
 
; RESERVE PORTS
push 4
pop dword [RESERVED_PORTS] ;,edi
mov eax, RESERVED_PORTS
mov ecx, 1
 
push 1
pop dword [RESERVED_PORTS+16+0] ;,dword 1
and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0
mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d
mov [eax], dword 4
 
push 1
pop dword [RESERVED_PORTS+32+0] ;,dword 1
push 0x30
pop dword [RESERVED_PORTS+32+4] ;,dword 0x30
push 0x4d
pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d
mov [eax+16], ecx
mov [eax+16+4], dword 0
mov [eax+16+4], dword 0x2D
 
push 1
pop dword [RESERVED_PORTS+48+0] ;,dword 1
push 0x50
pop dword [RESERVED_PORTS+48+4] ;,dword 0x50
mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf
mov [eax+32], ecx
mov [eax+32+4], dword 0x30
mov [eax+32+8], dword 0x4D
 
push 1
pop dword [RESERVED_PORTS+64+0] ;,dword 1
mov [eax+48], ecx
mov [eax+48+4], dword 0x50
mov [eax+28+8], dword 0xDF
 
mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5
mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff
mov [eax+64], ecx
mov [eax+64+4], dword 0xE5
mov [eax+64+8], dword 0xFF
 
ret
ret
 
setirqreadports:
 
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte
and dword [irq12read+4],0 ; end of port list
; mov [irq12read+4],dword 0 ; end of port list
;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte
;mov [irq04read+4],dword 0 ; end of port list
;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte
;mov [irq03read+4],dword 0 ; end of port list
 
ret
 
iglobal
process_number dd 0x1
endg
1148,97 → 1122,98
 
set_variables:
 
mov ecx,0x100 ; flush port 0x60
.fl60: in al,0x60
loop .fl60
push eax
mov ecx, 0x16 ; flush port 0x60
.fl60:
in al, 0x60
loop .fl60
push eax
 
mov ax,[BOOT_VAR+0x900c]
shr ax,1
shl eax,16
mov ax,[BOOT_VAR+0x900A]
shr ax,1
mov [MOUSE_X],eax
mov ax, [BOOT_VAR+0x900c]
shr ax, 1
shl eax, 16
mov ax, [BOOT_VAR+0x900A]
shr ax, 1
mov [MOUSE_X], eax
 
xor eax,eax
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list
xor eax, eax
mov [BTN_ADDR], dword BUTTON_INFO ; address of button list
 
mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer
mov byte [KEY_COUNT],al ; keyboard buffer
mov byte [BTN_COUNT],al ; button buffer
mov byte [MOUSE_BUFF_COUNT], al ; mouse buffer
mov byte [KEY_COUNT], al ; keyboard buffer
mov byte [BTN_COUNT], al ; button buffer
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y
 
;!! IP 04.02.2005:
mov byte [DONT_SWITCH],al ; change task if possible
pop eax
ret
mov byte [DONT_SWITCH], al; change task if possible
pop eax
ret
 
align 4
;input eax=43,bl-byte of output, ecx - number of port
sys_outport:
 
mov edi,ecx ; separate flag for read / write
and ecx,65535
mov edi, ecx ; separate flag for read / write
and ecx, 65535
 
mov eax,[RESERVED_PORTS]
test eax,eax
jnz .sopl8
inc eax
mov [esp+32],eax
ret
mov eax, [RESERVED_PORTS]
test eax, eax
jnz .sopl8
inc eax
mov [esp+32], eax
ret
 
.sopl8:
mov edx,[TASK_BASE]
mov edx,[edx+0x4]
mov edx, [TASK_BASE]
mov edx, [edx+0x4]
;and ecx,65535
;cld - set on interrupt 0x40
.sopl1:
 
mov esi,eax
shl esi,4
add esi,RESERVED_PORTS
cmp edx,[esi+0]
jne .sopl2
cmp ecx,[esi+4]
jb .sopl2
cmp ecx,[esi+8]
jg .sopl2
mov esi, eax
shl esi, 4
add esi, RESERVED_PORTS
cmp edx, [esi+0]
jne .sopl2
cmp ecx, [esi+4]
jb .sopl2
cmp ecx, [esi+8]
jg .sopl2
.sopl3:
 
test edi,0x80000000 ; read ?
jnz .sopl4
test edi, 0x80000000; read ?
jnz .sopl4
 
mov eax,ebx
mov dx,cx ; write
out dx,al
and [esp+32],dword 0
ret
mov eax, ebx
mov dx, cx ; write
out dx, al
and [esp+32], dword 0
ret
 
.sopl2:
.sopl2:
 
dec eax
jnz .sopl1
inc eax
mov [esp+32],eax
ret
dec eax
jnz .sopl1
inc eax
mov [esp+32], eax
ret
 
 
.sopl4:
 
mov dx,cx ; read
in al,dx
and eax,0xff
and [esp+32],dword 0
mov [esp+20],eax
ret
mov dx, cx ; read
in al, dx
and eax, 0xff
and [esp+32], dword 0
mov [esp+20], eax
ret
 
display_number:
;It is not optimization
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
; eax = print type, al=0 -> ebx is number
; al=1 -> ebx is pointer
; ah=0 -> display decimal
1250,175 → 1225,175
; ebx = number or pointer
; ecx = x shl 16 + y
; edx = color
xor edi, edi
xor edi, edi
display_number_force:
push eax
and eax,0x3fffffff
cmp eax,0xffff ; length > 0 ?
pop eax
jge cont_displ
ret
push eax
and eax, 0x3fffffff
cmp eax, 0xffff ; length > 0 ?
pop eax
jge cont_displ
ret
cont_displ:
push eax
and eax,0x3fffffff
cmp eax,61*0x10000 ; length <= 60 ?
pop eax
jb cont_displ2
ret
push eax
and eax, 0x3fffffff
cmp eax, 61*0x10000 ; length <= 60 ?
pop eax
jb cont_displ2
ret
cont_displ2:
 
pushad
pushad
 
cmp al,1 ; ecx is a pointer ?
jne displnl1
mov ebp,ebx
add ebp,4
mov ebp,[ebp+std_application_base_address]
mov ebx,[ebx+std_application_base_address]
cmp al, 1 ; ecx is a pointer ?
jne displnl1
mov ebp, ebx
add ebp, 4
mov ebp, [ebp+std_application_base_address]
mov ebx, [ebx+std_application_base_address]
displnl1:
sub esp,64
sub esp, 64
 
test ah,ah ; DECIMAL
jnz no_display_desnum
shr eax,16
and eax,0xC03f
test ah, ah ; DECIMAL
jnz no_display_desnum
shr eax, 16
and eax, 0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,10
push eax
and eax, 0x3f
mov edi, esp
add edi, 4+64-1
mov ecx, eax
mov eax, ebx
mov ebx, 10
d_desnum:
xor edx,edx
call division_64_bits
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_desnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
xor edx, edx
call division_64_bits
div ebx
add dl, 48
mov [edi], dl
dec edi
loop d_desnum
pop eax
call normalize_number
call draw_num_text
add esp, 64
popad
ret
no_display_desnum:
 
cmp ah,0x01 ; HEXADECIMAL
jne no_display_hexnum
shr eax,16
and eax,0xC03f
cmp ah, 0x01 ; HEXADECIMAL
jne no_display_hexnum
shr eax, 16
and eax, 0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,16
push eax
and eax, 0x3f
mov edi, esp
add edi, 4+64-1
mov ecx, eax
mov eax, ebx
mov ebx, 16
d_hexnum:
xor edx,edx
call division_64_bits
div ebx
xor edx, edx
call division_64_bits
div ebx
hexletters = __fdo_hexdigits
add edx,hexletters
mov dl,[edx]
mov [edi],dl
dec edi
loop d_hexnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
add edx, hexletters
mov dl, [edx]
mov [edi], dl
dec edi
loop d_hexnum
pop eax
call normalize_number
call draw_num_text
add esp, 64
popad
ret
no_display_hexnum:
 
cmp ah,0x02 ; BINARY
jne no_display_binnum
shr eax,16
and eax,0xC03f
cmp ah, 0x02 ; BINARY
jne no_display_binnum
shr eax, 16
and eax, 0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,2
push eax
and eax, 0x3f
mov edi, esp
add edi, 4+64-1
mov ecx, eax
mov eax, ebx
mov ebx, 2
d_binnum:
xor edx,edx
call division_64_bits
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_binnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
xor edx, edx
call division_64_bits
div ebx
add dl, 48
mov [edi], dl
dec edi
loop d_binnum
pop eax
call normalize_number
call draw_num_text
add esp, 64
popad
ret
no_display_binnum:
 
add esp,64
popad
ret
add esp, 64
popad
ret
 
normalize_number:
test ah,0x80
jz .continue
mov ecx,48
and eax,0x3f
test ah, 0x80
jz .continue
mov ecx, 48
and eax, 0x3f
@@:
inc edi
cmp [edi],cl
jne .continue
dec eax
cmp eax,1
ja @r
mov al,1
inc edi
cmp [edi], cl
jne .continue
dec eax
cmp eax, 1
ja @r
mov al, 1
.continue:
and eax,0x3f
ret
and eax, 0x3f
ret
 
division_64_bits:
test [esp+1+4],byte 0x40
jz .continue
push eax
mov eax,ebp
div ebx
mov ebp,eax
pop eax
test [esp+1+4], byte 0x40
jz .continue
push eax
mov eax, ebp
div ebx
mov ebp, eax
pop eax
.continue:
ret
ret
 
draw_num_text:
mov esi,eax
mov edx,64+4
sub edx,eax
add edx,esp
mov ebx,[esp+64+32-8+4]
mov esi, eax
mov edx, 64+4
sub edx, eax
add edx, esp
mov ebx, [esp+64+32-8+4]
; add window start x & y
mov ecx,[TASK_BASE]
mov ecx, [TASK_BASE]
 
mov edi,[CURRENT_TASK]
shl edi,8
mov edi, [CURRENT_TASK]
shl edi, 8
 
mov eax,[ecx-twdw+WDATA.box.left]
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
shl eax,16
add eax,[ecx-twdw+WDATA.box.top]
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
add ebx,eax
mov ecx,[esp+64+32-12+4]
and ecx, not 0x80000000 ; force counted string
mov eax, [esp+64+8] ; background color (if given)
mov edi, [esp+64+4]
jmp dtext
mov eax, [ecx-twdw+WDATA.box.left]
add eax, [edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
shl eax, 16
add eax, [ecx-twdw+WDATA.box.top]
add eax, [edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
add ebx, eax
mov ecx, [esp+64+32-12+4]
and ecx, not 0x80000000 ; force counted string
mov eax, [esp+64+8] ; background color (if given)
mov edi, [esp+64+4]
jmp dtext
 
align 4
 
1436,21 → 1411,21
; 12 = enable pci access
 
 
and [esp+32],dword 0
dec ebx ; MIDI
jnz nsyse1
cmp ecx,0x100
and [esp+32], dword 0
dec ebx ; MIDI
jnz nsyse1
cmp ecx, 0x100
 
jb nsyse1
mov esi,65535
cmp esi,ecx
jb nsyse1
mov esi, 65535
cmp esi, ecx
 
jb nsyse1
mov [midi_base],cx ;bx
mov word [mididp],cx ;bx
inc cx ;bx
mov word [midisp],cx ;bx
ret
jb nsyse1
mov [midi_base], cx ;bx
mov word [mididp], cx;bx
inc cx ;bx
mov word [midisp], cx;bx
ret
 
iglobal
midi_base dw 0
1457,74 → 1432,74
endg
 
nsyse1:
dec ebx ; KEYBOARD
jnz nsyse2
mov edi,[TASK_BASE]
mov eax,[edi+TASKDATA.mem_start]
add eax,edx
dec ebx ; KEYBOARD
jnz nsyse2
mov edi, [TASK_BASE]
mov eax, [edi+TASKDATA.mem_start]
add eax, edx
 
dec ecx
jnz kbnobase
mov ebx,keymap
mov ecx,128
call memmove
ret
dec ecx
jnz kbnobase
mov ebx, keymap
mov ecx, 128
call memmove
ret
kbnobase:
dec ecx
jnz kbnoshift
dec ecx
jnz kbnoshift
 
mov ebx,keymap_shift
mov ecx,128
call memmove
ret
mov ebx, keymap_shift
mov ecx, 128
call memmove
ret
kbnoshift:
dec ecx
jnz kbnoalt
mov ebx,keymap_alt
mov ecx,128
call memmove
ret
dec ecx
jnz kbnoalt
mov ebx, keymap_alt
mov ecx, 128
call memmove
ret
kbnoalt:
sub ecx,6
jnz kbnocountry
mov word [keyboard],dx
ret
sub ecx, 6
jnz kbnocountry
mov word [keyboard], dx
ret
kbnocountry:
mov [esp+32],dword 1
ret
mov [esp+32], dword 1
ret
nsyse2:
dec ebx ; CD
jnz nsyse4
dec ebx ; CD
jnz nsyse4
 
test ecx,ecx
jz nosesl
test ecx, ecx
jz nosesl
 
cmp ecx, 4
ja nosesl
mov [cd_base],cl
cmp ecx, 4
ja nosesl
mov [cd_base], cl
 
dec ecx
jnz noprma
mov [cdbase],0x1f0
mov [cdid],0xa0
dec ecx
jnz noprma
mov [cdbase], 0x1f0
mov [cdid], 0xa0
noprma:
 
dec ecx
jnz noprsl
mov [cdbase],0x1f0
mov [cdid],0xb0
dec ecx
jnz noprsl
mov [cdbase], 0x1f0
mov [cdid], 0xb0
noprsl:
dec ecx
jnz nosema
mov [cdbase],0x170
mov [cdid],0xa0
dec ecx
jnz nosema
mov [cdbase], 0x170
mov [cdid], 0xa0
nosema:
dec ecx
jnz nosesl
mov [cdbase],0x170
mov [cdid],0xb0
dec ecx
jnz nosesl
mov [cdbase], 0x170
mov [cdid], 0xb0
nosesl:
ret
ret
 
iglobal
cd_base db 0
1531,60 → 1506,60
 
endg
nsyse4:
sub ebx,2 ; SYSTEM LANGUAGE
jnz nsyse5
mov [syslang],ecx
ret
 
sub ebx, 2 ; SYSTEM LANGUAGE
jnz nsyse5
mov [syslang], ecx
ret
nsyse5:
sub ebx,2 ; HD BASE
jnz nsyse7
 
test ecx,ecx
jz nosethd
sub ebx, 2 ; HD BASE
jnz nsyse7
 
cmp ecx,4
ja nosethd
mov [hd_base],cl
test ecx, ecx
jz nosethd
 
cmp ecx,1
jnz noprmahd
mov [hdbase],0x1f0
and dword [hdid],0x0
mov dword [hdpos],ecx
cmp ecx, 4
ja nosethd
mov [hd_base], cl
 
cmp ecx, 1
jnz noprmahd
mov [hdbase], 0x1f0
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
noprmahd:
 
cmp ecx,2
jnz noprslhd
mov [hdbase],0x1f0
mov [hdid],0x10
mov dword [hdpos],ecx
cmp ecx, 2
jnz noprslhd
mov [hdbase], 0x1f0
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
noprslhd:
 
cmp ecx,3
jnz nosemahd
mov [hdbase],0x170
and dword [hdid],0x0
mov dword [hdpos],ecx
cmp ecx, 3
jnz nosemahd
mov [hdbase], 0x170
and dword [hdid], 0x0
mov dword [hdpos], ecx
; call set_FAT32_variables
nosemahd:
 
cmp ecx,4
jnz noseslhd
mov [hdbase],0x170
mov [hdid],0x10
mov dword [hdpos],ecx
cmp ecx, 4
jnz noseslhd
mov [hdbase], 0x170
mov [hdid], 0x10
mov dword [hdpos], ecx
; call set_FAT32_variables
noseslhd:
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
and dword [hd1_status],0 ; free
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
and dword [hd1_status], 0 ; free
nosethd:
ret
ret
 
iglobal
hd_base db 0
1593,42 → 1568,37
nsyse7:
 
; cmp eax,8 ; HD PARTITION
dec ebx
jnz nsyse8
mov [fat32part],ecx
dec ebx
jnz nsyse8
mov [fat32part], ecx
; call set_FAT32_variables
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
; pusha
call choice_necessity_partition_1
call choice_necessity_partition_1
; popa
and dword [hd1_status],0 ; free
ret
and dword [hd1_status], 0 ; free
ret
 
nsyse8:
; cmp eax,11 ; ENABLE LBA READ
and ecx,1
sub ebx,3
jnz no_set_lba_read
mov [lba_read_enabled],ecx
ret
and ecx, 1
sub ebx, 3
jnz no_set_lba_read
mov [lba_read_enabled], ecx
ret
 
no_set_lba_read:
; cmp eax,12 ; ENABLE PCI ACCESS
dec ebx
jnz no_set_pci_access
mov [pci_access_enabled],ecx
ret
no_set_pci_access:
dec ebx
jnz sys_setup_err
mov [pci_access_enabled], ecx
ret
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'vmodeint.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
sys_setup_err:
or [esp+32],dword -1
ret
or [esp+32], dword -1
ret
 
align 4
 
1643,119 → 1613,119
; 9=get hs timer tic
 
; cmp eax,1
dec ebx
jnz ngsyse1
movzx eax,[midi_base]
mov [esp+32],eax
ret
dec ebx
jnz ngsyse1
movzx eax, [midi_base]
mov [esp+32], eax
ret
ngsyse1:
; cmp eax,2
dec ebx
jnz ngsyse2
dec ebx
jnz ngsyse2
 
mov edi,[TASK_BASE]
mov ebx,[edi+TASKDATA.mem_start]
add ebx,edx
mov edi, [TASK_BASE]
mov ebx, [edi+TASKDATA.mem_start]
add ebx, edx
 
; cmp ebx,1
dec ecx
jnz kbnobaseret
mov eax,keymap
mov ecx,128
call memmove
ret
dec ecx
jnz kbnobaseret
mov eax, keymap
mov ecx, 128
call memmove
ret
kbnobaseret:
; cmp ebx,2
dec ecx
jnz kbnoshiftret
dec ecx
jnz kbnoshiftret
 
mov eax,keymap_shift
mov ecx,128
call memmove
ret
mov eax, keymap_shift
mov ecx, 128
call memmove
ret
kbnoshiftret:
; cmp ebx,3
dec ecx
jne kbnoaltret
dec ecx
jne kbnoaltret
 
mov eax,keymap_alt
mov ecx,128
call memmove
ret
mov eax, keymap_alt
mov ecx, 128
call memmove
ret
kbnoaltret:
; cmp ebx,9
sub ecx,6
jnz ngsyse2
movzx eax,word [keyboard]
mov [esp+32],eax
ret
sub ecx, 6
jnz ngsyse2
movzx eax, word [keyboard]
mov [esp+32], eax
ret
 
 
ngsyse2:
; cmp eax,3
dec ebx
jnz ngsyse3
movzx eax,[cd_base]
mov [esp+32],eax
ret
dec ebx
jnz ngsyse3
movzx eax, [cd_base]
mov [esp+32], eax
ret
ngsyse3:
; cmp eax,5
sub ebx,2
jnz ngsyse5
mov eax,[syslang]
mov [esp+32],eax
ret
sub ebx, 2
jnz ngsyse5
mov eax, [syslang]
mov [esp+32], eax
ret
ngsyse5:
; cmp eax,7
sub ebx,2
jnz ngsyse7
movzx eax,[hd_base]
mov [esp+32],eax
ret
sub ebx, 2
jnz ngsyse7
movzx eax, [hd_base]
mov [esp+32], eax
ret
ngsyse7:
; cmp eax,8
dec ebx
jnz ngsyse8
mov eax,[fat32part]
mov [esp+32],eax
ret
dec ebx
jnz ngsyse8
mov eax, [fat32part]
mov [esp+32], eax
ret
ngsyse8:
; cmp eax,9
dec ebx
jnz ngsyse9
mov eax,[timer_ticks] ;[0xfdf0]
mov [esp+32],eax
ret
dec ebx
jnz ngsyse9
mov eax, [timer_ticks];[0xfdf0]
mov [esp+32], eax
ret
ngsyse9:
; cmp eax,11
sub ebx,2
jnz ngsyse11
mov eax,[lba_read_enabled]
mov [esp+32],eax
ret
sub ebx, 2
jnz ngsyse11
mov eax, [lba_read_enabled]
mov [esp+32], eax
ret
ngsyse11:
; cmp eax,12
dec ebx
jnz ngsyse12
mov eax,[pci_access_enabled]
mov [esp+32],eax
ret
dec ebx
jnz ngsyse12
mov eax, [pci_access_enabled]
mov [esp+32], eax
ret
ngsyse12:
mov [esp+32],dword 1
ret
mov [esp+32], dword 1
ret
 
 
get_timer_ticks:
mov eax,[timer_ticks]
ret
mov eax, [timer_ticks]
ret
 
iglobal
align 4
mousefn dd msscreen, mswin, msbutton, msset
dd app_load_cursor
dd app_set_cursor
dd app_delete_cursor
dd msz
dd app_load_cursor
dd app_set_cursor
dd app_delete_cursor
dd msz
endg
 
readmousepos:
1769,107 → 1739,107
; eax=6 delete cursor ; reserved
; eax=7 get mouse_z
 
cmp ebx, 7
ja msset
jmp [mousefn+ebx*4]
cmp ebx, 7
ja msset
jmp [mousefn+ebx*4]
msscreen:
mov eax,[MOUSE_X]
shl eax,16
mov ax,[MOUSE_Y]
mov [esp+36-4],eax
ret
mov eax, [MOUSE_X]
shl eax, 16
mov ax, [MOUSE_Y]
mov [esp+36-4], eax
ret
mswin:
mov eax,[MOUSE_X]
shl eax,16
mov ax,[MOUSE_Y]
mov esi,[TASK_BASE]
mov bx, word [esi-twdw+WDATA.box.left]
shl ebx,16
mov bx, word [esi-twdw+WDATA.box.top]
sub eax,ebx
mov eax, [MOUSE_X]
shl eax, 16
mov ax, [MOUSE_Y]
mov esi, [TASK_BASE]
mov bx, word [esi-twdw+WDATA.box.left]
shl ebx, 16
mov bx, word [esi-twdw+WDATA.box.top]
sub eax, ebx
 
mov edi,[CURRENT_TASK]
shl edi,8
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol eax,16
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol eax,16
mov [esp+36-4],eax
ret
mov edi, [CURRENT_TASK]
shl edi, 8
sub ax, word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol eax, 16
sub ax, word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol eax, 16
mov [esp+36-4], eax
ret
msbutton:
movzx eax,byte [BTN_DOWN]
mov [esp+36-4],eax
ret
movzx eax, byte [BTN_DOWN]
mov [esp+36-4], eax
ret
msz:
mov edi, [TASK_COUNT]
movzx edi, word [WIN_POS + edi*2]
cmp edi, [CURRENT_TASK]
jne @f
mov ax,[MOUSE_SCROLL_H]
shl eax,16
mov ax,[MOUSE_SCROLL_V]
mov [esp+36-4],eax
and [MOUSE_SCROLL_H],word 0
and [MOUSE_SCROLL_V],word 0
ret
mov edi, [TASK_COUNT]
movzx edi, word [WIN_POS + edi*2]
cmp edi, [CURRENT_TASK]
jne @f
mov ax, [MOUSE_SCROLL_H]
shl eax, 16
mov ax, [MOUSE_SCROLL_V]
mov [esp+36-4], eax
and [MOUSE_SCROLL_H], word 0
and [MOUSE_SCROLL_V], word 0
ret
@@:
and [esp+36-4],dword 0
and [esp+36-4], dword 0
; ret
msset:
ret
ret
 
app_load_cursor:
cmp ecx, OS_BASE
jae msset
stdcall load_cursor, ecx, edx
mov [esp+36-4], eax
ret
cmp ecx, OS_BASE
jae msset
stdcall load_cursor, ecx, edx
mov [esp+36-4], eax
ret
 
app_set_cursor:
stdcall set_cursor, ecx
mov [esp+36-4], eax
ret
stdcall set_cursor, ecx
mov [esp+36-4], eax
ret
 
app_delete_cursor:
stdcall delete_cursor, ecx
mov [esp+36-4], eax
ret
stdcall delete_cursor, ecx
mov [esp+36-4], eax
ret
 
is_input:
 
push edx
mov dx,word [midisp]
in al,dx
and al,0x80
pop edx
ret
push edx
mov dx, word [midisp]
in al, dx
and al, 0x80
pop edx
ret
 
is_output:
 
push edx
mov dx,word [midisp]
in al,dx
and al,0x40
pop edx
ret
push edx
mov dx, word [midisp]
in al, dx
and al, 0x40
pop edx
ret
 
 
get_mpu_in:
 
push edx
mov dx,word [mididp]
in al,dx
pop edx
ret
push edx
mov dx, word [mididp]
in al, dx
pop edx
ret
 
 
put_mpu_out:
 
push edx
mov dx,word [mididp]
out dx,al
pop edx
ret
push edx
mov dx, word [mididp]
out dx, al
pop edx
ret
 
 
 
1876,52 → 1846,52
align 4
 
sys_midi:
cmp [mididp],0
jnz sm0
mov [esp+36],dword 1
ret
cmp [mididp], 0
jnz sm0
mov [esp+36], dword 1
ret
sm0:
and [esp+36],dword 0
dec ebx
jnz smn1
and [esp+36], dword 0
dec ebx
jnz smn1
; call setuart
su1:
call is_output
test al,al
jnz su1
mov dx,word [midisp]
mov al,0xff
out dx,al
call is_output
test al, al
jnz su1
mov dx, word [midisp]
mov al, 0xff
out dx, al
su2:
mov dx,word [midisp]
mov al,0xff
out dx,al
call is_input
test al,al
jnz su2
call get_mpu_in
cmp al,0xfe
jnz su2
mov dx, word [midisp]
mov al, 0xff
out dx, al
call is_input
test al, al
jnz su2
call get_mpu_in
cmp al, 0xfe
jnz su2
su3:
call is_output
test al,al
jnz su3
mov dx,word [midisp]
mov al,0x3f
out dx,al
ret
call is_output
test al, al
jnz su3
mov dx, word [midisp]
mov al, 0x3f
out dx, al
ret
smn1:
dec ebx
jnz smn2
dec ebx
jnz smn2
sm10:
call get_mpu_in
call is_output
test al,al
jnz sm10
mov al,bl
call put_mpu_out
smn2:
ret
call get_mpu_in
call is_output
test al, al
jnz sm10
mov al, bl
call put_mpu_out
smn2:
ret
 
detect_devices:
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1931,353 → 1901,384
;include 'detect/dev_hdcd.inc'
;include 'detect/sear_par.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ret
ret
 
sys_end:
 
mov ecx, [current_slot]
mov eax, [ecx+APPDATA.tls_base]
test eax, eax
jz @F
mov ecx, [current_slot]
mov eax, [ecx+APPDATA.tls_base]
test eax, eax
jz @F
 
stdcall user_free, eax
stdcall user_free, eax
@@:
 
mov eax,[TASK_BASE]
mov [eax+TASKDATA.state], 3 ; terminate this program
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], 3; terminate this program
 
waitterm: ; wait here for termination
mov ebx,100
call delay_hs
jmp waitterm
waitterm: ; wait here for termination
mov ebx, 100
call delay_hs
jmp waitterm
 
iglobal
align 4
sys_system_table:
dd exit_for_anyone ; 1 = obsolete
dd sysfn_terminate ; 2 = terminate thread
dd sysfn_activate ; 3 = activate window
dd sysfn_getidletime ; 4 = get idle time
dd sysfn_getcpuclock ; 5 = get cpu clock
dd sysfn_saveramdisk ; 6 = save ramdisk
dd sysfn_getactive ; 7 = get active window
dd sysfn_sound_flag ; 8 = get/set sound_flag
dd sysfn_shutdown ; 9 = shutdown with parameter
dd sysfn_minimize ; 10 = minimize window
dd sysfn_getdiskinfo ; 11 = get disk subsystem info
dd sysfn_lastkey ; 12 = get last pressed key
dd sysfn_getversion ; 13 = get kernel version
dd sysfn_waitretrace ; 14 = wait retrace
dd sysfn_centermouse ; 15 = center mouse cursor
dd sysfn_getfreemem ; 16 = get free memory size
dd sysfn_getallmem ; 17 = get total memory size
dd sysfn_terminate2 ; 18 = terminate thread using PID
; instead of slot
dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration
dd sysfn_meminfo ; 20 = get extended memory info
dd sysfn_pid_to_slot ; 21 = get slot number for pid
dd sysfn_min_rest_window ; 22 = minimize and restore any window
dd sysfn_deactivate ; 1 = deactivate window
dd sysfn_terminate ; 2 = terminate thread
dd sysfn_activate ; 3 = activate window
dd sysfn_getidletime ; 4 = get idle time
dd sysfn_getcpuclock ; 5 = get cpu clock
dd sysfn_saveramdisk ; 6 = save ramdisk
dd sysfn_getactive ; 7 = get active window
dd sysfn_sound_flag ; 8 = get/set sound_flag
dd sysfn_shutdown ; 9 = shutdown with parameter
dd sysfn_minimize ; 10 = minimize window
dd sysfn_getdiskinfo ; 11 = get disk subsystem info
dd sysfn_lastkey ; 12 = get last pressed key
dd sysfn_getversion ; 13 = get kernel version
dd sysfn_waitretrace ; 14 = wait retrace
dd sysfn_centermouse ; 15 = center mouse cursor
dd sysfn_getfreemem ; 16 = get free memory size
dd sysfn_getallmem ; 17 = get total memory size
dd sysfn_terminate2 ; 18 = terminate thread using PID
; instead of slot
dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration
dd sysfn_meminfo ; 20 = get extended memory info
dd sysfn_pid_to_slot ; 21 = get slot number for pid
dd sysfn_min_rest_window ; 22 = minimize and restore any window
sysfn_num = ($ - sys_system_table)/4
endg
 
;------------------------------------------------------------------------------
sys_system:
dec ebx
cmp ebx, sysfn_num
jae @f
jmp dword [sys_system_table + ebx*4]
dec ebx
cmp ebx, sysfn_num
jae @f
jmp dword [sys_system_table + ebx*4]
@@:
ret
ret
;------------------------------------------------------------------------------
sysfn_shutdown: ; 18.9 = system shutdown
cmp ecx, 1
jl exit_for_anyone
cmp ecx, 4
jg exit_for_anyone
mov [BOOT_VAR+0x9030], cl
 
 
sysfn_shutdown: ; 18.9 = system shutdown
cmp ecx,1
jl exit_for_anyone
cmp ecx,4
jg exit_for_anyone
mov [BOOT_VAR+0x9030],cl
 
mov eax,[TASK_COUNT]
mov [SYS_SHUTDOWN],al
mov [shutdown_processes],eax
and dword [esp+32], 0
mov eax, [TASK_COUNT]
mov [SYS_SHUTDOWN], al
mov [shutdown_processes], eax
and dword [esp+32], 0
exit_for_anyone:
ret
ret
uglobal
shutdown_processes: dd 0x0
shutdown_processes:
dd 0x0
endg
;------------------------------------------------------------------------------
sysfn_terminate: ; 18.2 = TERMINATE
cmp ecx, 2
jb noprocessterminate
mov edx, [TASK_COUNT]
cmp ecx, edx
ja noprocessterminate
mov eax, [TASK_COUNT]
shl ecx, 5
mov edx, [ecx+CURRENT_TASK+TASKDATA.pid]
add ecx, CURRENT_TASK+TASKDATA.state
cmp byte [ecx], 9
jz noprocessterminate
 
sysfn_terminate: ; 18.2 = TERMINATE
cmp ecx,2
jb noprocessterminate
mov edx,[TASK_COUNT]
cmp ecx,edx
ja noprocessterminate
mov eax,[TASK_COUNT]
shl ecx,5
mov edx,[ecx+CURRENT_TASK+TASKDATA.pid]
add ecx,CURRENT_TASK+TASKDATA.state
cmp byte [ecx], 9
jz noprocessterminate
 
;call MEM_Heap_Lock ;guarantee that process isn't working with heap
mov [ecx],byte 3 ; clear possible i40's
mov [ecx], byte 3; clear possible i40's
;call MEM_Heap_UnLock
 
cmp edx,[application_table_status] ; clear app table stat
jne noatsc
and [application_table_status],0
cmp edx, [application_table_status]; clear app table stat
jne noatsc
and [application_table_status], 0
noatsc:
noprocessterminate:
ret
 
ret
;------------------------------------------------------------------------------
sysfn_terminate2:
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
je .stf
sti
call change_task
jmp .table_status
cli
cmp [application_table_status], 0
je .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
mov eax,ecx
call pid_to_slot
test eax,eax
jz .not_found
mov ecx,eax
cli
call sysfn_terminate
and [application_table_status],0
sti
and dword [esp+32],0
ret
call set_application_table_status
mov eax, ecx
call pid_to_slot
test eax, eax
jz .not_found
mov ecx, eax
cli
call sysfn_terminate
and [application_table_status], 0
sti
and dword [esp+32], 0
ret
.not_found:
mov [application_table_status],0
or dword [esp+32],-1
ret
mov [application_table_status], 0
or dword [esp+32], -1
ret
;------------------------------------------------------------------------------
sysfn_deactivate: ; 18.1 = DEACTIVATE WINDOW
cmp ecx, 2
jb .nowindowdeactivate
cmp ecx, [TASK_COUNT]
ja .nowindowdeactivate
movzx esi, word [WIN_STACK + ecx*2]
cmp esi, 1
je .nowindowdeactivate ; already deactive
 
sysfn_activate: ; 18.3 = ACTIVATE WINDOW
cmp ecx,2
jb .nowindowactivate
cmp ecx,[TASK_COUNT]
ja .nowindowactivate
mov edi, ecx
shl edi, 5
add edi, window_data
movzx esi, word [WIN_STACK + ecx * 2]
lea esi, [WIN_POS + esi * 2]
call window._.window_deactivate
xor eax, eax
mov byte[MOUSE_BACKGROUND], al
mov byte[DONT_DRAW_MOUSE], al
mov byte[MOUSE_DOWN], 0
 
mov [window_minimize], 2 ; restore window if minimized
call syscall_display_settings._.calculate_whole_screen
call syscall_display_settings._.redraw_whole_screen
.nowindowdeactivate:
ret
;------------------------------------------------------------------------------
sysfn_activate: ; 18.3 = ACTIVATE WINDOW
cmp ecx, 2
jb .nowindowactivate
cmp ecx, [TASK_COUNT]
ja .nowindowactivate
 
movzx esi, word [WIN_STACK + ecx*2]
cmp esi, [TASK_COUNT]
je .nowindowactivate ; already active
mov [window_minimize], 2; restore window if minimized
 
mov edi, ecx
shl edi, 5
add edi, window_data
movzx esi, word [WIN_STACK + ecx * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
movzx esi, word [WIN_STACK + ecx*2]
cmp esi, [TASK_COUNT]
je .nowindowactivate; already active
 
mov edi, ecx
shl edi, 5
add edi, window_data
movzx esi, word [WIN_STACK + ecx * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
.nowindowactivate:
ret
 
sysfn_getidletime: ; 18.4 = GET IDLETIME
mov eax,[idleusesec]
mov [esp+32], eax
ret
 
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC
mov eax,[CPU_FREQ]
mov [esp+32], eax
ret
 
ret
;------------------------------------------------------------------------------
sysfn_getidletime: ; 18.4 = GET IDLETIME
mov eax, [idleusesec]
mov [esp+32], eax
ret
;------------------------------------------------------------------------------
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC
mov eax, [CPU_FREQ]
mov [esp+32], eax
ret
;------------------------------------------------------------------------------
; SAVE ramdisk to /hd/1/menuet.img
;!!!!!!!!!!!!!!!!!!!!!!!!
include 'blkdev/rdsave.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!
;------------------------------------------------------------------------------
align 4
sysfn_getactive: ; 18.7 = get active window
mov eax, [TASK_COUNT]
movzx eax, word [WIN_POS + eax*2]
mov [esp+32],eax
ret
 
sysfn_sound_flag: ; 18.8 = get/set sound_flag
sysfn_getactive: ; 18.7 = get active window
mov eax, [TASK_COUNT]
movzx eax, word [WIN_POS + eax*2]
mov [esp+32], eax
ret
;------------------------------------------------------------------------------
sysfn_sound_flag: ; 18.8 = get/set sound_flag
; cmp ecx,1
dec ecx
jnz nogetsoundflag
movzx eax,byte [sound_flag] ; get sound_flag
mov [esp+32],eax
ret
dec ecx
jnz nogetsoundflag
movzx eax, byte [sound_flag]; get sound_flag
mov [esp+32], eax
ret
nogetsoundflag:
; cmp ecx,2
dec ecx
jnz nosoundflag
xor byte [sound_flag], 1
dec ecx
jnz nosoundflag
xor byte [sound_flag], 1
nosoundflag:
ret
 
sysfn_minimize: ; 18.10 = minimize window
mov [window_minimize],1
ret
ret
;------------------------------------------------------------------------------
sysfn_minimize: ; 18.10 = minimize window
mov [window_minimize], 1
ret
;------------------------------------------------------------------------------
align 4
sysfn_getdiskinfo: ; 18.11 = get disk info table
sysfn_getdiskinfo: ; 18.11 = get disk info table
; cmp ecx,1
dec ecx
jnz full_table
dec ecx
jnz full_table
small_table:
call for_all_tables
mov ecx,10
cld
rep movsb
ret
call for_all_tables
mov ecx, 10
cld
rep movsb
ret
for_all_tables:
mov edi,edx
mov esi,DRIVE_DATA
ret
mov edi, edx
mov esi, DRIVE_DATA
ret
full_table:
; cmp ecx,2
dec ecx
jnz exit_for_anyone
call for_all_tables
mov ecx,16384
cld
rep movsd
ret
 
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility)
and dword [esp+32], 0
ret
 
sysfn_getversion: ; 18.13 = get kernel ID and version
mov edi,ebx
mov esi,version_inf
mov ecx,version_end-version_inf
rep movsb
ret
 
dec ecx
jnz exit_for_anyone
call for_all_tables
mov ecx, 16384
cld
rep movsd
ret
;------------------------------------------------------------------------------
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility)
and dword [esp+32], 0
ret
;------------------------------------------------------------------------------
sysfn_getversion: ; 18.13 = get kernel ID and version
mov edi, ecx
mov esi, version_inf
mov ecx, version_end-version_inf
rep movsb
ret
;------------------------------------------------------------------------------
sysfn_waitretrace: ; 18.14 = sys wait retrace
;wait retrace functions
sys_wait_retrace:
mov edx,0x3da
mov edx, 0x3da
WaitRetrace_loop:
in al,dx
test al,1000b
jz WaitRetrace_loop
and [esp+32],dword 0
ret
 
in al, dx
test al, 1000b
jz WaitRetrace_loop
and [esp+32], dword 0
ret
;------------------------------------------------------------------------------
align 4
sysfn_centermouse: ; 18.15 = mouse centered
sysfn_centermouse: ; 18.15 = mouse centered
; removed here by <Lrz>
; call mouse_centered
;* mouse centered - start code- Mario79
;mouse_centered:
; push eax
mov eax,[Screen_Max_X]
shr eax,1
mov [MOUSE_X],ax
mov eax,[Screen_Max_Y]
shr eax,1
mov [MOUSE_Y],ax
mov eax, [Screen_Max_X]
shr eax, 1
mov [MOUSE_X], ax
mov eax, [Screen_Max_Y]
shr eax, 1
mov [MOUSE_Y], ax
; ret
;* mouse centered - end code- Mario79
xor eax,eax
and [esp+32],eax
xor eax, eax
and [esp+32], eax
; pop eax
 
ret
ret
;------------------------------------------------------------------------------
align 4
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
test ecx,ecx ; get mouse speed factor
jnz .set_mouse_acceleration
xor eax,eax
mov ax,[mouse_speed_factor]
mov [esp+32],eax
ret
test ecx, ecx; get mouse speed factor
jnz .set_mouse_acceleration
xor eax, eax
mov ax, [mouse_speed_factor]
mov [esp+32], eax
ret
.set_mouse_acceleration:
; cmp ecx,1 ; set mouse speed factor
dec ecx
jnz .get_mouse_delay
mov [mouse_speed_factor],dx
ret
dec ecx
jnz .get_mouse_delay
mov [mouse_speed_factor], dx
ret
.get_mouse_delay:
; cmp ecx,2 ; get mouse delay
dec ecx
jnz .set_mouse_delay
mov eax,[mouse_delay]
mov [esp+32],eax
ret
dec ecx
jnz .set_mouse_delay
mov eax, [mouse_delay]
mov [esp+32], eax
ret
.set_mouse_delay:
; cmp ecx,3 ; set mouse delay
dec ecx
jnz .set_pointer_position
mov [mouse_delay],edx
ret
dec ecx
jnz .set_pointer_position
mov [mouse_delay], edx
ret
.set_pointer_position:
; cmp ecx,4 ; set mouse pointer position
dec ecx
jnz .set_mouse_button
mov [MOUSE_Y],dx ;y
ror edx,16
mov [MOUSE_X],dx ;x
rol edx,16
ret
dec ecx
jnz .set_mouse_button
cmp dx, word[Screen_Max_Y]
ja .end
rol edx, 16
cmp dx, word[Screen_Max_X]
ja .end
mov [MOUSE_X], edx
ret
.set_mouse_button:
; cmp ecx,5 ; set mouse button features
dec ecx
jnz .end
mov [BTN_DOWN],dl
mov [mouse_active],1
dec ecx
jnz .end
mov [BTN_DOWN], dl
mov [mouse_active], 1
.end:
ret
 
ret
;------------------------------------------------------------------------------
sysfn_getfreemem:
mov eax, [pg_data.pages_free]
shl eax, 2
mov [esp+32],eax
ret
mov eax, [pg_data.pages_free]
shl eax, 2
mov [esp+32], eax
ret
 
sysfn_getallmem:
mov eax,[MEM_AMOUNT]
shr eax, 10
mov [esp+32],eax
ret
mov eax, [MEM_AMOUNT]
shr eax, 10
mov [esp+32], eax
ret
 
; // Alver, 2007-22-08 // {
sysfn_pid_to_slot:
mov eax, ecx
call pid_to_slot
mov [esp+32], eax
ret
mov eax, ecx
call pid_to_slot
mov [esp+32], eax
ret
 
sysfn_min_rest_window:
pushad
mov eax, edx ; ebx - operating
shr ecx, 1
jnc @f
call pid_to_slot
pushad
mov eax, edx ; ebx - operating
shr ecx, 1
jnc @f
call pid_to_slot
@@:
or eax, eax ; eax - number of slot
jz .error
cmp eax, 255 ; varify maximal slot number
ja .error
movzx eax, word [WIN_STACK + eax*2]
shr ecx, 1
jc .restore
or eax, eax ; eax - number of slot
jz .error
cmp eax, 255 ; varify maximal slot number
ja .error
movzx eax, word [WIN_STACK + eax*2]
shr ecx, 1
jc .restore
; .minimize:
call minimize_window
jmp .exit
call minimize_window
jmp .exit
.restore:
call restore_minimized_window
call restore_minimized_window
.exit:
popad
xor eax, eax
mov [esp+32], eax
ret
popad
xor eax, eax
mov [esp+32], eax
ret
.error:
popad
xor eax, eax
dec eax
mov [esp+32], eax
ret
popad
xor eax, eax
dec eax
mov [esp+32], eax
ret
; } \\ Alver, 2007-22-08 \\
 
uglobal
2285,39 → 2286,39
screen_workarea RECT
;// mike.dld, 2006-29-01 ]
window_minimize db 0
sound_flag db 0
sound_flag db 0
endg
 
UID_NONE=0
UID_MENUETOS=1 ;official
UID_KOLIBRI=2 ;russian
 
iglobal
version_inf:
db 0,7,7,0 ; version 0.7.7.0
db UID_KOLIBRI
db 0
dd __REV__
version_end:
endg
 
UID_NONE=0
UID_MENUETOS=1 ;official
UID_KOLIBRI=2 ;russian
 
sys_cachetodiskette:
cmp ebx, 1
jne .no_floppy_a_save
mov [flp_number], 1
jmp .save_image_on_floppy
cmp ebx, 1
jne .no_floppy_a_save
mov [flp_number], 1
jmp .save_image_on_floppy
.no_floppy_a_save:
cmp ebx, 2
jne .no_floppy_b_save
mov [flp_number], 2
cmp ebx, 2
jne .no_floppy_b_save
mov [flp_number], 2
.save_image_on_floppy:
call save_image
mov [esp + 32], dword 0
cmp [FDC_Status], 0
je .yes_floppy_save
call save_image
mov [esp + 32], dword 0
cmp [FDC_Status], 0
je .yes_floppy_save
.no_floppy_b_save:
mov [esp + 32], dword 1
mov [esp + 32], dword 1
.yes_floppy_save:
ret
ret
 
uglobal
; bgrchanged dd 0x0
2328,350 → 2329,346
 
sys_background:
 
cmp ebx,1 ; BACKGROUND SIZE
jnz nosb1
test ecx,ecx
cmp ebx, 1 ; BACKGROUND SIZE
jnz nosb1
test ecx, ecx
; cmp ecx,0
jz sbgrr
test edx,edx
jz sbgrr
test edx, edx
; cmp edx,0
jz sbgrr
jz sbgrr
@@:
;;Maxis use atomic bts for mutexes 4.4.2009
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
@@:
mov [BgrDataWidth],ecx
mov [BgrDataHeight],edx
mov [BgrDataWidth], ecx
mov [BgrDataHeight], edx
; mov [bgrchanged],1
 
pushad
pushad
; return memory for old background
mov eax, [img_background]
cmp eax, static_background_data
jz @f
stdcall kernel_free, eax
mov eax, [img_background]
cmp eax, static_background_data
jz @f
stdcall kernel_free, eax
@@:
; calculate RAW size
xor eax,eax
inc eax
cmp [BgrDataWidth],eax
jae @f
mov [BgrDataWidth],eax
xor eax, eax
inc eax
cmp [BgrDataWidth], eax
jae @f
mov [BgrDataWidth], eax
@@:
cmp [BgrDataHeight],eax
jae @f
mov [BgrDataHeight],eax
cmp [BgrDataHeight], eax
jae @f
mov [BgrDataHeight], eax
@@:
mov eax,[BgrDataWidth]
imul eax,[BgrDataHeight]
lea eax,[eax*3]
mov [mem_BACKGROUND],eax
mov eax, [BgrDataWidth]
imul eax, [BgrDataHeight]
lea eax, [eax*3]
mov [mem_BACKGROUND], eax
; get memory for new background
stdcall kernel_alloc, eax
test eax, eax
jz .memfailed
mov [img_background], eax
jmp .exit
stdcall kernel_alloc, eax
test eax, eax
jz .memfailed
mov [img_background], eax
jmp .exit
.memfailed:
; revert to static monotone data
mov [img_background], static_background_data
xor eax, eax
inc eax
mov [BgrDataWidth], eax
mov [BgrDataHeight], eax
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
xor eax, eax
inc eax
mov [BgrDataWidth], eax
mov [BgrDataHeight], eax
mov [mem_BACKGROUND], 4
.exit:
popad
mov [bgrlock], 0
popad
mov [bgrlock], 0
 
sbgrr:
ret
ret
 
nosb1:
 
cmp ebx,2 ; SET PIXEL
jnz nosb2
cmp ebx, 2 ; SET PIXEL
jnz nosb2
 
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
@@:
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
 
mov ebx,[eax+ecx]
and ebx,0xFF000000 ;255*256*256*256
and edx,0x00FFFFFF ;255*256*256+255*256+255
add edx,ebx
mov [eax+ecx],edx
mov ebx, [eax+ecx]
and ebx, 0xFF000000;255*256*256*256
and edx, 0x00FFFFFF;255*256*256+255*256+255
add edx, ebx
mov [eax+ecx], edx
.ret:
ret
ret
nosb2:
 
cmp ebx,3 ; DRAW BACKGROUND
jnz nosb3
cmp ebx, 3 ; DRAW BACKGROUND
jnz nosb3
draw_background_temp:
; cmp [bgrchanged],1 ;0
; je nosb31
;draw_background_temp:
; mov [bgrchanged],1 ;0
mov [background_defined], 1
call force_redraw_background
mov [REDRAW_BACKGROUND], byte 2
mov [background_defined], 1
mov byte[BACKGROUND_CHANGED], 1
call force_redraw_background
nosb31:
ret
ret
nosb3:
 
cmp ebx,4 ; TILED / STRETCHED
jnz nosb4
cmp ecx,[BgrDrawMode]
je nosb41
mov [BgrDrawMode],ecx
cmp ebx, 4 ; TILED / STRETCHED
jnz nosb4
cmp ecx, [BgrDrawMode]
je nosb41
mov [BgrDrawMode], ecx
; mov [bgrchanged],1
nosb41:
ret
ret
nosb4:
 
cmp ebx,5 ; BLOCK MOVE TO BGR
jnz nosb5
cmp [img_background], static_background_data
jnz @f
test edx, edx
jnz .fin
cmp esi, 4
ja .fin
cmp ebx, 5 ; BLOCK MOVE TO BGR
jnz nosb5
cmp [img_background], static_background_data
jnz @f
test edx, edx
jnz .fin
cmp esi, 4
ja .fin
@@:
; bughere
mov eax, ecx
mov ebx, edx
add ebx, [img_background] ;IMG_BACKGROUND
mov ecx, esi
call memmove
mov eax, ecx
mov ebx, edx
add ebx, [img_background];IMG_BACKGROUND
mov ecx, esi
call memmove
.fin:
ret
ret
nosb5:
 
cmp ebx, 6
jnz nosb6
cmp ebx, 6
jnz nosb6
;;Maxis use atomic bts for mutex 4.4.2009
@@:
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
@@:
mov eax, [CURRENT_TASK]
mov [bgrlockpid], eax
cmp [img_background], static_background_data
jz .nomem
stdcall user_alloc, [mem_BACKGROUND]
mov [esp+32], eax
test eax, eax
jz .nomem
mov ebx, eax
shr ebx, 12
or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK
mov esi, [img_background]
shr esi, 12
mov ecx, [mem_BACKGROUND]
add ecx, 0xFFF
shr ecx, 12
mov eax, [CURRENT_TASK]
mov [bgrlockpid], eax
cmp [img_background], static_background_data
jz .nomem
stdcall user_alloc, [mem_BACKGROUND]
mov [esp+32], eax
test eax, eax
jz .nomem
mov ebx, eax
shr ebx, 12
or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK
mov esi, [img_background]
shr esi, 12
mov ecx, [mem_BACKGROUND]
add ecx, 0xFFF
shr ecx, 12
.z:
mov eax, [page_tabs+ebx*4]
test al, 1
jz @f
call free_page
mov eax, [page_tabs+ebx*4]
test al, 1
jz @f
call free_page
@@:
mov eax, [page_tabs+esi*4]
or al, PG_UW
mov [page_tabs+ebx*4], eax
mov eax, ebx
shl eax, 12
invlpg [eax]
inc ebx
inc esi
loop .z
ret
mov eax, [page_tabs+esi*4]
or al, PG_UW
mov [page_tabs+ebx*4], eax
mov eax, ebx
shl eax, 12
invlpg [eax]
inc ebx
inc esi
loop .z
ret
.nomem:
and [bgrlockpid], 0
mov [bgrlock], 0
and [bgrlockpid], 0
mov [bgrlock], 0
nosb6:
cmp ebx, 7
jnz nosb7
cmp [bgrlock], 0
jz .err
mov eax, [CURRENT_TASK]
cmp [bgrlockpid], eax
jnz .err
mov eax, ecx
mov ebx, ecx
shr eax, 12
mov ecx, [page_tabs+(eax-1)*4]
test cl, USED_BLOCK+DONT_FREE_BLOCK
jz .err
jnp .err
push eax
shr ecx, 12
dec ecx
cmp ebx, 7
jnz nosb7
cmp [bgrlock], 0
jz .err
mov eax, [CURRENT_TASK]
cmp [bgrlockpid], eax
jnz .err
mov eax, ecx
mov ebx, ecx
shr eax, 12
mov ecx, [page_tabs+(eax-1)*4]
test cl, USED_BLOCK+DONT_FREE_BLOCK
jz .err
jnp .err
push eax
shr ecx, 12
dec ecx
@@:
and dword [page_tabs+eax*4], 0
mov edx, eax
shl edx, 12
push eax
invlpg [edx]
pop eax
inc eax
loop @b
pop eax
and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK
stdcall user_free, ebx
mov [esp+32], eax
and [bgrlockpid], 0
mov [bgrlock], 0
ret
and dword [page_tabs+eax*4], 0
mov edx, eax
shl edx, 12
push eax
invlpg [edx]
pop eax
inc eax
loop @b
pop eax
and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK
stdcall user_free, ebx
mov [esp+32], eax
and [bgrlockpid], 0
mov [bgrlock], 0
ret
.err:
and dword [esp+32], 0
ret
and dword [esp+32], 0
ret
 
nosb7:
ret
ret
 
force_redraw_background:
and [draw_data+32 + RECT.left],dword 0
and [draw_data+32 + RECT.top],dword 0
push eax ebx
mov eax,[Screen_Max_X]
mov ebx,[Screen_Max_Y]
mov [draw_data+32 + RECT.right],eax
mov [draw_data+32 + RECT.bottom],ebx
pop ebx eax
mov byte [REDRAW_BACKGROUND], 1
ret
and [draw_data+32 + RECT.left], 0
and [draw_data+32 + RECT.top], 0
push eax ebx
mov eax, [Screen_Max_X]
mov ebx, [Screen_Max_Y]
mov [draw_data+32 + RECT.right], eax
mov [draw_data+32 + RECT.bottom], ebx
pop ebx eax
inc byte[REDRAW_BACKGROUND]
ret
 
align 4
 
sys_getbackground:
; cmp eax,1 ; SIZE
dec ebx
jnz nogb1
mov eax,[BgrDataWidth]
shl eax,16
mov ax,[BgrDataHeight]
mov [esp+32],eax
ret
dec ebx
jnz nogb1
mov eax, [BgrDataWidth]
shl eax, 16
mov ax, [BgrDataHeight]
mov [esp+32], eax
ret
 
nogb1:
; cmp eax,2 ; PIXEL
dec ebx
jnz nogb2
dec ebx
jnz nogb2
 
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
@@:
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
 
mov eax,[ecx+eax]
mov eax, [ecx+eax]
 
and eax, 0xFFFFFF
mov [esp+32],eax
and eax, 0xFFFFFF
mov [esp+32], eax
.ret:
ret
ret
nogb2:
 
; cmp eax,4 ; TILED / STRETCHED
dec ebx
dec ebx
jnz nogb4
mov eax,[BgrDrawMode]
dec ebx
dec ebx
jnz nogb4
mov eax, [BgrDrawMode]
nogb4:
mov [esp+32],eax
ret
mov [esp+32], eax
ret
 
align 4
 
sys_getkey:
mov [esp + 32],dword 1
; test main buffer
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT]
cmp ecx, edx
jne .finish
cmp [KEY_COUNT], byte 0
je .finish
movzx eax, byte [KEY_BUFF]
shl eax, 8
push eax
dec byte [KEY_COUNT]
and byte [KEY_COUNT], 127
movzx ecx, byte [KEY_COUNT]
add ecx, 2
mov eax, KEY_BUFF + 1
mov ebx, KEY_BUFF
call memmove
pop eax
mov [esp + 32], dword 1
; test main buffer
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT]
cmp ecx, edx
jne .finish
cmp [KEY_COUNT], byte 0
je .finish
movzx eax, byte [KEY_BUFF]
shl eax, 8
push eax
dec byte [KEY_COUNT]
and byte [KEY_COUNT], 127
movzx ecx, byte [KEY_COUNT]
add ecx, 2
mov eax, KEY_BUFF + 1
mov ebx, KEY_BUFF
call memmove
pop eax
.ret_eax:
mov [esp + 32], eax
ret
mov [esp + 32], eax
ret
.finish:
; test hotkeys buffer
mov ecx, hotkey_buffer
mov ecx, hotkey_buffer
@@:
cmp [ecx], ebx
jz .found
add ecx, 8
cmp ecx, hotkey_buffer + 120 * 8
jb @b
ret
cmp [ecx], ebx
jz .found
add ecx, 8
cmp ecx, hotkey_buffer + 120 * 8
jb @b
ret
.found:
mov ax, [ecx + 6]
shl eax, 16
mov ah, [ecx + 4]
mov al, 2
and dword [ecx + 4], 0
and dword [ecx], 0
jmp .ret_eax
mov ax, [ecx + 6]
shl eax, 16
mov ah, [ecx + 4]
mov al, 2
and dword [ecx + 4], 0
and dword [ecx], 0
jmp .ret_eax
 
align 4
 
sys_getbutton:
 
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
mov [esp + 32], dword 1
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT] ; less than 256 processes
cmp ecx, edx
jne .exit
movzx eax, byte [BTN_COUNT]
test eax, eax
jz .exit
mov eax, [BTN_BUFF]
shl eax, 8
; // Alver 22.06.2008 // {
mov al, byte [btn_down_determ]
and al,0xFE ; delete left button bit
; } \\ Alver \\
mov [BTN_COUNT], byte 0
mov [esp + 32], eax
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
mov [esp + 32], dword 1
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT] ; less than 256 processes
cmp ecx, edx
jne .exit
movzx eax, byte [BTN_COUNT]
test eax, eax
jz .exit
mov eax, [BTN_BUFF]
and al, 0xFE ; delete left button bit
mov [BTN_COUNT], byte 0
mov [esp + 32], eax
.exit:
ret
ret
 
 
align 4
2689,120 → 2686,125
; +30 dword PID , process idenfification number
;
 
cmp ecx,-1 ; who am I ?
jne .no_who_am_i
mov ecx,[CURRENT_TASK]
cmp ecx, -1 ; who am I ?
jne .no_who_am_i
mov ecx, [CURRENT_TASK]
.no_who_am_i:
cmp ecx, max_processes
ja .nofillbuf
cmp ecx, max_processes
ja .nofillbuf
 
; +4: word: position of the window of thread in the window stack
mov ax, [WIN_STACK + ecx * 2]
mov [ebx+4], ax
mov ax, [WIN_STACK + ecx * 2]
mov [ebx+4], ax
; +6: word: number of the thread slot, which window has in the window stack
; position ecx (has no relation to the specific thread)
mov ax, [WIN_POS + ecx * 2]
mov [ebx+6], ax
mov ax, [WIN_POS + ecx * 2]
mov [ebx+6], ax
 
shl ecx, 5
shl ecx, 5
 
; +0: dword: memory usage
mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage]
mov [ebx], eax
mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage]
mov [ebx], eax
; +10: 11 bytes: name of the process
push ecx
lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name]
add ebx, 10
mov ecx, 11
call memmove
pop ecx
push ecx
lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name]
add ebx, 10
mov ecx, 11
call memmove
pop ecx
 
; +22: address of the process in memory
; +26: size of used memory - 1
push edi
lea edi, [ebx+12]
xor eax, eax
mov edx, 0x100000*16
cmp ecx, 1 shl 5
je .os_mem
mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size]
mov eax, std_application_base_address
push edi
lea edi, [ebx+12]
xor eax, eax
mov edx, 0x100000*16
cmp ecx, 1 shl 5
je .os_mem
mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size]
mov eax, std_application_base_address
.os_mem:
stosd
lea eax, [edx-1]
stosd
stosd
lea eax, [edx-1]
stosd
 
; +30: PID/TID
mov eax, [ecx+CURRENT_TASK+TASKDATA.pid]
stosd
mov eax, [ecx+CURRENT_TASK+TASKDATA.pid]
stosd
 
; window position and size
push esi
lea esi, [ecx + window_data + WDATA.box]
movsd
movsd
movsd
movsd
push esi
lea esi, [ecx + window_data + WDATA.box]
movsd
movsd
movsd
movsd
 
; Process state (+50)
mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state]
stosd
mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state]
stosd
 
; Window client area box
lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox]
movsd
movsd
movsd
movsd
lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox]
movsd
movsd
movsd
movsd
 
; Window state
mov al, [ecx+window_data+WDATA.fl_wstate]
stosb
mov al, [ecx+window_data+WDATA.fl_wstate]
stosb
 
pop esi
pop edi
; Event mask (+71)
mov EAX, dword [ECX+CURRENT_TASK+TASKDATA.event_mask]
stosd
 
pop esi
pop edi
 
.nofillbuf:
; return number of processes
 
mov eax,[TASK_COUNT]
mov [esp+32],eax
ret
mov eax, [TASK_COUNT]
mov [esp+32], eax
ret
 
align 4
sys_clock:
cli
cli
; Mikhail Lisovin xx Jan 2005
@@: mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
@@:
mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
@@:
; end Lisovin's fix
 
xor al,al ; seconds
out 0x70,al
in al,0x71
movzx ecx,al
mov al,02 ; minutes
shl ecx,16
out 0x70,al
in al,0x71
movzx edx,al
mov al,04 ; hours
shl edx,8
out 0x70,al
in al,0x71
add ecx,edx
movzx edx,al
add ecx,edx
sti
mov [esp + 32], ecx
ret
xor al, al ; seconds
out 0x70, al
in al, 0x71
movzx ecx, al
mov al, 02 ; minutes
shl ecx, 16
out 0x70, al
in al, 0x71
movzx edx, al
mov al, 04 ; hours
shl edx, 8
out 0x70, al
in al, 0x71
add ecx, edx
movzx edx, al
add ecx, edx
sti
mov [esp + 32], ecx
ret
 
 
align 4
2809,570 → 2811,92
 
sys_date:
 
cli
@@: mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
cli
@@:
mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
@@:
 
mov ch,0
mov al,7 ; date
out 0x70,al
in al,0x71
mov cl,al
mov al,8 ; month
shl ecx,16
out 0x70,al
in al,0x71
mov ch,al
mov al,9 ; year
out 0x70,al
in al,0x71
mov cl,al
sti
mov [esp+32], ecx
ret
mov ch, 0
mov al, 7 ; date
out 0x70, al
in al, 0x71
mov cl, al
mov al, 8 ; month
shl ecx, 16
out 0x70, al
in al, 0x71
mov ch, al
mov al, 9 ; year
out 0x70, al
in al, 0x71
mov cl, al
sti
mov [esp+32], ecx
ret
 
 
; redraw status
 
sys_redrawstat:
cmp ebx, 1
jne no_widgets_away
; buttons away
mov ecx,[CURRENT_TASK]
cmp ebx, 1
jne no_widgets_away
; buttons away
mov ecx, [CURRENT_TASK]
sys_newba2:
mov edi,[BTN_ADDR]
cmp [edi], dword 0 ; empty button list ?
je end_of_buttons_away
movzx ebx, word [edi]
inc ebx
mov eax,edi
mov edi, [BTN_ADDR]
cmp [edi], dword 0 ; empty button list ?
je end_of_buttons_away
movzx ebx, word [edi]
inc ebx
mov eax, edi
sys_newba:
dec ebx
jz end_of_buttons_away
dec ebx
jz end_of_buttons_away
 
add eax, 0x10
cmp cx, [eax]
jnz sys_newba
add eax, 0x10
cmp cx, [eax]
jnz sys_newba
 
push eax ebx ecx
mov ecx,ebx
inc ecx
shl ecx, 4
mov ebx, eax
add eax, 0x10
call memmove
dec dword [edi]
pop ecx ebx eax
push eax ebx ecx
mov ecx, ebx
inc ecx
shl ecx, 4
mov ebx, eax
add eax, 0x10
call memmove
dec dword [edi]
pop ecx ebx eax
 
jmp sys_newba2
jmp sys_newba2
 
end_of_buttons_away:
 
ret
ret
 
no_widgets_away:
 
cmp ebx, 2
jnz srl1
cmp ebx, 2
jnz srl1
 
mov edx, [TASK_BASE] ; return whole screen draw area for this app
add edx, draw_data - CURRENT_TASK
mov [edx + RECT.left], 0
mov [edx + RECT.top], 0
mov eax, [Screen_Max_X]
mov [edx + RECT.right], eax
mov eax, [Screen_Max_Y]
mov [edx + RECT.bottom], eax
mov edx, [TASK_BASE] ; return whole screen draw area for this app
add edx, draw_data - CURRENT_TASK
mov [edx + RECT.left], 0
mov [edx + RECT.top], 0
mov eax, [Screen_Max_X]
mov [edx + RECT.right], eax
mov eax, [Screen_Max_Y]
mov [edx + RECT.bottom], eax
 
mov edi, [TASK_BASE]
or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app
call sys_window_mouse
ret
 
srl1:
ret
ret
 
 
sys_drawwindow:
 
mov eax,edx
shr eax,16+8
and eax,15
 
; cmp eax,0 ; type I - original style
jne nosyswI
inc [mouse_pause]
call [_display.disable_mouse]
call sys_set_window
call [_display.disable_mouse]
call drawwindow_I
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswI:
 
cmp al,1 ; type II - only reserve area, no draw
jne nosyswII
inc [mouse_pause]
call [_display.disable_mouse]
call sys_set_window
call [_display.disable_mouse]
call sys_window_mouse
dec [mouse_pause]
call [draw_pointer]
ret
nosyswII:
 
cmp al,2 ; type III - new style
jne nosyswIII
inc [mouse_pause]
call [_display.disable_mouse]
call sys_set_window
call [_display.disable_mouse]
call drawwindow_III
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswIII:
 
cmp al,3 ; type IV - skinned window
je draw_skin_window
cmp al,4 ; type V - skinned window not sized! {not_sized_skin_window}
jne nosyswV
draw_skin_window:
 
inc [mouse_pause]
call [_display.disable_mouse]
call sys_set_window
call [_display.disable_mouse]
mov eax, [TASK_COUNT]
movzx eax, word [WIN_POS + eax*2]
cmp eax, [CURRENT_TASK]
setz al
movzx eax, al
push eax
call drawwindow_IV
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswV:
 
ret
 
 
draw_window_caption:
inc [mouse_pause]
call [_display.disable_mouse]
 
xor eax,eax
mov edx,[TASK_COUNT]
movzx edx,word[WIN_POS+edx*2]
cmp edx,[CURRENT_TASK]
jne @f
inc eax
@@: mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx ebx,[edx+WDATA.fl_wstyle]
and bl,0x0F
cmp bl,3
je .draw_caption_style_3 ;{for 3 and 4 style write caption}
cmp bl,4
je .draw_caption_style_3
 
jmp .not_style_3
.draw_caption_style_3:
 
push edx
call drawwindow_IV_caption
add esp,4
jmp .2
 
.not_style_3:
cmp bl,2
jne .not_style_2
 
call drawwindow_III_caption
jmp .2
 
.not_style_2:
cmp bl,0
jne .2
 
call drawwindow_I_caption
 
;--------------------------------------------------------------
.2: ;jmp @f
mov edi,[CURRENT_TASK]
shl edi,5
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION
jz @f
mov edx,[edi*8+SLOT_BASE+APPDATA.wnd_caption]
or edx,edx
jz @f
 
movzx eax,[edi+window_data+WDATA.fl_wstyle]
and al,0x0F
cmp al,3
je .skinned
cmp al,4
je .skinned
 
jmp .not_skinned
.skinned:
mov ebp,[edi+window_data+WDATA.box.left-2]
mov bp,word[edi+window_data+WDATA.box.top]
movzx eax,word[edi+window_data+WDATA.box.width]
sub ax,[_skinmargins.left]
sub ax,[_skinmargins.right]
push edx
cwde
cdq
mov ebx,6
idiv ebx
pop edx
or eax,eax
js @f
mov esi,eax
mov ebx,dword[_skinmargins.left-2]
mov bx,word[_skinh]
sub bx,[_skinmargins.bottom]
sub bx,[_skinmargins.top]
sar bx,1
adc bx,0
add bx,[_skinmargins.top]
add bx,-3
add ebx,ebp
jmp .dodraw
 
.not_skinned:
cmp al,1
je @f
 
mov ebp,[edi+window_data+WDATA.box.left-2]
mov bp,word[edi+window_data+WDATA.box.top]
movzx eax,word[edi+window_data+WDATA.box.width]
sub eax,16
push edx
cwde
cdq
mov ebx,6
idiv ebx
pop edx
or eax,eax
js @f
mov esi,eax
mov ebx,0x00080007
add ebx,ebp
.dodraw:
mov ecx,[common_colours+16];0x00FFFFFF
or ecx, 0x80000000
xor edi,edi
; // Alver 22.06.2008 // {
; call dtext
call dtext_asciiz_esi
; } \\ Alver \\
 
@@:
;--------------------------------------------------------------
dec [mouse_pause]
call [draw_pointer]
ret
 
iglobal
align 4
window_topleft dd \
1, 21,\ ;type 0
0, 0,\ ;type 1
5, 20,\ ;type 2
5, ?,\ ;type 3 {set by skin}
5, ? ;type 4 {set by skin}
endg
 
set_window_clientbox:
push eax ecx edi
 
mov eax,[_skinh]
mov [window_topleft+4*7],eax
mov [window_topleft+4*9],eax
 
mov ecx,edi
sub edi,window_data
shl edi,3
test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE
jz @f
 
movzx eax,[ecx+WDATA.fl_wstyle]
and eax,0x0F
mov eax,[eax*8+window_topleft+0]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax
shl eax,1
neg eax
add eax,[ecx+WDATA.box.width]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax
 
movzx eax,[ecx+WDATA.fl_wstyle]
and eax,0x0F
push [eax*8+window_topleft+0]
mov eax,[eax*8+window_topleft+4]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax
neg eax
sub eax,[esp]
add eax,[ecx+WDATA.box.height]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax
add esp,4
 
pop edi ecx eax
ret
@@:
xor eax,eax
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax
mov eax,[ecx+WDATA.box.width]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax
mov eax,[ecx+WDATA.box.height]
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax
 
pop edi ecx eax
ret
 
sys_set_window:
 
mov eax,[CURRENT_TASK]
shl eax,5
add eax,window_data
 
; colors
mov [eax+WDATA.cl_workarea],edx
mov [eax+WDATA.cl_titlebar],esi
mov [eax+WDATA.cl_frames],edi
 
mov edi, eax
 
; check flag (?)
test [edi+WDATA.fl_wdrawn],1
jnz newd
 
mov eax,[timer_ticks] ;[0xfdf0]
add eax,100
mov [new_window_starting],eax
 
movsx eax,bx
mov [edi+WDATA.box.width],eax
movsx eax,cx
mov [edi+WDATA.box.height],eax
sar ebx,16
sar ecx,16
mov [edi+WDATA.box.left],ebx
mov [edi+WDATA.box.top],ecx
 
call check_window_position
 
push ecx esi edi ; save for window fullscreen/resize
;mov esi,edi
 
mov cl, [edi+WDATA.fl_wstyle]
mov eax, [edi+WDATA.cl_frames]
 
sub edi,window_data
shl edi,3
add edi,SLOT_BASE
 
and cl,0x0F
mov [edi+APPDATA.wnd_caption],0
cmp cl,3
je set_APPDATA_wnd_caption
cmp cl,4 ; {SPraid.simba}
je set_APPDATA_wnd_caption
 
jmp @f
set_APPDATA_wnd_caption:
mov [edi+APPDATA.wnd_caption],eax
@@: mov esi,[esp+0]
 
add edi, APPDATA.saved_box
movsd
movsd
movsd
movsd
pop edi esi ecx
 
mov esi, [CURRENT_TASK]
movzx esi, word [WIN_STACK+esi*2]
lea esi, [WIN_POS+esi*2]
call waredraw
 
;;; mov ebx, 1
;;; call delay_hs
mov eax, [edi+WDATA.box.left]
mov ebx, [edi+WDATA.box.top]
mov ecx, [edi+WDATA.box.width]
mov edx, [edi+WDATA.box.height]
add ecx, eax
add edx, ebx
call calculatescreen
 
mov [KEY_COUNT],byte 0 ; empty keyboard buffer
mov [BTN_COUNT],byte 0 ; empty button buffer
 
newd:
call set_window_clientbox
 
mov [edi+WDATA.fl_redraw],byte 0 ; no redraw
mov edx,edi
 
ret
 
syscall_windowsettings:
 
.set_window_caption:
dec ebx ; subfunction #1 - set window caption
jnz .exit_fail
 
; NOTE: only window owner thread can set its caption,
; so there's no parameter for PID/TID
 
mov edi,[CURRENT_TASK]
shl edi,5
 
; have to check if caption is within application memory limit
; check is trivial, and if application resizes its memory,
; caption still can become over bounds
; diamond, 31.10.2006: check removed because with new memory manager
; there can be valid data after APPDATA.mem_size bound
; mov ecx,[edi*8+SLOT_BASE+APPDATA.mem_size]
; add ecx,255 ; max caption length
; cmp ebx,ecx
; ja .exit_fail
 
mov [edi*8+SLOT_BASE+APPDATA.wnd_caption],ecx
or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION
 
call draw_window_caption
 
xor eax,eax ; eax = 0 (success)
ret
 
; .get_window_caption:
; dec eax ; subfunction #2 - get window caption
; jnz .exit_fail
 
; not implemented yet
 
.exit_fail:
xor eax,eax
inc eax ; eax = 1 (fail)
ret
 
 
sys_window_move:
 
mov edi,[CURRENT_TASK]
shl edi,5
add edi,window_data
 
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jnz .window_move_return
 
push dword [edi + WDATA.box.left] ; save old coordinates
push dword [edi + WDATA.box.top]
push dword [edi + WDATA.box.width]
push dword [edi + WDATA.box.height]
 
cmp eax,-1 ; set new position and size
je .no_x_reposition
mov [edi + WDATA.box.left], eax
.no_x_reposition:
cmp ebx,-1
je .no_y_reposition
mov [edi + WDATA.box.top], ebx
.no_y_reposition:
 
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
jnz .no_y_resizing
 
cmp ecx,-1
je .no_x_resizing
mov [edi + WDATA.box.width], ecx
.no_x_resizing:
cmp edx,-1
je .no_y_resizing
mov [edi + WDATA.box.height], edx
.no_y_resizing:
 
call check_window_position
call set_window_clientbox
 
pushad ; save for window fullscreen/resize
mov esi,edi
sub edi,window_data
shr edi,5
shl edi,8
add edi, SLOT_BASE + APPDATA.saved_box
mov ecx,4
cld
rep movsd
popad
 
pushad ; calculcate screen at new position
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx,eax
add edx,ebx
 
call calculatescreen
popad
 
pop edx ; calculcate screen at old position
pop ecx
pop ebx
pop eax
add ecx,eax
add edx,ebx
mov [draw_limits.left],eax ; save for drawlimits
mov [draw_limits.top],ebx
mov [draw_limits.right],ecx
mov [draw_limits.bottom],edx
call calculatescreen
 
mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw
 
mov eax,edi ; redraw screen at old position
xor esi,esi
call redrawscreen
 
mov [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
 
call [draw_pointer]
 
mov [window_move_pr],0
 
.window_move_return:
 
ret
 
uglobal
window_move_pr dd 0x0
window_move_eax dd 0x0
window_move_ebx dd 0x0
window_move_ecx dd 0x0
window_move_edx dd 0x0
endg
 
;ok - 100% work
;nt - not tested
;---------------------------------------------------------------------------------------------
3393,108 → 2917,108
iglobal
align 4
sheduler:
dd sys_sheduler.00
dd change_task
dd sys_sheduler.02
dd sys_sheduler.03
dd sys_sheduler.04
dd sys_sheduler.00
dd change_task
dd sys_sheduler.02
dd sys_sheduler.03
dd sys_sheduler.04
endg
sys_sheduler:
sys_sheduler:
;rewritten by <Lrz> 29.12.2009
jmp dword [sheduler+ebx*4]
jmp dword [sheduler+ebx*4]
;.shed_counter:
.00:
mov eax,[context_counter]
mov [esp+32],eax
ret
mov eax, [context_counter]
mov [esp+32], eax
ret
 
.02:
;.perf_control:
inc ebx ;before ebx=2, ebx=3
cmp ebx,ecx ;if ecx=3, ebx=3
jz cache_disable
inc ebx ;before ebx=2, ebx=3
cmp ebx, ecx ;if ecx=3, ebx=3
jz cache_disable
 
dec ebx ;ebx=2
cmp ebx,ecx ;
jz cache_enable ;if ecx=2 and ebx=2
dec ebx ;ebx=2
cmp ebx, ecx ;
jz cache_enable ;if ecx=2 and ebx=2
 
dec ebx ;ebx=1
cmp ebx,ecx
jz is_cache_enabled ;if ecx=1 and ebx=1
dec ebx ;ebx=1
cmp ebx, ecx
jz is_cache_enabled ;if ecx=1 and ebx=1
 
dec ebx
test ebx,ecx ;ebx=0 and ecx=0
jz modify_pce ;if ecx=0
dec ebx
test ebx, ecx ;ebx=0 and ecx=0
jz modify_pce ;if ecx=0
 
ret
ret
 
.03:
.03:
;.rdmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
mov eax,esi
mov ecx,edx
rdmsr
mov [esp+32],eax
mov [esp+20],edx ;ret in ebx?
ret
mov eax, esi
mov ecx, edx
rdmsr
mov [esp+32], eax
mov [esp+20], edx ;ret in ebx?
ret
 
.04:
;.wrmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
; Fast Call MSR can't be destroy
; ® MSR_AMD_EFER ¬®¦­® ¨§¬¥­ïâì, â.ª. ¢ í⮬ ॣ¨áâॠ«¨è
; ¢ª«îç îâáï/¢ëª«îç îâáï à áè¨à¥­­ë¥ ¢®§¬®¦­®áâ¨
cmp edx,MSR_SYSENTER_CS
je @f
cmp edx,MSR_SYSENTER_ESP
je @f
cmp edx,MSR_SYSENTER_EIP
je @f
cmp edx,MSR_AMD_STAR
je @f
; Fast Call MSR can't be destroy
; ® MSR_AMD_EFER ¬®¦­® ¨§¬¥­ïâì, â.ª. ¢ í⮬ ॣ¨áâॠ«¨è
; ¢ª«îç îâáï/¢ëª«îç îâáï à áè¨à¥­­ë¥ ¢®§¬®¦­®áâ¨
cmp edx, MSR_SYSENTER_CS
je @f
cmp edx, MSR_SYSENTER_ESP
je @f
cmp edx, MSR_SYSENTER_EIP
je @f
cmp edx, MSR_AMD_STAR
je @f
 
mov eax,esi
mov ecx,edx
wrmsr
; mov [esp + 32], eax
; mov [esp + 20], edx ;ret in ebx?
mov eax, esi
mov ecx, edx
wrmsr
; mov [esp + 32], eax
; mov [esp + 20], edx ;ret in ebx?
@@:
ret
ret
 
cache_disable:
mov eax,cr0
or eax,01100000000000000000000000000000b
mov cr0,eax
wbinvd ;set MESI
ret
mov eax, cr0
or eax, 01100000000000000000000000000000b
mov cr0, eax
wbinvd ;set MESI
ret
 
cache_enable:
mov eax,cr0
and eax,10011111111111111111111111111111b
mov cr0,eax
ret
mov eax, cr0
and eax, 10011111111111111111111111111111b
mov cr0, eax
ret
 
is_cache_enabled:
mov eax,cr0
mov ebx,eax
and eax,01100000000000000000000000000000b
jz cache_disabled
mov [esp+32],ebx
mov eax, cr0
mov ebx, eax
and eax, 01100000000000000000000000000000b
jz cache_disabled
mov [esp+32], ebx
cache_disabled:
mov dword [esp+32],eax ;0
ret
mov dword [esp+32], eax;0
ret
 
modify_pce:
mov eax,cr4
mov eax, cr4
; mov ebx,0
; or bx,100000000b ;pce
; xor eax,ebx ;invert pce
bts eax,8 ;pce=cr4[8]
mov cr4,eax
mov [esp+32],eax
ret
bts eax, 8;pce=cr4[8]
mov cr4, eax
mov [esp+32], eax
ret
;---------------------------------------------------------------------------------------------
 
 
3501,21 → 3025,21
; check if pixel is allowed to be drawn
 
checkpixel:
push eax edx
push eax edx
 
mov edx,[Screen_Max_X] ; screen x size
inc edx
imul edx, ebx
add eax, [_WinMapAddress]
mov dl, [eax+edx] ; lea eax, [...]
mov edx, [Screen_Max_X] ; screen x size
inc edx
imul edx, ebx
add eax, [_WinMapAddress]
mov dl, [eax+edx]; lea eax, [...]
 
xor ecx, ecx
mov eax, [CURRENT_TASK]
cmp al, dl
setne cl
xor ecx, ecx
mov eax, [CURRENT_TASK]
cmp al, dl
setne cl
 
pop edx eax
ret
pop edx eax
ret
 
iglobal
cpustring db 'CPU',0
3522,7 → 3046,7
endg
 
uglobal
background_defined db 0 ; diamond, 11.04.2006
background_defined db 0 ; diamond, 11.04.2006
endg
 
align 4
3530,39 → 3054,40
 
checkmisc:
 
cmp [ctrl_alt_del], 1
jne nocpustart
cmp [ctrl_alt_del], 1
jne nocpustart
 
mov ebp, cpustring
call fs_execute_from_sysdir
mov ebp, cpustring
call fs_execute_from_sysdir
 
mov [ctrl_alt_del], 0
mov [ctrl_alt_del], 0
 
nocpustart:
cmp [mouse_active], 1
jne mouse_not_active
mov [mouse_active], 0
xor edi, edi
mov ecx, [TASK_COUNT]
cmp [mouse_active], 1
jne mouse_not_active
mov [mouse_active], 0
xor edi, edi
mov ecx, [TASK_COUNT]
set_mouse_event:
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b
loop set_mouse_event
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b
loop set_mouse_event
 
mouse_not_active:
cmp [REDRAW_BACKGROUND],byte 0 ; background update ?
jz nobackgr
cmp [background_defined], 0
jz nobackgr
cmp [REDRAW_BACKGROUND], byte 2
jnz no_set_bgr_event
xor edi, edi
mov ecx, [TASK_COUNT]
cmp byte[BACKGROUND_CHANGED], 0
jz no_set_bgr_event
xor edi, edi
mov ecx, [TASK_COUNT]
set_bgr_event:
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], 16
loop set_bgr_event
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], 16
loop set_bgr_event
mov byte[BACKGROUND_CHANGED], 0
no_set_bgr_event:
cmp byte[REDRAW_BACKGROUND], 0 ; background update ?
jz nobackgr
cmp [background_defined], 0
jz nobackgr
; mov [draw_data+32 + RECT.left],dword 0
; mov [draw_data+32 + RECT.top],dword 0
; mov eax,[Screen_Max_X]
3569,57 → 3094,65
; mov ebx,[Screen_Max_Y]
; mov [draw_data+32 + RECT.right],eax
; mov [draw_data+32 + RECT.bottom],ebx
call drawbackground
mov [REDRAW_BACKGROUND],byte 0
mov [MOUSE_BACKGROUND],byte 0
@@:
call drawbackground
xor eax, eax
xchg al, [REDRAW_BACKGROUND]
test al, al ; got new update request?
jnz @b
mov [draw_data+32 + RECT.left], eax
mov [draw_data+32 + RECT.top], eax
mov [draw_data+32 + RECT.right], eax
mov [draw_data+32 + RECT.bottom], eax
mov [MOUSE_BACKGROUND], byte 0
 
nobackgr:
 
; system shutdown request
 
cmp [SYS_SHUTDOWN],byte 0
je noshutdown
cmp [SYS_SHUTDOWN], byte 0
je noshutdown
 
mov edx,[shutdown_processes]
mov edx, [shutdown_processes]
 
cmp [SYS_SHUTDOWN],dl
jne no_mark_system_shutdown
cmp [SYS_SHUTDOWN], dl
jne no_mark_system_shutdown
 
lea ecx,[edx-1]
mov edx,OS_BASE+0x3040
jecxz @f
lea ecx, [edx-1]
mov edx, OS_BASE+0x3040
jecxz @f
markz:
mov [edx+TASKDATA.state],byte 3
add edx,0x20
loop markz
mov [edx+TASKDATA.state], byte 3
add edx, 0x20
loop markz
@@:
 
no_mark_system_shutdown:
 
call [_display.disable_mouse]
call [_display.disable_mouse]
 
dec byte [SYS_SHUTDOWN]
je system_shutdown
dec byte [SYS_SHUTDOWN]
je system_shutdown
 
noshutdown:
 
 
mov eax,[TASK_COUNT] ; termination
mov ebx,TASK_DATA+TASKDATA.state
mov esi,1
mov eax, [TASK_COUNT] ; termination
mov ebx, TASK_DATA+TASKDATA.state
mov esi, 1
 
newct:
mov cl,[ebx]
cmp cl,byte 3
jz terminate
cmp cl,byte 4
jz terminate
mov cl, [ebx]
cmp cl, byte 3
jz terminate
cmp cl, byte 4
jz terminate
 
add ebx,0x20
inc esi
dec eax
jnz newct
ret
add ebx, 0x20
inc esi
dec eax
jnz newct
ret
 
; redraw screen
 
3627,145 → 3160,151
 
; eax , if process window_data base is eax, do not set flag/limits
 
pushad
push eax
pushad
push eax
 
;;; mov ebx,2
;;; call delay_hs
 
;mov ecx,0 ; redraw flags for apps
xor ecx,ecx
;mov ecx,0 ; redraw flags for apps
xor ecx, ecx
newdw2:
 
inc ecx
push ecx
inc ecx
push ecx
 
mov eax,ecx
shl eax,5
add eax,window_data
mov eax, ecx
shl eax, 5
add eax, window_data
 
cmp eax,[esp+4]
je not_this_task
; check if window in redraw area
mov edi,eax
cmp eax, [esp+4]
je not_this_task
; check if window in redraw area
mov edi, eax
 
cmp ecx,1 ; limit for background
jz bgli
cmp ecx, 1 ; limit for background
jz bgli
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx,eax
add edx,ebx
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
 
mov ecx,[draw_limits.bottom] ; ecx = area y end ebx = window y start
cmp ecx,ebx
jb ricino
mov ecx, [draw_limits.bottom] ; ecx = area y end ebx = window y start
cmp ecx, ebx
jb ricino
 
mov ecx,[draw_limits.right] ; ecx = area x end eax = window x start
cmp ecx,eax
jb ricino
mov ecx, [draw_limits.right] ; ecx = area x end eax = window x start
cmp ecx, eax
jb ricino
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
 
mov eax,[draw_limits.top] ; eax = area y start edx = window y end
cmp edx,eax
jb ricino
mov eax, [draw_limits.top] ; eax = area y start edx = window y end
cmp edx, eax
jb ricino
 
mov eax,[draw_limits.left] ; eax = area x start ecx = window x end
cmp ecx,eax
jb ricino
mov eax, [draw_limits.left] ; eax = area x start ecx = window x end
cmp ecx, eax
jb ricino
 
bgli:
bgli:
 
cmp ecx,1
jnz .az
mov al,[REDRAW_BACKGROUND]
cmp al,2
jz newdw8
test al,al
jz .az
lea eax,[edi+draw_data-window_data]
mov ebx,[draw_limits.left]
cmp ebx,[eax+RECT.left]
jae @f
mov [eax+RECT.left],ebx
@@:
mov ebx,[draw_limits.top]
cmp ebx,[eax+RECT.top]
jae @f
mov [eax+RECT.top],ebx
@@:
mov ebx,[draw_limits.right]
cmp ebx,[eax+RECT.right]
jbe @f
mov [eax+RECT.right],ebx
@@:
mov ebx,[draw_limits.bottom]
cmp ebx,[eax+RECT.bottom]
jbe @f
mov [eax+RECT.bottom],ebx
@@:
jmp newdw8
.az:
cmp dword[esp], 1
jnz .az
; cmp byte[BACKGROUND_CHANGED], 0
; jnz newdw8
cmp byte[REDRAW_BACKGROUND], 0
jz .az
mov dl, 0
lea eax, [edi+draw_data-window_data]
mov ebx, [draw_limits.left]
cmp ebx, [eax+RECT.left]
jae @f
mov [eax+RECT.left], ebx
mov dl, 1
@@:
mov ebx, [draw_limits.top]
cmp ebx, [eax+RECT.top]
jae @f
mov [eax+RECT.top], ebx
mov dl, 1
@@:
mov ebx, [draw_limits.right]
cmp ebx, [eax+RECT.right]
jbe @f
mov [eax+RECT.right], ebx
mov dl, 1
@@:
mov ebx, [draw_limits.bottom]
cmp ebx, [eax+RECT.bottom]
jbe @f
mov [eax+RECT.bottom], ebx
mov dl, 1
@@:
add byte[REDRAW_BACKGROUND], dl
jmp newdw8
.az:
 
mov eax,edi
add eax,draw_data-window_data
mov eax, edi
add eax, draw_data-window_data
 
mov ebx,[draw_limits.left] ; set limits
mov [eax + RECT.left], ebx
mov ebx,[draw_limits.top]
mov [eax + RECT.top], ebx
mov ebx,[draw_limits.right]
mov [eax + RECT.right], ebx
mov ebx,[draw_limits.bottom]
mov [eax + RECT.bottom], ebx
mov ebx, [draw_limits.left] ; set limits
mov [eax + RECT.left], ebx
mov ebx, [draw_limits.top]
mov [eax + RECT.top], ebx
mov ebx, [draw_limits.right]
mov [eax + RECT.right], ebx
mov ebx, [draw_limits.bottom]
mov [eax + RECT.bottom], ebx
 
sub eax,draw_data-window_data
sub eax, draw_data-window_data
 
cmp dword [esp],1
jne nobgrd
mov byte [REDRAW_BACKGROUND], 1
cmp dword [esp], 1
jne nobgrd
inc byte[REDRAW_BACKGROUND]
 
newdw8:
nobgrd:
 
mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw
mov [eax + WDATA.fl_redraw], byte 1 ; mark as redraw
 
ricino:
 
not_this_task:
 
pop ecx
pop ecx
 
cmp ecx,[TASK_COUNT]
jle newdw2
cmp ecx, [TASK_COUNT]
jle newdw2
 
pop eax
popad
pop eax
popad
 
ret
ret
 
calculatebackground: ; background
 
mov edi, [_WinMapAddress] ; set os to use all pixels
mov eax,0x01010101
mov ecx, [_WinMapSize]
shr ecx, 2
rep stosd
mov edi, [_WinMapAddress] ; set os to use all pixels
mov eax, 0x01010101
mov ecx, [_WinMapSize]
shr ecx, 2
rep stosd
 
mov byte [REDRAW_BACKGROUND], 0 ; do not draw background!
mov byte[REDRAW_BACKGROUND], 0 ; do not draw background!
mov byte[BACKGROUND_CHANGED], 0
 
ret
ret
 
uglobal
imax dd 0x0
imax dd 0x0
endg
 
 
3773,96 → 3312,97
delay_ms: ; delay in 1/1000 sec
 
 
push eax
push ecx
push eax
push ecx
 
mov ecx,esi
; <CPU clock fix by Sergey Kuzmin aka Wildwest>
imul ecx, 33941
shr ecx, 9
; </CPU clock fix>
mov ecx, esi
; <CPU clock fix by Sergey Kuzmin aka Wildwest>
imul ecx, 33941
shr ecx, 9
; </CPU clock fix>
 
in al,0x61
and al,0x10
mov ah,al
cld
in al, 0x61
and al, 0x10
mov ah, al
cld
 
cnt1: in al,0x61
and al,0x10
cmp al,ah
jz cnt1
cnt1:
in al, 0x61
and al, 0x10
cmp al, ah
jz cnt1
 
mov ah,al
loop cnt1
mov ah, al
loop cnt1
 
pop ecx
pop eax
pop ecx
pop eax
 
ret
ret
 
 
set_app_param:
mov edi, [TASK_BASE]
mov eax, [edi + TASKDATA.event_mask]
mov [edi + TASKDATA.event_mask], ebx
mov [esp+32], eax
ret
mov edi, [TASK_BASE]
mov eax, [edi + TASKDATA.event_mask]
mov [edi + TASKDATA.event_mask], ebx
mov [esp+32], eax
ret
 
 
 
delay_hs: ; delay in 1/100 secs
; ebx = delay time
push ecx
push edx
push ecx
push edx
 
mov edx,[timer_ticks]
mov edx, [timer_ticks]
 
newtic:
mov ecx,[timer_ticks]
sub ecx,edx
cmp ecx,ebx
jae zerodelay
mov ecx, [timer_ticks]
sub ecx, edx
cmp ecx, ebx
jae zerodelay
 
call change_task
call change_task
 
jmp newtic
jmp newtic
 
zerodelay:
pop edx
pop ecx
pop edx
pop ecx
 
ret
ret
 
align 16 ;very often call this subrutine
align 16 ;very often call this subrutine
memmove: ; memory move in bytes
 
; eax = from
; ebx = to
; ecx = no of bytes
test ecx, ecx
jle .ret
test ecx, ecx
jle .ret
 
push esi edi ecx
push esi edi ecx
 
mov edi, ebx
mov esi, eax
mov edi, ebx
mov esi, eax
 
test ecx, not 11b
jz @f
test ecx, not 11b
jz @f
 
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 11b
jz .finish
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 11b
jz .finish
@@:
rep movsb
rep movsb
 
.finish:
pop ecx edi esi
pop ecx edi esi
.ret:
ret
ret
 
 
; <diamond> Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead.
3914,106 → 3454,9
 
 
align 4
 
sys_programirq:
 
mov eax, [TASK_BASE]
add ebx, [eax + TASKDATA.mem_start]
 
cmp ecx, 16
jae .not_owner
mov edi, [eax + TASKDATA.pid]
cmp edi, [irq_owner + 4 * ecx]
je .spril1
.not_owner:
xor ecx, ecx
inc ecx
jmp .end
.spril1:
 
shl ecx, 6
mov esi, ebx
lea edi, [irq00read + ecx]
push 16
pop ecx
 
cld
rep movsd
.end:
mov [esp+32], ecx
ret
 
 
align 4
 
get_irq_data:
movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data
xor bh, bh
cmp ebx, 16
jae .not_owner
mov edx, [4 * ebx + irq_owner] ; check for irq owner
 
mov eax,[TASK_BASE]
 
cmp edx,[eax+TASKDATA.pid]
je gidril1
.not_owner:
xor edx, edx
dec edx
jmp gid1
 
gidril1:
 
shl ebx, 12
lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size
mov edx, [eax] ; + 0x4 - data offset
dec esi
jz gid1
test edx, edx ; check if buffer is empty
jz gid1
 
mov ebx, [eax + 0x4]
mov edi, ecx
 
mov ecx, 4000 ; buffer size, used frequently
 
cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again
jb @f
 
xor ebx, ebx
 
@@:
 
lea esi, [ebx + edx] ; calculate data size and offset
cld
cmp esi, ecx ; if greater than the buffer size, begin cycle again
jbe @f
 
sub ecx, ebx
sub edx, ecx
 
lea esi, [eax + ebx + 0x10]
rep movsb
 
xor ebx, ebx
@@:
lea esi, [eax + ebx + 0x10]
mov ecx, edx
add ebx, edx
 
rep movsb
mov edx, [eax]
mov [eax], ecx ; set data size to zero
mov [eax + 0x4], ebx ; set data offset
 
gid1:
mov [esp+32], edx ; eax
ret
 
 
set_io_access_rights:
push edi eax
mov edi, tss._io_map_0
push edi eax
mov edi, tss._io_map_0
; mov ecx,eax
; and ecx,7 ; offset in byte
; shr eax,3 ; number of byte
4020,19 → 3463,19
; add edi,eax
; mov ebx,1
; shl ebx,cl
test ebp,ebp
test ebp, ebp
; cmp ebp,0 ; enable access - ebp = 0
jnz siar1
jnz .siar1
; not ebx
; and [edi],byte bl
btr [edi], eax
pop eax edi
ret
siar1:
bts [edi], eax
btr [edi], eax
pop eax edi
ret
.siar1:
bts [edi], eax
; or [edi],byte bl ; disable access - ebp = 1
pop eax edi
ret
pop eax edi
ret
;reserve/free group of ports
; * eax = 46 - number function
; * ebx = 0 - reserve, 1 - free
4039,7 → 3482,7
; * ecx = number start arrea of ports
; * edx = number end arrea of ports (include last number of port)
;Return value:
; * eax = 0 - succesful
; * eax = 0 - succesful
; * eax = 1 - error
; * The system has reserve this ports:
; 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (include last number of port).
4046,8 → 3489,8
;destroys eax,ebx, ebp
r_f_port_area:
 
test ebx, ebx
jnz free_port_area
test ebx, ebx
jnz free_port_area
; je r_port_area
; jmp free_port_area
 
4055,267 → 3498,202
 
; pushad
 
cmp ecx,edx ; beginning > end ?
ja rpal1
cmp edx,65536
jae rpal1
mov eax,[RESERVED_PORTS]
test eax,eax ; no reserved areas ?
je rpal2
cmp eax,255 ; max reserved
jae rpal1
cmp ecx, edx ; beginning > end ?
ja rpal1
cmp edx, 65536
jae rpal1
mov eax, [RESERVED_PORTS]
test eax, eax ; no reserved areas ?
je rpal2
cmp eax, 255 ; max reserved
jae rpal1
rpal3:
mov ebx,eax
shl ebx,4
add ebx,RESERVED_PORTS
cmp ecx,[ebx+8]
ja rpal4
cmp edx,[ebx+4]
jae rpal1
mov ebx, eax
shl ebx, 4
add ebx, RESERVED_PORTS
cmp ecx, [ebx+8]
ja rpal4
cmp edx, [ebx+4]
jae rpal1
; jb rpal4
; jmp rpal1
rpal4:
dec eax
jnz rpal3
jmp rpal2
dec eax
jnz rpal3
jmp rpal2
rpal1:
; popad
; mov eax,1
xor eax,eax
inc eax
ret
xor eax, eax
inc eax
ret
rpal2:
; popad
; enable port access at port IO map
cli
pushad ; start enable io map
cli
pushad ; start enable io map
 
cmp edx,65536 ;16384
jae no_unmask_io ; jge
mov eax,ecx
cmp edx, 65536;16384
jae no_unmask_io; jge
mov eax, ecx
; push ebp
xor ebp,ebp ; enable - eax = port
xor ebp, ebp ; enable - eax = port
new_port_access:
; pushad
call set_io_access_rights
call set_io_access_rights
; popad
inc eax
cmp eax,edx
jbe new_port_access
inc eax
cmp eax, edx
jbe new_port_access
; pop ebp
no_unmask_io:
popad ; end enable io map
sti
popad ; end enable io map
sti
 
mov eax,[RESERVED_PORTS]
add eax,1
mov [RESERVED_PORTS],eax
shl eax,4
add eax,RESERVED_PORTS
mov ebx,[TASK_BASE]
mov ebx,[ebx+TASKDATA.pid]
mov [eax],ebx
mov [eax+4],ecx
mov [eax+8],edx
mov eax, [RESERVED_PORTS]
add eax, 1
mov [RESERVED_PORTS], eax
shl eax, 4
add eax, RESERVED_PORTS
mov ebx, [TASK_BASE]
mov ebx, [ebx+TASKDATA.pid]
mov [eax], ebx
mov [eax+4], ecx
mov [eax+8], edx
 
xor eax, eax
ret
xor eax, eax
ret
 
free_port_area:
 
; pushad
mov eax,[RESERVED_PORTS] ; no reserved areas ?
test eax,eax
jz frpal2
mov ebx,[TASK_BASE]
mov ebx,[ebx+TASKDATA.pid]
mov eax, [RESERVED_PORTS]; no reserved areas ?
test eax, eax
jz frpal2
mov ebx, [TASK_BASE]
mov ebx, [ebx+TASKDATA.pid]
frpal3:
mov edi,eax
shl edi,4
add edi,RESERVED_PORTS
cmp ebx,[edi]
jne frpal4
cmp ecx,[edi+4]
jne frpal4
cmp edx,[edi+8]
jne frpal4
jmp frpal1
mov edi, eax
shl edi, 4
add edi, RESERVED_PORTS
cmp ebx, [edi]
jne frpal4
cmp ecx, [edi+4]
jne frpal4
cmp edx, [edi+8]
jne frpal4
jmp frpal1
frpal4:
dec eax
jnz frpal3
dec eax
jnz frpal3
frpal2:
; popad
inc eax
ret
inc eax
ret
frpal1:
push ecx
mov ecx,256
sub ecx,eax
shl ecx,4
mov esi,edi
add esi,16
cld
rep movsb
push ecx
mov ecx, 256
sub ecx, eax
shl ecx, 4
mov esi, edi
add esi, 16
cld
rep movsb
 
dec dword [RESERVED_PORTS]
dec dword [RESERVED_PORTS]
;popad
;disable port access at port IO map
 
; pushad ; start disable io map
pop eax ;start port
cmp edx,65536 ;16384
jge no_mask_io
pop eax ;start port
cmp edx, 65536;16384
jge no_mask_io
 
; mov eax,ecx
xor ebp,ebp
inc ebp
xor ebp, ebp
inc ebp
new_port_access_disable:
; pushad
; mov ebp,1 ; disable - eax = port
call set_io_access_rights
call set_io_access_rights
; popad
inc eax
cmp eax,edx
jbe new_port_access_disable
inc eax
cmp eax, edx
jbe new_port_access_disable
no_mask_io:
; popad ; end disable io map
xor eax, eax
ret
xor eax, eax
ret
 
 
reserve_free_irq:
 
xor esi, esi
inc esi
cmp ecx, 16
jae ril1
 
push ecx
lea ecx, [irq_owner + 4 * ecx]
mov edx, [ecx]
mov eax, [TASK_BASE]
mov edi, [eax + TASKDATA.pid]
pop eax
dec ebx
jnz reserve_irq
 
cmp edx, edi
jne ril1
dec esi
mov [ecx], esi
 
jmp ril1
 
reserve_irq:
 
cmp dword [ecx], 0
jne ril1
 
mov ebx, [f_irqs + 4 * eax]
 
stdcall attach_int_handler, eax, ebx, dword 0
 
mov [ecx], edi
 
dec esi
ril1:
mov [esp+32], esi ; return in eax
ret
 
iglobal
f_irqs:
dd 0x0
dd 0x0
dd p_irq2
dd p_irq3
dd p_irq4
dd p_irq5
dd p_irq6
dd p_irq7
dd p_irq8
dd p_irq9
dd p_irq10
dd p_irq11
dd 0x0
dd 0x0
dd p_irq14
dd p_irq15
 
endg
 
align 4
drawbackground:
inc [mouse_pause]
cmp [SCR_MODE],word 0x12
je dbrv20
inc [mouse_pause]
cmp [SCR_MODE], word 0x12
je dbrv20
dbrv12:
cmp [SCR_MODE],word 0100000000000000b
jge dbrv20
cmp [SCR_MODE],word 0x13
je dbrv20
call vesa12_drawbackground
dec [mouse_pause]
call [draw_pointer]
ret
cmp [SCR_MODE], word 0100000000000000b
jge dbrv20
cmp [SCR_MODE], word 0x13
je dbrv20
call vesa12_drawbackground
dec [mouse_pause]
call [draw_pointer]
ret
dbrv20:
cmp [BgrDrawMode],dword 1
jne bgrstr
call vesa20_drawbackground_tiled
dec [mouse_pause]
call [draw_pointer]
ret
cmp [BgrDrawMode], dword 1
jne bgrstr
call vesa20_drawbackground_tiled
dec [mouse_pause]
call [draw_pointer]
ret
bgrstr:
call vesa20_drawbackground_stretch
dec [mouse_pause]
call [draw_pointer]
ret
call vesa20_drawbackground_stretch
dec [mouse_pause]
call [draw_pointer]
ret
 
align 4
 
syscall_putimage: ; PutImage
syscall_putimage: ; PutImage
sys_putimage:
test ecx,0x80008000
jnz .exit
test ecx,0x0000FFFF
jz .exit
test ecx,0xFFFF0000
jnz @f
test ecx, 0x80008000
jnz .exit
test ecx, 0x0000FFFF
jz .exit
test ecx, 0xFFFF0000
jnz @f
.exit:
ret
ret
@@:
mov edi,[current_slot]
add dx,word[edi+APPDATA.wnd_clientbox.top]
rol edx,16
add dx,word[edi+APPDATA.wnd_clientbox.left]
rol edx,16
mov edi, [current_slot]
add dx, word[edi+APPDATA.wnd_clientbox.top]
rol edx, 16
add dx, word[edi+APPDATA.wnd_clientbox.left]
rol edx, 16
.forced:
push ebp esi 0
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
push ebp esi 0
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
sys_putimage_bpp:
; call [disable_mouse] ; this will be done in xxx_putimage
; mov eax, vga_putimage
cmp [SCR_MODE], word 0x12
jz @f ;.doit
mov eax, vesa12_putimage
cmp [SCR_MODE], word 0100000000000000b
jae @f
cmp [SCR_MODE], word 0x13
jnz .doit
cmp [SCR_MODE], word 0x12
jz @f ;.doit
mov eax, vesa12_putimage
cmp [SCR_MODE], word 0100000000000000b
jae @f
cmp [SCR_MODE], word 0x13
jnz .doit
@@:
mov eax, vesa20_putimage
mov eax, vesa20_putimage
.doit:
inc [mouse_pause]
call eax
dec [mouse_pause]
pop ebp esi ebp
jmp [draw_pointer]
 
syscall_putimage_palette:
mov edi, esi
mov esi, edx
mov edx, ecx
mov ecx, ebx
mov ebx, eax
inc [mouse_pause]
call eax
dec [mouse_pause]
pop ebp esi ebp
jmp [draw_pointer]
align 4
sys_putimage_palette:
; ebx = pointer to image
; ecx = [xsize]*65536 + [ysize]
4323,326 → 3701,326
; esi = number of bits per pixel, must be 8, 24 or 32
; edi = pointer to palette
; ebp = row delta
mov eax, [CURRENT_TASK]
shl eax, 8
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol edx, 16
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol edx, 16
mov eax, [CURRENT_TASK]
shl eax, 8
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol edx, 16
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol edx, 16
.forced:
cmp esi, 1
jnz @f
push edi
mov eax, [edi+4]
sub eax, [edi]
push eax
push dword [edi]
push 0ffffff80h
mov edi, esp
call put_mono_image
add esp, 12
pop edi
ret
cmp esi, 1
jnz @f
push edi
mov eax, [edi+4]
sub eax, [edi]
push eax
push dword [edi]
push 0ffffff80h
mov edi, esp
call put_mono_image
add esp, 12
pop edi
ret
@@:
cmp esi, 2
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_2bit_image
pop eax
pop edi
ret
cmp esi, 2
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_2bit_image
pop eax
pop edi
ret
@@:
cmp esi, 4
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_4bit_image
pop eax
pop edi
ret
cmp esi, 4
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_4bit_image
pop eax
pop edi
ret
@@:
push ebp esi ebp
cmp esi, 8
jnz @f
mov ebp, putimage_get8bpp
mov esi, putimage_init8bpp
jmp sys_putimage_bpp
push ebp esi ebp
cmp esi, 8
jnz @f
mov ebp, putimage_get8bpp
mov esi, putimage_init8bpp
jmp sys_putimage_bpp
@@:
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
mov esi, putimage_init15bpp
jmp sys_putimage_bpp
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
mov esi, putimage_init15bpp
jmp sys_putimage_bpp
@@:
cmp esi, 16
jnz @f
mov ebp, putimage_get16bpp
mov esi, putimage_init16bpp
jmp sys_putimage_bpp
cmp esi, 16
jnz @f
mov ebp, putimage_get16bpp
mov esi, putimage_init16bpp
jmp sys_putimage_bpp
@@:
cmp esi, 24
jnz @f
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
jmp sys_putimage_bpp
cmp esi, 24
jnz @f
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
jmp sys_putimage_bpp
@@:
cmp esi, 32
jnz @f
mov ebp, putimage_get32bpp
mov esi, putimage_init32bpp
jmp sys_putimage_bpp
cmp esi, 32
jnz @f
mov ebp, putimage_get32bpp
mov esi, putimage_init32bpp
jmp sys_putimage_bpp
@@:
pop ebp esi ebp
ret
pop ebp esi ebp
ret
 
put_mono_image:
push ebp esi ebp
mov ebp, putimage_get1bpp
mov esi, putimage_init1bpp
jmp sys_putimage_bpp
push ebp esi ebp
mov ebp, putimage_get1bpp
mov esi, putimage_init1bpp
jmp sys_putimage_bpp
put_2bit_image:
push ebp esi ebp
mov ebp, putimage_get2bpp
mov esi, putimage_init2bpp
jmp sys_putimage_bpp
push ebp esi ebp
mov ebp, putimage_get2bpp
mov esi, putimage_init2bpp
jmp sys_putimage_bpp
put_4bit_image:
push ebp esi ebp
mov ebp, putimage_get4bpp
mov esi, putimage_init4bpp
jmp sys_putimage_bpp
push ebp esi ebp
mov ebp, putimage_get4bpp
mov esi, putimage_init4bpp
jmp sys_putimage_bpp
 
putimage_init24bpp:
lea eax, [eax*3]
lea eax, [eax*3]
putimage_init8bpp:
ret
ret
 
align 16
putimage_get24bpp:
movzx eax, byte [esi+2]
shl eax, 16
mov ax, [esi]
add esi, 3
ret 4
movzx eax, byte [esi+2]
shl eax, 16
mov ax, [esi]
add esi, 3
ret 4
align 16
putimage_get8bpp:
movzx eax, byte [esi]
push edx
mov edx, [esp+8]
mov eax, [edx+eax*4]
pop edx
inc esi
ret 4
movzx eax, byte [esi]
push edx
mov edx, [esp+8]
mov eax, [edx+eax*4]
pop edx
inc esi
ret 4
 
putimage_init1bpp:
add eax, ecx
push ecx
add eax, 7
add ecx, 7
shr eax, 3
shr ecx, 3
sub eax, ecx
pop ecx
ret
add eax, ecx
push ecx
add eax, 7
add ecx, 7
shr eax, 3
shr ecx, 3
sub eax, ecx
pop ecx
ret
align 16
putimage_get1bpp:
push edx
mov edx, [esp+8]
mov al, [edx]
add al, al
jnz @f
lodsb
adc al, al
push edx
mov edx, [esp+8]
mov al, [edx]
add al, al
jnz @f
lodsb
adc al, al
@@:
mov [edx], al
sbb eax, eax
and eax, [edx+8]
add eax, [edx+4]
pop edx
ret 4
mov [edx], al
sbb eax, eax
and eax, [edx+8]
add eax, [edx+4]
pop edx
ret 4
 
putimage_init2bpp:
add eax, ecx
push ecx
add ecx, 3
add eax, 3
shr ecx, 2
shr eax, 2
sub eax, ecx
pop ecx
ret
add eax, ecx
push ecx
add ecx, 3
add eax, 3
shr ecx, 2
shr eax, 2
sub eax, ecx
pop ecx
ret
align 16
putimage_get2bpp:
push edx
mov edx, [esp+8]
mov al, [edx]
mov ah, al
shr al, 6
shl ah, 2
jnz .nonewbyte
lodsb
mov ah, al
shr al, 6
shl ah, 2
add ah, 1
push edx
mov edx, [esp+8]
mov al, [edx]
mov ah, al
shr al, 6
shl ah, 2
jnz .nonewbyte
lodsb
mov ah, al
shr al, 6
shl ah, 2
add ah, 1
.nonewbyte:
mov [edx], ah
mov edx, [edx+4]
movzx eax, al
mov eax, [edx+eax*4]
pop edx
ret 4
mov [edx], ah
mov edx, [edx+4]
movzx eax, al
mov eax, [edx+eax*4]
pop edx
ret 4
 
putimage_init4bpp:
add eax, ecx
push ecx
add ecx, 1
add eax, 1
shr ecx, 1
shr eax, 1
sub eax, ecx
pop ecx
ret
add eax, ecx
push ecx
add ecx, 1
add eax, 1
shr ecx, 1
shr eax, 1
sub eax, ecx
pop ecx
ret
align 16
putimage_get4bpp:
push edx
mov edx, [esp+8]
add byte [edx], 80h
jc @f
movzx eax, byte [edx+1]
mov edx, [edx+4]
and eax, 0x0F
mov eax, [edx+eax*4]
pop edx
ret 4
push edx
mov edx, [esp+8]
add byte [edx], 80h
jc @f
movzx eax, byte [edx+1]
mov edx, [edx+4]
and eax, 0x0F
mov eax, [edx+eax*4]
pop edx
ret 4
@@:
movzx eax, byte [esi]
add esi, 1
mov [edx+1], al
shr eax, 4
mov edx, [edx+4]
mov eax, [edx+eax*4]
pop edx
ret 4
movzx eax, byte [esi]
add esi, 1
mov [edx+1], al
shr eax, 4
mov edx, [edx+4]
mov eax, [edx+eax*4]
pop edx
ret 4
 
putimage_init32bpp:
shl eax, 2
ret
shl eax, 2
ret
align 16
putimage_get32bpp:
lodsd
ret 4
lodsd
ret 4
 
putimage_init15bpp:
putimage_init16bpp:
add eax, eax
ret
add eax, eax
ret
align 16
putimage_get15bpp:
; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x1F shl 5
and edx, 0x1F shl 10
shl eax, 3
shl ecx, 6
shl edx, 9
or eax, ecx
or eax, edx
pop edx ecx
ret 4
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x1F shl 5
and edx, 0x1F shl 10
shl eax, 3
shl ecx, 6
shl edx, 9
or eax, ecx
or eax, edx
pop edx ecx
ret 4
 
align 16
putimage_get16bpp:
; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x3F shl 5
and edx, 0x1F shl 11
shl eax, 3
shl ecx, 5
shl edx, 8
or eax, ecx
or eax, edx
pop edx ecx
ret 4
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x3F shl 5
and edx, 0x1F shl 11
shl eax, 3
shl ecx, 5
shl edx, 8
or eax, ecx
or eax, edx
pop edx ecx
ret 4
 
; eax x beginning
; ebx y beginning
; ecx x end
; edx y end
; edx y end
; edi color
 
__sys_drawbar:
mov esi,[current_slot]
add eax,[esi+APPDATA.wnd_clientbox.left]
add ecx,[esi+APPDATA.wnd_clientbox.left]
add ebx,[esi+APPDATA.wnd_clientbox.top]
add edx,[esi+APPDATA.wnd_clientbox.top]
mov esi, [current_slot]
add eax, [esi+APPDATA.wnd_clientbox.left]
add ecx, [esi+APPDATA.wnd_clientbox.left]
add ebx, [esi+APPDATA.wnd_clientbox.top]
add edx, [esi+APPDATA.wnd_clientbox.top]
.forced:
inc [mouse_pause]
inc [mouse_pause]
; call [disable_mouse]
cmp [SCR_MODE],word 0x12
je dbv20
cmp [SCR_MODE], word 0x12
je dbv20
sdbv20:
cmp [SCR_MODE],word 0100000000000000b
jge dbv20
cmp [SCR_MODE],word 0x13
je dbv20
call vesa12_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
cmp [SCR_MODE], word 0100000000000000b
jge dbv20
cmp [SCR_MODE], word 0x13
je dbv20
call vesa12_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
dbv20:
call vesa20_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
call vesa20_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
 
 
 
kb_read:
 
push ecx edx
push ecx edx
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kr_loop:
in al,0x64
test al,1
jnz kr_ready
loop kr_loop
mov ah,1
jmp kr_exit
in al, 0x64
test al, 1
jnz kr_ready
loop kr_loop
mov ah, 1
jmp kr_exit
kr_ready:
push ecx
mov ecx,32
push ecx
mov ecx, 32
kr_delay:
loop kr_delay
pop ecx
in al,0x60
xor ah,ah
loop kr_delay
pop ecx
in al, 0x60
xor ah, ah
kr_exit:
 
pop edx ecx
pop edx ecx
 
ret
ret
 
 
kb_write:
 
push ecx edx
push ecx edx
 
mov dl,al
mov dl, al
; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
; kw_loop1:
; in al,0x64
4652,211 → 4030,154
; mov ah,1
; jmp kw_exit
; kw_ok1:
in al,0x60
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
in al, 0x60
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kw_loop:
in al,0x64
test al,2
jz kw_ok
loop kw_loop
mov ah,1
jmp kw_exit
in al, 0x64
test al, 2
jz kw_ok
loop kw_loop
mov ah, 1
jmp kw_exit
kw_ok:
mov al,dl
out 0x60,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
mov al, dl
out 0x60, al
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kw_loop3:
in al,0x64
test al,2
jz kw_ok3
loop kw_loop3
mov ah,1
jmp kw_exit
in al, 0x64
test al, 2
jz kw_ok3
loop kw_loop3
mov ah, 1
jmp kw_exit
kw_ok3:
mov ah,8
mov ah, 8
kw_loop4:
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
kw_loop5:
in al,0x64
test al,1
jnz kw_ok4
loop kw_loop5
dec ah
jnz kw_loop4
in al, 0x64
test al, 1
jnz kw_ok4
loop kw_loop5
dec ah
jnz kw_loop4
kw_ok4:
xor ah,ah
xor ah, ah
kw_exit:
 
pop edx ecx
pop edx ecx
 
ret
ret
 
 
kb_cmd:
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
c_wait:
in al,0x64
test al,2
jz c_send
loop c_wait
jmp c_error
in al, 0x64
test al, 2
jz c_send
loop c_wait
jmp c_error
c_send:
mov al,bl
out 0x64,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
mov al, bl
out 0x64, al
mov ecx, 0x1ffff; last 0xffff, new value in view of fast CPU's
c_accept:
in al,0x64
test al,2
jz c_ok
loop c_accept
in al, 0x64
test al, 2
jz c_ok
loop c_accept
c_error:
mov ah,1
jmp c_exit
mov ah, 1
jmp c_exit
c_ok:
xor ah,ah
xor ah, ah
c_exit:
ret
ret
 
 
setmouse: ; set mousepicture -pointer
; ps2 mouse enable
; ps2 mouse enable
 
mov [MOUSE_PICTURE],dword mousepointer
mov [MOUSE_PICTURE], dword mousepointer
 
cli
cli
 
ret
ret
 
if used _rdtsc
_rdtsc:
bt [cpu_caps], CAPS_TSC
jnc ret_rdtsc
rdtsc
ret
bt [cpu_caps], CAPS_TSC
jnc ret_rdtsc
rdtsc
ret
ret_rdtsc:
mov edx,0xffffffff
mov eax,0xffffffff
ret
mov edx, 0xffffffff
mov eax, 0xffffffff
ret
end if
 
rerouteirqs:
 
cli
 
mov al,0x11 ; icw4, edge triggered
out 0x20,al
call pic_delay
out 0xA0,al
call pic_delay
 
mov al,0x20 ; generate 0x20 +
out 0x21,al
call pic_delay
mov al,0x28 ; generate 0x28 +
out 0xA1,al
call pic_delay
 
mov al,0x04 ; slave at irq2
out 0x21,al
call pic_delay
mov al,0x02 ; at irq9
out 0xA1,al
call pic_delay
 
mov al,0x01 ; 8086 mode
out 0x21,al
call pic_delay
out 0xA1,al
call pic_delay
 
mov al,255 ; mask all irq's
out 0xA1,al
call pic_delay
out 0x21,al
call pic_delay
 
mov ecx,0x1000
cld
picl1: call pic_delay
loop picl1
 
mov al,255 ; mask all irq's
out 0xA1,al
call pic_delay
out 0x21,al
call pic_delay
 
cli
 
ret
 
 
pic_delay:
 
jmp pdl1
pdl1: ret
 
 
sys_msg_board_str:
 
pushad
pushad
@@:
cmp [esi],byte 0
je @f
mov eax,1
movzx ebx,byte [esi]
call sys_msg_board
inc esi
jmp @b
cmp [esi], byte 0
je @f
mov eax, 1
movzx ebx, byte [esi]
call sys_msg_board
inc esi
jmp @b
@@:
popad
ret
popad
ret
 
sys_msg_board_byte:
; in: al = byte to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 2
shl eax, 24
jmp @f
pushad
mov ecx, 2
shl eax, 24
jmp @f
 
sys_msg_board_word:
; in: ax = word to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 4
shl eax, 16
jmp @f
pushad
mov ecx, 4
shl eax, 16
jmp @f
 
sys_msg_board_dword:
; in: eax = dword to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 8
pushad
mov ecx, 8
@@:
push ecx
rol eax, 4
push eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
mov bl, al
xor eax, eax
inc eax
call sys_msg_board
pop eax
pop ecx
loop @b
popad
ret
push ecx
rol eax, 4
push eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
mov bl, al
xor eax, eax
inc eax
call sys_msg_board
pop eax
pop ecx
loop @b
popad
ret
 
uglobal
msg_board_data: times 4096 db 0
msg_board_data:
times 4096 db 0
msg_board_count dd 0x0
endg
 
4865,83 → 4186,94
; eax=1 : write : bl byte to write
; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al
 
mov ecx, [msg_board_count]
cmp eax, 1
jne .smbl1
mov ecx, [msg_board_count]
cmp eax, 1
jne .smbl1
 
if defined debug_com_base
 
push dx ax
push dx ax
 
@@: ; Wait for empty transmit register (yes, this slows down system..)
mov dx, debug_com_base+5
in al, dx
test al, 1 shl 5
jz @r
@@: ; Wait for empty transmit register (yes, this slows down system..)
mov dx, debug_com_base+5
in al, dx
test al, 1 shl 5
jz @r
 
mov dx, debug_com_base ; Output the byte
mov al, bl
out dx, al
mov dx, debug_com_base ; Output the byte
mov al, bl
out dx, al
 
pop ax dx
pop ax dx
 
end if
 
mov [msg_board_data+ecx],bl
inc ecx
and ecx, 4095
mov [msg_board_count], ecx
mov [check_idle_semaphore], 5
ret
mov [msg_board_data+ecx], bl
inc ecx
and ecx, 4095
mov [msg_board_count], ecx
mov [check_idle_semaphore], 5
ret
.smbl1:
cmp eax, 2
jne .smbl2
test ecx, ecx
jz .smbl21
mov eax, msg_board_data+1
mov ebx, msg_board_data
movzx edx, byte [ebx]
call memmove
dec [msg_board_count]
mov [esp + 36], edx ;eax
mov [esp + 24], dword 1
ret
cmp eax, 2
jne .smbl2
test ecx, ecx
jz .smbl21
mov eax, msg_board_data+1
mov ebx, msg_board_data
movzx edx, byte [ebx]
call memmove
dec [msg_board_count]
mov [esp + 36], edx ;eax
mov [esp + 24], dword 1
ret
.smbl21:
mov [esp+36], ecx
mov [esp+24], ecx
mov [esp+36], ecx
mov [esp+24], ecx
.smbl2:
ret
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 66 sys function. ;;
;; in eax=66,ebx in [0..5],ecx,edx ;;
;; out eax ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
align 4
f66call:
dd sys_process_def.1 ; 1 = set keyboard mode
dd sys_process_def.2 ; 2 = get keyboard mode
dd sys_process_def.3 ; 3 = get keyboard ctrl, alt, shift
dd sys_process_def.4
dd sys_process_def.5
endg
 
 
sys_process_def:
mov edi, [CURRENT_TASK]
 
dec eax ; 1 = set keyboard mode
jne no_set_keyboard_setup
 
shl edi,8
mov [edi+SLOT_BASE + APPDATA.keyboard_mode],bl
sys_process_def:
dec ebx
cmp ebx, 5
jae .not_support ;if >=6 then or eax,-1
 
ret
mov edi, [CURRENT_TASK]
jmp dword [f66call+ebx*4]
 
no_set_keyboard_setup:
.not_support:
or eax, -1
ret
 
dec eax ; 2 = get keyboard mode
jne no_get_keyboard_setup
.1:
shl edi, 8
mov [edi+SLOT_BASE + APPDATA.keyboard_mode], cl
 
shl edi,8
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode]
ret
 
mov [esp+36],eax
 
ret
 
no_get_keyboard_setup:
 
dec eax ; 3 = get keyboard ctrl, alt, shift
jne no_get_keyboard_cas
 
.2: ; 2 = get keyboard mode
shl edi, 8
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode]
mov [esp+32], eax
ret
; xor eax,eax
; movzx eax,byte [shift]
; movzx ebx,byte [ctrl]
4950,285 → 4282,273
; movzx ebx,byte [alt]
; shl ebx,3
; add eax,ebx
 
.3: ;3 = get keyboard ctrl, alt, shift
;// mike.dld [
mov eax, [kb_state]
mov eax, [kb_state]
;// mike.dld ]
mov [esp+32], eax
ret
 
mov [esp+36],eax
 
ret
 
no_get_keyboard_cas:
 
dec eax
jnz no_add_keyboard_hotkey
 
mov eax, hotkey_list
.4:
mov eax, hotkey_list
@@:
cmp dword [eax+8], 0
jz .found_free
add eax, 16
cmp eax, hotkey_list+16*256
jb @b
mov dword [esp+36], 1
ret
cmp dword [eax+8], 0
jz .found_free
add eax, 16
cmp eax, hotkey_list+16*256
jb @b
mov dword [esp+32], 1
ret
.found_free:
mov [eax+8], edi
mov [eax+4], ecx
movzx ebx, bl
lea ebx, [hotkey_scancodes+ebx*4]
mov ecx, [ebx]
mov [eax], ecx
mov [ebx], eax
mov [eax+12], ebx
jecxz @f
mov [ecx+12], eax
mov [eax+8], edi
mov [eax+4], edx
movzx ecx, cl
lea ecx, [hotkey_scancodes+ecx*4]
mov edx, [ecx]
mov [eax], edx
mov [ecx], eax
mov [eax+12], ecx
jecxz @f
mov [edx+12], eax
@@:
and dword [esp+36], 0
ret
and dword [esp+32], 0
ret
 
no_add_keyboard_hotkey:
 
dec eax
jnz no_del_keyboard_hotkey
 
movzx ebx, bl
lea ebx, [hotkey_scancodes+ebx*4]
mov eax, [ebx]
.5:
movzx ebx, cl
lea ebx, [hotkey_scancodes+ebx*4]
mov eax, [ebx]
.scan:
test eax, eax
jz .notfound
cmp [eax+8], edi
jnz .next
cmp [eax+4], ecx
jz .found
test eax, eax
jz .notfound
cmp [eax+8], edi
jnz .next
cmp [eax+4], edx
jz .found
.next:
mov eax, [eax]
jmp .scan
mov eax, [eax]
jmp .scan
.notfound:
mov dword [esp+36], 1
ret
mov dword [esp+32], 1
ret
.found:
mov ecx, [eax]
jecxz @f
mov edx, [eax+12]
mov [ecx+12], edx
mov ecx, [eax]
jecxz @f
mov edx, [eax+12]
mov [ecx+12], edx
@@:
mov ecx, [eax+12]
mov edx, [eax]
mov [ecx], edx
xor edx, edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax], edx
mov [esp+36], edx
ret
mov ecx, [eax+12]
mov edx, [eax]
mov [ecx], edx
xor edx, edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax], edx
mov [esp+32], edx
ret
 
no_del_keyboard_hotkey:
ret
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 61 sys function. ;;
;; in eax=61,ebx in [1..3] ;;
;; out eax ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
align 4
f61call:
dd sys_gs.1 ; resolution
dd sys_gs.2 ; bits per pixel
dd sys_gs.3 ; bytes per scanline
endg
 
sys_gs: ; direct screen access
 
cmp eax,1 ; resolution
jne no_gs1
mov eax,[Screen_Max_X]
shl eax,16
mov ax,[Screen_Max_Y]
add eax,0x00010001
mov [esp+36],eax
ret
no_gs1:
align 4
 
cmp eax,2 ; bits per pixel
jne no_gs2
movzx eax,byte [ScreenBPP]
mov [esp+36],eax
ret
no_gs2:
sys_gs: ; direct screen access
dec ebx
cmp ebx, 2
ja .not_support
jmp dword [f61call+ebx*4]
.not_support:
or [esp+32], dword -1
ret
 
cmp eax,3 ; bytes per scanline
jne no_gs3
mov eax,[BytesPerScanLine]
mov [esp+36],eax
ret
no_gs3:
 
or [esp+36],dword -1
ret
.1: ; resolution
mov eax, [Screen_Max_X]
shl eax, 16
mov ax, [Screen_Max_Y]
add eax, 0x00010001
mov [esp+32], eax
ret
.2: ; bits per pixel
movzx eax, byte [ScreenBPP]
mov [esp+32], eax
ret
.3: ; bytes per scanline
mov eax, [BytesPerScanLine]
mov [esp+32], eax
ret
 
 
align 4 ; PCI functions
 
sys_pci:
 
call pci_api
mov [esp+36],eax
ret
 
 
align 4 ; system functions
 
syscall_setpixel: ; SetPixel
syscall_setpixel: ; SetPixel
 
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, [TASK_BASE]
add eax, [edx-twdw+WDATA.box.left]
add ebx, [edx-twdw+WDATA.box.top]
mov edi, [current_slot]
add eax, [edi+APPDATA.wnd_clientbox.left]
add ebx, [edi+APPDATA.wnd_clientbox.top]
xor edi, edi ; no force
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, [TASK_BASE]
add eax, [edx-twdw+WDATA.box.left]
add ebx, [edx-twdw+WDATA.box.top]
mov edi, [current_slot]
add eax, [edi+APPDATA.wnd_clientbox.left]
add ebx, [edi+APPDATA.wnd_clientbox.top]
xor edi, edi ; no force
; mov edi, 1
call [_display.disable_mouse]
jmp [putpixel]
call [_display.disable_mouse]
jmp [putpixel]
 
align 4
 
syscall_writetext: ; WriteText
syscall_writetext: ; WriteText
 
mov eax,[TASK_BASE]
mov ebp,[eax-twdw+WDATA.box.left]
push esi
mov esi,[current_slot]
add ebp,[esi+APPDATA.wnd_clientbox.left]
shl ebp,16
add ebp,[eax-twdw+WDATA.box.top]
add bp,word[esi+APPDATA.wnd_clientbox.top]
pop esi
add ebx,ebp
mov eax,edi
xor edi,edi
jmp dtext
mov eax, [TASK_BASE]
mov ebp, [eax-twdw+WDATA.box.left]
push esi
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
shl ebp, 16
add ebp, [eax-twdw+WDATA.box.top]
add bp, word[esi+APPDATA.wnd_clientbox.top]
pop esi
add ebx, ebp
mov eax, edi
xor edi, edi
jmp dtext
 
align 4
 
syscall_openramdiskfile: ; OpenRamdiskFile
syscall_openramdiskfile: ; OpenRamdiskFile
 
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, 12
call fileread
mov [esp+32], eax
ret
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, 12
call fileread
mov [esp+32], eax
ret
 
align 4
 
syscall_drawrect: ; DrawRect
syscall_drawrect: ; DrawRect
 
mov edi, edx ; color + gradient
and edi, 0x80FFFFFF
test bx, bx ; x.size
je .drectr
test cx, cx ; y.size
je .drectr
mov edi, edx ; color + gradient
and edi, 0x80FFFFFF
test bx, bx ; x.size
je .drectr
test cx, cx ; y.size
je .drectr
 
mov eax, ebx ; bad idea
mov ebx, ecx
mov eax, ebx ; bad idea
mov ebx, ecx
 
movzx ecx, ax ; ecx - x.size
shr eax, 16 ; eax - x.coord
movzx edx, bx ; edx - y.size
shr ebx, 16 ; ebx - y.coord
mov esi, [current_slot]
movzx ecx, ax ; ecx - x.size
shr eax, 16 ; eax - x.coord
movzx edx, bx ; edx - y.size
shr ebx, 16 ; ebx - y.coord
mov esi, [current_slot]
 
add eax, [esi + APPDATA.wnd_clientbox.left]
add ebx, [esi + APPDATA.wnd_clientbox.top]
add ecx, eax
add edx, ebx
jmp [drawbar]
add eax, [esi + APPDATA.wnd_clientbox.left]
add ebx, [esi + APPDATA.wnd_clientbox.top]
add ecx, eax
add edx, ebx
jmp [drawbar]
.drectr:
ret
ret
 
align 4
syscall_getscreensize: ; GetScreenSize
mov ax, [Screen_Max_X]
shl eax, 16
mov ax, [Screen_Max_Y]
mov [esp + 32], eax
ret
syscall_getscreensize: ; GetScreenSize
mov ax, [Screen_Max_X]
shl eax, 16
mov ax, [Screen_Max_Y]
mov [esp + 32], eax
ret
 
align 4
 
syscall_cdaudio: ; CD
syscall_cdaudio: ; CD
 
cmp ebx, 4
jb .audio
jz .eject
cmp ebx, 5
jnz .ret
cmp ebx, 4
jb .audio
jz .eject
cmp ebx, 5
jnz .ret
.load:
call .reserve
call LoadMedium
;call .free
jmp .free
call .reserve
call LoadMedium
;call .free
jmp .free
; ret
.eject:
call .reserve
call clear_CD_cache
call allow_medium_removal
call EjectMedium
call .reserve
call clear_CD_cache
call allow_medium_removal
call EjectMedium
; call .free
jmp .free
jmp .free
; ret
.audio:
call sys_cd_audio
mov [esp+36-4],eax
call sys_cd_audio
mov [esp+36-4], eax
.ret:
ret
ret
 
.reserve:
call reserve_cd
mov eax, ecx
shr eax, 1
and eax, 1
inc eax
mov [ChannelNumber], ax
mov eax, ecx
and eax, 1
mov [DiskNumber], al
call reserve_cd_channel
and ebx, 3
inc ebx
mov [cdpos], ebx
add ebx, ebx
mov cl, 8
sub cl, bl
mov al, [DRIVE_DATA+1]
shr al, cl
test al, 2
jz .free;.err
ret
call reserve_cd
mov eax, ecx
shr eax, 1
and eax, 1
inc eax
mov [ChannelNumber], ax
mov eax, ecx
and eax, 1
mov [DiskNumber], al
call reserve_cd_channel
and ebx, 3
inc ebx
mov [cdpos], ebx
add ebx, ebx
mov cl, 8
sub cl, bl
mov al, [DRIVE_DATA+1]
shr al, cl
test al, 2
jz .free;.err
ret
.free:
call free_cd_channel
and [cd_status], 0
ret
call free_cd_channel
and [cd_status], 0
ret
.err:
call .free
call .free
; pop eax
ret
ret
 
align 4
 
syscall_getpixel: ; GetPixel
mov ecx, [Screen_Max_X]
inc ecx
xor edx, edx
mov eax, ebx
div ecx
mov ebx, edx
xchg eax, ebx
call dword [GETPIXEL] ; eax - x, ebx - y
mov [esp + 32], ecx
ret
syscall_getpixel: ; GetPixel
mov ecx, [Screen_Max_X]
inc ecx
xor edx, edx
mov eax, ebx
div ecx
mov ebx, edx
xchg eax, ebx
call dword [GETPIXEL]; eax - x, ebx - y
mov [esp + 32], ecx
ret
 
align 4
 
5237,133 → 4557,115
;ebx = pointer to bufer for img BBGGRRBBGGRR...
;ecx = [size x]*65536 + [size y]
;edx = [start x]*65536 + [start y]
pushad
inc [mouse_pause]
pushad
inc [mouse_pause]
; Check of use of the hardware cursor.
cmp [_display.disable_mouse],__sys_disable_mouse
jne @f
cmp [_display.disable_mouse], __sys_disable_mouse
jne @f
; Since the test for the coordinates of the mouse should not be used,
; then use the call [disable_mouse] is not possible!
cmp dword [MOUSE_VISIBLE],dword 0
jne @f
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE],dword 1
cmp dword [MOUSE_VISIBLE], dword 0
jne @f
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE], dword 1
@@:
mov edi,ebx
mov eax,edx
shr eax,16
mov ebx,edx
and ebx,0xffff
dec eax
dec ebx
mov edi, ebx
mov eax, edx
shr eax, 16
mov ebx, edx
and ebx, 0xffff
dec eax
dec ebx
; eax - x, ebx - y
mov edx,ecx
shr ecx,16
and edx,0xffff
mov esi,ecx
mov edx, ecx
 
shr ecx, 16
and edx, 0xffff
mov esi, ecx
; ecx - size x, edx - size y
mov ebp,edx
dec ebp
lea ebp,[ebp*3]
imul ebp,esi
mov esi,ecx
dec esi
lea esi,[esi*3]
add ebp,esi
add ebp,edi
 
add ebx,edx
mov ebp, edx
dec ebp
lea ebp, [ebp*3]
 
imul ebp, esi
 
mov esi, ecx
dec esi
lea esi, [esi*3]
 
add ebp, esi
add ebp, edi
 
add ebx, edx
 
.start_y:
push ecx edx
push ecx edx
.start_x:
push eax ebx ecx
add eax,ecx
push eax ebx ecx
add eax, ecx
 
call dword [GETPIXEL] ; eax - x, ebx - y
mov [ebp],cx
shr ecx,16
mov [ebp+2],cl
call dword [GETPIXEL]; eax - x, ebx - y
 
pop ecx ebx eax
sub ebp,3
dec ecx
jnz .start_x
pop edx ecx
dec ebx
dec edx
jnz .start_y
dec [mouse_pause]
mov [ebp], cx
shr ecx, 16
mov [ebp+2], cl
 
pop ecx ebx eax
sub ebp, 3
dec ecx
jnz .start_x
pop edx ecx
dec ebx
dec edx
jnz .start_y
dec [mouse_pause]
; Check of use of the hardware cursor.
cmp [_display.disable_mouse],__sys_disable_mouse
jne @f
call [draw_pointer]
cmp [_display.disable_mouse], __sys_disable_mouse
jne @f
call [draw_pointer]
@@:
popad
ret
popad
ret
 
align 4
 
syscall_drawline: ; DrawLine
syscall_drawline: ; DrawLine
 
mov edi, [TASK_BASE]
movzx eax, word[edi-twdw+WDATA.box.left]
mov ebp, eax
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
add ax, word[esi+APPDATA.wnd_clientbox.left]
add ebp,ebx
shl eax, 16
movzx ebx, word[edi-twdw+WDATA.box.top]
add eax, ebp
mov ebp, ebx
add ebp, [esi+APPDATA.wnd_clientbox.top]
add bx, word[esi+APPDATA.wnd_clientbox.top]
add ebp, ecx
shl ebx, 16
xor edi, edi
add ebx, ebp
mov ecx, edx
jmp [draw_line]
mov edi, [TASK_BASE]
movzx eax, word[edi-twdw+WDATA.box.left]
mov ebp, eax
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
add ax, word[esi+APPDATA.wnd_clientbox.left]
add ebp, ebx
shl eax, 16
movzx ebx, word[edi-twdw+WDATA.box.top]
add eax, ebp
mov ebp, ebx
add ebp, [esi+APPDATA.wnd_clientbox.top]
add bx, word[esi+APPDATA.wnd_clientbox.top]
add ebp, ecx
shl ebx, 16
xor edi, edi
add ebx, ebp
mov ecx, edx
jmp [draw_line]
 
align 4
 
syscall_getirqowner: ; GetIrqOwner
 
cmp ebx,16
jae .err
 
cmp [irq_rights + 4 * ebx], dword 2
je .err
 
mov eax,[4 * ebx + irq_owner]
mov [esp+32],eax
 
ret
.err:
or dword [esp+32], -1
ret
 
align 4
syscall_reserveportarea: ; ReservePortArea and FreePortArea
 
syscall_reserveportarea: ; ReservePortArea and FreePortArea
call r_f_port_area
mov [esp+32], eax
ret
 
call r_f_port_area
mov [esp+32],eax
ret
 
align 4
 
syscall_threads: ; CreateThreads
syscall_threads: ; CreateThreads
; eax=1 create thread
;
; ebx=thread start
5371,386 → 4673,386
;
; on return : eax = pid
 
call new_sys_threads
call new_sys_threads
 
mov [esp+32],eax
ret
mov [esp+32], eax
ret
 
align 4
 
read_from_hd: ; Read from hd - fn not in use
read_from_hd: ; Read from hd - fn not in use
 
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add eax,[edi]
add ecx,[edi]
add edx,[edi]
call file_read
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add eax, [edi]
add ecx, [edi]
add edx, [edi]
call file_read
 
mov [esp+36],eax
mov [esp+24],ebx
mov [esp+36], eax
mov [esp+24], ebx
 
ret
ret
 
paleholder:
ret
ret
 
align 4
set_screen:
cmp eax, [Screen_Max_X]
jne .set
cmp eax, [Screen_Max_X]
jne .set
 
cmp edx, [Screen_Max_Y]
jne .set
ret
cmp edx, [Screen_Max_Y]
jne .set
ret
.set:
pushfd
cli
pushfd
cli
 
mov [Screen_Max_X], eax
mov [Screen_Max_Y], edx
mov [BytesPerScanLine], ecx
mov [Screen_Max_X], eax
mov [Screen_Max_Y], edx
mov [BytesPerScanLine], ecx
 
mov [screen_workarea.right],eax
mov [screen_workarea.bottom], edx
mov [screen_workarea.right], eax
mov [screen_workarea.bottom], edx
 
push ebx
push esi
push edi
push ebx
push esi
push edi
 
pushad
pushad
 
stdcall kernel_free, [_WinMapAddress]
stdcall kernel_free, [_WinMapAddress]
 
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
 
stdcall kernel_alloc, eax
mov [_WinMapAddress], eax
test eax, eax
jz .epic_fail
stdcall kernel_alloc, eax
mov [_WinMapAddress], eax
test eax, eax
jz .epic_fail
 
popad
popad
 
call repos_windows
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
call calculatescreen
pop edi
pop esi
pop ebx
call repos_windows
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
call calculatescreen
pop edi
pop esi
pop ebx
 
popfd
ret
popfd
ret
 
.epic_fail:
hlt ; Houston, we've had a problem
hlt ; Houston, we've had a problem
 
; --------------- APM ---------------------
uglobal
apm_entry dp 0
apm_vf dd 0
apm_entry dp 0
apm_vf dd 0
endg
 
align 4
sys_apm:
xor eax,eax
cmp word [apm_vf], ax ; Check APM BIOS enable
jne @f
inc eax
or dword [esp + 44], eax ; error
add eax,7
mov dword [esp + 32], eax ; 32-bit protected-mode interface not supported
ret
xor eax, eax
cmp word [apm_vf], ax ; Check APM BIOS enable
jne @f
inc eax
or dword [esp + 44], eax ; error
add eax, 7
mov dword [esp + 32], eax ; 32-bit protected-mode interface not supported
ret
 
@@:
; xchg eax, ecx
; xchg ebx, ecx
 
cmp dx, 3
ja @f
and [esp + 44], byte 0xfe ; emulate func 0..3 as func 0
mov eax,[apm_vf]
mov [esp + 32], eax
shr eax, 16
mov [esp + 28], eax
ret
cmp dx, 3
ja @f
and [esp + 44], byte 0xfe ; emulate func 0..3 as func 0
mov eax, [apm_vf]
mov [esp + 32], eax
shr eax, 16
mov [esp + 28], eax
ret
 
@@:
 
mov esi,[master_tab+(OS_BASE shr 20)]
xchg [master_tab], esi
push esi
mov edi, cr3
mov cr3, edi ;flush TLB
mov esi, [master_tab+(OS_BASE shr 20)]
xchg [master_tab], esi
push esi
mov edi, cr3
mov cr3, edi ;flush TLB
 
call pword [apm_entry] ;call APM BIOS
call pword [apm_entry] ;call APM BIOS
 
xchg eax, [esp]
mov [master_tab], eax
mov eax, cr3
mov cr3, eax
pop eax
xchg eax, [esp]
mov [master_tab], eax
mov eax, cr3
mov cr3, eax
pop eax
 
mov [esp + 4 ], edi
mov [esp + 8], esi
mov [esp + 20], ebx
mov [esp + 24], edx
mov [esp + 28], ecx
mov [esp + 32], eax
setc al
and [esp + 44], byte 0xfe
or [esp + 44], al
ret
mov [esp + 4 ], edi
mov [esp + 8], esi
mov [esp + 20], ebx
mov [esp + 24], edx
mov [esp + 28], ecx
mov [esp + 32], eax
setc al
and [esp + 44], byte 0xfe
or [esp + 44], al
ret
; -----------------------------------------
 
align 4
 
undefined_syscall: ; Undefined system call
mov [esp + 32], dword -1
ret
undefined_syscall: ; Undefined system call
mov [esp + 32], dword -1
ret
 
align 4
system_shutdown: ; shut down the system
system_shutdown: ; shut down the system
 
cmp byte [BOOT_VAR+0x9030], 1
jne @F
ret
cmp byte [BOOT_VAR+0x9030], 1
jne @F
ret
@@:
call stop_all_services
push 3 ; stop playing cd
pop eax
call sys_cd_audio
call stop_all_services
push 3 ; stop playing cd
pop eax
call sys_cd_audio
 
yes_shutdown_param:
cli
cli
 
mov eax, kernel_file ; load kernel.mnt to 0x7000:0
push 12
pop esi
xor ebx,ebx
or ecx,-1
mov edx, OS_BASE+0x70000
call fileread
if ~ defined extended_primary_loader
mov eax, kernel_file ; load kernel.mnt to 0x7000:0
push 12
pop esi
xor ebx, ebx
or ecx, -1
mov edx, OS_BASE+0x70000
call fileread
 
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
mov edi,OS_BASE+0x40000
mov ecx,1000
rep movsb
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
mov edi, OS_BASE+0x40000
mov ecx, 1000
rep movsb
end if
 
mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff
mov edi, OS_BASE
mov ecx,0x10000/4
cld
rep movsd
mov esi, BOOT_VAR ; restore 0x0 - 0xffff
mov edi, OS_BASE
mov ecx, 0x10000/4
cld
rep movsd
 
call restorefatchain
call restorefatchain
 
mov al, 0xFF
out 0x21, al
out 0xA1, al
call IRQ_mask_all
 
if 0
mov word [OS_BASE+0x467+0],pr_mode_exit
mov word [OS_BASE+0x467+2],0x1000
mov word [OS_BASE+0x467+0], pr_mode_exit
mov word [OS_BASE+0x467+2], 0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
mov al, 0x0F
out 0x70, al
mov al, 0x05
out 0x71, al
 
mov al,0xFE
out 0x64,al
mov al, 0xFE
out 0x64, al
 
hlt
jmp $-1
hlt
jmp $-1
 
else
cmp byte [OS_BASE + 0x9030], 2
jnz no_acpi_power_off
cmp byte [OS_BASE + 0x9030], 2
jnz no_acpi_power_off
 
; scan for RSDP
; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA).
movzx eax, word [OS_BASE + 0x40E]
shl eax, 4
jz @f
mov ecx, 1024/16
call scan_rsdp
jnc .rsdp_found
movzx eax, word [OS_BASE + 0x40E]
shl eax, 4
jz @f
mov ecx, 1024/16
call scan_rsdp
jnc .rsdp_found
@@:
; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh.
mov eax, 0xE0000
mov ecx, 0x2000
call scan_rsdp
jc no_acpi_power_off
mov eax, 0xE0000
mov ecx, 0x2000
call scan_rsdp
jc no_acpi_power_off
.rsdp_found:
mov esi, [eax+16] ; esi contains physical address of the RSDT
mov ebp, [ipc_tmp]
stdcall map_page, ebp, esi, PG_MAP
lea eax, [esi+1000h]
lea edx, [ebp+1000h]
stdcall map_page, edx, eax, PG_MAP
and esi, 0xFFF
add esi, ebp
cmp dword [esi], 'RSDT'
jnz no_acpi_power_off
mov ecx, [esi+4]
sub ecx, 24h
jbe no_acpi_power_off
shr ecx, 2
add esi, 24h
mov esi, [eax+16] ; esi contains physical address of the RSDT
mov ebp, [ipc_tmp]
stdcall map_page, ebp, esi, PG_MAP
lea eax, [esi+1000h]
lea edx, [ebp+1000h]
stdcall map_page, edx, eax, PG_MAP
and esi, 0xFFF
add esi, ebp
cmp dword [esi], 'RSDT'
jnz no_acpi_power_off
mov ecx, [esi+4]
sub ecx, 24h
jbe no_acpi_power_off
shr ecx, 2
add esi, 24h
.scan_fadt:
lodsd
mov ebx, eax
lea eax, [ebp+2000h]
stdcall map_page, eax, ebx, PG_MAP
lea eax, [ebp+3000h]
add ebx, 0x1000
stdcall map_page, eax, ebx, PG_MAP
and ebx, 0xFFF
lea ebx, [ebx+ebp+2000h]
cmp dword [ebx], 'FACP'
jz .fadt_found
loop .scan_fadt
jmp no_acpi_power_off
lodsd
mov ebx, eax
lea eax, [ebp+2000h]
stdcall map_page, eax, ebx, PG_MAP
lea eax, [ebp+3000h]
add ebx, 0x1000
stdcall map_page, eax, ebx, PG_MAP
and ebx, 0xFFF
lea ebx, [ebx+ebp+2000h]
cmp dword [ebx], 'FACP'
jz .fadt_found
loop .scan_fadt
jmp no_acpi_power_off
.fadt_found:
; ebx is linear address of FADT
mov edi, [ebx+40] ; physical address of the DSDT
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
lea eax, [ebp+5000h]
lea esi, [edi+0x1000]
stdcall map_page, eax, esi, PG_MAP
and esi, 0xFFF
sub edi, esi
cmp dword [esi+ebp+4000h], 'DSDT'
jnz no_acpi_power_off
mov eax, [esi+ebp+4004h] ; DSDT length
sub eax, 36+4
jbe no_acpi_power_off
add esi, 36
mov edi, [ebx+40] ; physical address of the DSDT
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
lea eax, [ebp+5000h]
lea esi, [edi+0x1000]
stdcall map_page, eax, esi, PG_MAP
and esi, 0xFFF
sub edi, esi
cmp dword [esi+ebp+4000h], 'DSDT'
jnz no_acpi_power_off
mov eax, [esi+ebp+4004h] ; DSDT length
sub eax, 36+4
jbe no_acpi_power_off
add esi, 36
.scan_dsdt:
cmp dword [esi+ebp+4000h], '_S5_'
jnz .scan_dsdt_cont
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
jnz .scan_dsdt_cont
mov dl, [esi+ebp+4000h+6]
cmp dl, 4 ; _S5_ package must contain 4 bytes
; ...in theory; in practice, VirtualBox has 2 bytes
ja .scan_dsdt_cont
cmp dl, 1
jb .scan_dsdt_cont
lea esi, [esi+ebp+4000h+7]
xor ecx, ecx
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov cl, [esi]
cmp dword [esi+ebp+4000h], '_S5_'
jnz .scan_dsdt_cont
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
jnz .scan_dsdt_cont
mov dl, [esi+ebp+4000h+6]
cmp dl, 4 ; _S5_ package must contain 4 bytes
; ...in theory; in practice, VirtualBox has 2 bytes
ja .scan_dsdt_cont
cmp dl, 1
jb .scan_dsdt_cont
lea esi, [esi+ebp+4000h+7]
xor ecx, ecx
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov cl, [esi]
@@:
inc esi
cmp dl, 2
jb @f
cmp byte [esi], 0
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov ch, [esi]
inc esi
cmp dl, 2
jb @f
cmp byte [esi], 0
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov ch, [esi]
@@:
jmp do_acpi_power_off
jmp do_acpi_power_off
.scan_dsdt_cont:
inc esi
cmp esi, 0x1000
jb @f
sub esi, 0x1000
add edi, 0x1000
push eax
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
push PG_MAP
lea eax, [edi+1000h]
push eax
lea eax, [ebp+5000h]
push eax
stdcall map_page
pop eax
inc esi
cmp esi, 0x1000
jb @f
sub esi, 0x1000
add edi, 0x1000
push eax
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
push PG_MAP
lea eax, [edi+1000h]
push eax
lea eax, [ebp+5000h]
push eax
stdcall map_page
pop eax
@@:
dec eax
jnz .scan_dsdt
jmp no_acpi_power_off
dec eax
jnz .scan_dsdt
jmp no_acpi_power_off
do_acpi_power_off:
mov edx, [ebx+48]
test edx, edx
jz .nosmi
mov al, [ebx+52]
out dx, al
mov edx, [ebx+64]
mov edx, [ebx+48]
test edx, edx
jz .nosmi
mov al, [ebx+52]
out dx, al
mov edx, [ebx+64]
@@:
in ax, dx
test al, 1
jz @b
in ax, dx
test al, 1
jz @b
.nosmi:
and cx, 0x0707
shl cx, 2
or cx, 0x2020
mov edx, [ebx+64]
in ax, dx
and ax, 203h
or ah, cl
out dx, ax
mov edx, [ebx+68]
test edx, edx
jz @f
in ax, dx
and ax, 203h
or ah, ch
out dx, ax
and cx, 0x0707
shl cx, 2
or cx, 0x2020
mov edx, [ebx+64]
in ax, dx
and ax, 203h
or ah, cl
out dx, ax
mov edx, [ebx+68]
test edx, edx
jz @f
in ax, dx
and ax, 203h
or ah, ch
out dx, ax
@@:
jmp $
jmp $
 
 
no_acpi_power_off:
mov word [OS_BASE+0x467+0],pr_mode_exit
mov word [OS_BASE+0x467+2],0x1000
mov word [OS_BASE+0x467+0], pr_mode_exit
mov word [OS_BASE+0x467+2], 0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
mov al, 0x0F
out 0x70, al
mov al, 0x05
out 0x71, al
 
mov al,0xFE
out 0x64,al
mov al, 0xFE
out 0x64, al
 
hlt
jmp $-1
hlt
jmp $-1
 
scan_rsdp:
add eax, OS_BASE
add eax, OS_BASE
.s:
cmp dword [eax], 'RSD '
jnz .n
cmp dword [eax+4], 'PTR '
jnz .n
xor edx, edx
xor esi, esi
cmp dword [eax], 'RSD '
jnz .n
cmp dword [eax+4], 'PTR '
jnz .n
xor edx, edx
xor esi, esi
@@:
add dl, [eax+esi]
inc esi
cmp esi, 20
jnz @b
test dl, dl
jz .ok
add dl, [eax+esi]
inc esi
cmp esi, 20
jnz @b
test dl, dl
jz .ok
.n:
add eax, 10h
loop .s
stc
add eax, 10h
loop .s
stc
.ok:
ret
ret
end if
 
include "data32.inc"
/kernel/branches/net/kernel32.inc
15,59 → 15,32
 
$Revision$
 
struct POINT
x dd ?
y dd ?
ends
 
;struc db [a] { common . db a
; if ~used .
; display 'not used db: ',`.,13,10
; end if }
;struc dw [a] { common . dw a
; if ~used .
; display 'not used dw: ',`.,13,10
; end if }
;struc dd [a] { common . dd a
; if ~used .
; display 'not used dd: ',`.,13,10
; end if }
;struc dp [a] { common . dp a
; if ~used .
; display 'not used dp: ',`.,13,10
; end if }
;struc dq [a] { common . dq a
; if ~used .
; display 'not used dq: ',`.,13,10
; end if }
;struc dt [a] { common . dt a
; if ~used .
; display 'not used dt: ',`.,13,10
; end if }
struct RECT
left dd ?
top dd ?
right dd ?
bottom dd ?
ends
 
struc RECT {
.left dd ?
.top dd ?
.right dd ?
.bottom dd ?
}
virtual at 0
RECT RECT
end virtual
struct BOX
left dd ?
top dd ?
width dd ?
height dd ?
ends
 
struc BOX {
.left dd ?
.top dd ?
.width dd ?
.height dd ?
}
virtual at 0
BOX BOX
end virtual
struct DISPMODE
width dw ?
height dw ?
bpp dw ?
freq dw ?
ends
 
struc DISPMODE {
.width rw 1
.height rw 1
.bpp rw 1
.freq rw 1
}
 
; constants definition
WSTATE_NORMAL = 00000000b
WSTATE_MAXIMIZED = 00000001b
80,110 → 53,111
WSTYLE_HASCAPTION = 00010000b
WSTYLE_CLIENTRELATIVE = 00100000b
 
struc TASKDATA
{
.event_mask dd ?
.pid dd ?
dw ?
.state db ?
db ?
dw ?
.wnd_number db ?
db ?
.mem_start dd ?
.counter_sum dd ?
.counter_add dd ?
.cpu_usage dd ?
}
virtual at 0
TASKDATA TASKDATA
end virtual
 
TSTATE_RUNNING = 0
TSTATE_RUN_SUSPENDED = 1
TSTATE_WAIT_SUSPENDED = 2
TSTATE_ZOMBIE = 3
TSTATE_TERMINATING = 4
TSTATE_WAITING = 5
TSTATE_FREE = 9
struct TASKDATA
event_mask dd ?
pid dd ?
dw ?
state db ?
db ?
dw ?
wnd_number db ?
db ?
mem_start dd ?
counter_sum dd ?
counter_add dd ?
cpu_usage dd ?
ends
 
TSTATE_RUNNING = 0
TSTATE_RUN_SUSPENDED = 1
TSTATE_WAIT_SUSPENDED = 2
TSTATE_ZOMBIE = 3
TSTATE_TERMINATING = 4
TSTATE_WAITING = 5
TSTATE_FREE = 9
 
; structures definition
struc WDATA {
.box BOX
.cl_workarea dd ?
.cl_titlebar dd ?
.cl_frames dd ?
.reserved db ?
.fl_wstate db ?
.fl_wdrawn db ?
.fl_redraw db ?
.sizeof:
}
virtual at 0
WDATA WDATA
end virtual
struct WDATA
box BOX
cl_workarea dd ?
cl_titlebar dd ?
cl_frames dd ?
reserved db ?
fl_wstate db ?
fl_wdrawn db ?
fl_redraw db ?
ends
 
label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3
 
struc APPDATA
{
.app_name db 11 dup(?)
db 5 dup(?)
struct DBG_REGS
dr0 dd ?
dr1 dd ?
dr2 dd ?
dr3 dd ?
dr7 dd ?
ends
 
.fpu_state dd ? ;+16
.ev_count_ dd ? ;unused ;+20
.exc_handler dd ? ;+24
.except_mask 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
.saved_esp dd ? ;+64
.io_map rd 2 ;+68
.dbg_state dd ? ;+76
.cur_dir dd ? ;+80
.wait_timeout dd ? ;+84
.saved_esp0 dd ? ;+88
.wait_begin dd ? ;+92 +++
.wait_test dd ? ;+96 +++
.wait_param dd ? ;+100 +++
.tls_base dd ? ;+104
.dlls_list_ptr dd ? ;+108
db 16 dup(?) ;+112
struct APPDATA
app_name rb 11
rb 5
 
.wnd_shape dd ? ;+128
.wnd_shape_scale dd ? ;+132
dd ? ;+136
.mem_size dd ? ;+140
.saved_box BOX
.ipc_start dd ?
.ipc_size dd ?
.event_mask dd ?
.debugger_slot dd ?
dd ?
.keyboard_mode db ?
db 3 dup(?)
.dir_table dd ?
.dbg_event_mem dd ?
.dbg_regs:
.dbg_regs.dr0 dd ?
.dbg_regs.dr1 dd ?
.dbg_regs.dr2 dd ?
.dbg_regs.dr3 dd ?
.dbg_regs.dr7 dd ?
.wnd_caption dd ?
.wnd_clientbox BOX
}
virtual at 0
APPDATA APPDATA
end virtual
fpu_state dd ? ;+16
ev_count_ dd ? ;unused ;+20
exc_handler dd ? ;+24
except_mask dd ? ;+28
pl0_stack dd ? ;+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
saved_esp dd ? ;+64
io_map rd 2 ;+68
dbg_state dd ? ;+76
cur_dir dd ? ;+80
wait_timeout dd ? ;+84
saved_esp0 dd ? ;+88
wait_begin dd ? ;+92 +++
wait_test dd ? ;+96 +++
wait_param dd ? ;+100 +++
tls_base dd ? ;+104
dlls_list_ptr dd ? ;+108
rb 16 ;+112
 
wnd_shape dd ? ;+128
wnd_shape_scale dd ? ;+132
dd ? ;+136
mem_size dd ? ;+140
saved_box BOX
ipc_start dd ?
ipc_size dd ?
event_mask dd ?
debugger_slot dd ?
dd ?
keyboard_mode db ?
rb 3
dir_table dd ?
dbg_event_mem dd ?
dbg_regs DBG_REGS
wnd_caption dd ?
wnd_clientbox BOX
 
ends
 
 
 
 
;// mike.dld, 2006-29-01 ]
 
struct MUTEX
lhead LHEAD
count dd ?
ends
 
 
; Core functions
include "core/sync.inc" ; macros for synhronization objects
include "core/sys32.inc" ; process management
199,6 → 173,9
include "core/exports.inc"
include "core/string.inc"
include "core/v86.inc" ; virtual-8086 manager
include "core/irq.inc" ; irq handling functions
include "core/apic.inc" ; Interrupt Controller functions
include "core/timers.inc"
 
; GUI stuff
include "gui/window.inc"
210,6 → 187,8
 
; file system
 
include "blkdev/disk.inc" ; support for plug-n-play disks
include "blkdev/disk_cache.inc" ; caching for plug-n-play disks
include "fs/fs.inc" ; syscall
include "fs/fat32.inc" ; read / write for fat32 filesystem
include "fs/ntfs.inc" ; read / write for ntfs filesystem
217,6 → 196,7
include "blkdev/rd.inc" ; ramdisk read /write
include "fs/fs_lfn.inc" ; syscall, version 2
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
include "fs/ext2.inc" ; read / write for ext2 filesystem
 
; sound
 
226,6 → 206,7
 
include "video/vesa12.inc" ; Vesa 1.2 functions
include "video/vesa20.inc" ; Vesa 2.0 functions
include "video/blitter.inc" ;
include "video/vga.inc" ; VGA 16 color functions
include "video/cursors.inc" ; cursors functions
 
/kernel/branches/net/macros.inc
11,6 → 11,9
 
$Revision$
 
 
;// mike.dld, 2006-29-01 [
 
; macros definition
macro diff16 title,l1,l2
{
62,14 → 65,14
a db 'K : ',string,13,10,0
endg_nested
if ~ f eq
pushfd
pushfd
end if
push esi
mov esi, a
call sys_msg_board_str
pop esi
push esi
mov esi, a
call sys_msg_board_str
pop esi
if ~ f eq
popfd
popfd
end if
}
; \end{diamond}[29.09.2006]
76,49 → 79,35
 
macro Mov op1,op2,op3 ; op1 = op2 = op3
{
mov op2,op3
mov op1,op2
mov op2, op3
mov op1, op2
}
 
 
if __CPU_type eq p5 ; CMOVcc isnt supported on the P5
 
cmove fix cmovz
macro cmovz reg1, reg2 {
 
local .jumpaddr
 
jnz .jumpaddr
mov reg1, reg2
.jumpaddr:
macro __list_add new, prev, next
{
mov [next+LHEAD.prev], new
mov [new+LHEAD.next], next
mov [new+LHEAD.prev], prev
mov [prev+LHEAD.next], new
}
 
cmovne fix cmovnz
macro cmovnz reg1, reg2 {
 
local .jumpaddr
 
jz .jumpaddr
mov reg1, reg2
.jumpaddr:
macro list_add new, head
{
mov eax, [head+LHEAD.next]
__list_add new, head, eax
}
 
macro cmovg reg1, reg2 {
 
local .jumpaddr
 
jle .jumpaddr
mov reg1, reg2
.jumpaddr:
macro list_add_tail new, head
{
mov eax, [head+LHEAD.prev]
__list_add new, eax, head
}
 
macro cmovl reg1, reg2 {
 
local .jumpaddr
 
jge .jumpaddr
mov reg1, reg2
.jumpaddr:
macro list_del entry
{
mov edx, [entry+list_fd]
mov ecx, [entry+list_bk]
mov [edx+list_bk], ecx
mov [ecx+list_fd], edx
}
 
end if
/kernel/branches/net/memmap.inc
62,33 → 62,36
; 3c dword cpu usage in cpu timer tics
;
;
; 5000 -> 68FF free
; 6900 -> 6EFF saved picture under mouse pointer
; 5000 -> 68FF free (6k6)
; 6900 -> 6EFF saved picture under mouse pointer (1k5)
;
; 6F00 -> 6FFF free
; 6F00 -> 6FFF free (256)
;
; 7000 -> 7FFF used CD driver
;
; 8000 -> A3FF used FLOPPY driver
;
; A400 -> B0FF free
; A400 -> B0FF free (3k3), unused ACTIVE_PROC_STACK
 
; B100 -> B307 IDT for int_0x00..int_0x40
 
; B308 -> BFFF free
; B308 -> BFFF free (3k3)
 
; C000 -> C3FF window stack C000 no of windows - all in words
; C402 -> C7FF window position in stack
; D000 -> D1FF FDC controller
; D200 -> D3FF FDC controller for Fat12
; D400 -> DFFF free
; D400 -> DFFF free (3k)
; E000 byte multitasking started
; E020 dword putpixel address
; E024 dword getpixel address
; E030 dword Vesa 1.2 pm bank switch address
; E034 -> F1FF free (4k5)
; F200 dword mousepicture -pointer
; F204 dword mouse appearance counter
; F208 -> F2FF free (248)
; F300 dword x & y temp for windowmove
; F304 -> F3FF free (252)
; F400 byte no of keys in buffer
; F401 byte 'buffer'
; F402 -> F4FF reserved for keys
96,8 → 99,13
; F501 dword 'buffer'
; F502 -> F5FF reserved for buttons
; F600 dword tsc / second
; F604 byte mouse port: 1 ps2, 2 com1, 3 com2
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; F604 byte (unused?) mouse port: 1 ps2, 2 com1, 3 com2
; F605 -> FAFF free (1k2)
; FB00 -> FB0F mouse memory 00 chunk count, that includes:
; FB08 word -- mouse H-scroll
; FB0A word -- mouse x
; FB0C word -- mouse y
; FB0E word -- mouse V-scroll
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
109,18 → 117,21
; FBF1 byte bits per pixel
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FD00 -> FDFF free (256)
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FE10 -> FE7F free (112)
; FE80 dword address of LFB in physical
; FE84 dword address of applications memory start in physical
; FE84 dword address of applications memory start in physical ?
; FE88 dword address of button list
; FE8C dword memory to use
; FE8C dword memory to use
; FE90 -> FEFF free (112)
; FF00 byte 1 = system shutdown request
; FF01 dword free
; FFF0 byte 1 = redraw background request from app
; FFF1 byte 1 = diskette int occur
; FF01 byte task activation request?
; FFF0 byte >0 if redraw background request from app
; FFF1 byte >0 if background changed
; FFF2 write and read bank in screen
; FFF4 byte 0 if first mouse draw & do not return picture under
; FFF5 byte 1 do not draw pointer
177,20 → 188,22
; BC dword address of debug event memory
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7
;
; 0x80090000 -> 9FFFF tmp
; 0x80090000 -> 9FFFF tmp (64k) - unused?
; 0x800A0000 -> AFFFF screen access area
; 0x800B0000 -> FFFFF bios rest in peace -area
; 0x80100000 -> 27FFFF diskette image
; 0x80280000 -> 281FFF ramdisk fat
; 0x80282000 -> 283FFF floppy fat
; 0x800B0000 -> FFFFF bios rest in peace -area (320k) ?
; 0x80100000 -> 27FFFF diskette image (1m5)
; 0x80280000 -> 281FFF ramdisk fat (8k)
; 0x80282000 -> 283FFF floppy fat (8k)
;
; 0x80284000 -> 28BFFF HDD DMA AREA
; 0x8028C000 -> 297FFF free (48 Kb)
; 0x80284000 -> 28BFFF HDD DMA AREA (32k)
; 0x8028C000 -> 297FFF free (48k)
;
; 0x80298000 -> 29ffff auxiliary table for background smoothing code
; 0x80298000 -> 29ffff auxiliary table for background smoothing code (32k)
;
; 0x802A0000 -> 2B00ff wav device data
; 0x802C0000 -> 2C3fff button info
; 0x802A0000 -> 2B00ff wav device buffer (64k)
; 0x802A0000 -> 2B00ff wav device status (256)
; 0x802B0100 -> 2Bffff free (63k8)
; 0x802C0000 -> 2C3fff button info (8k)
;
; 0000 word number of buttons
; first button entry at 0x10
202,9 → 215,9
; +000A word y size
; +000C word button id number : bits 16-31
;
; 0x802C4000 -> 2CFFFF free (48Kb)
; 0x802C4000 -> 2CFFFF free (48k)
;
; 0x802D0000 -> 2DFFFF reserved port area
; 0x802D0000 -> 2DFFFF reserved port area (64k)
;
; 0000 dword no of port areas reserved
; 0010 dword process id
212,34 → 225,37
; dword end port
; dword 0
;
; 0x802E0000 -> 2EFFFF irq data area
; 0x802F0000 -> 2FFFFF low memory save
; 0x802E0000 -> 2EFFFF irq data area (64k)
; 0x802F0000 -> 2FFFFF low memory save (64k)
;
; 0x80300000 -> 31FFFF tcp memory 128 Kb
; 0x80320000 -> 327FFF tcp memory 32 Kb
; 0x80300000 -> 31FFFF tcp memory (128k)
; 0x80320000 -> 327FFF tcp memory (32k)
;
; 0x80328000 -> 32FFFF !vrr driver 32 Kb
; 0x80328000 -> 32FFFF !vrr driver (32k)
 
; 0x80330000 -> 377FFF skin data
; 0x80330000 -> 377FFF skin data (32k)
 
; 0x80338000 -> 33AFFF draw data - 256 entries
; 0x80338000 -> 338FFF draw data - 256 entries (4k)
; 00 dword draw limit - x start
; 04 dword draw limit - y start
; 08 dword draw limit - x end
; 0C dword draw limit - y end
; 0x80339000 -> 3BFFF3 free (12k)
; 0x8033BFF4 -> 33BFFF background info
; 0x8033C000 page map (length b = memsize shr 15)
; 0x8033C000 + b start of static pagetables
 
; 0x8033C000 -> 47BFFF display info
; 0x803FFFFF <- no direct address translation beyond this point
; =============================================================
 
; 0x8047CF80 -> 47CFFF TSS 128 bytes
; 0x8047D000 -> 47EFFF IO map for (8192*8)=65536 ports
; 0x805FF000 -> 5FFF80 TSS
; 0x80600000 -> 601FFF i/o maps
 
; 0x8047F000 -> 48FFFF page map max 128 Kb
;
 
; 0x80800000 -> kernel heap
; 0x81FFFFFF heap min limit
; 0x80FFFFFF heap min limit
; 0xFDBFFFFF heap max limit
 
; 0xF0000000 -> 0xF1FFFFFF PCI-express extended config space
; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb
; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb
; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb
/kernel/branches/net/network/stack.inc
150,6 → 150,13
 
}
 
 
wait_mutex: ; stub
inc dword [ebx]
 
ret
 
 
include "queue.inc"
 
include "ethernet.inc"
/kernel/branches/net/proc32.inc
4,53 → 4,53
 
; Macroinstructions for defining and calling procedures
 
macro stdcall proc,[arg] ; directly call STDCALL procedure
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
pushd arg
common
end if
call proc }
call proc }
 
macro invoke proc,[arg] ; indirectly call STDCALL procedure
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
pushd arg
common
end if
call [proc] }
call [proc] }
 
macro ccall proc,[arg] ; directly call CDECL procedure
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
call proc
if size@ccall
add esp,size@ccall
add esp, size@ccall
end if }
 
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
call [proc]
if size@ccall
add esp,size@ccall
add esp, size@ccall
end if }
 
macro proc [args] ; define procedure
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
59,10 → 59,10
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
push ebp
mov ebp, esp
if localbytes
sub esp,localbytes
sub esp, localbytes
end if
end if
irps reg, reglist \{ push reg \} }
72,12 → 72,12
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
leave
end if
if (flag and 10000b) | (parmbytes=0)
retn
retn
else
retn parmbytes
retn parmbytes
end if }
 
macro define@proc name,statement
85,20 → 85,20
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
133,9 → 133,9
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }
end if \} }
 
macro defargs@proc [arg]
{ common
144,21 → 144,21
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 \}
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 ? \}
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
177,8 → 177,8
match any =dup (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
 
203,11 → 203,11
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
mov byte [name+position@initlocal], byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
mov word [name+position@initlocal], word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
mov dword [name+position@initlocal], dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
227,43 → 227,43
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
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 \\}
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
/kernel/branches/net/sound/playnote.inc
21,23 → 21,23
align 4
sound_interface:
 
cmp eax, edi ; this is subfunction #55 ?
jne retFunc55 ; if no then return.
cmp eax, ebx ; this is subfunction #55 ?
jne retFunc55 ; if no then return.
 
cmp byte [sound_flag],0
jne retFunc55
cmp byte [sound_flag], 0
jne retFunc55
 
movzx eax, byte [countDelayNote]
or al, al ; player is busy ?
jnz retFunc55 ; return counter delay Note
movzx eax, byte [countDelayNote]
or al, al ; player is busy ?
jnz retFunc55 ; return counter delay Note
 
mov [memAdrNote],edx
call get_pid
mov [pidProcessNote],eax
xor eax, eax ; Ok! EAX = 0
mov [memAdrNote], esi;edx
call get_pid
mov [pidProcessNote], eax
xor eax, eax ; Ok! EAX = 0
retFunc55:
mov [esp+36], eax ; return value EAX for application
ret
mov [esp+32], eax ; return value EAX for application
ret
 
iglobal
align 4
53,114 → 53,114
 
playNote:
; jmp NotPlayNotes
mov esi, [memAdrNote]
or esi, esi ; ESI = 0 ? - OFF Notes Play ?
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure
cmp eax, [count_timer_Note]
jb NotPlayNotes
push eax
inc eax
mov [count_timer_Note], eax
mov al, [countDelayNote]
dec al ; decrement counter Delay for Playing Note
jz NewLoadNote@Delay
cmp al, 0xFF ; this is first Note Play ?
jne NextDelayNote
mov esi, [memAdrNote]
or esi, esi ; ESI = 0 ? - OFF Notes Play ?
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure
cmp eax, [count_timer_Note]
jb NotPlayNotes
push eax
inc eax
mov [count_timer_Note], eax
mov al, [countDelayNote]
dec al ; decrement counter Delay for Playing Note
jz NewLoadNote@Delay
cmp al, 0xFF ; this is first Note Play ?
jne NextDelayNote
;This is FIRST Note, save counter channel 2 chip 8253
mov al, 0xB6 ; control byte to timer chip 8253
out 0x43, al ; Send it to the control port chip 8253
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253
mov ah, al ; AH = Lower byte counter channel 2
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253
mov al, 0xB6 ; control byte to timer chip 8253
out 0x43, al ; Send it to the control port chip 8253
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253
mov ah, al ; AH = Lower byte counter channel 2
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253
NewLoadNote@Delay:
cld
cld
; lodsb ; load AL - counter Delay
call ReadNoteByte
or al, al ; THE END ?
jz EndPlayNote
cmp al, 0x81
jnc NoteforOctave
mov [countDelayNote], al
call ReadNoteByte
or al, al ; THE END ?
jz EndPlayNote
cmp al, 0x81
jnc NoteforOctave
mov [countDelayNote], al
; lodsw ; load AX - counter for Note!
call ReadNoteByte
mov ah,al
call ReadNoteByte
xchg al,ah
jmp pokeNote
call ReadNoteByte
mov ah, al
call ReadNoteByte
xchg al, ah
jmp pokeNote
 
EndPlayNote: ; THE END Play Notes!
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253
xchg al, ah ; reverse byte in word
out 0x42, al ; restore Lower byte counter channel 2
mov al, ah ; AL = Upper byte counter channel 2
out 0x42, al ; restore Upper byte channel 2
xor eax, eax ; EAX = 0
mov [memAdrNote], eax ; clear header control Delay-Note string
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253
xchg al, ah ; reverse byte in word
out 0x42, al ; restore Lower byte counter channel 2
mov al, ah ; AL = Upper byte counter channel 2
out 0x42, al ; restore Upper byte channel 2
xor eax, eax ; EAX = 0
mov [memAdrNote], eax; clear header control Delay-Note string
NextDelayNote:
mov [countDelayNote], al ; save new counter delay Note
pop eax
mov [countDelayNote], al; save new counter delay Note
pop eax
NotPlayNotes:
RET
 
NoteforOctave:
sub al, 0x81 ; correction value for delay Note
mov [countDelayNote], al ; save counter delay this new Note
sub al, 0x81 ; correction value for delay Note
mov [countDelayNote], al; save counter delay this new Note
; lodsb ; load pack control code
call ReadNoteByte
cmp al, 0xFF ; this is PAUSE ?
jne packCode ; no, this is PACK CODE
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
jmp saveESI
call ReadNoteByte
cmp al, 0xFF ; this is PAUSE ?
jne packCode ; no, this is PACK CODE
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
jmp saveESI
 
packCode:
mov cl, al ; save code
and al, 0xF ; clear upper bits
dec al ; correction
add al, al ; transform number to offset constant
movsx eax, al ; EAX - offset
add eax, dword kontrOctave ; EAX - address from constant
mov ax, [eax] ; read constant
shr cl, 4 ; transform for number Octave
shr ax, cl ; calculate from Note this Octave!
mov cl, al ; save code
and al, 0xF ; clear upper bits
dec al ; correction
add al, al ; transform number to offset constant
movsx eax, al ; EAX - offset
add eax, dword kontrOctave; EAX - address from constant
mov ax, [eax] ; read constant
shr cl, 4 ; transform for number Octave
shr ax, cl ; calculate from Note this Octave!
pokeNote:
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253
mov al, ah
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253
in al, 0x61 ; Get contents of system port B chip 8255
or al, 3 ; Turn ON timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253
mov al, ah
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253
in al, 0x61 ; Get contents of system port B chip 8255
or al, 3 ; Turn ON timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
saveESI:
; mov [memAdrNote], esi ; save new header control Delay-Note string
pop eax
pop eax
RET
ReadNoteByte:
;result:
; al - note
push eax
push ecx
push edx
push esi
push eax
push ecx
push edx
push esi
 
mov eax,[pidProcessNote]
call pid_to_slot
test eax,eax
jz .failed
lea ecx,[esp+12]
mov edx,1
mov esi,[memAdrNote]
inc [memAdrNote]
mov eax, [pidProcessNote]
call pid_to_slot
test eax, eax
jz .failed
lea ecx, [esp+12]
mov edx, 1
mov esi, [memAdrNote]
inc [memAdrNote]
 
call read_process_memory
call read_process_memory
.failed:
pop esi
pop edx
pop ecx
pop eax
ret
pop esi
pop edx
pop ecx
pop eax
ret
;------------------- END CODE -------------------
/kernel/branches/net/struct.inc
7,89 → 7,89
match child parent, name \{ fields@struct equ child,fields@\#parent \}
sub@struct equ
struc db [val] \{ \common define field@struct .,db,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc dw [val] \{ \common define field@struct .,dw,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc du [val] \{ \common define field@struct .,du,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc dd [val] \{ \common define field@struct .,dd,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc dp [val] \{ \common define field@struct .,dp,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc dq [val] \{ \common define field@struct .,dq,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc dt [val] \{ \common define field@struct .,dt,<val>
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rb count \{ define field@struct .,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rw count \{ define field@struct .,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rd count \{ define field@struct .,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rp count \{ define field@struct .,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rq count \{ define field@struct .,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
struc rt count \{ define field@struct .,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
fields@struct equ fields@struct,field@struct \}
macro db [val] \{ \common \local anonymous
define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,db,<val>
fields@struct equ fields@struct,field@struct \}
macro dw [val] \{ \common \local anonymous
define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dw,<val>
fields@struct equ fields@struct,field@struct \}
macro du [val] \{ \common \local anonymous
define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,du,<val>
fields@struct equ fields@struct,field@struct \}
macro dd [val] \{ \common \local anonymous
define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dd,<val>
fields@struct equ fields@struct,field@struct \}
macro dp [val] \{ \common \local anonymous
define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dp,<val>
fields@struct equ fields@struct,field@struct \}
macro dq [val] \{ \common \local anonymous
define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dq,<val>
fields@struct equ fields@struct,field@struct \}
macro dt [val] \{ \common \local anonymous
define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dt,<val>
fields@struct equ fields@struct,field@struct \}
macro rb count \{ \local anonymous
define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,db,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rw count \{ \local anonymous
define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dw,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rd count \{ \local anonymous
define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dd,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rp count \{ \local anonymous
define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dp,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rq count \{ \local anonymous
define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dq,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro rt count \{ \local anonymous
define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
define field@struct anonymous,dt,count dup (?)
fields@struct equ fields@struct,field@struct \}
macro union \{ fields@struct equ fields@struct,,union,<
sub@struct equ union \}
sub@struct equ union \}
macro struct \{ fields@struct equ fields@struct,,substruct,<
sub@struct equ substruct \} }
sub@struct equ substruct \} }
 
macro ends
{ match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
restruc rb,rw,rd,rp,rq,rt
purge db,dw,du,dd,dp,dq,dt
purge rb,rw,rd,rp,rq,rt
purge union,struct
match name tail,fields@struct, \\{ if $
display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah
err
end if \\}
match name=,fields,fields@struct \\{ fields@struct equ
make@struct name,fields
define fields@\\#name fields \\}
end virtual \}
match any, sub@struct \{ fields@struct equ fields@struct> \}
restore sub@struct }
 
100,7 → 100,7
forward
local sub
match , field \{ make@substruct type,name,sub def
define equ define,.,sub, \}
define equ define,.,sub, \}
match any, field \{ define equ define,.#field,type,<def> \}
common
match fields, define \{ define@struct fields \} }
138,39 → 138,39
forward
match , value \\\\{ field type def \\\\}
match any, value \\\\{ field type value
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
if ~ field eq .
rb sizeof.#name#field - ($-field)
end if \\\\}
common label . at \\..base \\\}
\\}
macro name value \\{
match any, fields@struct \\\{ \\\local anonymous
fields@struct equ fields@struct,anonymous,name,<values> \\\}
fields@struct equ fields@struct,anonymous,name,<values> \\\}
match , fields@struct \\\{
forward
match , value \\\\{ type def \\\\}
match any, value \\\\{ \\\\local ..field
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
..field = $
type value
if ~ field eq .
rb sizeof.#name#field - ($-..field)
end if \\\\}
common \\\} \\} \} }
 
macro enable@substruct
{ macro make@substruct substruct,parent,name,[field,type,def]
\{ \common
\local define
define equ parent,name
\local define
define equ parent,name
\forward
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\local sub
match , field \\{ match any, type \\\{ enable@substruct
make@substruct type,parent,sub def
purge make@substruct
define equ define,.,sub, \\\} \\}
match any, field \\{ define equ define,.\#field,type,<def> \\}
\common
match fields, define \\{ define@\#substruct fields \\} \} }
match fields, define \\{ define@\#substruct fields \\} \} }
 
enable@substruct
 
204,14 → 204,14
last@union equ
forward
match any, last@union \\{ virtual at .\#name
field type def
end virtual \\}
field type def
end virtual \\}
match , last@union \\{ match , value \\\{ field type def \\\}
match any, value \\\{ field type value \\\} \\}
match any, value \\\{ field type value \\\} \\}
last@union equ field
common rb sizeof.#name - ($ - .\#name) \}
macro name [value] \{ \common \local ..anonymous
..anonymous name value \} }
..anonymous name value \} }
 
macro define@substruct parent,name,[field,type,def]
{ common
232,9 → 232,9
forward
match , value \\{ field type def \\}
match any, value \\{ field type value
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
if ~ field eq .
rb sizeof.#parent#field - ($-field)
end if \\}
common \}
macro name value \{ \local ..anonymous
..anonymous name \} }
..anonymous name \} }
/kernel/branches/net/unpacker.inc
21,7 → 21,7
push eax
add esi, 12
and al, not 0xC0
dec eax
dec al
jz .lzma
.failed:
pop eax
94,14 → 94,14
 
.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)
.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)
.kNumPosBitsMax = 4
.kNumPosStatesMax = (1 shl .kNumPosBitsMax)
 
.kLenNumLowBits = 3
.kLenNumLowSymbols = (1 shl .kLenNumLowBits)
110,64 → 110,64
.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)
.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
.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)
.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
.LZMA_BASE_SIZE = 1846 ; must be ==Literal
.LZMA_LIT_SIZE = 768
 
.kNumTopBits = 24
.kTopValue = (1 shl .kNumTopBits)
.kNumTopBits = 24
.kTopValue = (1 shl .kNumTopBits)
 
.kNumBitModelTotalBits = 11
.kBitModelTotal = (1 shl .kNumBitModelTotalBits)
.kNumMoveBits = 5
.kNumBitModelTotalBits = 11
.kBitModelTotal = (1 shl .kNumBitModelTotalBits)
.kNumMoveBits = 5
 
push edi
; int state=0;
xor ebx, ebx
mov [.previousByte], bl
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
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
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
174,354 → 174,355
; rd->BufferLim = stream+bufferSize
; rd->Range = 0xFFFFFFFF
pop edi
mov ebp, [esi-8] ; dest_length
add ebp, edi ; ebp = destination limit
lodsd
mov ebp, [esi-8] ; dest_length
add ebp, edi ; ebp = destination limit
lodsd
; rd->code_ = eax
mov [.code_], eax
or [.range], -1
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, [.IsMatch*4 + eax + edx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .1
movzx eax, [.previousByte]
cmp edi, ebp
jae .main_loop_done
mov edx, edi
and edx, .posStateMask
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.IsMatch*4 + eax + edx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .1
movzx eax, [.previousByte]
if .literalPosMask
mov ah, dl
and ah, .literalPosMask
mov ah, dl
and ah, .literalPosMask
end if
shr eax, 8-.lc
imul eax, .LZMA_LIT_SIZE*4
add eax, .Literal*4
add eax, [.p]
cmp ebx, .kNumLitStates
jb .literal
xor edx, edx
sub edx, [.rep0]
mov dl, [edi + edx]
call .LzmaLiteralDecodeMatch
jmp @f
shr eax, 8-.lc
imul eax, .LZMA_LIT_SIZE*4
add eax, .Literal*4
add eax, [.p]
cmp ebx, .kNumLitStates
jb .literal
xor edx, edx
sub edx, [.rep0]
mov dl, [edi + edx]
call .LzmaLiteralDecodeMatch
jmp @f
.literal:
call .LzmaLiteralDecode
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
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, [.IsRep*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jnc .10
lea eax, [.IsRepG0*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .111
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.IsRep0Long*4 + eax + edx*4]
add eax, [.p]
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
lea eax, [.IsRep*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jnc .10
lea eax, [.IsRepG0*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .111
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.IsRep0Long*4 + eax + edx*4]
add eax, [.p]
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, [.IsRepG1*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep1]
jnc .l3
lea eax, [.IsRepG1*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep1]
jnc .l3
.l1:
lea eax, [.IsRepG2*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep2]
jnc .l2
xchg [.rep3], eax
lea eax, [.IsRepG2*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep2]
jnc .l2
xchg [.rep3], eax
.l2:
push [.rep1]
pop [.rep2]
push [.rep1]
pop [.rep2]
.l3:
xchg eax, [.rep0]
mov [.rep1], eax
xchg eax, [.rep0]
mov [.rep1], eax
.1101:
mov eax, .RepLencoder*4
add eax, [.p]
call .LzmaLenDecode
cmp bl, 7
setc bl
adc bl, bl
xor bl, 3
add bl, 8
jmp .repmovsb
mov eax, .RepLencoder*4
add eax, [.p]
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, .Lencoder*4
add eax, [.p]
call .LzmaLenDecode
mov eax, .kNumLenToPosStates-1
cmp eax, ecx
jb @f
mov eax, ecx
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, .Lencoder*4
add eax, [.p]
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, .PosSlot*4
add eax, [.p]
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, (.SpecPos - 1)*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
jmp .l6
push ecx
mov ecx, .kNumPosSlotBits
shl eax, cl
shl eax, 2
add eax, .PosSlot*4
add eax, [.p]
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, (.SpecPos - 1)*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
jmp .l6
.l5:
sub ecx, .kNumAlignBits
call .RangeDecoderDecodeDirectBits
mov ecx, .kNumAlignBits
shl eax, cl
add [.rep0], eax
mov eax, .Align_*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
sub ecx, .kNumAlignBits
call .RangeDecoderDecodeDirectBits
mov ecx, .kNumAlignBits
shl eax, cl
add [.rep0], eax
mov eax, .Align_*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
.l6:
pop ecx
inc [.rep0]
jz .main_loop_done
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
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
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
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
lahf
cmp [.range], .kTopValue
jae @f
shl [.range], 8
shl [.code_], 8
lodsb
mov byte [.code_], al
@@:
sahf
pop edx
ret
sahf
pop edx
ret
.ae:
sub [.range], edx
sub [.code_], edx
mov edx, [eax]
shr edx, .kNumMoveBits
sub [eax], edx
stc
jmp .n
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
xor eax, eax
.l:
shr [.range], 1
shl eax, 1
mov edx, [.code_]
sub edx, [.range]
jb @f
mov [.code_], edx
or eax, 1
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
cmp [.range], .kTopValue
jae @f
shl [.range], 8
shl [.code_], 8
push eax
lodsb
mov byte [.code_], al
pop eax
@@:
loop .l
ret
loop .l
ret
 
.LzmaLiteralDecode:
; in: eax->probs
; out: al=byte; destroys edx
push ecx
mov ecx, 1
push ecx
mov ecx, 1
@@:
push eax
lea eax, [eax+ecx*4]
call .RangeDecoderBitDecode
pop eax
adc cl, cl
jnc @b
push eax
lea eax, [eax+ecx*4]
call .RangeDecoderBitDecode
pop eax
adc cl, cl
jnc @b
.LzmaLiteralDecode.ret:
mov al, cl
pop ecx
ret
mov al, cl
pop ecx
ret
.LzmaLiteralDecodeMatch:
; in: eax->probs, dl=matchByte
; out: al=byte; destroys edx
push ecx
mov ecx, 1
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
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
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
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]
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 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
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 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
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.p dd ?
unpack.code_ dd ?
unpack.range dd ?
unpack.rep0 dd ?
unpack.rep1 dd ?
unpack.rep2 dd ?
unpack.rep3 dd ?
unpack.previousByte db ?
;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
unpack.p dd ?
unpack.code_ dd ?
unpack.range dd ?
unpack.rep0 dd ?
unpack.rep1 dd ?
unpack.rep2 dd ?
unpack.rep3 dd ?
unpack.previousByte db ?
endg
/kernel/branches/net/video/blitter.inc
0,0 → 1,444
 
 
 
struc BLITTER
{
.dc.xmin rd 1 ; 0
.dc.ymin rd 1 ; 4
.dc.xmax rd 1 ; 8
.dc.ymax rd 1 ; 12
 
.sc:
.sc.xmin rd 1 ; 16
.sc.ymin rd 1 ; 20
.sc.xmax rd 1 ; 24
.sc.ymax rd 1 ; 28
 
.dst_x rd 1 ; 32
.dst_y rd 1 ; 36
.src_x rd 1 ; 40
.src_y rd 1 ; 44
.w rd 1 ; 48
.h rd 1 ; 52
 
.bitmap rd 1 ; 56
.stride rd 1 ; 60
 
}
 
virtual at 0
BLITTER BLITTER
end virtual
 
 
align 4
 
__L1OutCode:
push ebx
mov ebx, 8
cmp edx, [eax]
jl .L2
xor ebx, ebx
cmp edx, [eax+8]
setg bl
sal ebx, 2
.L2:
cmp ecx, [eax+4]
jge .L3
or ebx, 1
jmp .L4
 
.L3:
cmp ecx, [eax+12]
jle .L4
or ebx, 2
.L4:
mov eax, ebx
pop ebx
ret
 
align 4
block_clip:
push ebp
push edi
push esi
push ebx
sub esp, 4
 
mov ebx, eax
mov [esp], edx
mov ebp, ecx
mov ecx, [ecx]
mov edx, [edx]
call __L1OutCode
 
mov esi, eax
mov edx, [esp+28]
mov ecx, [edx]
.L21:
mov eax, [esp+24]
mov edx, [eax]
mov eax, ebx
call __L1OutCode
 
mov edi, eax
.L20:
mov eax, edi
and eax, esi
jne .L9
cmp esi, edi
je .L9
test esi, esi
jne .L10
test edi, 1
je .L11
mov eax, [ebx+4]
jmp .L25
.L11:
test edi, 2
je .L13
mov eax, [ebx+12]
.L25:
mov edx, [esp+28]
jmp .L22
.L13:
test edi, 4
je .L14
mov eax, [ebx+8]
jmp .L26
.L14:
and edi, 8
je .L12
mov eax, [ebx]
.L26:
mov edx, [esp+24]
.L22:
mov [edx], eax
.L12:
mov eax, [esp+28]
mov ecx, [eax]
jmp .L21
.L10:
test esi, 1
je .L16
mov eax, [ebx+4]
jmp .L23
.L16:
test esi, 2
je .L18
mov eax, [ebx+12]
.L23:
mov [ebp+0], eax
jmp .L17
.L18:
test esi, 4
je .L19
mov eax, [ebx+8]
jmp .L24
.L19:
and esi, 8
je .L17
mov eax, [ebx]
.L24:
mov edx, [esp]
mov [edx], eax
.L17:
mov ecx, [ebp+0]
mov eax, [esp]
mov edx, [eax]
mov eax, ebx
call __L1OutCode
mov esi, eax
jmp .L20
.L9:
add esp, 4
pop ebx
pop esi
pop edi
pop ebp
ret
 
align 4
blit_clip:
 
.sx0 equ 36
.sy0 equ 32
.sx1 equ 28
.sy1 equ 24
 
.dx0 equ 20
.dy0 equ 16
.dx1 equ 12
.dy1 equ 8
 
 
push edi
push esi
push ebx
sub esp, 40
 
mov ebx, ecx
mov edx, [ecx+BLITTER.src_x]
mov [esp+.sx0], edx
mov eax, [ecx+BLITTER.src_y]
mov [esp+.sy0], eax
add edx, [ecx+BLITTER.w]
dec edx
mov [esp+.sx1], edx
add eax, [ecx+BLITTER.h]
dec eax
mov [esp+.sy1], eax
 
lea ecx, [esp+.sy0]
lea edx, [esp+.sx0]
lea eax, [ebx+BLITTER.sc]
lea esi, [esp+.sy1]
 
mov [esp+4], esi
lea esi, [esp+.sx1]
mov [esp], esi
call block_clip
 
mov esi, 1
test eax, eax
jne .L28
 
mov edi, [esp+.sx0]
mov edx, [ebx+BLITTER.dst_x]
add edx, edi
sub edx, [ebx+BLITTER.src_x]
mov [esp+.dx0], edx
 
mov ecx, [esp+.sy0]
mov eax, [ebx+BLITTER.dst_y]
add eax, ecx
sub eax, [ebx+BLITTER.src_y]
mov [esp+.dy0], eax
sub edx, edi
add edx, [esp+.sx1]
mov [esp+.dx1], edx
 
sub eax, ecx
add eax, [esp+.sy1]
mov [esp+.dy1], eax
 
lea ecx, [esp+.dy0]
lea edx, [esp+.dx0]
lea eax, [esp+.dy1]
mov [esp+4], eax
lea eax, [esp+.dx1]
mov [esp], eax
mov eax, ebx
call block_clip
test eax, eax
jne .L28
 
mov edx, [esp+.dx0]
mov eax, [esp+.dx1]
inc eax
sub eax, edx
mov [ebx+BLITTER.w], eax
 
mov eax, [esp+.dy0]
mov ecx, [esp+.dy1]
inc ecx
sub ecx, eax
mov [ebx+BLITTER.h], ecx
 
mov ecx, [ebx+BLITTER.src_x]
add ecx, edx
sub ecx, [ebx+BLITTER.dst_x]
mov [ebx+BLITTER.src_x], ecx
 
mov ecx, [ebx+BLITTER.src_y]
add ecx, eax
sub ecx, [ebx+BLITTER.dst_y]
mov [ebx+BLITTER.src_y], ecx
mov [ebx+BLITTER.dst_x], edx
mov [ebx+BLITTER.dst_y], eax
xor esi, esi
.L28:
mov eax, esi
add esp, 40
pop ebx
pop esi
pop edi
 
 
purge .sx0
purge .sy0
purge .sx1
purge .sy1
 
purge .dx0
purge .dy0
purge .dx1
purge .dy1
 
ret
 
 
 
align 4
 
blit_32:
push ebp
push edi
push esi
push ebx
sub esp, 72
 
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.width]
mov edx, [eax-twdw + WDATA.box.height]
 
xor eax, eax
 
mov [esp+BLITTER.dc.xmin], eax
mov [esp+BLITTER.dc.ymin], eax
mov [esp+BLITTER.dc.xmax], ebx
mov [esp+BLITTER.dc.ymax], edx
 
mov [esp+BLITTER.sc.xmin], eax
mov [esp+BLITTER.sc.ymin], eax
mov eax, [ecx+24]
dec eax
mov [esp+BLITTER.sc.xmax], eax
mov eax, [ecx+28]
dec eax
mov [esp+BLITTER.sc.ymax], eax
 
mov eax, [ecx]
mov [esp+BLITTER.dst_x], eax
mov eax, [ecx+4]
mov [esp+BLITTER.dst_y], eax
 
mov eax, [ecx+16]
mov [esp+BLITTER.src_x], eax
mov eax, [ecx+20]
mov [esp+BLITTER.src_y], eax
mov eax, [ecx+8]
mov [esp+BLITTER.w], eax
mov eax, [ecx+12]
mov [esp+BLITTER.h], eax
 
 
mov eax, [ecx+32]
mov [esp+56], eax
mov eax, [ecx+36]
mov [esp+60], eax
 
mov ecx, esp
call blit_clip
test eax, eax
jne .L57
 
inc [mouse_pause]
call [_display.disable_mouse]
 
mov eax, [TASK_BASE]
 
mov ebx, [esp+BLITTER.dst_x]
mov ebp, [esp+BLITTER.dst_y]
add ebx, [eax-twdw + WDATA.box.left]
add ebp, [eax-twdw + WDATA.box.top]
mov edi, ebp
 
imul edi, [_display.pitch]
imul ebp, [_display.width]
add ebp, ebx
add ebp, [_WinMapAddress]
 
mov eax, [esp+BLITTER.src_y]
imul eax, [esp+BLITTER.stride]
mov esi, [esp+BLITTER.src_x]
lea esi, [eax+esi*4]
add esi, [esp+BLITTER.bitmap]
 
mov ecx, [esp+BLITTER.h]
mov edx, [esp+BLITTER.w]
 
test ecx, ecx ;FIXME check clipping
jz .L57
 
test edx, edx
jz .L57
 
cmp [_display.bpp], 32
jne .core_24
 
lea edi, [edi+ebx*4]
 
mov ebx, [CURRENT_TASK]
 
align 4
.outer32:
xor ecx, ecx
 
align 4
.inner32:
cmp [ebp+ecx], bl
jne @F
 
mov eax, [esi+ecx*4]
mov [LFB_BASE+edi+ecx*4], eax
@@:
inc ecx
dec edx
jnz .inner32
 
add esi, [esp+BLITTER.stride]
add edi, [_display.pitch]
add ebp, [_display.width]
 
mov edx, [esp+BLITTER.w]
dec [esp+BLITTER.h]
jnz .outer32
 
.done:
dec [mouse_pause]
call [draw_pointer]
.L57:
add esp, 72
pop ebx
pop esi
pop edi
pop ebp
ret
 
.core_24:
lea ebx, [ebx+ebx*2]
lea edi, [LFB_BASE+edi+ebx]
mov ebx, [CURRENT_TASK]
 
align 4
.outer24:
mov [esp+64], edi
xor ecx, ecx
 
align 4
.inner24:
cmp [ebp+ecx], bl
jne @F
 
mov eax, [esi+ecx*4]
 
lea edi, [edi+ecx*2]
mov [edi+ecx], ax
shr eax, 16
mov [edi+ecx+2], al
@@:
mov edi, [esp+64]
inc ecx
dec edx
jnz .inner24
 
add esi, [esp+BLITTER.stride]
add edi, [_display.pitch]
add ebp, [_display.width]
 
mov edx, [esp+BLITTER.w]
dec [esp+BLITTER.h]
jnz .outer24
 
jmp .done
/kernel/branches/net/video/cursors.inc
43,246 → 43,246
counter dd ?
endl
 
mov esi, [src]
add esi,[esi+18]
mov eax,esi
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
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
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 edi, [dst]
add edi, 32*31*4
mov [rBase], edi
 
mov esi,[pQuad]
mov esi, [pQuad]
.l21:
mov ebx, [pBits]
mov ebx, [ebx]
bswap ebx
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
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 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
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 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
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
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 edi, [dst]
add edi, 32*31*4
mov [rBase], edi
 
mov esi,[pQuad]
mov ebx, [pBits]
mov esi, [pQuad]
mov ebx, [pBits]
.l4:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 16
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 16
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
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
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
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
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
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
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
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 edi, [dst]
add edi, 32*31*4
mov [rBase], edi
 
mov esi,[pQuad]
mov ebx, [pBits]
mov esi, [pQuad]
mov ebx, [pBits]
.l81:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
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
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
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
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
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 edi, [dst]
add edi, 32*31*4
mov [rBase], edi
 
mov esi,[pAnd]
mov ebx, [pQuad]
mov esi, [pAnd]
mov ebx, [pQuad]
.row_24:
mov eax, [esi]
bswap eax
mov [counter], 32
mov eax, [esi]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
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
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
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
mov eax, [hcursor]
cmp [eax+CURSOR.magic], 'CURS'
jne .fail
; cmp [eax+CURSOR.size], CURSOR_SIZE
; jne .fail
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
.fail:
mov eax, [def_cursor]
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
mov eax, [def_cursor]
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
endp
 
; param
295,83 → 295,77
.flags equ esp+4
.hcursor equ esp+8
 
sub esp, 4 ;space for .hcursor
push ecx
push ebx
sub esp, 4 ;space for .hcursor
push ecx
push ebx
 
mov ebx, eax
mov eax, CURSOR.sizeof
call create_kernel_object
test eax, eax
jz .fail
mov ebx, eax
mov eax, CURSOR.sizeof
call create_kernel_object
test eax, eax
jz .fail
 
mov [.hcursor],eax
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
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
stdcall kernel_alloc, 0x1000
test eax, eax
jz .fail
 
mov edi, [.hcursor]
mov [edi+CURSOR.base], eax
mov edi, [.hcursor]
mov [edi+CURSOR.base], eax
 
mov esi, [.src]
mov ebx, [.flags]
cmp bx, LOAD_INDIRECT
je .indirect
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
movzx ecx, word [esi+10]
movzx edx, word [esi+12]
mov [edi+CURSOR.hot_x], ecx
mov [edi+CURSOR.hot_y], edx
 
stdcall init_cursor, eax, esi
stdcall init_cursor, eax, esi
 
mov eax, [.hcursor]
lea eax, [eax+CURSOR.list_next]
lea edx, [_display.cr_list.next]
mov ecx, [.hcursor]
lea ecx, [ecx+CURSOR.list_next]
lea edx, [_display.cr_list.next]
 
pushfd
cli
mov ecx, [edx]
pushfd
cli
list_add ecx, edx ;list_add_tail(new, head)
popfd
 
mov [eax], ecx
mov [eax+4], edx
 
mov [ecx+4], eax
mov [edx], eax
popfd
 
mov eax, [.hcursor]
mov eax, [.hcursor]
.check_hw:
cmp [_display.init_cursor], 0
je .fail
cmp [_display.init_cursor], 0
je .fail
 
push eax
call [_display.init_cursor]
add esp, 4
push eax
call [_display.init_cursor]
add esp, 4
 
mov eax, [.hcursor]
mov eax, [.hcursor]
.fail:
add esp, 12
ret
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
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
jmp .check_hw
xchg edi, eax
mov ecx, 1024
cld
rep movsd
jmp .check_hw
 
align 4
proc load_cursor stdcall, src:dword, flags:dword
379,42 → 373,42
handle dd ?
endl
 
xor eax, eax
cmp [create_cursor], eax
je .fail2
xor eax, eax
cmp [create_cursor], eax
je .fail2
 
mov [handle], eax
cmp word [flags], LOAD_FROM_FILE
jne @F
mov [handle], eax
cmp word [flags], LOAD_FROM_FILE
jne @F
 
stdcall load_file, [src]
test eax, eax
jz .fail
mov [src], eax
stdcall load_file, [src]
test eax, eax
jz .fail
mov [src], eax
@@:
push ebx
push esi
push edi
push ebx
push esi
push edi
 
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
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
 
cmp word [flags], LOAD_FROM_FILE
jne .exit
stdcall kernel_free, [src]
cmp word [flags], LOAD_FROM_FILE
jne .exit
stdcall kernel_free, [src]
.exit:
pop edi
pop esi
pop ebx
pop edi
pop esi
pop ebx
.fail:
mov eax, [handle]
mov eax, [handle]
.fail2:
ret
ret
endp
 
align 4
428,26 → 422,26
out_size dd ?
endl
 
mov esi, [hcursor]
cmp [esi+CURSOR.magic], 'CURS'
jne .fail
mov esi, [hcursor]
cmp [esi+CURSOR.magic], 'CURS'
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, 5
mov ebx, [CURRENT_TASK+ebx+4]
cmp ebx, [esi+CURSOR.pid]
jne .fail
 
mov ebx, [current_slot]
cmp esi, [ebx+APPDATA.cursor]
jne @F
mov eax, [def_cursor]
mov [ebx+APPDATA.cursor], eax
mov ebx, [current_slot]
cmp esi, [ebx+APPDATA.cursor]
jne @F
mov eax, [def_cursor]
mov [ebx+APPDATA.cursor], eax
@@:
mov eax, [hcursor]
call [eax+APPOBJ.destroy]
mov eax, [hcursor]
call [eax+APPOBJ.destroy]
.fail:
ret
ret
endp
 
; param
456,81 → 450,89
align 4
destroy_cursor:
 
push eax
stdcall kernel_free, [eax+CURSOR.base]
pop eax
push eax
stdcall kernel_free, [eax+CURSOR.base]
 
call destroy_kernel_object
ret
mov eax, [esp]
lea eax, [eax+CURSOR.list_next]
 
pushfd
cli
list_del eax
popfd
 
pop eax
call destroy_kernel_object
ret
 
align 4
select_cursor:
mov eax, [esp+4]
mov [_display.cursor], eax
ret 4
mov eax, [esp+4]
mov [_display.cursor], eax
ret 4
 
align 4
proc restore_24 stdcall, x:dword, y:dword
 
push ebx
push ebx
 
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
 
push esi
push edi
push esi
push edi
 
mov esi, cur_saved_data
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
push ecx
mov esi, cur_saved_data
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
push ecx
@@:
mov edi, ebx
add ebx, [BytesPerScanLine]
mov edi, ebx
add ebx, [BytesPerScanLine]
 
mov ecx, [esp]
rep movsb
dec edx
jnz @B
mov ecx, [esp]
rep movsb
dec edx
jnz @B
 
pop ecx
pop edi
pop esi
pop ecx
pop edi
pop esi
.ret:
pop ebx
ret
pop ebx
ret
endp
 
align 4
proc restore_32 stdcall, x:dword, y:dword
 
push ebx
push ebx
 
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
 
push esi
push edi
push esi
push edi
 
mov esi, cur_saved_data
mov esi, cur_saved_data
@@:
mov edi, ebx
add ebx, [BytesPerScanLine]
mov edi, ebx
add ebx, [BytesPerScanLine]
 
mov ecx, [cur.w]
rep movsd
dec edx
jnz @B
mov ecx, [cur.w]
rep movsd
dec edx
jnz @B
 
pop edi
pop edi
.ret:
pop esi
pop ebx
ret
pop esi
pop ebx
ret
endp
 
align 4
541,101 → 543,101
_dy dd ?
endl
 
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
mov ebx, [BytesPerScanLine]
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
mov ebx, [BytesPerScanLine]
 
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
 
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
 
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+ecx*3]
add edx, eax
mov [cur_saved_base],edx
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+ecx*3]
add edx, eax
mov [cur_saved_base], edx
 
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
mov [cur.right], ebx
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
mov edi, cur_saved_data
mov eax, edi
mov edi, cur_saved_data
@@:
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
rep movsb
dec eax
jnz @B
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
rep movsb
dec eax
jnz @B
 
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
 
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
.pix:
lodsd
test eax, 0xFF000000
jz @F
mov [edi], ax
shr eax, 16
mov [edi+2],al
lodsd
test eax, 0xFF000000
jz @F
mov [edi], ax
shr eax, 16
mov [edi+2], al
@@:
add edi, 3
dec ecx
jnz .pix
add edi, 3
dec ecx
jnz .pix
 
dec [h]
jnz .row
ret
dec [h]
jnz .row
ret
endp
 
 
647,159 → 649,151
_dy dd ?
endl
 
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
 
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
 
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
 
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+eax+ecx*4]
mov [cur_saved_base],edx
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+eax+ecx*4]
mov [cur_saved_base], edx
 
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
mov [cur.right], ebx
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
mov edi, cur_saved_data
mov eax, edi
mov edi, cur_saved_data
@@:
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
rep movsd
dec eax
jnz @B
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
rep movsd
dec eax
jnz @B
 
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
 
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
.pix:
lodsd
test eax, 0xFF000000
jz @F
mov [edi], eax
lodsd
test eax, 0xFF000000
jz @F
mov [edi], eax
@@:
add edi, 4
dec ecx
jnz .pix
add edi, 4
dec ecx
jnz .pix
 
dec [h]
jnz .row
ret
dec [h]
jnz .row
ret
endp
 
 
align 4
get_display:
mov eax, _display
ret
mov eax, _display
ret
 
align 4
init_display:
 
xor eax, eax
mov edi, _display
xor eax, eax
mov edi, _display
 
mov [edi+display_t.init_cursor], eax
mov [edi+display_t.select_cursor], eax
mov [edi+display_t.show_cursor], eax
mov [edi+display_t.move_cursor], eax
mov [edi+display_t.restore_cursor], eax
mov [edi+display_t.init_cursor], eax
mov [edi+display_t.select_cursor], eax
mov [edi+display_t.show_cursor], eax
mov [edi+display_t.move_cursor], eax
mov [edi+display_t.restore_cursor], eax
 
lea ecx, [edi+display_t.cr_list.next]
mov [edi+display_t.cr_list.next], ecx
mov [edi+display_t.cr_list.prev], ecx
lea ecx, [edi+display_t.cr_list.next]
mov [edi+display_t.cr_list.next], ecx
mov [edi+display_t.cr_list.prev], ecx
 
cmp [SCR_MODE],word 0x13
jbe .fail
cmp [SCR_MODE], word 0x13
jbe .fail
 
test word [SCR_MODE], 0x4000
jz .fail
test word [SCR_MODE], 0x4000
jz .fail
 
mov ebx, restore_32
mov ecx, move_cursor_32
movzx eax, byte [ScreenBPP]
cmp eax, 32
je @F
mov ebx, restore_32
mov ecx, move_cursor_32
movzx eax, byte [ScreenBPP]
cmp eax, 32
je @F
 
mov ebx, restore_24
mov ecx, move_cursor_24
cmp eax, 24
jne .fail
mov ebx, restore_24
mov ecx, move_cursor_24
cmp eax, 24
jne .fail
@@:
mov [_display.select_cursor], select_cursor
mov [_display.move_cursor], ecx
mov [_display.restore_cursor], ebx
mov [_display.select_cursor], select_cursor
mov [_display.move_cursor], ecx
mov [_display.restore_cursor], ebx
 
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM
mov [def_cursor], eax
ret
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM
mov [def_cursor], eax
ret
.fail:
xor eax, eax
mov [_display.select_cursor], eax
mov [_display.move_cursor], eax
ret
xor eax, eax
mov [_display.select_cursor], eax
mov [_display.move_cursor], eax
ret
 
 
 
 
 
 
 
 
 
 
align 4
def_arrow:
file 'arrow.cur'
/kernel/branches/net/video/vesa12.inc
61,19 → 61,19
 
if TRIDENT
set_bank:
pushfd
cli
cmp al,[BANK_RW]
je .retsb
pushfd
cli
cmp al, [BANK_RW]
je .retsb
 
mov [BANK_RW],al
push dx
mov dx,3D8h
out dx,al
pop dx
mov [BANK_RW], al
push dx
mov dx, 3D8h
out dx, al
pop dx
.retsb:
popfd
ret
popfd
ret
end if
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
82,83 → 82,83
 
if S3_VIDEO
set_bank:
pushfd
cli
cmp al,[BANK_RW]
je .retsb
pushfd
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
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
out dx, al ;3d5 -?
dec dx
mov al, 0x31
out dx, al ;CR31 Memory Configuration Register
inc dx
mov al, 0x48
out dx, al ;3d5 -?
dec dx
mov al, 0x31
out dx, al ;CR31 Memory Configuration Register
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear.
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h,
;for the 864/964 see index 69h.
 
inc dx
in al, dx
dec dx
mov ah, al
mov al, 0x31
out dx, ax
mov al, ah
or al, 9
inc dx
out dx, al
dec dx
mov al, 0x35
out dx, al ;CR35 CRT Register Lock
inc dx
in al, dx
dec dx
and al, 0xF0
mov ch, cl
and ch, 0x0F
or ch, al
mov al, 0x35
out dx, al
inc dx
mov al, ch
out dx, ax
dec dx
mov al, 0x51 ;Extended System Control 2 Register
out dx, al
inc dx
in al, dx
dec dx
and al, 0xF3
shr cl, 2
and cl, 0x0C
or cl, al
mov al, 0x51
out dx, al
inc dx
mov al, cl
out dx, al
dec dx
mov al, 0x38
out dx, al
inc dx
xor al, al
out dx, al
dec dx
pop cx
pop dx
pop ax
inc dx
in al, dx
dec dx
mov ah, al
mov al, 0x31
out dx, ax
mov al, ah
or al, 9
inc dx
out dx, al
dec dx
mov al, 0x35
out dx, al ;CR35 CRT Register Lock
inc dx
in al, dx
dec dx
and al, 0xF0
mov ch, cl
and ch, 0x0F
or ch, al
mov al, 0x35
out dx, al
inc dx
mov al, ch
out dx, ax
dec dx
mov al, 0x51 ;Extended System Control 2 Register
out dx, al
inc dx
in al, dx
dec dx
and al, 0xF3
shr cl, 2
and cl, 0x0C
or cl, al
mov al, 0x51
out dx, al
inc dx
mov al, cl
out dx, al
dec dx
mov al, 0x38
out dx, al
inc dx
xor al, al
out dx, al
dec dx
pop cx
pop dx
pop ax
.retsb:
popfd
ret
popfd
ret
end if
 
;Set bank function for Intel 810/815 chipsets
169,33 → 169,33
if INTEL_VIDEO
 
set_bank:
pushfd
cli
pushfd
cli
 
cmp al,[BANK_RW]
je .retsb
cmp al, [BANK_RW]
je .retsb
 
mov [BANK_RW],al
push ax
push dx
mov dx,3CEh
mov ah,al ; Save value for later use
mov al,10h ; Index GR10 (Address Mapping)
out dx,al ; Select GR10
inc dl
mov al,3 ; Set bits 0 and 1 (Enable linear page mapping)
out dx,al ; Write value
dec dl
mov al,11h ; Index GR11 (Page Selector)
out dx,al ; Select GR11
inc dl
mov al,ah ; Write address
out dx,al ; Write the value
pop dx
pop ax
mov [BANK_RW], al
push ax
push dx
mov dx, 3CEh
mov ah, al ; Save value for later use
mov al, 10h ; Index GR10 (Address Mapping)
out dx, al ; Select GR10
inc dl
mov al, 3 ; Set bits 0 and 1 (Enable linear page mapping)
out dx, al ; Write value
dec dl
mov al, 11h ; Index GR11 (Page Selector)
out dx, al ; Select GR11
inc dl
mov al, ah ; Write address
out dx, al ; Write the value
pop dx
pop ax
.retsb:
popfd
ret
popfd
ret
end if
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
203,268 → 203,268
if (TRIDENT or S3_VIDEO or INTEL_VIDEO)
else
set_bank:
pushfd
cli
pushfd
cli
 
cmp al,[BANK_RW]
je .retsb
cmp al, [BANK_RW]
je .retsb
 
mov [BANK_RW],al
push ax
push dx
mov ah,al
mov dx,0x03D4
mov al,0x39
out dx,al
inc dl
mov al,0xA5
out dx,al
dec dl
mov al,6Ah
out dx,al
inc dl
mov al,ah
out dx,al
dec dl
mov al,0x39
out dx,al
inc dl
mov al,0x5A
out dx,al
dec dl
pop dx
pop ax
mov [BANK_RW], al
push ax
push dx
mov ah, al
mov dx, 0x03D4
mov al, 0x39
out dx, al
inc dl
mov al, 0xA5
out dx, al
dec dl
mov al, 6Ah
out dx, al
inc dl
mov al, ah
out dx, al
dec dl
mov al, 0x39
out dx, al
inc dl
mov al, 0x5A
out dx, al
dec dl
pop dx
pop ax
 
.retsb:
popfd
ret
popfd
ret
end if
 
vesa12_drawbackground:
 
call [_display.disable_mouse]
call [_display.disable_mouse]
 
push eax
push ebx
push ecx
push edx
push eax
push ebx
push ecx
push edx
 
xor edx,edx
mov eax,dword[BgrDataWidth]
mov ebx,dword[BgrDataHeight]
mul ebx
mov ebx,3
mul ebx
mov [imax],eax
mov eax,[draw_data+32+RECT.left]
mov ebx,[draw_data+32+RECT.top]
xor edi,edi ;no force
xor edx, edx
mov eax, dword[BgrDataWidth]
mov ebx, dword[BgrDataHeight]
mul ebx
mov ebx, 3
mul ebx
mov [imax], eax
mov eax, [draw_data+32+RECT.left]
mov ebx, [draw_data+32+RECT.top]
xor edi, edi;no force
 
v12dp3:
 
push eax
push ebx
push eax
push ebx
 
cmp [BgrDrawMode],dword 1 ; tiled background
jne no_vesa12_tiled_bgr
cmp [BgrDrawMode], dword 1 ; tiled background
jne no_vesa12_tiled_bgr
 
push edx
push edx
 
xor edx,edx
div dword [BgrDataWidth]
xor edx, edx
div dword [BgrDataWidth]
 
push edx
mov eax,ebx
xor edx,edx
div dword [BgrDataHeight]
mov ebx,edx
pop eax
push edx
mov eax, ebx
xor edx, edx
div dword [BgrDataHeight]
mov ebx, edx
pop eax
 
pop edx
pop edx
 
no_vesa12_tiled_bgr:
 
cmp [BgrDrawMode],dword 2 ; stretched background
jne no_vesa12_stretched_bgr
cmp [BgrDrawMode], dword 2 ; stretched background
jne no_vesa12_stretched_bgr
 
push edx
push edx
 
mul dword [BgrDataWidth]
mov ecx,[Screen_Max_X]
inc ecx
div ecx
mul dword [BgrDataWidth]
mov ecx, [Screen_Max_X]
inc ecx
div ecx
 
push eax
mov eax,ebx
mul dword [BgrDataHeight]
mov ecx,[Screen_Max_Y]
inc ecx
div ecx
mov ebx,eax
pop eax
push eax
mov eax, ebx
mul dword [BgrDataHeight]
mov ecx, [Screen_Max_Y]
inc ecx
div ecx
mov ebx, eax
pop eax
 
pop edx
pop edx
 
no_vesa12_stretched_bgr:
 
 
mov esi,ebx
imul esi, dword [BgrDataWidth]
add esi,eax
lea esi,[esi*3]
add esi,[img_background] ;IMG_BACKGROUND
pop ebx
pop eax
mov esi, ebx
imul esi, dword [BgrDataWidth]
add esi, eax
lea esi, [esi*3]
add esi, [img_background];IMG_BACKGROUND
pop ebx
pop eax
 
v12di4:
 
mov cl,[esi+2]
shl ecx,16
mov cx,[esi]
mov cl, [esi+2]
shl ecx, 16
mov cx, [esi]
pusha
mov esi,eax
mov edi,ebx
mov eax,[Screen_Max_X]
add eax,1
mul ebx
add eax, [_WinMapAddress]
cmp [eax+esi],byte 1
jnz v12nbgp
mov eax,[BytesPerScanLine]
mov ebx,edi
mul ebx
add eax, esi
lea eax, [VGABasePtr+eax+esi*2]
cmp [ScreenBPP],byte 24
jz v12bgl3
add eax,esi
mov esi, eax
mov edi, ebx
mov eax, [Screen_Max_X]
add eax, 1
mul ebx
add eax, [_WinMapAddress]
cmp [eax+esi], byte 1
jnz v12nbgp
mov eax, [BytesPerScanLine]
mov ebx, edi
mul ebx
add eax, esi
lea eax, [VGABasePtr+eax+esi*2]
cmp [ScreenBPP], byte 24
jz v12bgl3
add eax, esi
 
v12bgl3:
 
push ebx
push eax
push ebx
push eax
 
sub eax,VGABasePtr
sub eax, VGABasePtr
 
shr eax,16
call set_bank
pop eax
and eax,65535
add eax,VGABasePtr
pop ebx
shr eax, 16
call set_bank
pop eax
and eax, 65535
add eax, VGABasePtr
pop ebx
 
mov [eax],cx
add eax,2
shr ecx,16
mov [eax],cl
mov [eax], cx
add eax, 2
shr ecx, 16
mov [eax], cl
sti
 
v12nbgp:
 
popa
add esi,3
inc eax
cmp eax,[draw_data+32+RECT.right]
jg v12nodp31
jmp v12dp3
add esi, 3
inc eax
cmp eax, [draw_data+32+RECT.right]
jg v12nodp31
jmp v12dp3
 
v12nodp31:
 
mov eax,[draw_data+32+RECT.left]
inc ebx
cmp ebx,[draw_data+32+RECT.bottom]
jg v12dp4
jmp v12dp3
mov eax, [draw_data+32+RECT.left]
inc ebx
cmp ebx, [draw_data+32+RECT.bottom]
jg v12dp4
jmp v12dp3
 
v12dp4:
 
pop edx
pop ecx
pop ebx
pop eax
pop edx
pop ecx
pop ebx
pop eax
ret
 
 
vesa12_drawbar:
 
call [_display.disable_mouse]
call [_display.disable_mouse]
 
;; mov [novesachecksum],dword 0
sub edx,ebx
sub ecx,eax
push esi
push edi
push eax
push ebx
push ecx
push edx
mov ecx,[TASK_BASE]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mov ebx,[BytesPerScanLine]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start
jz dbpi2412
add eax,ecx
sub edx, ebx
sub ecx, eax
push esi
push edi
push eax
push ebx
push ecx
push edx
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, [BytesPerScanLine]
mul ebx
pop ecx
add eax, ecx ; x
add eax, ecx
add eax, ecx
cmp [ScreenBPP], byte 24; 24 or 32 bpp ? - x start
jz dbpi2412
add eax, ecx
 
dbpi2412:
 
add eax,VGABasePtr
mov edi,eax
add eax, VGABasePtr
mov edi, eax
 
; x size
 
mov eax,[esp+4] ; [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz dbpi24312
add ecx,eax
mov eax, [esp+4]; [esp+6]
mov ecx, eax
add ecx, eax
add ecx, eax
cmp [ScreenBPP], byte 24; 24 or 32 bpp ? - x size
jz dbpi24312
add ecx, eax
 
dbpi24312:
 
mov ebx,[esp+0]
mov ebx, [esp+0]
 
; check limits ?
 
push eax
push ecx
mov eax,[TASK_BASE]
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.left]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.top]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx,[Screen_Max_X]
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx,[Screen_Max_Y]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
push eax
push ecx
mov eax, [TASK_BASE]
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.left]
cmp ecx, 0
jnz dbcblimitlset12
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.top]
cmp ecx, 0
jnz dbcblimitlset12
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx, [Screen_Max_X]
jnz dbcblimitlset12
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx, [Screen_Max_Y]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
 
dbcblimitlset12:
 
pop ecx
pop eax
push dword 1
pop ecx
pop eax
push dword 1
 
dbcblimitlno12:
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jz dbpi24bit12
jmp dbpi32bit12
cmp [ScreenBPP], byte 24; 24 or 32 bpp ?
jz dbpi24bit12
jmp dbpi32bit12
 
 
; DRAWBAR 24 BBP
472,101 → 472,101
 
dbpi24bit12:
 
push eax
push ebx
push edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
cld
push eax
push ebx
push edx
mov eax, ecx
mov ebx, 3
div ebx
mov ecx, eax
pop edx
pop ebx
pop eax
cld
 
dbnewpi12:
 
push ebx
push edi
push ecx
push ebx
push edi
push ecx
 
xor edx,edx
mov eax,edi
sub eax,VGABasePtr
mov ebx,3
div ebx
add eax, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
cld
xor edx, edx
mov eax, edi
sub eax, VGABasePtr
mov ebx, 3
div ebx
add eax, [_WinMapAddress]
mov ebx, [CURRENT_TASK]
cld
 
dbnp2412:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp24no12
cmp [esp+5*4],dword 0
jz dbimp24yes12
mov dl, [eax]
push eax
push ecx
cmp dl, bl
jnz dbimp24no12
cmp [esp+5*4], dword 0
jz dbimp24yes12
; call dbcplimit
; jnz dbimp24no12
 
dbimp24yes12:
 
push edi
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
and edi,0xffff
add edi,VGABasePtr
mov eax,[esp+8+3*4+16+4+4]
push edi
mov eax, edi
sub eax, VGABasePtr
shr eax, 16
call set_bank
and edi, 0xffff
add edi, VGABasePtr
mov eax, [esp+8+3*4+16+4+4]
stosw
shr eax,16
shr eax, 16
stosb
sti
pop edi
add edi,3
pop ecx
pop eax
inc eax
loop dbnp2412
jmp dbnp24d12
pop edi
add edi, 3
pop ecx
pop eax
inc eax
loop dbnp2412
jmp dbnp24d12
 
dbimp24no12:
 
pop ecx
pop eax
pop ecx
pop eax
cld
add edi,3
inc eax
loop dbnp2412
add edi, 3
inc eax
loop dbnp2412
 
dbnp24d12:
 
mov eax,[esp+3*4+16+4]
test eax,0x80000000
jz nodbgl2412
cmp al,0
jz nodbgl2412
dec eax
mov [esp+3*4+16+4],eax
mov eax, [esp+3*4+16+4]
test eax, 0x80000000
jz nodbgl2412
cmp al, 0
jz nodbgl2412
dec eax
mov [esp+3*4+16+4], eax
 
nodbgl2412:
 
pop ecx
pop edi
pop ebx
add edi,[BytesPerScanLine]
dec ebx
jz dbnonewpi12
jmp dbnewpi12
pop ecx
pop edi
pop ebx
add edi, [BytesPerScanLine]
dec ebx
jz dbnonewpi12
jmp dbnewpi12
 
dbnonewpi12:
 
add esp,7*4
add esp, 7*4
 
ret
ret
 
 
; DRAWBAR 32 BBP
574,109 → 574,109
 
dbpi32bit12:
 
cld
shr ecx,2
cld
shr ecx, 2
 
dbnewpi3212:
 
push ebx
push edi
push ecx
push ebx
push edi
push ecx
 
mov eax,edi
sub eax,VGABasePtr
shr eax,2
add eax, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
cld
mov eax, edi
sub eax, VGABasePtr
shr eax, 2
add eax, [_WinMapAddress]
mov ebx, [CURRENT_TASK]
cld
 
dbnp3212:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp32no12
cmp [esp+5*4],dword 0
jz dbimp32yes12
mov dl, [eax]
push eax
push ecx
cmp dl, bl
jnz dbimp32no12
cmp [esp+5*4], dword 0
jz dbimp32yes12
; call dbcplimit
; jnz dbimp32no12
 
dbimp32yes12:
 
push edi
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
and edi,0xffff
add edi,VGABasePtr
mov eax,[esp+8+3*4+16+4+4]
push edi
mov eax, edi
sub eax, VGABasePtr
shr eax, 16
call set_bank
and edi, 0xffff
add edi, VGABasePtr
mov eax, [esp+8+3*4+16+4+4]
stosw
shr eax,16
shr eax, 16
stosb
sti
pop edi
add edi,4
inc ebp
pop ecx
pop eax
inc eax
loop dbnp3212
jmp dbnp32d12
pop edi
add edi, 4
inc ebp
pop ecx
pop eax
inc eax
loop dbnp3212
jmp dbnp32d12
 
dbimp32no12:
 
pop ecx
pop eax
inc eax
add edi,4
inc ebp
loop dbnp3212
pop ecx
pop eax
inc eax
add edi, 4
inc ebp
loop dbnp3212
 
dbnp32d12:
 
mov eax,[esp+12+16+4]
test eax,0x80000000
jz nodbgl3212
cmp al,0
jz nodbgl3212
dec eax
mov [esp+12+16+4],eax
mov eax, [esp+12+16+4]
test eax, 0x80000000
jz nodbgl3212
cmp al, 0
jz nodbgl3212
dec eax
mov [esp+12+16+4], eax
 
nodbgl3212:
 
pop ecx
pop edi
pop ebx
add edi,[BytesPerScanLine]
dec ebx
jz nodbnewpi3212
jmp dbnewpi3212
pop ecx
pop edi
pop ebx
add edi, [BytesPerScanLine]
dec ebx
jz nodbnewpi3212
jmp dbnewpi3212
 
nodbnewpi3212:
 
add esp,7*4
ret
add esp, 7*4
ret
 
 
Vesa12_putpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[esp+28]
mov edi, eax; x
mov eax, ebx; y
lea edi, [edi+edi*2]
mov ebx, [BytesPerScanLine]
mul ebx
add edi, eax
mov eax, edi
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov eax, [esp+28]
stosw
shr eax,16
mov [edi],al
shr eax, 16
mov [edi], al
sti
ret
 
684,19 → 684,19
 
Vesa12_putpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[esp+28]
mov [edi],ecx
mov edi, eax; x
mov eax, ebx; y
shl edi, 2
mov ebx, [BytesPerScanLine]
mul ebx
add edi, eax
mov eax, edi
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov ecx, [esp+28]
mov [edi], ecx
sti
ret
 
703,19 → 703,19
 
Vesa12_getpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[edi]
and ecx,255*256*256+255*256+255
mov edi, eax; x
mov eax, ebx; y
lea edi, [edi+edi*2]
mov ebx, [BytesPerScanLine]
mul ebx
add edi, eax
mov eax, edi
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov ecx, [edi]
and ecx, 255*256*256+255*256+255
sti
ret
 
722,20 → 722,20
 
Vesa12_getpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[BytesPerScanLine]
xor edx,edx
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[edi]
and ecx,255*256*256+255*256+255
mov edi, eax; x
mov eax, ebx; y
shl edi, 2
mov ebx, [BytesPerScanLine]
xor edx, edx
mul ebx
add edi, eax
mov eax, edi
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov ecx, [edi]
and ecx, 255*256*256+255*256+255
sti
 
ret
754,91 → 754,91
; mov ecx,320*65536+240
; mov edx,20*65536+20
 
call [_display.disable_mouse]
call [_display.disable_mouse]
 
mov [novesachecksum],dword 0
push esi
push edi
push eax
push ebx
push ecx
push edx
movzx eax,word [esp+2]
movzx ebx,word [esp+0]
mov ecx,[TASK_BASE]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mul dword [BytesPerScanLine]
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start
jz pi2412
add eax,ecx
mov [novesachecksum], dword 0
push esi
push edi
push eax
push ebx
push ecx
push edx
movzx eax, word [esp+2]
movzx ebx, word [esp+0]
mov ecx, [TASK_BASE]
add eax, [ecx-twdw+WDATA.box.left]
add ebx, [ecx-twdw+WDATA.box.top]
push eax
mov eax, ebx ; y
mul dword [BytesPerScanLine]
pop ecx
add eax, ecx ; x
add eax, ecx
add eax, ecx
cmp [ScreenBPP], byte 24; 24 or 32 bpp ? - x start
jz pi2412
add eax, ecx
 
pi2412:
 
add eax,VGABasePtr
mov edi,eax
add eax, VGABasePtr
mov edi, eax
 
; x size
 
movzx ecx,word [esp+6]
movzx ecx, word [esp+6]
 
mov esi,[esp+8]
movzx ebx,word [esp+4]
mov esi, [esp+8]
movzx ebx, word [esp+4]
 
; check limits while draw ?
 
push ecx
mov eax,[TASK_BASE]
cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0
jnz dbcblimitlset212
cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx,[Screen_Max_X]
jnz dbcblimitlset212
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx,[Screen_Max_Y]
jnz dbcblimitlset212
pop ecx
push 0
jmp dbcblimitlno212
push ecx
mov eax, [TASK_BASE]
cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0
jnz dbcblimitlset212
cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0
jnz dbcblimitlset212
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx, [Screen_Max_X]
jnz dbcblimitlset212
mov ecx, [eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx, [Screen_Max_Y]
jnz dbcblimitlset212
pop ecx
push 0
jmp dbcblimitlno212
 
dbcblimitlset212:
 
pop ecx
push 1
pop ecx
push 1
 
dbcblimitlno212:
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jnz pi32bit12
cmp [ScreenBPP], byte 24; 24 or 32 bpp ?
jnz pi32bit12
 
pi24bit12:
 
newpi12:
 
push edi
push ecx
push ebx
push edi
push ecx
push ebx
 
mov edx,edi
sub edx,VGABasePtr
mov ebx,3
div ebx
add edx, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
mov bh,[esp+4*3]
mov edx, edi
sub edx, VGABasePtr
mov ebx, 3
div ebx
add edx, [_WinMapAddress]
mov ebx, [CURRENT_TASK]
mov bh, [esp+4*3]
 
np2412:
 
cmp bl,[edx]
jnz imp24no12
cmp bl, [edx]
jnz imp24no12
; mov eax,[esi]
push dword [esp+4*3+20]
call ebp
849,48 → 849,48
 
imp24yes12:
 
push edi
push eax
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
pop eax
and edi,0xffff
add edi,VGABasePtr
mov [edi],ax
shr eax,16
mov [edi+2],al
pop edi
push edi
push eax
mov eax, edi
sub eax, VGABasePtr
shr eax, 16
call set_bank
pop eax
and edi, 0xffff
add edi, VGABasePtr
mov [edi], ax
shr eax, 16
mov [edi+2], al
pop edi
 
imp24no12:
 
inc edx
inc edx
; add esi,3
add edi,3
dec ecx
jnz np2412
add edi, 3
dec ecx
jnz np2412
 
np24d12:
 
pop ebx
pop ecx
pop edi
pop ebx
pop ecx
pop edi
 
add edi,[BytesPerScanLine]
add esi,[esp+32]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get2bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
add edi, [BytesPerScanLine]
add esi, [esp+32]
cmp ebp, putimage_get1bpp
jz .correct
cmp ebp, putimage_get2bpp
jz .correct
cmp ebp, putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
mov eax, [esp+20]
mov byte[eax], 80h
@@:
dec ebx
jnz newpi12
dec ebx
jnz newpi12
 
nonewpi12:
 
903,21 → 903,21
 
newpi3212:
 
push edi
push ecx
push ebx
push edi
push ecx
push ebx
 
mov edx,edi
sub edx,VGABasePtr
shr edx,2
add edx, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
mov bh,[esp+4*3]
mov edx, edi
sub edx, VGABasePtr
shr edx, 2
add edx, [_WinMapAddress]
mov ebx, [CURRENT_TASK]
mov bh, [esp+4*3]
 
np3212:
 
cmp bl,[edx]
jnz imp32no12
cmp bl, [edx]
jnz imp32no12
; mov eax,[esi]
push dword [esp+4*3+20]
call ebp
928,44 → 928,44
 
imp32yes12:
 
push edi
push eax
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
pop eax
and edi,0xffff
mov [edi+VGABasePtr],eax
pop edi
push edi
push eax
mov eax, edi
sub eax, VGABasePtr
shr eax, 16
call set_bank
pop eax
and edi, 0xffff
mov [edi+VGABasePtr], eax
pop edi
 
imp32no12:
 
inc edx
inc edx
; add esi,3
add edi,4
dec ecx
jnz np3212
add edi, 4
dec ecx
jnz np3212
 
np32d12:
 
pop ebx
pop ecx
pop edi
pop ebx
pop ecx
pop edi
 
add edi,[BytesPerScanLine]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get2bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
add edi, [BytesPerScanLine]
cmp ebp, putimage_get1bpp
jz .correct
cmp ebp, putimage_get2bpp
jz .correct
cmp ebp, putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
mov eax, [esp+20]
mov byte[eax], 80h
@@:
dec ebx
jnz newpi3212
dec ebx
jnz newpi3212
 
nonewpi3212:
 
976,29 → 976,29
 
vesa12_read_screen_pixel:
 
and eax,0x3FFFFF
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jz v12rsp24
mov edi,eax
shl edi,2
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[edi]
and eax,0x00ffffff
ret
and eax, 0x3FFFFF
cmp [ScreenBPP], byte 24; 24 or 32 bpp ?
jz v12rsp24
mov edi, eax
shl edi, 2
mov eax, edi
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov eax, [edi]
and eax, 0x00ffffff
ret
v12rsp24:
 
imul eax,3
mov edi,eax
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[edi]
and eax,0x00ffffff
ret
imul eax, 3
mov edi, eax
shr eax, 16
call set_bank
and edi, 65535
add edi, VGABasePtr
mov eax, [edi]
and eax, 0x00ffffff
ret
 
 
/kernel/branches/net/video/vesa20.inc
42,27 → 42,27
; ecx = 00 RR GG BB
 
getpixel:
push eax ebx edx edi
call dword [GETPIXEL]
pop edi edx ebx eax
ret
push eax ebx edx edi
call dword [GETPIXEL]
pop edi edx ebx eax
ret
 
Vesa20_getpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2]; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
 
Vesa20_getpixel32:
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
 
;*************************************************
 
102,195 → 102,195
; edi = parameter for 'get' function
 
vesa20_putimage:
pushad
call [_display.disable_mouse]
sub esp, putimg.stack_data
pushad
call [_display.disable_mouse]
sub esp, putimg.stack_data
; save pointer to image
mov [putimg.pti], ebx
mov [putimg.pti], ebx
; unpack the size
mov eax, ecx
and ecx, 0xFFFF
shr eax, 16
mov [putimg.image_sx], eax
mov [putimg.image_sy], ecx
mov eax, ecx
and ecx, 0xFFFF
shr eax, 16
mov [putimg.image_sx], eax
mov [putimg.image_sy], ecx
; unpack the coordinates
mov eax, edx
and edx, 0xFFFF
shr eax, 16
mov [putimg.image_cx], eax
mov [putimg.image_cy], edx
mov eax, edx
and edx, 0xFFFF
shr eax, 16
mov [putimg.image_cx], eax
mov [putimg.image_cy], edx
; calculate absolute (i.e. screen) coordinates
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.left]
add ebx, [putimg.image_cx]
mov [putimg.abs_cx], ebx
mov ebx, [eax-twdw + WDATA.box.top]
add ebx, [putimg.image_cy]
mov [putimg.abs_cy], ebx
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.left]
add ebx, [putimg.image_cx]
mov [putimg.abs_cx], ebx
mov ebx, [eax-twdw + WDATA.box.top]
add ebx, [putimg.image_cy]
mov [putimg.abs_cy], ebx
; real_sx = MIN(wnd_sx-image_cx, image_sx);
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx
mov ebx, [eax-twdw + WDATA.box.width]; ebx = wnd_sx
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
ret
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
.end_x:
mov [putimg.real_sx], ebx
mov [putimg.real_sx], ebx
; init real_sy
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy
mov ebx, [eax-twdw + WDATA.box.height]; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
ret
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
.end_y:
mov [putimg.real_sy], ebx
mov [putimg.real_sy], ebx
; line increment
mov eax, [putimg.image_sx]
mov ecx, [putimg.real_sx]
sub eax, ecx
mov eax, [putimg.image_sx]
mov ecx, [putimg.real_sx]
sub eax, ecx
;; imul eax, [putimg.source_bpp]
; lea eax, [eax + eax * 2]
call esi
add eax, [putimg.arg_0]
mov [putimg.line_increment], eax
call esi
add eax, [putimg.arg_0]
mov [putimg.line_increment], eax
; winmap new line increment
mov eax, [Screen_Max_X]
inc eax
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
mov eax, [Screen_Max_X]
inc eax
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
; screen new line increment
mov eax, [BytesPerScanLine]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
mov eax, [BytesPerScanLine]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
; pointer to image
mov esi, [putimg.pti]
mov esi, [putimg.pti]
; pointer to screen
mov edx, [putimg.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [putimg.abs_cx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
add edx, eax
mov edx, [putimg.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [putimg.abs_cx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [putimg.abs_cy]
imul eax, [Screen_Max_X]
add eax, [putimg.abs_cy]
add eax, [putimg.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
mov eax, [putimg.abs_cy]
imul eax, [Screen_Max_X]
add eax, [putimg.abs_cy]
add eax, [putimg.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
; get process number
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 32
je put_image_end_32
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 32
je put_image_end_32
;put_image_end_24:
mov edi, [putimg.real_sy]
mov edi, [putimg.real_sy]
align 4
.new_line:
mov ecx, [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
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; mov eax, [esi] ; eax = RRBBGGRR
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
.skip:
; add esi, 3 ;[putimg.source_bpp]
add edx, 3
inc ebp
dec ecx
jnz .new_x
add edx, 3
inc ebp
dec ecx
jnz .new_x
; pop edx ebp
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
ret
add esp, putimg.stack_data
popad
ret
 
put_image_end_32:
mov edi, [putimg.real_sy]
mov edi, [putimg.real_sy]
align 4
.new_line:
mov ecx, [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
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; mov eax, [esi] ; ecx = RRBBGGRR
mov [LFB_BASE+edx], eax
mov [LFB_BASE+edx], eax
.skip:
; add esi, [putimg.source_bpp]
add edx, 4
inc ebp
dec ecx
jnz .new_x
add edx, 4
inc ebp
dec ecx
jnz .new_x
; pop edx ebp
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline];[BytesPerScanLine]
add ebp, [putimg.winmap_newline];[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
call VGA__putimage
mov [EGA_counter],1
ret
add esp, putimg.stack_data
popad
call VGA__putimage
mov [EGA_counter], 1
ret
 
 
;*************************************************
303,50 → 303,50
; edi = 0x00000001 force
 
;;; mov [novesachecksum], dword 0
pushad
cmp [Screen_Max_X], eax
jb .exit
cmp [Screen_Max_Y], ebx
jb .exit
test edi,1 ; force ?
jnz .forced
pushad
cmp [Screen_Max_X], eax
jb .exit
cmp [Screen_Max_Y], ebx
jb .exit
test edi, 1 ; force ?
jnz .forced
 
; not forced:
 
push eax
mov edx,[_display.width] ; screen x size
imul edx, ebx
add eax, [_WinMapAddress]
movzx edx, byte [eax+edx]
cmp edx, [CURRENT_TASK]
pop eax
jne .exit
push eax
mov edx, [_display.width]; screen x size
imul edx, ebx
add eax, [_WinMapAddress]
movzx edx, byte [eax+edx]
cmp edx, [CURRENT_TASK]
pop eax
jne .exit
 
.forced:
; check if negation
test ecx,0x01000000
jz .noneg
call getpixel
not ecx
mov [esp+32-8],ecx
test ecx, 0x01000000
jz .noneg
call getpixel
not ecx
mov [esp+32-8], ecx
.noneg:
; OK to set pixel
call dword [PUTPIXEL] ; call the real put_pixel function
call dword [PUTPIXEL]; call the real put_pixel function
.exit:
popad
ret
popad
ret
 
align 4
Vesa20_putpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
mov eax, [esp+32-8+4]
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2]; edi = x*3
mov eax, [esp+32-8+4]
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
 
 
align 4
353,21 → 353,21
Vesa20_putpixel32:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
mov [LFB_BASE+edi], eax
ret
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4]; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4]; eax = color
mov [LFB_BASE+edi], eax
ret
 
;*************************************************
 
;align 4
calculate_edi:
mov edi, ebx
imul edi, [Screen_Max_X]
add edi, ebx
add edi, eax
ret
mov edi, ebx
imul edi, [Screen_Max_X]
add edi, ebx
add edi, eax
ret
 
;*************************************************
 
376,7 → 376,7
align 4
__sys_draw_line:
; inc [mouse_pause]
call [_display.disable_mouse]
call [_display.disable_mouse]
 
; draw a line
; eax = HIWORD = x1
394,107 → 394,138
dl_dx equ esp+4
dl_dy equ esp+0
 
xor edx, edx ; clear edx
xor esi, esi ; unpack arguments
xor ebp, ebp
mov si, ax ; esi = x2
mov bp, bx ; ebp = y2
shr eax, 16 ; eax = x1
shr ebx, 16 ; ebx = y1
push eax ; save x1
push ebx ; save y1
push esi ; save x2
push ebp ; save y2
xor edx, edx ; clear edx
xor esi, esi ; unpack arguments
xor ebp, ebp
mov si, ax ; esi = x2
mov bp, bx ; ebp = y2
shr eax, 16 ; eax = x1
shr ebx, 16 ; ebx = y1
push eax ; save x1
push ebx ; save y1
push esi ; save x2
push ebp ; save y2
; checking x-axis...
sub esi, eax ; esi = x2-x1
push esi ; save y2-y1
jl .x2lx1 ; is x2 less than x1 ?
jg .no_vline ; x1 > x2 ?
mov edx, ebp ; else (if x1=x2)
call vline
push edx ; necessary to rightly restore stack frame at .exit
jmp .exit
sub esi, eax ; esi = x2-x1
push esi ; save y2-y1
jl .x2lx1 ; is x2 less than x1 ?
jg .no_vline ; x1 > x2 ?
mov edx, ebp ; else (if x1=x2)
call vline
push edx ; necessary to rightly restore stack frame at .exit
jmp .exit
.x2lx1:
neg esi ; get esi absolute value
neg esi ; get esi absolute value
.no_vline:
; checking y-axis...
sub ebp, ebx ; ebp = y2-y1
push ebp ; save y2-y1
jl .y2ly1 ; is y2 less than y1 ?
jg .no_hline ; y1 > y2 ?
mov edx, [dl_x2] ; else (if y1=y2)
call hline
jmp .exit
sub ebp, ebx ; ebp = y2-y1
push ebp ; save y2-y1
jl .y2ly1 ; is y2 less than y1 ?
jg .no_hline ; y1 > y2 ?
mov edx, [dl_x2]; else (if y1=y2)
call hline
jmp .exit
 
.y2ly1:
neg ebp ; get ebp absolute value
neg ebp ; get ebp absolute value
.no_hline:
cmp ebp, esi
jle .x_rules ; |y2-y1| < |x2-x1| ?
cmp [dl_y2], ebx ; make sure y1 is at the begining
jge .no_reverse1
neg dword [dl_dx]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
cmp ebp, esi
jle .x_rules ; |y2-y1| < |x2-x1| ?
cmp [dl_y2], ebx; make sure y1 is at the begining
jge .no_reverse1
neg dword [dl_dx]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse1:
mov eax, [dl_dx]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1)
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0
mov esi, eax ; esi = dx
jmp .y_rules
mov eax, [dl_dx]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1)
;--------------------------------------
; correction for the remainder of the division
shl edx, 1
cmp ebp, edx
jb @f
inc eax
@@:
;--------------------------------------
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 *65536; <<16 ; ebp = dy = 1.0
mov esi, eax ; esi = dx
jmp .y_rules
 
.x_rules:
cmp [dl_x2], eax ; make sure x1 is at the begining
jge .no_reverse2
neg dword [dl_dy]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
cmp [dl_x2], eax ; make sure x1 is at the begining
jge .no_reverse2
neg dword [dl_dy]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse2:
xor edx, edx
mov eax, [dl_dy]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1)
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0
mov ebp, eax ; ebp = dy
xor edx, edx
mov eax, [dl_dy]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1)
;--------------------------------------
; correction for the remainder of the division
shl edx, 1
cmp esi, edx
jb @f
inc eax
@@:
;--------------------------------------
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 *65536;<< 16 ; esi = dx = 1.0
mov ebp, eax ; ebp = dy
.y_rules:
mov eax, [dl_x1]
mov ebx, [dl_y1]
shl eax, 16
shl ebx, 16
mov eax, [dl_x1]
mov ebx, [dl_y1]
shl eax, 16
shl ebx, 16
;-----------------------------------------------------------------------------
align 4
.draw:
push eax ebx
shr eax, 16
shr ebx, 16
call [putpixel]
pop ebx eax
add ebx, ebp ; y = y+dy
add eax, esi ; x = x+dx
dec edx
jnz .draw
push eax ebx
;--------------------------------------
; correction for the remainder of the division
test ah, 0x80
jz @f
add eax, 1 shl 16
@@:
;--------------------------------------
shr eax, 16
;--------------------------------------
; correction for the remainder of the division
test bh, 0x80
jz @f
add ebx, 1 shl 16
@@:
;--------------------------------------
shr ebx, 16
call [putpixel]
pop ebx eax
add ebx, ebp ; y = y+dy
add eax, esi ; x = x+dx
dec edx
jnz .draw
; force last drawn pixel to be at (x2,y2)
mov eax, [dl_x2]
mov ebx, [dl_y2]
call [putpixel]
mov eax, [dl_x2]
mov ebx, [dl_y2]
call [putpixel]
.exit:
add esp, 6*4
popa
add esp, 6*4
popa
; dec [mouse_pause]
call [draw_pointer]
ret
call [draw_pointer]
ret
 
 
hline:
504,18 → 535,18
; ebx = y
; ecx = color
; edi = force ?
push eax edx
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
push eax edx
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
align 4
@@:
call [putpixel]
inc eax
cmp eax, edx
jle @b
pop edx eax
ret
call [putpixel]
inc eax
cmp eax, edx
jle @b
pop edx eax
ret
 
 
vline:
525,18 → 556,18
; edx = y2
; ecx = color
; edi = force ?
push ebx edx
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
push ebx edx
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
align 4
@@:
call [putpixel]
inc ebx
cmp ebx, edx
jle @b
pop edx ebx
ret
call [putpixel]
inc ebx
cmp ebx, edx
jle @b
pop edx ebx
ret
 
 
;*************************************************
565,97 → 596,97
; edx ye
; edi color
vesa20_drawbar:
pushad
call [_display.disable_mouse]
sub esp, drbar.stack_data
mov [drbar.color], edi
sub edx, ebx
jle .exit ;// mike.dld, 2005-01-29
sub ecx, eax
jle .exit ;// mike.dld, 2005-01-29
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
mov [drbar.bar_cx], eax
mov [drbar.bar_cy], ebx
mov edi, [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
mov [drbar.abs_cy], ebx
pushad
call [_display.disable_mouse]
sub esp, drbar.stack_data
mov [drbar.color], edi
sub edx, ebx
jle .exit ;// mike.dld, 2005-01-29
sub ecx, eax
jle .exit ;// mike.dld, 2005-01-29
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
mov [drbar.bar_cx], eax
mov [drbar.bar_cy], ebx
mov edi, [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
mov [drbar.abs_cy], ebx
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx
mov ebx, [edi-twdw + WDATA.box.width]; ebx = wnd_sx
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [drbar.bar_cx]
ja @f
sub ebx, [drbar.bar_cx]
ja @f
.exit: ;// mike.dld, 2005-01-29
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sx]
jbe .end_x
mov ebx, [drbar.bar_sx]
cmp ebx, [drbar.bar_sx]
jbe .end_x
mov ebx, [drbar.bar_sx]
.end_x:
mov [drbar.real_sx], ebx
mov [drbar.real_sx], ebx
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy
mov ebx, [edi-twdw + WDATA.box.height]; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
inc ebx
; \end{diamond}
sub ebx, [drbar.bar_cy]
ja @f
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
sub ebx, [drbar.bar_cy]
ja @f
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sy]
jbe .end_y
mov ebx, [drbar.bar_sy]
cmp ebx, [drbar.bar_sy]
jbe .end_y
mov ebx, [drbar.bar_sy]
.end_y:
mov [drbar.real_sy], ebx
mov [drbar.real_sy], ebx
; line_inc_map
mov eax, [Screen_Max_X]
sub eax, [drbar.real_sx]
inc eax
mov [drbar.line_inc_map], eax
mov eax, [Screen_Max_X]
sub eax, [drbar.real_sx]
inc eax
mov [drbar.line_inc_map], eax
; line_inc_scr
mov eax, [drbar.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
neg eax
add eax, [BytesPerScanLine]
mov [drbar.line_inc_scr], eax
mov eax, [drbar.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
neg eax
add eax, [BytesPerScanLine]
mov [drbar.line_inc_scr], eax
; pointer to screen
mov edx, [drbar.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [drbar.abs_cx]
mov edx, [drbar.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [drbar.abs_cx]
; movzx ebx, byte [ScreenBPP]
; shr ebx, 3
imul eax, ebx
add edx, eax
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [drbar.abs_cy]
imul eax, [Screen_Max_X]
add eax, [drbar.abs_cy]
add eax, [drbar.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
mov eax, [drbar.abs_cy]
imul eax, [Screen_Max_X]
add eax, [drbar.abs_cy]
add eax, [drbar.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
; get process number
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 24
jne draw_bar_end_32
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 24
jne draw_bar_end_32
draw_bar_end_24:
mov eax, [drbar.color] ;; BBGGRR00
mov bh, al ;; bh = BB
shr eax, 8 ;; eax = RRGG
mov eax, [drbar.color] ;; BBGGRR00
mov bh, al ;; bh = BB
shr eax, 8 ;; eax = RRGG
; eax - color high RRGG
; bl - process num
; bh - color low BB
663,78 → 694,78
; edx - pointer to screen
; esi - counter
; edi - counter
mov esi, [drbar.real_sy]
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
mov edi, [drbar.real_sx]
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
cmp byte [ebp], bl
jne .skip
 
mov [LFB_BASE+edx], bh
mov [LFB_BASE+edx + 1], ax
mov [LFB_BASE+edx], bh
mov [LFB_BASE+edx + 1], ax
.skip:
; add pixel
add edx, 3
inc ebp
dec edi
jnz .new_x
add edx, 3
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x00800000
jz @f
test bh, bh
jz @f
dec bh
test eax, 0x00800000
jz @f
test bh, bh
jz @f
dec bh
@@:
; </Ivan 15.10.04>
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
xor eax, eax
ret
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
xor eax, eax
ret
 
draw_bar_end_32:
mov eax, [drbar.color] ;; BBGGRR00
mov esi, [drbar.real_sy]
mov eax, [drbar.color] ;; BBGGRR00
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
mov edi, [drbar.real_sx]
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
cmp byte [ebp], bl
jne .skip
 
mov [LFB_BASE+edx], eax
mov [LFB_BASE+edx], eax
.skip:
; add pixel
add edx, 4
inc ebp
dec edi
jnz .new_x
add edx, 4
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x80000000
jz @f
test al, al
jz @f
dec al
test eax, 0x80000000
jz @f
test al, al
jz @f
dec al
@@:
; </Ivan 15.10.04>
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
call VGA_draw_bar
xor eax, eax
mov [EGA_counter],1
ret
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
call VGA_draw_bar
xor eax, eax
mov [EGA_counter], 1
ret
 
align 4
vesa20_drawbackground_tiled:
760,7 → 791,7
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
add ebp, [_WinMapAddress]
add ebp, [_WinMapAddress]
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
; 2) Calculate offset in background memory block
push eax
931,7 → 962,7
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
sdp3a:
mov eax, [_WinMapAddress]
mov eax, [_WinMapAddress]
cmp [ebp+eax], byte 1
jnz snbgp
mov eax, [bgr_cur_line+esi]
997,12 → 1028,12
mov edi, bgr_cur_line
mov ecx, [Screen_Max_X]
inc ecx
rep movsd
rep movsd
jmp bgr_resmooth1
sdpdone:
add esp, 44
popad
mov [EGA_counter],1
mov [EGA_counter], 1
call VGA_drawbackground
ret
 
/kernel/branches/net/video/vga.inc
17,102 → 17,102
paletteVGA:
 
;16 colour palette
mov dx,0x3c8
mov al,0
out dx,al
mov dx, 0x3c8
mov al, 0
out dx, al
 
mov ecx,16
mov dx,0x3c9
xor eax,eax
mov ecx, 16
mov dx, 0x3c9
xor eax, eax
 
palvganew:
 
mov al,0
test ah,4
jz palvgalbl1
add al,31
test ah,8
jz palvgalbl1
add al,32
mov al, 0
test ah, 4
jz palvgalbl1
add al, 31
test ah, 8
jz palvgalbl1
add al, 32
palvgalbl1:
out dx,al ; red 0,31 or 63
mov al,0
test ah,2
jz palvgalbl2
add al,31
test ah,8
jz palvgalbl2
add al,32
out dx, al; red 0,31 or 63
mov al, 0
test ah, 2
jz palvgalbl2
add al, 31
test ah, 8
jz palvgalbl2
add al, 32
palvgalbl2:
out dx,al ; blue 0,31 or 63
mov al,0
test ah,1
jz palvgalbl3
add al,31
test ah,8
jz palvgalbl3
add al,32
out dx, al; blue 0,31 or 63
mov al, 0
test ah, 1
jz palvgalbl3
add al, 31
test ah, 8
jz palvgalbl3
add al, 32
palvgalbl3:
out dx,al ; green 0,31 or 63
add ah,1
loop palvganew
out dx, al; green 0,31 or 63
add ah, 1
loop palvganew
; mov dx, 3ceh
; mov ax, 0005h
; out dx, ax
ret
ret
 
palette320x200:
 
mov edx,0x3c8
xor eax, eax
out dx,al
mov ecx,256
mov edx,0x3c9
xor eax,eax
mov edx, 0x3c8
xor eax, eax
out dx, al
mov ecx, 256
mov edx, 0x3c9
xor eax, eax
 
palnew:
mov al,0
test ah,64
jz pallbl1
add al,21
mov al, 0
test ah, 64
jz pallbl1
add al, 21
pallbl1:
test ah,128
jz pallbl2
add al,42
test ah, 128
jz pallbl2
add al, 42
pallbl2:
out dx,al
mov al,0
test ah,8
jz pallbl3
add al,8
out dx, al
mov al, 0
test ah, 8
jz pallbl3
add al, 8
pallbl3:
test ah,16
jz pallbl4
add al,15
test ah, 16
jz pallbl4
add al, 15
pallbl4:
test ah,32
jz pallbl5
add al,40
test ah, 32
jz pallbl5
add al, 40
pallbl5:
out dx,al
mov al,0
test ah,1
jz pallbl6
add al,8
out dx, al
mov al, 0
test ah, 1
jz pallbl6
add al, 8
pallbl6:
test ah,2
jz pallbl7
add al,15
test ah, 2
jz pallbl7
add al, 15
pallbl7:
test ah,4
jz pallbl8
add al,40
test ah, 4
jz pallbl8
add al, 40
pallbl8:
out dx,al
add ah,1
loop palnew
out dx, al
add ah, 1
loop palnew
 
ret
ret
align 4
uglobal
novesachecksum dd 0x0
126,250 → 126,250
align 4
checkVga_N13:
 
cmp [SCR_MODE],dword 0x13
jne @f
cmp [SCR_MODE], dword 0x13
jne @f
 
; cnvl:
pushad
cmp [EGA_counter],1
je novesal
mov ecx,[MOUSE_X]
cmp ecx,[novesachecksum]
jne novesal
cmp [EGA_counter], 1
je novesal
mov ecx, [MOUSE_X]
cmp ecx, [novesachecksum]
jne novesal
popad
@@:
ret
 
novesal:
mov [novesachecksum],ecx
mov ecx,0
movzx eax,word [MOUSE_Y]
cmp eax,100
jge m13l3
mov eax,100
mov [novesachecksum], ecx
mov ecx, 0
movzx eax, word [MOUSE_Y]
cmp eax, 100
jge m13l3
mov eax, 100
m13l3:
cmp eax,480-100
jbe m13l4
mov eax,480-100
cmp eax, 480-100
jbe m13l4
mov eax, 480-100
m13l4:
sub eax,100
imul eax,640*4
add ecx,eax
movzx eax,word [MOUSE_X]
cmp eax,160
jge m13l1
mov eax,160
sub eax, 100
imul eax, 640*4
add ecx, eax
movzx eax, word [MOUSE_X]
cmp eax, 160
jge m13l1
mov eax, 160
m13l1:
cmp eax,640-160
jbe m13l2
mov eax,640-160
cmp eax, 640-160
jbe m13l2
mov eax, 640-160
m13l2:
sub eax,160
shl eax,2
add ecx,eax
mov esi,[LFBAddress]
add esi,ecx
mov edi,VGABasePtr
mov edx,200
mov ecx,320
sub eax, 160
shl eax, 2
add ecx, eax
mov esi, [LFBAddress]
add esi, ecx
mov edi, VGABasePtr
mov edx, 200
mov ecx, 320
cld
m13pix:
lodsd
test eax,eax
jz .save_pixel
push eax
mov ebx,eax
and eax,(128+64+32) ; blue
shr eax,5
and ebx,(128+64+32)*256 ; green
shr ebx,8+2
add eax,ebx
pop ebx
and ebx,(128+64)*256*256 ; red
shr ebx,8+8
add eax,ebx
test eax, eax
jz .save_pixel
push eax
mov ebx, eax
and eax, (128+64+32) ; blue
shr eax, 5
and ebx, (128+64+32)*256; green
shr ebx, 8+2
add eax, ebx
pop ebx
and ebx, (128+64)*256*256; red
shr ebx, 8+8
add eax, ebx
.save_pixel:
stosb
loop m13pix
mov ecx,320
add esi,4*(640-320)
dec edx
jnz m13pix
mov [EGA_counter],0
loop m13pix
mov ecx, 320
add esi, 4*(640-320)
dec edx
jnz m13pix
mov [EGA_counter], 0
popad
ret
 
VGA_drawbackground:
; draw all
cmp [SCR_MODE],dword 0x12
cmp [SCR_MODE], dword 0x12
jne .end
pushad
mov esi,[LFBAddress]
mov edi,VGABasePtr
mov ebx,640/32 ; 640*480/(8*4)
mov edx,480
mov esi, [LFBAddress]
mov edi, VGABasePtr
mov ebx, 640/32; 640*480/(8*4)
mov edx, 480
@@:
push ebx edx esi edi
shl edx,9
lea edx,[edx+edx*4]
add esi,edx
shr edx,5
add edi,edx
call VGA_draw_long_line
pop edi esi edx ebx
dec edx
jnz @r
call VGA_draw_long_line_1
push ebx edx esi edi
shl edx, 9
lea edx, [edx+edx*4]
add esi, edx
shr edx, 5
add edi, edx
call VGA_draw_long_line
pop edi esi edx ebx
dec edx
jnz @r
call VGA_draw_long_line_1
popad
.end:
ret
 
VGA_draw_long_line:
mov dx,3ceh
mov ax,0ff08h
mov dx, 3ceh
mov ax, 0ff08h
cli
out dx, ax
mov ax,0005h
out dx, ax
out dx, ax
mov ax, 0005h
out dx, ax
m12pix:
call VGA_draw_32_pixels
dec ebx
jnz m12pix
mov dx,3c4h
mov ax,0ff02h
out dx,ax
mov dx,3ceh
mov ax,0205h
out dx,ax
mov dx,3ceh
mov al,08h
out dx,al
call VGA_draw_32_pixels
dec ebx
jnz m12pix
mov dx, 3c4h
mov ax, 0ff02h
out dx, ax
mov dx, 3ceh
mov ax, 0205h
out dx, ax
mov dx, 3ceh
mov al, 08h
out dx, al
sti
ret
 
VGA_draw_32_pixels:
xor eax,eax
mov ebp,VGA_8_pixels
mov [ebp],eax
mov [ebp+4],eax
mov [ebp+8],eax
mov [ebp+12],eax
mov ch,4
xor eax, eax
mov ebp, VGA_8_pixels
mov [ebp], eax
mov [ebp+4], eax
mov [ebp+8], eax
mov [ebp+12], eax
mov ch, 4
.main_loop:
mov cl,8
mov cl, 8
.convert_pixels_to_VGA:
lodsd ; eax = 24bit colour
test eax,eax
jz .end
rol eax,8
mov al,ch
ror eax,8
mov ch,1
dec cl
shl ch,cl
cmp al,85
test eax, eax
jz .end
rol eax, 8
mov al, ch
ror eax, 8
mov ch, 1
dec cl
shl ch, cl
cmp al, 85
jbe .p13green
or [ebp],ch
cmp al,170
or [ebp], ch
cmp al, 170
jbe .p13green
or [ebp+12],ch
or [ebp+12], ch
.p13green:
cmp ah,85
cmp ah, 85
jbe .p13red
or [ebp+4],ch
cmp ah,170
or [ebp+4], ch
cmp ah, 170
jbe .p13red
or [ebp+12],ch
or [ebp+12], ch
.p13red:
shr eax,8
cmp ah,85
shr eax, 8
cmp ah, 85
jbe .p13cont
or [ebp+8],ch
cmp ah,170
or [ebp+8], ch
cmp ah, 170
jbe .p13cont
or [ebp+12],ch
or [ebp+12], ch
.p13cont:
ror eax,8
mov ch,ah
inc cl
ror eax, 8
mov ch, ah
inc cl
.end:
dec cl
jnz .convert_pixels_to_VGA
inc ebp
dec ch
jnz .main_loop
push esi
sub ebp,4
mov esi,ebp
mov dx, 3c4h
mov ah, 1h
dec cl
jnz .convert_pixels_to_VGA
inc ebp
dec ch
jnz .main_loop
push esi
sub ebp, 4
mov esi, ebp
mov dx, 3c4h
mov ah, 1h
@@:
mov al, 02h
out dx,ax
xchg ax,bp
mov al, 02h
out dx, ax
xchg ax, bp
lodsd
mov [edi],eax
xchg ax,bp
shl ah, 1
cmp ah, 10h
jnz @r
add edi,4
pop esi
mov [edi], eax
xchg ax, bp
shl ah, 1
cmp ah, 10h
jnz @r
add edi, 4
pop esi
ret
 
VGA_putpixel:
; eax = x
; ebx = y
mov ecx,eax
mov ecx, eax
mov eax, [esp+32-8+4] ; color
shl ebx,9
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5
shl ebx, 9
lea ebx, [ebx+ebx*4] ; óìíîæåíèå íà 5
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov edi,edx
mov edi, edx
add edi, [LFBAddress] ; + LFB address
mov [edi], eax ; write to LFB for Vesa2.0
shr edx,5 ; change BytesPerPixel to 1/8
mov edi,edx
shr edx, 5 ; change BytesPerPixel to 1/8
mov edi, edx
add edi, VGABasePtr ; address of pixel in VGA area
and ecx,0x07 ; bit no. (modulo 8)
and ecx, 0x07 ; bit no. (modulo 8)
pushfd
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
xor edx,edx
test eax,eax
jz .p13cont
cmp al,85
jbe .p13green
or dl,0x01
cmp al,170
jbe .p13green
or dl,0x08
xor edx, edx
test eax, eax
jz .p13cont
cmp al, 85
jbe .p13green
or dl, 0x01
cmp al, 170
jbe .p13green
or dl, 0x08
.p13green:
cmp ah,85
jbe .p13red
or dl,0x02
cmp ah,170
jbe .p13red
or dl,0x08
cmp ah, 85
jbe .p13red
or dl, 0x02
cmp ah, 170
jbe .p13red
or dl, 0x08
.p13red:
shr eax,8
cmp ah,85
jbe .p13cont
or dl,0x04
cmp ah,170
jbe .p13cont
or dl,0x08
shr eax, 8
cmp ah, 85
jbe .p13cont
or dl, 0x04
cmp ah, 170
jbe .p13cont
or dl, 0x08
.p13cont:
ror edx,8
inc cl
xor eax,eax
inc ah
shr ax,cl
mov dx,3cfh
ror edx, 8
inc cl
xor eax, eax
inc ah
shr ax, cl
mov dx, 3cfh
cli
out dx,al
mov al,[edi] ; dummy read
rol edx,8
mov [edi],dl
out dx, al
mov al, [edi] ; dummy read
rol edx, 8
mov [edi], dl
popfd
;.end:
ret
377,20 → 377,20
VGA__putimage:
; ecx = size [x|y]
; edx = coordinates [x|y]
cmp [SCR_MODE],dword 0x12
cmp [SCR_MODE], dword 0x12
jne @f
pushad
rol edx,16
movzx eax,dx
rol edx,16
movzx ebx,dx
movzx edx,cx
rol ecx,16
movzx ecx,cx
call VGA_draw_bar_1
popad
pushad
rol edx, 16
movzx eax, dx
rol edx, 16
movzx ebx, dx
movzx edx, cx
rol ecx, 16
movzx ecx, cx
call VGA_draw_bar_1
popad
@@:
ret
ret
 
VGA_draw_bar:
; eax cx
397,54 → 397,54
; ebx cy
; ecx xe
; edx ye
cmp [SCR_MODE],dword 0x12
cmp [SCR_MODE], dword 0x12
jne @f
pushad
sub ecx,eax
sub edx,ebx
and eax,0xffff
and ebx,0xffff
and ecx,0xffff
and edx,0xffff
call VGA_draw_bar_1
popad
pushad
sub ecx, eax
sub edx, ebx
and eax, 0xffff
and ebx, 0xffff
and ecx, 0xffff
and edx, 0xffff
call VGA_draw_bar_1
popad
@@:
ret
ret
 
VGA_draw_bar_1:
mov [temp.cx],eax
mov [temp.cx], eax
mov eax, [TASK_BASE]
add ebx, [eax-twdw + 4]
mov eax, [eax-twdw + 0]
add eax, [temp.cx]
and eax,0xfff8
shl ebx,9
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5
and eax, 0xfff8
shl ebx, 9
lea ebx, [ebx+ebx*4]; óìíîæåíèå íà 5
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov esi,ebx
mov esi, ebx
add esi, [LFBAddress] ; + LFB address
shr ebx,5 ; change BytesPerPixel to 1/8
mov edi,ebx
shr ebx, 5 ; change BytesPerPixel to 1/8
mov edi, ebx
add edi, VGABasePtr ; address of pixel in VGA area
mov ebx,ecx
shr ebx,5
mov ebx, ecx
shr ebx, 5
inc ebx
.main_loop:
call VGA_draw_long_line_1
dec edx
jnz .main_loop
call VGA_draw_long_line_1
call VGA_draw_long_line_1
dec edx
jnz .main_loop
call VGA_draw_long_line_1
ret
 
VGA_draw_long_line_1:
push ebx edx esi edi
shl edx,9
lea edx,[edx+edx*4]
add esi,edx
shr edx,5
add edi,edx
call VGA_draw_long_line
pop edi esi edx ebx
push ebx edx esi edi
shl edx, 9
lea edx, [edx+edx*4]
add esi, edx
shr edx, 5
add edi, edx
call VGA_draw_long_line
pop edi esi edx ebx
ret