/kernel/branches/hd_kolibri/kernel/blkdev/cd_drv.inc |
---|
0,0 → 1,554 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI) |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
; Ïðîöåäóðà äëÿ ïîëíîãî ñ÷èòûâàíèÿ âñåõ |
; äàííûõ èç ñåêòîðà êîìïàêò-äèñêà |
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ |
MaxRetr equ 3 |
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû |
; (â òèêàõ) |
BSYWaitTime equ 1000 ;2 |
;************************************************* |
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ * |
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ * |
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. * |
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. * |
;************************************************* |
ReadCD: |
pusha |
; Çàäàòü ðàçìåð ñåêòîðà |
mov [CDBlockSize],2048 ;2352 |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ |
; ñåêòîðà äàííûõ |
; Çàäàòü êîä êîìàíäû Read CD |
mov [PacketCommand],byte 0x28 ;0xBE |
; Çàäàòü àäðåñ ñåêòîðà |
mov AX,word [CDSectorAddress+2] |
xchg AL,AH |
mov word [PacketCommand+2],AX |
mov AX,word [CDSectorAddress] |
xchg AL,AH |
mov word [PacketCommand+4],AX |
; mov eax,[CDSectorAddress] |
; mov [PacketCommand+2],eax |
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ |
mov [PacketCommand+8],byte 1 |
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå |
; mov [PacketCommand+9],byte 0xF8 |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
; call test_mario79 |
popa |
ret |
;******************************************** |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ * |
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ * |
;******************************************** |
ReadCDWRetr: |
pusha |
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå |
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê |
mov ECX,MaxRetr |
@@NextRetr: |
; Ïîäàòü êîìàíäó |
call ReadCD |
cmp [DevErrorCode],0 |
je @@End_4 |
; Çàäåðæêà íà 2,5 ñåêóíäû |
mov EAX,[timer_ticks] |
add EAX,250 ;50 |
@@Wait: |
call change_task |
cmp EAX,[timer_ticks] |
ja @@Wait |
loop @@NextRetr |
; call test_mario79 |
; Ñîîáùåíèå îá îøèáêå |
; mov SI,offset ErrS |
; call FatalError |
@@End_4: |
popa |
ret |
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå |
; ïàêåòíûõ êîìàíä â ðåæèìå PIO |
; |
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè |
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ) |
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä |
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû |
PacketCommand: rb 12 ;DB 12 DUP (?) |
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà |
;CDDataBuf DB 4096 DUP (0) |
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ |
CDBlockSize DW ? |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ |
CDSectorAddress: DD ? |
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì |
TickCounter_1 DD 0 |
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà |
WURStartTime DD 0 |
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ |
CDDataBuf_pointer dd 0 |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; * |
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. * |
;**************************************************** |
SendPacketDatCommand: |
pushad |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà |
mov AX,[CDBlockSize] |
mov [ATACylinder],AX |
mov [ATAHead],0 |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
; call test_mario79 |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
cli |
mov DX,[ATABasePortAddr] |
mov AX,[PacketCommand] |
out DX,AX |
mov AX,[PacketCommand+2] |
out DX,AX |
mov AX,[PacketCommand+4] |
out DX,AX |
mov AX,[PacketCommand+6] |
out DX,AX |
mov AX,[PacketCommand+8] |
out DX,AX |
mov AX,[PacketCommand+10] |
out DX,AX |
sti |
; Îæèäàíèå ãîòîâíîñòè äàííûõ |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_temp |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice1 |
cli |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf |
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ |
mov CX,[CDBlockSize] |
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ |
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2 |
; Ïðèíÿòü áëîê äàííûõ |
cld |
rep insw |
sti |
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ |
jmp @@End_8 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_1: |
mov [DevErrorCode],1 |
jmp @@End_8 |
@@Err6_temp: |
mov [DevErrorCode],7 |
jmp @@End_8 |
@@Err6: |
mov [DevErrorCode],6 |
@@End_8: |
popad |
ret |
;*********************************************** |
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, * |
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç * |
;* ãëîáàëüíûå ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå; * |
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. * |
;*********************************************** |
SendPacketNoDatCommand: |
pushad |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
mov [ATACylinder],0 |
mov [ATAHead],0 |
mov [ATACommand],0A0h |
call SendCommandToHDD_1 |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó |
; ïàêåòíîé êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice0_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,BSYWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice0_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitDevice0_1 |
; Ïîñëàòü ïàêåòíóþ êîìàíäó |
; cli |
mov DX,[ATABasePortAddr] |
mov AX,word [PacketCommand] |
out DX,AX |
mov AX,word [PacketCommand+2] |
out DX,AX |
mov AX,word [PacketCommand+4] |
out DX,AX |
mov AX,word [PacketCommand+6] |
out DX,AX |
mov AX,word [PacketCommand+8] |
out DX,AX |
mov AX,word [PacketCommand+10] |
out DX,AX |
; sti |
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
@@WaitDevice1_1: |
call change_task |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
mov EAX,[timer_ticks] |
sub EAX,[TickCounter_1] |
cmp EAX,MaxCDWaitTime |
ja @@Err1_3 ;îøèáêà òàéì-àóòà |
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitDevice1_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Err6_1 |
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY |
jz @@WaitDevice1_1 |
jmp @@End_9 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_3: |
mov [DevErrorCode],1 |
jmp @@End_9 |
@@Err6_1: |
mov [DevErrorCode],6 |
@@End_9: |
popad |
ret |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD_1: |
pushad |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2_4 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_4 |
cmp BX,2 |
ja @@Err3_4 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
; mov ecx,0xfff |
mov eax,[timer_ticks] |
mov [TickCounter_1],eax |
@@WaitHDReady_2: |
call change_task |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ |
; dec ecx |
; cmp ecx,0 |
; je @@Err1 |
mov eax,[timer_ticks] |
sub eax,[TickCounter_1] |
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê. |
ja @@Err1_4 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_2 |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady_2 |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5_4 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
jmp @@End_10 |
; Çàïèñàòü êîä îøèáêè |
@@Err1_4: |
mov [DevErrorCode],1 |
jmp @@End_10 |
@@Err2_4: |
mov [DevErrorCode],2 |
jmp @@End_10 |
@@Err3_4: |
mov [DevErrorCode],3 |
jmp @@End_10 |
@@Err4_4: |
mov [DevErrorCode],4 |
jmp @@End_10 |
@@Err5_4: |
mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
@@End_10: |
sti |
popad |
ret |
;************************************************* |
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
WaitUnitReady: |
pusha |
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè |
mov EAX,[timer_ticks] |
mov [WURStartTime],EAX |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY |
mov [PacketCommand],word 00h |
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ |
@@SendCommand: |
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè |
call SendPacketNoDatCommand |
call change_task |
; Ïðîâåðèòü êîä îøèáêè |
cmp [DevErrorCode],0 |
je @@End_11 |
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè |
mov EAX,[timer_ticks] |
sub EAX,[WURStartTime] |
cmp EAX,MaxCDWaitTime |
jb @@SendCommand |
; Îøèáêà òàéì-àóòà |
mov [DevErrorCode],1 |
@@End_11: |
popa |
ret |
;************************************************* |
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
LoadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ |
mov [PacketCommand+4],word 00000011b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
UnloadMedium: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT |
; Çàäàòü êîä êîìàíäû |
mov [PacketCommand],word 1Bh |
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ |
mov [PacketCommand+4],word 00000010b |
; Ïîäàòü êîìàíäó |
call SendPacketNoDatCommand |
popa |
ret |
;************************************************* |
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;************************************************* |
ReadCapacity: |
pusha |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
call clear_packet_buffer |
; Çàäàòü ðàçìåð áóôåðà â áàéòàõ |
mov [CDBlockSize],8 |
; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY |
mov [PacketCommand],word 25h |
; Ïîäàòü êîìàíäó |
call SendPacketDatCommand |
popa |
ret |
clear_packet_buffer: |
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû |
mov [PacketCommand],dword 0 |
mov [PacketCommand+4],dword 0 |
mov [PacketCommand+8],dword 0 |
ret |
/kernel/branches/hd_kolibri/kernel/blkdev/cdrom.inc |
---|
0,0 → 1,269 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
sys_cd_audio: |
cmp word [cdbase],word 0 |
jnz @f |
mov eax,1 |
ret |
@@: |
; eax=1 cdplay at ebx 0x00FFSSMM |
; eax=2 get tracklist size of ecx to [ebx] |
; eax=3 stop/pause playing |
cmp eax,1 |
jnz nocdp |
call sys_cdplay |
ret |
nocdp: |
cmp eax,2 |
jnz nocdtl |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call sys_cdtracklist |
ret |
nocdtl: |
cmp eax,3 |
jnz nocdpause |
call sys_cdpause |
ret |
nocdpause: |
mov eax,0xffffff01 |
ret |
sys_cd_atapi_command: |
pushad |
mov dx,word [cdbase] |
add dx,6 |
mov ax,word [cdid] |
out dx,al |
mov esi,10 |
call delay_ms |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x80 |
cmp al,0 |
jnz res |
jmp cdl6 |
res: |
mov dx,word [cdbase] |
add dx,7 |
mov al,0x8 |
out dx,al |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0xe |
out dx,al |
mov esi,1 |
call delay_ms |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0x8 |
out dx,al |
mov esi,30 |
call delay_ms |
xor cx,cx |
cdl5: |
inc cx |
cmp cx,10 |
jz cdl6 |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x88 |
cmp al,0x00 |
jz cdl5 |
mov esi,100 |
call delay_ms |
jmp cdl5 |
cdl6: |
mov dx,word [cdbase] |
add dx,4 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,5 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,7 |
mov al,0xec |
out dx,al |
mov esi,5 |
call delay_ms |
mov dx,word [cdbase] |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,128 |
out dx,al |
add dx,2 |
mov al,0xa0 |
out dx,al |
xor cx,cx |
mov dx,word [cdbase] |
add dx,7 |
cdl1: |
inc cx |
cmp cx,100 |
jz cdl2 |
in al,dx |
and ax,0x88 |
cmp al,0x8 |
jz cdl2 |
mov esi,2 |
call delay_ms |
jmp cdl1 |
cdl2: |
popad |
ret |
sys_cdplay: |
mov ax,5 |
push ax |
push ebx |
cdplay: |
call sys_cd_atapi_command |
cli |
mov dx,word [cdbase] |
mov ax,0x0047 |
out dx,ax |
mov al,1 |
mov ah,[esp+0] ; min xx |
out dx,ax |
mov ax,[esp+1] ; fr sec |
out dx,ax |
mov ax,256+99 |
out dx,ax |
mov ax,0x0001 |
out dx,ax |
mov ax,0x0000 |
out dx,ax |
mov esi,10 |
call delay_ms |
sti |
add dx,7 |
in al,dx |
test al,1 |
jz cdplayok |
mov ax,[esp+4] |
dec ax |
mov [esp+4],ax |
cmp ax,0 |
jz cdplayfail |
jmp cdplay |
cdplayfail: |
cdplayok: |
pop ebx |
pop ax |
xor eax, eax |
ret |
sys_cdtracklist: |
push ebx |
tcdplay: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x43+2*256 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,200 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
in al,dx |
mov cx,1000 |
mov dx,word [cdbase] |
add dx,7 |
cld |
cdtrnwewait: |
mov esi,10 |
call delay_ms |
in al,dx |
and al,128 |
cmp al,0 |
jz cdtrl1 |
loop cdtrnwewait |
cdtrl1: |
; read the result |
mov ecx,[esp+0] |
mov dx,word [cdbase] |
cdtrread: |
add dx,7 |
in al,dx |
and al,8 |
cmp al,8 |
jnz cdtrdone |
sub dx,7 |
in ax,dx |
mov [ecx],ax |
add ecx,2 |
jmp cdtrread |
cdtrdone: |
pop ecx |
xor eax, eax |
ret |
sys_cdpause: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x004B |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov esi,10 |
call delay_ms |
add dx,7 |
in al,dx |
xor eax, eax |
ret |
/kernel/branches/hd_kolibri/kernel/blkdev/fdc.inc |
---|
0,0 → 1,82 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
uglobal |
dmasize db 0x0 |
dmamode db 0x0 |
endg |
fdc_init: ;start with clean tracks. |
mov edi,OS_BASE+0xD201 |
mov al,0 |
mov ecx,160 |
rep stosb |
ret |
fdc_filesave: ;ebx: cluster to be saved. |
pusha ;returns immediately. does not trigger a write. |
mov eax,ebx |
add eax,31 |
mov bl,18 |
div bl |
mov ah,0 |
add eax,OS_BASE+0xD201 |
mov [eax],byte 1 ;This track is now dirty. |
popa |
ret |
fdc_irq: |
call [fdc_irq_func] |
fdc_null: |
ret |
save_image: |
call reserve_flp |
call restorefatchain |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
mov esi,RAMDISK |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
popa |
mov [flp_status],0 |
ret |
/kernel/branches/hd_kolibri/kernel/blkdev/flp_drv.inc |
---|
0,0 → 1,623 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
mov edi,[TASK_BASE] |
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 |
take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
mov esi,[TASK_BASE] |
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 |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
FDC_C DB ? |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,0xD000 |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
popad |
ret |
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH,AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL,AH |
out DX,AL |
@@End_5: |
; popa |
pop edx ecx eax |
ret |
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
pop ECX |
ret |
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],1 |
ret |
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func],FDCInterrupt |
ret |
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status],FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag],0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
ret |
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
; cmp [fdd_motor_status],1 |
; je fdd_motor_on |
mov al,[flp_number] |
cmp [fdd_motor_status],al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0 |
out DX,AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number],1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
mov AL,1Ch ; Floppy A |
jmp FDDMotorON_1 |
FDDMotorON_B: |
; call FDDMotorOFF_A |
mov AL,2Dh ; Floppy B |
FDDMotorON_1: |
out DX,AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;10 |
jb @@dT |
cmp [flp_number],1 |
jne fdd_motor_on_B |
mov [fdd_motor_status],1 |
jmp fdd_motor_on |
fdd_motor_on_B: |
mov [fdd_motor_status],2 |
fdd_motor_on: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax,[timer_ticks] |
mov [timer_fdd_motor],eax |
ret |
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
check_fdd_motor_status: |
cmp [fdd_motor_status],0 |
je end_check_fdd_motor_status_1 |
mov eax,[timer_ticks] |
sub eax,[timer_fdd_motor] |
cmp eax,500 |
jb end_check_fdd_motor_status |
call FDDMotorOFF |
mov [fdd_motor_status],0 |
end_check_fdd_motor_status_1: |
mov [flp_status],0 |
end_check_fdd_motor_status: |
ret |
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
push DX |
cmp [flp_number],1 |
jne FDDMotorOFF_1 |
call FDDMotorOFF_A |
jmp FDDMotorOFF_2 |
FDDMotorOFF_1: |
call FDDMotorOFF_B |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read],0 |
mov [flp_fat],0 |
ret |
FDDMotorOFF_A: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0Ch ; Floppy A |
out DX,AL |
ret |
FDDMotorOFF_B: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,5h ; Floppy B |
out DX,AL |
ret |
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL,07h |
call FDCDataOutput |
mov AL,00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
; mov [flp_status],0 |
;no_fdc_status_error: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL,0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL,[FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL,08h |
call FDCDataOutput |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_C],AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0],100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
mov AL,[FDC_C] |
cmp AL,[FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL,[FDC_ST0] |
and AL,100b |
shr AL,2 |
cmp AL,[FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status],FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status],FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
call save_timer_fdd_motor |
popa |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11011000b |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@ReadSector_1: |
call ReadSector |
cmp [FDC_Status],0 |
je @@Exit_2 |
cmp [FDC_Status],1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain |
; mov [flp_status],0 |
@@Exit_2: |
popa |
ret |
@@Err_3: |
mov [flp_status],0 |
popa |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11000000b ;11011000b |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@WriteSector_1: |
call WriteSector |
cmp [FDC_Status],0 |
je @@Exit_4 |
cmp [FDC_Status],1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain_1 |
@@Exit_4: |
popa |
ret |
@@Err_4: |
mov [flp_status],0 |
popa |
ret |
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_ST1],AL |
call FDCDataInput |
mov [FDC_ST2],AL |
call FDCDataInput |
mov [FDC_C],AL |
call FDCDataInput |
mov [FDC_H],AL |
call FDCDataInput |
mov [FDC_R],AL |
call FDCDataInput |
mov [FDC_N],AL |
pop AX |
ret |
/kernel/branches/hd_kolibri/kernel/blkdev/hd_drv.inc |
---|
0,0 → 1,871 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Low-level driver for HDD access |
; DMA support by Mario79 |
;************************************************************************** |
; |
; 0x600008 - first entry in cache list |
; |
; +0 - lba sector |
; +4 - state of cache sector |
; 0 = empty |
; 1 = used for read ( same as in hd ) |
; 2 = used for write ( differs from hd ) |
; |
; +65536 - cache entries |
; |
;************************************************************************** |
align 4 |
hd_read: |
;----------------------------------------------------------- |
; input : eax = block to read |
; ebx = destination |
;----------------------------------------------------------- |
and [hd_error], 0 |
push ecx esi edi ; scan cache |
mov ecx,cache_max ; entries in cache |
mov esi,OS_BASE+0x600000+8 |
mov edi,1 |
hdreadcache: |
cmp dword [esi+4],0 ; empty |
je nohdcache |
cmp [esi],eax ; correct sector |
je yeshdcache |
nohdcache: |
add esi,8 |
inc edi |
dec ecx |
jnz hdreadcache |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne return_01 |
cmp [dma_hdd], 1 |
jnz .nodma |
call hd_read_dma |
jmp @f |
.nodma: |
call hd_read_pio |
@@: |
lea esi,[edi*8+OS_BASE+0x600000] |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
yeshdcache: |
mov esi,edi |
shl esi,9 |
add esi,OS_BASE+0x600000+65536 |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
align 4 |
hd_read_pio: |
push eax edx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_read_error |
cli |
push edi |
shl edi,9 |
add edi,OS_BASE+0x600000+65536 |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx eax |
ret |
disable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,2 |
; out dx,al |
cli |
ret |
enable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,0 |
; out dx,al |
sti |
ret |
align 4 |
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
; check if the cache already has the sector and overwrite it |
mov ecx,cache_max |
mov esi,OS_BASE+0x600000+8 |
mov edi,1 |
hdwritecache: |
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
not_in_cache_write: |
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
; sector not found in cache |
; write the block to a new location |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
lea esi,[edi*8+OS_BASE+0x600000] |
mov [esi],eax ; sector number |
yes_in_cache_write: |
mov dword [esi+4],2 ; write - differs from hd |
shl edi,9 |
add edi,OS_BASE+0x600000+65536 |
mov esi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
hd_write_access_denied: |
pop edi esi ecx |
ret |
write_cache: |
;----------------------------------------------------------- |
; write all changed sectors to disk |
;----------------------------------------------------------- |
push eax ecx edx esi edi |
; write difference ( 2 ) from cache to hd |
mov ecx,cache_max |
mov esi,OS_BASE+0x600000+8 |
mov edi,1 |
write_cache_more: |
cmp dword [esi+4],2 ; if cache slot is not different |
jne .write_chain |
mov dword [esi+4],1 ; same as in hd |
mov eax,[esi] ; eax = sector to write |
cmp eax,[PARTITION_START] |
jb danger |
cmp eax,[PARTITION_END] |
ja danger |
cmp [allow_dma_write], 1 |
jnz .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
; ¡ê¥¤¨ï¥¬ § ¯¨áì æ¥¯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+8+4], 2 |
jnz .nonext |
push eax |
inc eax |
cmp eax, [esi+8] |
pop eax |
jnz .nonext |
cmp [cache_chain_started], 1 |
jz @f |
mov [cache_chain_started], 1 |
mov [cache_chain_size], 0 |
mov [cache_chain_pos], edi |
mov [cache_chain_ptr], esi |
@@: |
inc [cache_chain_size] |
cmp [cache_chain_size], 64 |
jnz .continue |
jmp .write_chain |
.nonext: |
call flush_cache_chain |
mov [cache_chain_size], 1 |
mov [cache_chain_ptr], esi |
call write_cache_sector |
jmp .continue |
.nodma: |
call cache_write_pio |
.write_chain: |
call flush_cache_chain |
.continue: |
danger: |
add esi,8 |
inc edi |
dec ecx |
jnz write_cache_more |
call flush_cache_chain |
return_02: |
pop edi esi edx ecx eax |
ret |
flush_cache_chain: |
cmp [cache_chain_started], 0 |
jz @f |
call write_cache_chain |
mov [cache_chain_started], 0 |
@@: |
ret |
align 4 |
cache_write_pio: |
call disable_ide_int |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_write_error |
; cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esi] ; eax = sector to write |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,30h |
out dx,al |
; sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_write_error |
push ecx esi |
; cli |
mov esi,edi |
shl esi,9 |
add esi,OS_BASE+0x600000+65536 ; esi = from memory position |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep outsw |
; sti |
call enable_ide_int |
pop esi ecx |
ret |
align 4 |
find_empty_slot: |
;----------------------------------------------------------- |
; find empty or read slot, flush cache if next 10% is used by write |
; output : edi = cache slot |
;----------------------------------------------------------- |
; push ecx esi |
search_again: |
mov ecx,cache_max*10/100 |
mov edi,[cache_search_start] |
search_for_empty: |
inc edi |
cmp edi,cache_max |
jbe inside_cache |
mov edi,1 |
inside_cache: |
cmp dword [edi*8+OS_BASE+0x600000+4],2 ; get cache slot info |
jb found_slot ; it's empty or read |
dec ecx |
jnz search_for_empty |
call write_cache ; no empty slots found, write all |
cmp [hd_error],0 |
jne found_slot_access_denied |
jmp search_again ; and start again |
found_slot: |
mov [cache_search_start],edi |
found_slot_access_denied: |
ret |
align 4 |
clear_hd_cache: |
push eax ecx edi |
mov edi,OS_BASE+0x600000 |
mov ecx,16384 |
xor eax,eax |
cld |
rep stosd ; clear hd cache with 0 |
mov [cache_search_start],eax |
mov [fat_in_cache],-1 |
mov [fat_change],0 |
pop edi ecx eax |
ret |
save_hd_wait_timeout: |
push eax |
mov eax,[timer_ticks];[0xfdf0] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
align 4 |
check_hd_wait_timeout: |
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax ;[0xfdf0],eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
;iglobal |
; hd_timeout_str db 'K : FS - HD timeout',0 |
; hd_read_str db 'K : FS - HD read error',0 |
; hd_write_str db 'K : FS - HD write error',0 |
; hd_lba_str db 'K : FS - HD LBA error',0 |
;endg |
hd_timeout_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_timeout_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD timeout\n" |
; jmp $ |
mov [hd_error],1 |
pop eax |
ret |
hd_read_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_read_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop edx eax |
ret |
hd_write_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD write error\n" |
ret |
hd_write_error_dma: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi, hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop esi |
ret |
hd_lba_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_lba_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD LBA error\n" |
jmp LBA_read_ret |
align 4 |
wait_for_hd_idle: |
push eax edx |
call save_hd_wait_timeout |
mov edx,[hdbase] |
add edx,0x7 |
wfhil1: |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,128 |
jnz wfhil1 |
@@: |
pop edx eax |
ret |
align 4 |
wait_for_sector_buffer: |
push eax edx |
mov edx,[hdbase] |
add edx,0x7 |
call save_hd_wait_timeout |
hdwait_sbuf: ; wait for sector buffer to be ready |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,8 |
jz hdwait_sbuf |
mov [hd_error],0 |
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
buf_wait_ok: |
pop edx eax |
ret |
; \begin{Mario79} |
align 4 |
wait_for_sector_dma_ide0: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq14_func], hdd_irq14 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
align 4 |
wait_for_sector_dma_ide1: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq15_func], hdd_irq15 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
iglobal |
align 4 |
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
IDE_descriptor_table: |
dd OS_BASE+284000h |
dw 2000h |
dw 8000h |
dma_cur_sector dd not 40h |
irq14_func dd hdd_irq_null |
irq15_func dd hdd_irq_null |
endg |
uglobal |
; all uglobals are zeroed at boot |
dma_process dd 0 |
dma_slot_ptr dd 0 |
cache_chain_pos dd 0 |
cache_chain_ptr dd 0 |
cache_chain_size db 0 |
cache_chain_started db 0 |
dma_task_switched db 0 |
dma_hdd db 0 |
allow_dma_write db 0 |
endg |
align 4 |
hdd_irq14: |
pushfd |
cli |
pushad |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
call update_counters |
mov ebx, [dma_process] |
cmp [CURRENT_TASK], ebx |
jz .noswitch |
mov [dma_task_switched], 1 |
mov edi, [dma_slot_ptr] |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
mov [CURRENT_TASK], ebx |
mov [TASK_BASE], edi |
mov byte [0xFFFF], 1 |
call do_change_task |
.noswitch: |
popad |
popfd |
align 4 |
hdd_irq_null: |
ret |
align 4 |
hdd_irq15: |
pushfd |
cli |
pushad |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
call update_counters |
mov ebx, [dma_process] |
cmp [CURRENT_TASK], ebx |
jz .noswitch |
mov [dma_task_switched], 1 |
mov edi, [dma_slot_ptr] |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
mov [CURRENT_TASK], ebx |
mov [TASK_BASE], edi |
mov byte [0xFFFF], 1 |
call do_change_task |
.noswitch: |
popad |
popfd |
ret |
align 4 |
hd_read_dma: |
push eax |
push edx |
mov edx, [dma_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, 15 |
cmp [esp+4], edx |
ja .notread |
mov eax, [esp+4] |
sub eax, [dma_cur_sector] |
shl eax, 9 |
add eax, OS_BASE+0x284000 |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
add edi, OS_BASE+0x610000 |
mov ecx, 512/4 |
cld |
rep movsd |
pop edi esi ecx |
pop edx |
pop eax |
ret |
.notread: |
mov eax, IDE_descriptor_table-OS_BASE |
mov dword [eax+OS_BASE], 0x284000 |
mov word [eax+4+OS_BASE], 0x2000 |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_read_error |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov eax, 10h |
out dx, al |
inc edx |
mov eax, [esp+4] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xC8 |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 9 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_read_error |
pop edx |
pop eax |
mov [dma_cur_sector], eax |
jmp hd_read_dma |
align 4 |
write_cache_chain: |
push esi |
mov eax, IDE_descriptor_table |
mov edx, [cache_chain_pos] |
shl edx, 9 |
add edx, OS_BASE+0x610000 |
mov [eax], edx |
movzx edx, [cache_chain_size] |
shl edx, 9 |
mov [eax+4], dx |
jmp do_write_dma |
write_cache_sector: |
push esi |
mov eax, IDE_descriptor_table |
mov edx, edi |
shl edx, 9 |
add edx, OS_BASE+0x610000 |
mov [eax], edx |
mov word [eax+4], 0x200 |
do_write_dma: |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov al, [cache_chain_size] |
out dx, al |
inc edx |
mov esi, [cache_chain_ptr] |
mov eax, [esi] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xCA |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 1 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
mov [dma_cur_sector], not 0x40 |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
pop esi |
ret |
uglobal |
IDEContrRegsBaseAddr dw ? |
endg |
; \end{Mario79} |
/kernel/branches/hd_kolibri/kernel/blkdev/rd.inc |
---|
0,0 → 1,2473 |
$Revision: 442 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; calculate fat chain |
calculatefatchain: |
pushad |
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 |
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters |
jnz fcnew |
popad |
ret |
restorefatchain: ; restore fat chain |
pushad |
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 |
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 |
popad |
ret |
ramdisk_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; rewr.by Mihasik |
;--------------------------------------------- |
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 |
rdfs1: |
repne scasw |
jnz rdfs2 ;if last cluster not 0 |
inc ebx |
test ecx, ecx |
jnz rdfs1 |
rdfs2: |
shl ebx,9 ;free clusters*512 |
mov edi,ebx |
pop ecx ebx eax |
ret |
expand_filename: |
;--------------------------------------------- |
; |
; exapand filename with '.' to 11 character |
; eax - pointer to filename |
;--------------------------------------------- |
push esi edi ebx |
mov edi,esp ; check for '.' in the name |
add edi,12+8 |
mov esi,eax |
mov eax,edi |
mov [eax+0],dword ' ' |
mov [eax+4],dword ' ' |
mov [eax+8],dword ' ' |
flr1: |
cmp [esi],byte '.' |
jne flr2 |
mov edi,eax |
add edi,7 |
jmp flr3 |
flr2: |
mov bl,[esi] |
mov [edi],bl |
flr3: |
inc esi |
inc edi |
mov ebx,eax |
add ebx,11 |
cmp edi,ebx |
jbe flr1 |
pop ebx edi esi |
ret |
fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X 0=root |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
test ebx,ebx ;if ebx=0 - set to 1 |
jnz frfl5 |
inc ebx |
frfl5: |
test ecx,ecx ;if ecx=0 - set to 1 |
jnz frfl6 |
inc ecx |
frfl6: |
test esi,esi ; return ramdisk root |
jnz fr_noroot ;if not root |
cmp ebx,14 ;14 clusters=root dir |
ja oorr |
cmp ecx,14 |
ja oorr |
jmp fr_do |
oorr: |
mov eax,5 ;out of root range (fnf) |
xor ebx,ebx |
dec ebx ;0xffffffff |
ret |
fr_do: ;reading rootdir |
mov edi,edx |
dec ebx |
push edx |
mov edx,ecx |
add edx,ebx |
cmp edx,15 ;ebx+ecx=14+1 |
pushf |
jbe fr_do1 |
sub edx,14 |
sub ecx,edx |
fr_do1: |
shl ebx,9 |
mov esi,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 |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifound |
add esp,32+28 ;if file not found |
ret |
fifound: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi=cluster |
frnew: |
add eax,31 ;bootsector+2*fat+filenames |
shl eax,9 ;*512 |
add eax,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 |
frfl7: |
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 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread |
sub [esp+24],dword 512 |
jmp frnew |
frnoread2: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
ret |
frnoread: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax ;read ok |
ret |
filedelete: |
;-------------------------------------------- |
; |
; filedelete - sys floppy |
; in: |
; eax - pointer to filename 11 chars |
; |
; out: |
; eax - 0 = successful, 5 = file not found |
; |
;-------------------------------------------- |
sub esp,32 |
call expand_filename |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifoundd |
pop edi esi edx ecx ebx eax ;file not found |
add esp,32 |
mov eax,5 |
ret |
fifoundd: |
mov [edi-11],byte 0xE5 ;mark filename deleted |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi = cluster |
frnewd: |
shl edi,1 ;find next cluster from FAT |
add edi,RAMDISK_FAT |
movzx eax,word [edi] |
mov [edi],word 0x0 ;clear fat chain cluster |
mov edi,eax |
cmp edi,dword 0xff8 ;last cluster ? |
jb frnewd |
pop edi esi edx ecx ebx eax |
add esp,32 |
xor eax,eax ; file found |
ret |
filesave: |
;---------------------------------------------------------- |
; |
; filesave - sys floppy |
; |
; eax points to filename 11 chars |
; |
; eax ; pointer to file name |
; ebx ; buffer |
; ecx ; count to write in bytes |
; edx ; 0 create new , 1 append |
; |
;----------------------------------------------------------- |
sub esp,32 |
call expand_filename |
test edx,edx |
jnz fsdel |
pusha |
call filedelete |
popa |
fsdel: |
call ramdisk_free_space |
cmp ecx,edi |
jbe rd_do_save |
add esp,32 |
mov eax,8 ;disk full |
ret |
rd_do_save: |
push eax ebx ecx edx esi edi |
mov edi,RAMDISK+512*18+512 ;Point at directory |
mov edx,224 +1 |
; find an empty spot for filename in the root dir |
l20ds: |
dec edx |
jz frnoreadds |
l21ds: |
cmp [edi],byte 0xE5 |
jz fifoundds |
cmp [edi],byte 0x0 |
jz fifoundds |
add edi,32 ; Advance to next entry |
jmp l20ds |
fifoundds: |
push edi ; move the filename to root dir |
mov esi,[esp+4+20] |
mov ecx,11 |
cld |
rep movsb |
pop edi |
mov edx,edi |
add edx,11+0xf ; edx <- cluster save position |
mov ebx,[esp+12] ; save file size |
mov [edi+28],ebx |
mov [edi+11],byte 0x20 ; attribute |
; Ivan Poddubny 11/12/2003: |
call get_date_for_file ; from FAT32.INC |
mov [edi+24],ax ; date |
call get_time_for_file ; from FAT32.INC |
mov [edi+22],ax ; time |
; End |
mov edi,RAMDISK_FAT ;pointer to first cluster |
mov ecx,2849 |
cld |
frnewds: |
xor ax,ax |
repne scasw |
mov ebx,2848 |
sub ebx,ecx |
mov [edx],bx ; save next cluster pos. to prev cl. |
mov edx,edi ; next save pos abs mem add |
dec edx |
dec edx |
call fdc_filesave |
pusha ; move save to floppy cluster |
add ebx,31 |
shl ebx,9 |
add ebx,RAMDISK |
mov eax,[esp+32+16] |
mov ecx,512 |
call memmove |
popa |
mov eax,[esp+12] |
cmp eax,512 |
jbe flnsa |
sub eax,512 |
mov [esp+12],eax |
add dword [esp+16], 512 |
jmp frnewds |
flnsa: |
mov [edi-2],word 4095 ; mark end of file - last cluster |
frnoreadds: |
pop edi esi edx ecx ebx eax |
add esp,32 |
; pusha |
; cli |
; call fdc_commitfile |
; sti |
; popa |
xor eax,eax ;ok write |
ret |
rd_findfile: |
;by Mihasik |
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx |
mov edi,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 |
rd_ff: |
ret |
; \begin{diamond} |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
test ax, ax |
jz .done |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
stosb |
jmp uni2ansi_str |
.done: |
mov byte [edi], 0 |
ret |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .ret |
; 0x80-0xAF -> 0x410-0x43F |
cmp al, 0xB0 |
jae @f |
add ax, 0x410-0x80 |
.ret: |
ret |
@@: |
; 0xE0-0xEF -> 0x440-0x44F |
cmp al, 0xE0 |
jb .unk |
cmp al, 0xF0 |
jae @f |
add ax, 0x440-0xE0 |
ret |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
ret |
.yo1: |
mov ax, 0x401 |
ret |
.yo2: |
mov ax, 0x451 |
ret |
char_toupper: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, ' ' |
jb .ret |
cmp al, 'à' |
jb .rus1 |
cmp al, 'ï' |
ja .ret |
; 0xE0-0xEF -> 0x90-0x9F |
sub al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0xA0-0xAF -> 0x80-0x8F |
.az: |
and al, not 0x20 |
ret |
fat_get_name: |
; in: edi->FAT entry |
; out: CF=1 - no valid entry |
; else CF=0 and ebp->ASCIIZ-name |
; (maximum length of filename is 255 (wide) symbols without trailing 0, |
; but implementation requires buffer 261 words) |
; destroys eax |
cmp byte [edi], 0 |
jz .no |
cmp byte [edi], 0xE5 |
jnz @f |
.no: |
stc |
ret |
@@: |
cmp byte [edi+11], 0xF |
jz .longname |
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 ecx, 8 |
@@: |
cmp byte [ebp+ecx-1], ' ' |
loope @b |
mov eax, [edi+8] |
cmp al, ' ' |
je .done |
shl eax, 8 |
mov al, '.' |
lea ebp, [ebp+ecx+1] |
mov [ebp], eax |
mov ecx, 3 |
@@: |
rol eax, 8 |
cmp al, ' ' |
jne .done |
loop @b |
dec ebp |
.done: |
and byte [ebp+ecx+1], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
mov ecx, 8 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
dec ebp |
dec ebp |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
cmp al, 20 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
pop edi esi |
.ret: |
clc |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
jnz .done |
pop eax |
test al, al |
jnz .loop |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
ret |
.done: |
cmp al, '/' |
jnz @f |
cmp byte [esp], 0 |
jnz @f |
mov [esp+4], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_time_to_bdfe: |
; in: eax=FAT time |
; out: eax=BDFE time |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 11 |
shl eax, 16 ; hours |
and edx, 0x1F |
add edx, edx |
mov al, dl ; seconds |
shr ecx, 5 |
and ecx, 0x3F |
mov ah, cl ; minutes |
pop edx ecx |
ret |
fat_date_to_bdfe: |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 9 |
add ax, 1980 |
shl eax, 16 ; year |
and edx, 0x1F |
mov al, dl ; day |
shr ecx, 5 |
and ecx, 0xF |
mov ah, cl ; month |
pop edx ecx |
ret |
bdfe_to_fat_time: |
push edx |
mov edx, eax |
shr eax, 16 |
and dh, 0x3F |
shl eax, 6 |
or al, dh |
shr dl, 1 |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
bdfe_to_fat_date: |
push edx |
mov edx, eax |
shr eax, 16 |
sub ax, 1980 |
and dh, 0xF |
shl eax, 4 |
or al, dh |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
movzx eax, word [edi+14] |
call fat_time_to_bdfe |
mov [esi+8], eax ; creation time |
movzx eax, word [edi+16] |
call fat_date_to_bdfe |
mov [esi+12], eax ; creation date |
and dword [esi+16], 0 ; last access time is not supported on FAT |
movzx eax, word [edi+18] |
call fat_date_to_bdfe |
mov [esi+20], eax ; last access date |
movzx eax, word [edi+22] |
call fat_time_to_bdfe |
mov [esi+24], eax ; last write time |
movzx eax, word [edi+24] |
call fat_date_to_bdfe |
mov [esi+28], eax ; last write date |
mov eax, [edi+28] |
mov [esi+32], eax ; file size (low dword) |
xor eax, eax |
mov [esi+36], eax ; file size (high dword) |
test ebp, ebp |
jz .ret |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
rep movsd |
mov [edi-2], ax |
@@: |
mov esi, edi |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
jmp @b |
bdfe_to_fat_entry: |
; convert BDFE at edx to FAT entry at edi |
; destroys eax |
; attributes byte |
test byte [edi+11], 8 ; volume label? |
jnz @f |
mov al, [edx] |
and al, 0x27 |
and byte [edi+11], 0x10 |
or byte [edi+11], al |
@@: |
mov eax, [edx+8] |
call bdfe_to_fat_time |
mov [edi+14], ax ; creation time |
mov eax, [edx+12] |
call bdfe_to_fat_date |
mov [edi+16], ax ; creation date |
mov eax, [edx+20] |
call bdfe_to_fat_date |
mov [edi+18], ax ; last access date |
mov eax, [edx+24] |
call bdfe_to_fat_time |
mov [edi+22], ax ; last write time |
mov eax, [edx+28] |
call bdfe_to_fat_date |
mov [edi+24], ax ; last write date |
ret |
ramdisk_root_first: |
mov edi, RAMDISK+512*19 |
clc |
ret |
ramdisk_root_next: |
add edi, 0x20 |
cmp edi, RAMDISK+512*33 |
cmc |
ret |
ramdisk_root_extend_dir: |
stc |
ret |
uglobal |
; this is for delete support |
rd_prev_sector dd ? |
rd_prev_prev_sector dd ? |
endg |
ramdisk_notroot_next: |
add edi, 0x20 |
test edi, 0x1FF |
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 |
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 |
.err2: |
pop ecx |
.err: |
stc |
ret |
ramdisk_notroot_next_write: |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ramdisk_root_next_write: |
ret |
ramdisk_notroot_extend_dir: |
pusha |
xor eax, eax |
mov edi, 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 |
rd_find_lfn: |
; in: esi->name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push ramdisk_root_first |
push ramdisk_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] |
mov [esp+8], eax |
mov dword [esp+4], ramdisk_notroot_first |
mov dword [esp], ramdisk_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRead - LFN variant for reading sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] ; cluster |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
lea eax, [edi+31] ; bootsector+2*fat+filenames |
shl eax, 9 ; *512 |
add eax, 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 |
@@: |
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 |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder |
; |
; esi points to filename; only root is folder on ramdisk |
; ebx pointer to structure 32-bit number = first wanted block |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskReadFolder: |
push edi |
cmp byte [esi], 0 |
jz .root |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push esi ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
pop ecx eax |
mov esi, edi ; esi points to block of data of folder entry (BDFE) |
.main_loop: |
mov edi, eax |
shl edi, 9 |
add edi, 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 |
; 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 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 |
.l2: |
add edi, 0x20 |
test edi, 0x1FF |
jnz .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
jmp .main_loop |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi edi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
clc |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
.succ: |
pop edi |
popad |
clc |
ret |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
jmp .succ |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, ' ' |
xchg al, [edi] |
dec ebx |
mov [ebx], al |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing ramdisk |
; fs_RamdiskCreateFolder - create folder on ramdisk |
; |
; esi points to file/folder name |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ (ignored for folders) |
; edx mem location to data (ignored for folders) |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskCreateFolder: |
mov al, 1 ; create folder |
jmp fs_RamdiskRewrite.common |
fs_RamdiskRewrite: |
xor eax, eax ; create file |
.common: |
cmp byte [esi], 0 |
jz @b |
pushad |
xor ebp, ebp |
push esi |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea ebp, [esi-1] |
jmp @b |
@@: |
pop esi |
test ebp, ebp |
jnz .noroot |
push ramdisk_root_extend_dir |
push ramdisk_root_next_write |
push ebp |
push ramdisk_root_first |
push ramdisk_root_next |
jmp .common1 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp+1], 0 |
jz .ret1 |
; check existence |
mov byte [ebp], 0 |
call rd_find_lfn |
mov byte [ebp], '/' |
lea esi, [ebp+1] |
jnc @f |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push ramdisk_notroot_extend_dir |
push ramdisk_notroot_next_write |
push ebp |
push ramdisk_notroot_first |
push ramdisk_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 20 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+20+28], 0 |
jz @f |
add esp, 20 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [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 |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 20 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <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 |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+8] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to last entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call .read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call .read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call .read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+20+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
push edx |
push ecx |
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 |
lea eax, [edi-(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 |
; write data |
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] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
xor eax, eax |
ret |
.disk_full2: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
push ERROR_DISK_FULL |
pop eax |
ret |
.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 |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskWrite - LFN variant for writing to sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_RamdiskWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_RamdiskWrite: |
cmp byte [esi], 0 |
jz @b |
pushad |
call rd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
popad |
push ERROR_ACCESS_DENIED |
jmp .ret0 |
@@: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
call fat_update_datetime |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push 0 ; return value=0 |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call ramdisk_extend_file |
jnc .length_ok |
; ramdisk_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
mov [esp], eax |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
mov [esp+28], eax ; eax=return value |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
movzx edi, word [edi+26] ; starting cluster |
.write_loop: |
sub ebx, 0x200 |
jae .next_cluster |
push ecx |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov eax, edi |
shl eax, 9 |
add eax, 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 |
ramdisk_extend_file.zero_size: |
xor eax, eax |
jmp ramdisk_extend_file.start_extend |
; extends file on ramdisk to given size, new data area is filled by 0 |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
ramdisk_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+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 |
@@: |
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 |
.start_extend: |
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 |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
mov ecx, edx |
push edi |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, 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 |
@@: |
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 |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
fat_update_datetime: |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskSetFileEnd - set end of file on ramdisk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskSetFileEnd: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop edi |
xor eax, eax |
ret |
.expand: |
push ecx |
mov ecx, eax |
call ramdisk_extend_file |
pop ecx |
pop edi |
ret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [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 |
; terminate FAT chain |
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 |
.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 |
.deleted: |
pop ecx |
pop edi |
xor eax, eax |
ret |
fs_RamdiskGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
fs_GetFileInfo_finish: |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push esi ebp |
xor ebp, ebp |
mov esi, edx |
and dword [esi+4], 0 |
call fat_entry_to_bdfe2 |
pop ebp esi |
pop edi |
xor eax, eax |
ret |
fs_RamdiskSetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
call bdfe_to_fat_entry |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskExecute - LFN variant for executing on sys floppy |
; |
; esi points to ramdisk filename (e.g. 'launcher') |
; ebp points to full filename (e.g. '/rd/1/launcher') |
; dword [ebx] = flags |
; dword [ebx+4] = cmdline |
; |
; ret ebx,edx destroyed |
; eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
fs_RamdiskExecute: |
mov edx, [ebx] |
mov ebx, [ebx+4] |
test ebx, ebx |
jz @f |
add ebx, std_application_base_address |
@@: |
;---------------------------------------------------------------- |
; |
; fs_RamdiskExecute.flags - second entry |
; |
; esi points to ramdisk filename (kernel address) |
; ebp points to full filename |
; edx flags |
; ebx cmdline (kernel address) |
; |
; ret eax > 0 - PID, < 0 - error |
; |
;-------------------------------------------------------------- |
.flags: |
cmp byte [esi], 0 |
jnz @f |
; cannot execute root! |
mov eax, -ERROR_ACCESS_DENIED |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
.found: |
movzx eax, word [edi+26] ; cluster |
push eax |
push dword [edi+28] ; size |
push .DoRead |
call fs_execute |
add esp, 12 |
pop edi |
ret |
.DoRead: |
; read next block |
; in: eax->parameters, edi->buffer |
; out: eax = error code |
pushad |
cmp dword [eax], 0 ; file size |
jz .eof |
mov edx, [eax+4] ; cluster |
lea esi, [edx+31] |
shl esi, 9 |
add esi, RAMDISK |
mov ecx, 512/4 |
rep movsd |
mov ecx, [eax] |
sub ecx, 512 |
jae @f |
add edi, ecx |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
@@: |
mov [eax], ecx |
mov dx, [edx*2+RAMDISK_FAT] |
mov [eax+4], dx ; high word is already zero |
popad |
xor eax, eax |
ret |
.eof: |
popad |
mov eax, 6 |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskDelete - delete file or empty folder from ramdisk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskDelete: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [rd_prev_sector], 0 |
and [rd_prev_prev_sector], 0 |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
movzx eax, word [edi+26] |
push ebx |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
test ebx, 0x1FF |
jnz .checkempty |
movzx eax, word [RAMDISK_FAT + eax*2] |
test eax, eax |
jz .empty |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 |
jmp .checkempty |
.notempty: |
pop ebx |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
.dodel: |
movzx eax, word [edi+26] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
test edi, 0x1FF |
jnz @f |
cmp [rd_prev_sector], 0 |
jz @f |
cmp [rd_prev_sector], -1 |
jz .lfndone |
mov edi, [rd_prev_sector] |
push [rd_prev_prev_sector] |
pop [rd_prev_sector] |
or [rd_prev_prev_sector], -1 |
shl edi, 9 |
add edi, RAMDISK + 31*0x200 + 0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
; delete FAT chain |
test eax, eax |
jz .done |
lea eax, [RAMDISK_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jmp .lfndone |
.done: |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
/kernel/branches/hd_kolibri/kernel/blkdev/rdsave.inc |
---|
0,0 → 1,30 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
saverd_fileinfo: |
dd 2 ; subfunction: write |
dd 0 ; (reserved) |
dd 0 ; (reserved) |
dd 1440*1024 ; size 1440 Kb |
dd 0x100000 - std_application_base_address ; base address |
db 0 |
.name: |
dd ? |
endg |
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) |
call restorefatchain |
mov eax, saverd_fileinfo - std_application_base_address |
mov [saverd_fileinfo.name], ebx |
pushad |
push eax |
call file_system_lfn |
pop eax |
popad |
mov [esp+36], eax |
ret |
/kernel/branches/hd_kolibri/kernel/boot/ETFONT.FNT |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/branches/hd_kolibri/kernel/boot/bootcode.inc |
---|
0,0 → 1,1305 |
$Revision: 437 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;; ;; |
;; BOOTCODE.INC ;; |
;; ;; |
;; KolibriOS 16-bit loader, ;; |
;; based on bootcode for MenuetOS ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;========================================================================== |
; |
; 16 BIT FUNCTIONS |
; |
;========================================================================== |
; 16-bit data |
org $+0x10000 |
old_ints_h: |
dw 0x400 |
dd 0 |
dw 0 |
kernel_restart_bootblock: |
db 1 ; version |
dw 1 ; floppy image is in memory |
dd 0 ; cannot save parameters |
align 32 |
; GDT TABLE |
gdts: |
dw gdte-$-1 |
dd gdts |
dw 0 |
; Attention! The order first four selectors not to change, is used in Fast System Call |
; must be : os_code, os_data, app_code, app_data, .... |
int_code_l: |
os_code_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
app_code_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db cpl3 |
dw G32+D32+0x8000+0x7; |
app_data_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db drw3 |
dw G32+D32+0x8000+0x7; |
; --------------- APM --------------------- |
apm_code_32: |
dw 0x0f ; limit 64kb |
db 0, 0, 0 |
dw 11010000b *256 +10011010b |
db 0x00 |
apm_code_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10011010b |
db 0x00 |
apm_data_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10010010b |
db 0x00 |
; ----------------------------------------- |
graph_data_l: |
dw 0x7ff |
dw 0x0000 |
db 0x00 |
dw 11010000b *256 +11110010b |
db 0x00 |
tss0_l: |
; times (max_processes+10) dd 0,0 |
gdte = $ + (max_processes+10)*8 |
; videomodes table |
gr_table: |
dw 0x112+0100000000000000b , 640 , 480 ; 1 |
dw 0x115+0100000000000000b , 800 , 600 ; 2 |
dw 0x118+0100000000000000b , 1024 , 768 ; 3 |
dw 0x11B+0100000000000000b , 1280 , 1024 ; 4 |
dw 0x112 , 640 , 480 ; 5 |
dw 0x115 , 800 , 600 ; 6 |
dw 0x118 , 1024 , 768 ; 7 |
dw 0x11B , 1280 ,1024 ; 8 |
dw 0x13, 640, 480 ; 9 |
dw 0x12, 640, 480 ; 0 |
; table for move to extended memory (int 15h, ah=87h) |
movedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
org $-0x10000 |
putchar: |
; in: al=character |
mov ah, 0Eh |
mov bh, 0 |
int 10h |
ret |
print: |
; in: si->string |
mov al, 186 |
call putchar |
mov al, ' ' |
call putchar |
printplain: |
; in: si->string |
pusha |
lodsb |
@@: |
call putchar |
lodsb |
cmp al, 0 |
jnz @b |
popa |
ret |
; Now int 16 is used for keyboard support. |
; This is shorter, simpler and more reliable. |
if 0 |
getkey: push ecx |
push edx |
add ebx,0x0101 |
xor eax,eax |
gk1: |
in al,0x60 |
mov cl,al |
gk0: |
in al,0x60 |
cmp al,cl |
je gk0 |
cmp ax,11 |
jg gk0 |
gk0_1: |
mov cl,al |
; add al,47 |
; mov [ds:keyinbs-0x10000],al |
; mov si,keyinbs-0x10000 |
; call printplain |
gk12: |
in al,0x60 |
cmp al,cl |
je gk12 |
cmp ax,240 |
jne gk13 |
mov al,cl |
jmp gk14 |
gk13: |
add cl,128 |
cmp al,cl |
jne gk1 |
sub al,128 |
gk14: |
movzx edx,bl |
cmp eax,edx |
jb gk1 |
movzx edx,bh |
cmp eax,edx |
jg gk1 |
test ebx,0x010000 |
jnz gk3 |
mov cx,0x1000 |
mov dx,cx |
add eax,47 |
mov cx,ax |
cmp cx,58 |
jb gk_nozero |
sub cx,10 |
gk_nozero: |
mov [ds:keyin-0x10000],cl |
mov si,keyin-0x10000 |
call printplain |
gk3: |
sub eax,48 |
pop edx |
pop ecx |
ret |
end if |
getkey: |
; get number in range [bl,bh] (bl,bh in ['0'..'9']) |
; in: bx=range |
; out: ax=digit (1..9, 10 for 0) |
mov ah, 0 |
int 16h |
cmp al, bl |
jb getkey |
cmp al, bh |
ja getkey |
push ax |
call putchar |
pop ax |
and ax, 0Fh |
jnz @f |
mov al, 10 |
@@: |
ret |
setcursor: |
; in: dl=column, dh=row |
mov ah, 2 |
mov bh, 0 |
int 10h |
ret |
macro _setcursor row,column |
{ |
mov dx, row*256 + column |
call setcursor |
} |
;pagetable_set: |
;eax - physical address |
;es:di - page table |
;ecx - number of pages to map |
; or al, 7 |
;@@: |
; stosd |
; add eax, 1000h |
; loop @b |
; ret |
boot_read_floppy: |
push si |
xor si, si |
mov ah, 2 ; read |
@@: |
push ax |
int 0x13 |
pop ax |
jnc @f |
inc si |
cmp si, 10 |
jb @b |
mov si, badsect-0x10000 |
sayerr_plain: |
call printplain |
jmp $ |
@@: |
pop si |
ret |
;========================================================================= |
; |
; 16 BIT CODE |
; |
;========================================================================= |
start_of_code: |
cld |
; \begin{diamond}[02.12.2005] |
cmp ax, 'KL' |
jnz @f |
mov word [cs:cfgmanager.loader_block-0x10000], si |
mov word [cs:cfgmanager.loader_block+2-0x10000], ds |
@@: |
; \end{diamond}[02.12.2005] |
mov word [cs:bx_from_load - 0x10000], bx ; {SPraid}[13.03.2007] |
; set up stack |
mov ax, 3000h |
mov ss, ax |
mov sp, 0EC00h |
; set up segment registers |
push cs |
pop ds |
push cs |
pop es |
; set videomode |
mov ax, 3 |
int 0x10 |
if lang eq ru |
; Load & set russian VGA font (RU.INC) |
mov bp,RU_FNT1-10000h ; RU_FNT1 - First part |
mov bx,1000h ; 768 bytes |
mov cx,30h ; 48 symbols |
mov dx,80h ; 128 - position of first symbol |
mov ax,1100h |
int 10h |
mov bp,RU_FNT2-10000h ; RU_FNT2 -Second part |
mov bx,1000h ; 512 bytes |
mov cx,20h ; 32 symbols |
mov dx,0E0h ; 224 - position of first symbol |
mov ax,1100h |
int 10h |
; End set VGA russian font |
else if lang eq et |
mov bp,ET_FNT-10000h ; ET_FNT1 |
mov bx,1000h ; |
mov cx,255 ; 256 symbols |
mov dx,0h ; 0 - position of first symbol |
mov ax,1100h |
int 10h |
end if |
; draw frames |
push 0xb800 |
pop es |
xor di, di |
; mov si,d80x25-0x10000 |
; mov cx,80*25 |
; mov ah,1*16+15 |
; dfl1: |
; lodsb |
; stosw |
; loop dfl1 |
mov ah, 1*16+15 |
; draw top |
mov si, d80x25_top - 0x10000 |
mov cx, d80x25_top_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
; draw spaces |
mov si, space_msg - 0x10000 |
mov cx, 25 - d80x25_top_num - d80x25_bottom_num |
dfl1: |
push cx |
push si |
mov cx, 80 |
@@: |
lodsb |
stosw |
loop @b |
pop si |
pop cx |
loop dfl1 |
; draw bottom |
mov si, d80x25_bottom - 0x10000 |
mov cx, d80x25_bottom_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
mov byte [space_msg-0x10000+80], 0 ; now space_msg is null terminated |
_setcursor d80x25_top_num,0 |
; TEST FOR 386+ |
mov bx, 0x4000 |
pushf |
pop ax |
mov dx,ax |
xor ax,bx |
push ax |
popf |
pushf |
pop ax |
and ax,bx |
and dx,bx |
cmp ax,dx |
jnz cpugood |
mov si,not386-0x10000 |
sayerr: |
call print |
jmp $ |
cpugood: |
; set up esp |
movzx esp, sp |
; FLUSH 8042 KEYBOARD CONTROLLER |
;// mike.dld [ |
; mov al,0xED |
; out 0x60,al |
; or cx,-1 |
; @@: |
; in al,0x64 |
; test al,2 |
; jz @f |
; loop @b |
; @@: |
; mov al,0 |
; out 0x60,al |
; or cx,-1 |
; @@: |
; in al,0x64 |
; test al,2 |
; jz @f |
; loop @b |
; @@: |
;// mike.dld ] |
; mov ecx,10000 |
; fl1: |
; in al,0x64 |
; loop fl1 |
; test al,1 |
; jz fl2 |
; in al,0x60 |
; jmp fl1 |
; fl2: |
;**************************************************************** |
; The function is modified Mario79 |
;***************************************************************** |
; wait_kbd: ; variant 1 |
; mov cx,2500h ;çàäåðæêà ïîðÿäêà 10 ìñåê |
; test_kbd: |
; in al,64h ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû |
; test al,2 ;ïðîâåðêà áèòà ãîòîâíîñòè |
; loopnz test_kbd |
push 0 |
pop es |
and word [es:0x9031], 0 |
; \begin{Mario79} |
; find HDD IDE DMA PCI device |
; check for PCI BIOS |
mov ax, 0xB101 |
int 0x1A |
jc .nopci |
cmp edx, 'PCI ' |
jnz .nopci |
; find PCI class code |
; class 1 = mass storage |
; subclass 1 = IDE controller |
; a) class 1, subclass 1, programming interface 0x80 |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x80 |
mov si, 0 ; device index = 0 |
int 0x1A |
jnc .found |
; b) class 1, subclass 1, programming interface 0x8A |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x8A |
mov si, 0 ; device index = 0 |
int 0x1A |
jnc .found |
; c) class 1, subclass 1, programming interface 0x85 |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x85 |
mov si, 0 |
int 0x1A |
jc .nopci |
.found: |
; get memory base |
mov ax, 0xB10A |
mov di, 0x20 ; memory base is config register at 0x20 |
int 0x1A |
jc .nopci |
and cx, 0xFFF0 ; clear address decode type |
mov [es:0x9031], cx |
.nopci: |
; \end{Mario79} |
mov al,0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå |
out 0x60,al |
xor cx,cx |
wait_loop: ; variant 2 |
; reading state of port of 8042 controller |
in al,64h |
and al,00000010b ; ready flag |
; wait until 8042 controller is ready |
loopnz wait_loop |
; --------------- APM --------------------- |
push 0 |
pop es |
mov word [es : 0x9044], 0 ; ver = 0.0 (APM not found) |
mov ax, 0x5300 |
xor bx, bx |
int 0x15 |
jc apm_end ; APM not found |
test cx, 2 |
jz apm_end ; APM 32-bit protected-mode interface not supported |
mov [es : 0x9044], ax ; Save APM Version |
mov [es : 0x9046], cx ; Save APM flags |
; Write APM ver ---- |
and ax, 0xf0f |
add ax, '00' |
mov si, msg_apm - 0x10000 |
mov [si + 5], ah |
mov [si + 7], al |
_setcursor 0, 3 |
call printplain |
; ------------------ |
mov ax, 0x5304 ; Disconnect interface |
xor bx, bx |
int 0x15 |
mov ax, 0x5303 ; Connect 32 bit mode interface |
xor bx, bx |
int 0x15 |
; init selectors |
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment |
shl eax, 4 |
mov [apm_code_32 - 0x10000 + 2], ax |
shr eax, 16 |
mov [apm_code_32 - 0x10000 + 4], al |
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment |
shl ecx, 4 |
mov [apm_code_16 - 0x10000 + 2], cx |
shr ecx, 16 |
mov [apm_code_16 - 0x10000 + 4], cl |
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment |
shl edx, 4 |
mov [apm_data_16 - 0x10000 + 2], dx |
shr edx, 16 |
mov [apm_data_16 - 0x10000 + 4], dl |
mov [es : 0x9040], ebx ; offset of APM entry point |
apm_end: |
_setcursor d80x25_top_num, 0 |
; ----------------------------------------- |
; DISPLAY VESA INFORMATION |
push 0 |
pop es |
mov ax,0x4f00 |
mov di,0xa000 |
int 0x10 |
cmp ax,0x004f |
mov si, novesa-0x10000 |
jnz @f |
mov bx, word [es:di+0x12] |
shl ebx,16 |
mov [es:0x9050], ebx |
mov ax,[es:di+4] |
add ax,'0'*256+'0' |
mov si,vervesa-0x10000 |
mov [si+vervesa_off], ah |
mov [si+vervesa_off+2], al |
@@: call print |
; \begin{diamond}[30.11.2005] |
cfgmanager: |
; settings: |
; a) preboot_graph = graphical mode |
; preboot_gprobe = probe this mode? |
; b) preboot_dma_write = use DMA write? |
; c) preboot_vrrm = use VRR? |
; d) preboot_device = from what boot? |
mov di, preboot_graph-0x10000 |
; check bootloader block |
cmp [.loader_block-0x10000], -1 |
jz .noloaderblock |
les bx, [.loader_block-0x10000] |
cmp byte [es:bx], 1 |
mov si, loader_block_error-0x10000 |
jnz sayerr |
test byte [es:bx+1], 1 |
jz @f |
; image in memory present |
cmp [di+preboot_device-preboot_graph], 0 |
jnz @f |
mov [di+preboot_device-preboot_graph], 3 |
@@: |
.noloaderblock: |
; determine default settings |
mov [.bSettingsChanged-0x10000], 0 |
cmp byte [di], 0 |
jnz .preboot_gr_end |
mov [di+preboot_gprobe-preboot_graph], 0 |
mov al, [vervesa+vervesa_off-0x10000] |
cmp al, 'x' |
jz .novesa |
cmp al, '1' |
jz .vesa12 |
mov [di+preboot_gprobe-preboot_graph], 2 |
mov al, 3 |
jmp @f |
.vesa12: |
mov al, 7 |
jmp @f |
.novesa: |
mov al, 10 |
@@: |
mov [di], al |
.preboot_gr_end: |
cmp [di+preboot_dma_write-preboot_graph], 1 |
adc [di+preboot_dma_write-preboot_graph], 0 |
cmp [di+preboot_vrrm-preboot_graph], 1 |
adc [di+preboot_vrrm-preboot_graph], 0 |
cmp [di+preboot_device-preboot_graph], 1 |
adc [di+preboot_device-preboot_graph], 0 |
; notify user |
mov si, linef-0x10000 |
call print |
mov si, start_msg-0x10000 |
call print |
mov si, time_msg-0x10000 |
call print |
; get start time |
call .gettime |
mov [.starttime-0x10000], eax |
mov word [.timer-0x10000], .newtimer |
mov word [.timer-0x10000+2], cs |
.printcfg: |
_setcursor 9,0 |
mov si, current_cfg_msg-0x10000 |
call print |
mov si, curvideo_msg-0x10000 |
call print |
mov al, [preboot_graph-0x10000] |
cmp al, 8 |
ja .pnovesa |
mov dl, al |
and eax, 3 |
mov si, [modes_msg-0x10000+eax*2] |
call printplain |
mov si, modevesa20-0x10000 |
cmp dl, 4 |
jbe @f |
mov si, modevesa12-0x10000 |
@@: |
call printplain |
cmp dl, 4 |
ja .x |
mov si, probeno_msg-0x10000 |
cmp [preboot_gprobe-0x10000], 2 |
jnz @f |
mov si, probeok_msg-0x10000 |
@@: |
call printplain |
.x: |
jmp .c |
.pnovesa: |
cmp al, 9 |
mov si, mode9-0x10000 |
jz @b |
mov si, mode10-0x10000 |
jmp @b |
.c: |
mov si, linef-0x10000 |
call printplain |
mov si, dma_msg-0x10000 |
cmp [preboot_dma_write-0x10000], 1 |
call .say_on_off |
mov si, vrrm_msg-0x10000 |
cmp [preboot_vrrm-0x10000], 1 |
call .say_on_off |
mov si, preboot_device_msg-0x10000 |
call print |
mov al, [preboot_device-0x10000] |
and eax, 3 |
mov si, [preboot_device_msgs-0x10000+eax*2] |
call printplain |
.wait: |
_setcursor 25,0 ; out of screen |
; set timer interrupt handler |
cli |
push 0 |
pop es |
mov eax, [es:8*4] |
mov [.oldtimer-0x10000], eax |
mov eax, [.timer-0x10000] |
mov [es:8*4], eax |
sti |
; wait for keypressed |
mov ah, 0 |
int 16h |
push ax |
; restore timer interrupt |
push 0 |
pop es |
mov eax, [.oldtimer-0x10000] |
mov [es:8*4], eax |
mov [.timer-0x10000], eax |
_setcursor 7,0 |
mov si, space_msg-0x10000 |
call printplain |
pop ax |
; switch on key |
cmp al, 13 |
jz .continue |
or al, 20h |
cmp al, 'a' |
jz .change_a |
cmp al, 'b' |
jz .change_b |
cmp al, 'c' |
jz .change_c |
cmp al, 'd' |
jnz .wait |
_setcursor 15,0 |
mov si,bdev-0x10000 |
call print |
mov bx,'13' |
call getkey |
mov [preboot_device-0x10000], al |
_setcursor 13,0 |
.d: |
mov [.bSettingsChanged-0x10000], 1 |
mov si, space_msg-0x10000 |
call printplain |
_setcursor 15,0 |
mov cx, 6 |
@@: |
call printplain |
loop @b |
jmp .printcfg |
.change_a: |
_setcursor 15,0 |
mov si, gr_mode-0x10000 |
call printplain |
mov bx, '09' |
call getkey |
mov [preboot_graph-0x10000], al |
cmp al, 4 |
ja @f |
mov si, probetext-0x10000 |
call printplain |
mov bx, '12' |
call getkey |
mov [preboot_gprobe-0x10000], al |
@@: |
_setcursor 10,0 |
jmp .d |
.change_b: |
_setcursor 15,0 |
mov si, ask_dma-0x10000 |
call print |
mov bx, '12' |
call getkey |
mov [preboot_dma_write-0x10000], al |
_setcursor 11,0 |
jmp .d |
.change_c: |
_setcursor 15,0 |
mov si, vrrmprint-0x10000 |
call print |
mov bx, '12' |
call getkey |
mov [preboot_vrrm-0x10000], al |
_setcursor 12,0 |
jmp .d |
.say_on_off: |
pushf |
call print |
mov si, on_msg-0x10000 |
popf |
jz @f |
mov si, off_msg-0x10000 |
@@: call printplain |
ret |
; novesa and vervesa strings are not used at the moment of executing this code |
virtual at novesa |
.oldtimer dd ? |
.starttime dd ? |
.bSettingsChanged db ? |
.timer dd ? |
end virtual |
org $+0x10000 |
.loader_block dd -1 |
org $-0x10000 |
.gettime: |
mov ah, 0 |
int 1Ah |
xchg ax, cx |
shl eax, 10h |
xchg ax, dx |
ret |
.newtimer: |
push ds |
push cs |
pop ds |
pushf |
call [.oldtimer-0x10000] |
pushad |
call .gettime |
sub eax, [.starttime-0x10000] |
sub ax, 18*5 |
jae .timergo |
neg ax |
add ax, 18-1 |
mov bx, 18 |
xor dx, dx |
div bx |
if lang eq ru |
; ¯®¤®¦¤¨â¥ 5 ᥪã¤, 4/3/2 ᥪã¤ë, 1 ᥪã¤ã |
cmp al, 5 |
mov cl, ' ' |
jae @f |
cmp al, 1 |
mov cl, 'ã' |
jz @f |
mov cl, 'ë' |
@@: mov [time_str+9-0x10000], cl |
else if lang eq et |
cmp al, 1 |
ja @f |
mov [time_str+9-0x10000], ' ' |
mov [time_str+10-0x10000],' ' |
@@: |
else |
; wait 5/4/3/2 seconds, 1 second |
cmp al, 1 |
mov cl, 's' |
ja @f |
mov cl, ' ' |
@@: mov [time_str+9-0x10000], cl |
end if |
add al, '0' |
mov [time_str+1-0x10000], al |
mov si, time_msg-0x10000 |
_setcursor 7,0 |
call print |
_setcursor 25,0 |
popad |
pop ds |
iret |
.timergo: |
push 0 |
pop es |
mov eax, [.oldtimer-0x10000] |
mov [es:8*4], eax |
mov sp, 0EC00h |
.continue: |
sti |
_setcursor 6,0 |
mov si, space_msg-0x10000 |
call printplain |
call printplain |
_setcursor 6,0 |
mov si, loading_msg-0x10000 |
call print |
_setcursor 15,0 |
cmp [.bSettingsChanged-0x10000], 0 |
jz .load |
cmp [.loader_block-0x10000], -1 |
jz .load |
les bx, [.loader_block-0x10000] |
mov eax, [es:bx+3] |
push ds |
pop es |
test eax, eax |
jz .load |
push eax |
mov si, save_quest-0x10000 |
call print |
.waityn: |
mov ah, 0 |
int 16h |
or al, 20h |
cmp al, 'n' |
jz .loadc |
cmp al, 'y' |
jnz .waityn |
call putchar |
mov byte [space_msg-0x10000+80], 186 |
pop eax |
push cs |
push .cont |
push eax |
retf |
.loadc: |
pop eax |
.cont: |
push cs |
pop ds |
mov si, space_msg-0x10000 |
mov byte [si+80], 0 |
_setcursor 15,0 |
call printplain |
_setcursor 15,0 |
.load: |
; \end{diamond}[02.12.2005] |
; ASK GRAPHICS MODE |
movzx ax, [preboot_graph-0x10000] |
push 0 |
pop es |
; address is gr_table+6*(ax-1)-0x10000 |
add ax, ax |
lea si, [gr_table-0x10000 + eax + eax*2 - 6] |
mov bx,[si+0] |
mov cx,[si+2] |
mov dx,[si+4] |
cmp al, 9*2 |
mov al, 32 ; BPP |
jb @f |
mov [es:0x9000], al |
mov dword [es:0x9018], 0xFFFFFFFF; 0x800000 |
@@: |
mov [es:0x9008],bx |
mov [es:0x900A],cx |
mov [es:0x900C],dx |
test bh, bh |
jz nov |
; USE DEFAULTS OR PROBE |
; bx - mode : cx - x size : dx - y size |
cmp [preboot_gprobe-0x10000], 1 |
jz noprobe |
mov bx,0x100 |
newprobe: |
inc bx |
cmp bx,0x17f |
mov si,prnotfnd-0x10000 |
jz sayerr |
probemore: |
push cx |
mov ax,0x4f01 |
mov cx,bx |
and cx,0xfff |
mov di,0xa000 |
int 0x10 |
pop cx |
test byte [es:di], 80h ; lfb? |
jz newprobe |
cmp [es:di+0x12], cx ; x size? |
jnz newprobe |
cmp [es:di+0x14], dx ; y size? |
jnz newprobe |
cmp byte [es:di+0x19], 32 ;24 |
jb newprobe |
; add bx,0100000000000000b |
or bh, 40h |
mov [es:0x9008],bx |
noprobe: |
; FIND VESA 2.0 LFB & BPP |
mov ax,0x4f01 |
mov cx,bx |
and cx,0xfff |
mov di,0xa000 |
int 0x10 |
; LFB |
mov eax,[es:di+0x28] |
mov [es:0x9018],eax |
; ---- vbe voodoo |
BytesPerLine equ 0x10 |
mov ax, [es:di+BytesPerLine] |
mov [es:0x9001],ax |
; BPP |
mov al,byte [es:di+0x19] |
mov [es:0x9000],al |
nov: |
cmp al,24 |
mov si,bt24-0x10000 |
jz bppl |
cmp al,32 |
mov si,bt32-0x10000 |
jz bppl |
mov si,btns-0x10000 |
jmp sayerr |
bppl: |
call print |
; FIND VESA 1.2 PM BANK SWITCH ADDRESS |
push es |
mov ax,0x4f0A |
xor bx, bx |
int 0x10 |
xor eax,eax |
mov ax,es |
shl eax,4 |
movzx ebx,di |
add eax,ebx |
mov bx,[es:di] |
add eax,ebx |
pop es |
mov [es:0x9014],eax |
; GRAPHICS ACCELERATION |
; force yes |
mov [es:0x901C], byte 1 |
; DMA WRITE |
mov al, [preboot_dma_write-0x10000] |
mov [es:0x901F],al |
; VRR_M USE |
mov al,[preboot_vrrm-0x10000] |
mov [es:0x9030],al |
mov [es:0x901E],byte 1 |
; BOOT DEVICE |
mov al, [preboot_device-0x10000] |
dec al |
mov [boot_dev-0x10000],al |
; READ DISKETTE TO MEMORY |
; cmp [boot_dev-0x10000],0 |
jne no_sys_on_floppy |
mov si,diskload-0x10000 |
call print |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
; now load floppy image to memory |
; at first load boot sector and first FAT table |
mov cx, 0x0001 ; startcyl,startsector |
xor dx, dx ; starthead,drive |
mov al, 1+9 ; no of sectors to read |
mov bx, 0xB000 ; es:bx -> data area |
call boot_read_floppy |
; and copy them to extended memory |
mov si, movedesc-0x10000 |
mov [si+8*2+3], bh |
push es |
push ds |
pop es |
mov cx, 256*10 |
mov ah, 0x87 |
int 0x15 |
test ah, ah |
jz @f |
sayerr_floppy: |
mov dx, 0x3f2 |
mov al, 0 |
out dx, al |
mov si, memmovefailed-0x10000 |
jmp sayerr_plain |
@@: |
add dword [si+8*3+2], 512*10 |
; copy FAT to second copy |
mov byte [si+8*2+3], 0xB2 |
mov cx, 256*9 |
mov ah, 0x87 |
int 0x15 |
pop es |
test ah, ah |
jnz sayerr_floppy |
add dword [si+8*3+2], 512*9 |
; calculate total number of sectors to read |
mov ax, 1+9+14 ; boot+FAT+root |
mov di, 0xB203 |
.calc_loop: |
test word [es:di], 0xFFF |
jz @f |
inc ax |
@@: |
test word [es:di+1], 0xFFF0 |
jz @f |
inc ax |
@@: |
add di, 3 |
cmp di, 0xB200+1440*3 |
jb .calc_loop |
push ax |
mov bp, 1+9 ; already read sectors |
; now read rest |
mov byte [si+8*2+3], 0xA0 |
mov di, 2-14 ; absolute sector-31 |
mov cx, 0x0002 ; cylinder=0, sector=2 |
mov dx, 0x0100 ; head=1, disk=0 |
.read_loop: |
; determine whether sector must be read |
cmp di, 2 |
jl .read |
mov bx, di |
shr bx, 1 |
jnc .even |
test word [es:bx+di+0xB200], 0xFFF0 |
jmp @f |
.even: |
test word [es:bx+di+0xB200], 0xFFF |
@@: |
jz .skip |
.read: |
mov bx, 0xA000 |
mov al, 1 ; 1 sector |
call boot_read_floppy |
inc bp |
push es |
push ds |
pop es |
pusha |
mov cx, 256 |
mov ah, 0x87 |
int 0x15 |
test ah, ah |
popa |
pop es |
jnz sayerr_floppy |
.skip: |
add dword [si+8*3+2], 512 |
inc cx |
cmp cl, 19 |
jnz @f |
mov cl, 1 |
inc dh |
cmp dh, 2 |
jnz @f |
mov dh, 0 |
inc ch |
@@: |
pop ax |
push ax |
pusha |
; draw percentage |
; total sectors: ax |
; read sectors: bp |
xchg ax, bp |
mov cx, 100 |
mul cx |
div bp |
aam |
xchg al, ah |
add ax, '00' |
mov si, pros-0x10000 |
cmp [si], ax |
jz @f |
mov [si], ax |
call printplain |
@@: |
popa |
inc di |
cmp di, 2880-31 |
jnz .read_loop |
; mov cx, 0x0001 ; startcyl,startsector |
; xor dx, dx ; starthead,drive |
; push word 80*2 ; read no of sect |
; reads: |
; pusha |
; xor si,si |
; newread: |
; mov bx,0xa000 ; es:bx -> data area |
; mov ax,0x0200+18 ; read, no of sectors to read |
; int 0x13 |
; test ah, ah |
; jz goodread |
; inc si |
; cmp si,10 |
; jnz newread |
; mov si,badsect-0x10000 |
;sayerr_plain: |
; call printplain |
; jmp $ |
; goodread: |
; ; move -> 1mb |
; mov si,movedesc-0x10000 |
; push es |
; push ds |
; pop es |
; mov cx,256*18 |
; mov ah,0x87 |
; int 0x15 |
; pop es |
; |
; test ah,ah ; was the move successfull ? |
; je goodmove |
; mov dx,0x3f2 ; floppy motor off |
; mov al,0 |
; out dx,al |
; mov si,memmovefailed-0x10000 |
; jmp sayerr_plain |
; goodmove: |
; |
; add dword [movedesc-0x10000+0x18+2], 512*18 |
; popa |
; inc dh |
; cmp dh,2 |
; jnz bb2 |
; mov dh,0 |
; inc ch |
; pusha ; print prosentage |
; mov si,pros-0x10000 |
; shr ch, 2 |
; mov al, '5' |
; test ch, 1 |
; jnz @f |
; mov al, '0' |
;@@: |
; mov [si+1], al |
; shr ch, 1 |
; add ch, '0' |
; mov [si], ch |
; call printplain |
; popa |
; bb2: |
; pop ax |
; dec ax |
; push ax |
; jnz reads |
; readdone: |
; pop ax |
mov si,backspace2-0x10000 |
call printplain |
mov si,okt-0x10000 |
call printplain |
no_sys_on_floppy: |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov dx,0x3f2 ; floppy motor off |
mov al,0 |
out dx,al |
; SET GRAPHICS |
xor ax, ax |
mov es, ax |
mov ax,[es:0x9008] ; vga & 320x200 |
mov bx, ax |
cmp ax,0x13 |
je setgr |
cmp ax,0x12 |
je setgr |
mov ax,0x4f02 ; Vesa |
setgr: |
int 0x10 |
test ah,ah |
mov si, fatalsel-0x10000 |
jnz sayerr |
; set mode 0x12 graphics registers: |
cmp bx,0x12 |
jne gmok2 |
mov al,0x05 |
mov dx,0x03ce |
push dx |
out dx,al ; select GDC mode register |
mov al,0x02 |
inc dx |
out dx,al ; set write mode 2 |
mov al,0x02 |
mov dx,0x03c4 |
out dx,al ; select VGA sequencer map mask register |
mov al,0x0f |
inc dx |
out dx,al ; set mask for all planes 0-3 |
mov al,0x08 |
pop dx |
out dx,al ; select GDC bit mask register |
; for writes to 0x03cf |
gmok2: |
push ds |
pop es |
/kernel/branches/hd_kolibri/kernel/boot/booteng.inc |
---|
0,0 → 1,94 |
$Revision: 437 $ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
db 'NO WARRANTY ',186 |
db 186,' See file COPYING for details ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "Display: EGA/CGA",13,10,0 |
vervesa db "Version of Vesa: Vesa x.x",13,10,0 |
vervesa_off=22 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 Colors: [9] 320x200, " |
db "VGA 16 Colors: [0] 640x480",13,10 |
db 186," Select mode: ",0 |
bt24 db "Bits Per Pixel: 24",13,10,0 |
bt32 db "Bits Per Pixel: 32",13,10,0 |
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz" |
db " only for transfers:",13,10 |
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0 |
;askmouse db " Mouse at:" |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " Select port [1-3]: ",0 |
;no_com1 db 13,10,186, " No COM1 mouse",0 |
;no_com2 db 13,10,186, " No COM2 mouse",0 |
ask_dma db "Use DMA for HDD writing? [1-yes/2-no]: ",0 |
;gr_direct db 186," Use direct LFB writing? " |
; db "[1-yes/2-no] ? ",0 |
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 |
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 |
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-use preloaded ram-image from kernel restart]: ",0 |
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, " |
db "2-probe bios (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "Fatal - Videomode not found.",0 |
;modena db "Fatal - VBE 0x112+ required.",0 |
not386 db "Fatal - CPU 386+ required.",0 |
btns db "Fatal - Can't determine color depth.",0 |
fatalsel db "Fatal - Graphics mode not supported by hardware.",0 |
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0 |
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db "Loading diskette: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0 |
time_msg db " or wait " |
time_str db " 5 seconds" |
db " before automatical continuation",13,10,0 |
current_cfg_msg db "Current settings:",13,10,0 |
curvideo_msg db " [a] Videomode: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 |
modevesa20 db " with LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 colors",0 |
mode10 db "640x480, VGA 16 colors",0 |
probeno_msg db " (standard mode)",0 |
probeok_msg db " (check nonstandard modes)",0 |
dma_msg db " [b] Use DMA for HDD writing:",0 |
on_msg db " on",13,10,0 |
off_msg db " off",13,10,0 |
vrrm_msg db " [c] Use VRR:",0 |
preboot_device_msg db " [d] Floppy image: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db "real floppy",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "use already loaded image",13,10,0 |
loading_msg db "Loading KolibriOS...",0 |
save_quest db "Remember current settings? [y/n]: ",0 |
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0 |
/kernel/branches/hd_kolibri/kernel/boot/bootet.inc |
---|
0,0 → 1,94 |
$Revision: 437 $ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
db 'NO WARRANTY ',186 |
db 186,' See file COPYING for details ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "Ekraan: EGA/CGA",13,10,0 |
vervesa db "Vesa versioon: Vesa x.x",13,10,0 |
vervesa_off=20 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 värvi: [9] 320x200, " |
db "VGA 16 värvi: [0] 640x480",13,10 |
db 186," Vali reziim: ",0 |
bt24 db "Bitti pikseli kohta: 24",13,10,0 |
bt32 db "Bitti pikseli kohta: 32",13,10,0 |
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" |
db " ainult:",13,10 |
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 |
;askmouse db " Hiir:" |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " Vali port [1-3]: ",0 |
;no_com1 db 13,10,186, " No COM1 mouse",0 |
;no_com2 db 13,10,186, " No COM2 mouse",0 |
ask_dma db "Use DMA for HDD writing? [1-jah/2-ei]: ",0 |
;gr_direct db 186," Use direct LFB writing? " |
; db "[1-yes/2-no] ? ",0 |
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 |
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 |
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-kasuta eellaaditud mäluketast kerneli restardist]: ",0 |
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, " |
db "2-leia biosist (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 |
;modena db "Fataalne - VBE 0x112+ on vajalik.",0 |
not386 db "Fataalne - CPU 386+ on vajalik.",0 |
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0 |
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 |
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 |
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db "Loen disketti: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0 |
time_msg db " või oota " |
time_str db " 5 sekundit" |
db " automaatseks jätkamiseks",13,10,0 |
current_cfg_msg db "Praegused seaded:",13,10,0 |
curvideo_msg db " [a] Videoreziim: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 |
modevesa20 db " koos LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 värvi",0 |
mode10 db "640x480, VGA 16 värvi",0 |
probeno_msg db " (standard reziim)",0 |
probeok_msg db " (kontrolli ebastandardseid reziime)",0 |
dma_msg db " [b] Use DMA for HDD writing:",0 |
on_msg db " sees",13,10,0 |
off_msg db " väljas",13,10,0 |
vrrm_msg db " [c] Kasuta VRR:",0 |
preboot_device_msg db " [d] Disketi kujutis: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db "reaalne diskett",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "kasuta juba laaditud kujutist",13,10,0 |
loading_msg db "Laadin KolibriOS...",0 |
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0 |
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 |
/kernel/branches/hd_kolibri/kernel/boot/bootge.inc |
---|
0,0 → 1,99 |
$Revision: 437 $ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
; db 'NO WARRANTY ',186 |
; db 186,' See file COPYING for details ' |
; db ' ',186 |
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' |
db ' Garantie vertrieben ',186 |
db 186,' Details stehen in der Datei COPYING ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "Anzeige: EGA/CGA ",13,10,0 |
vervesa db "Vesa-Version: Vesa ",13,10,0 |
vervesa_off=22 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 Farben: [9] 320x200, " |
db "VGA 16 Farben: [0] 640x480",13,10 |
db 186," Waehle Modus: ",0 |
bt24 db "Bits Per Pixel: 24",13,10,0 |
bt32 db "Bits Per Pixel: 32",13,10,0 |
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" |
db " only for transfers:",13,10 |
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 |
;askmouse db " Maus angeschlossen an:" |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " Waehle Port [1-3]: ",0 |
;no_com1 db 13,10,186, " Keine COM1 Maus",0 |
;no_com2 db 13,10,186, " Keine COM2 Maus",0 |
ask_dma db "Nutze DMA zum HDD Aufschreiben? [1-ja/2-nein]: ",0 |
;gr_direct db 186," Benutze direct LFB? " |
; db "[1-ja/2-nein] ? ",0 |
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 |
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 |
bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-benutze ein bereits geladenes Kernel image]: ",0 |
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, " |
db "2-BIOS Test (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "Fatal - Videomodus nicht gefunden.",0 |
;modena db "Fatal - VBE 0x112+ required.",0 |
not386 db "Fatal - CPU 386+ benoetigt.",0 |
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0 |
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0 |
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0 |
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db "Lade Diskette: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0 |
time_msg db " oder warte " |
time_str db " 5 Sekunden" |
db " bis zum automatischen Start",13,10,0 |
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0 |
curvideo_msg db " [a] Videomodus: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 |
modevesa20 db " mit LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 colors",0 |
mode10 db "640x480, VGA 16 colors",0 |
probeno_msg db " (Standard Modus)",0 |
probeok_msg db " (teste nicht-standard Modi)",0 |
dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0 |
on_msg db " an",13,10,0 |
off_msg db " aus",13,10,0 |
vrrm_msg db " [c] Nutze VRR:",0 |
preboot_device_msg db " [d] Diskettenimage: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db "Echte Diskette",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "Nutze bereits geladenes Image",13,10,0 |
loading_msg db "Lade KolibriOS...",0 |
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0 |
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0 |
/kernel/branches/hd_kolibri/kernel/boot/bootru.inc |
---|
0,0 → 1,95 |
$Revision: 437 $ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
db 186,' Kolibri OS ®á®¢ Menuet OS ¨ ¥ ¯à¥¤®áâ ¢«ï¥â ' |
db '¨ª ª¨å £ àa⨩. ',186 |
db 186,' ®¤à®¡¥¥ ᬮâà¨â¥ ä ©« GNU.TXT ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "¨¤¥®ª àâ : EGA/CGA",13,10,0 |
vervesa db "¥àá¨ï VESA: Vesa x.x",13,10,0 |
vervesa_off=19 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 ¢¥â®¢: [9] 320x200, " |
db "VGA 16 ¢¥â®¢: [0] 640x480",13,10 |
db 186," ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",0 |
bt24 db "«ã¡¨ 梥â : 24",13,10,0 |
bt32 db "«ã¡¨ 梥â : 32",13,10,0 |
vrrmprint db "ᯮ«ì§®¢ âì VRR? (ç áâ®â ª ¤à®¢ ¢ëè¥ 60 æ" |
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10 |
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-¥â]: ",0 |
;askmouse db "ëèì:" ; 186, " " |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " ë¡¥à¨â¥ ¯®àâ [1-3]: ",0 |
;no_com1 db 13,10,186," No COM1 mouse",0 |
;no_com2 db 13,10,186," No COM2 mouse",0 |
ask_dma db "ᯮ«ì§®¢ âì DMA ¤«ï § ¯¨á¨ HDD? [1-¤ /2-¥â]: ",0 |
;gr_direct db 186," ᯮ«ì§®¢ âì «¨¥©ë© ¢¨¤¥®¡ãä¥à? " |
; db "[1-¤ /2-¥â]: ",0 |
;mem_model db 13,10,186," ¡ê+¬ ¯ ¬ï⨠[1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0 |
;bootlog db 13,10,186," à®á¬®âà¥âì ¦ãà « § £à㧪¨? [1-¥â/2-¤ ]: ",0 |
bdev db " £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §]: ",0 |
probetext db 13,10,13,10,186," â ¤ àâë© ¢¨¤¥®à¥¦¨¬? [1-¤ , " |
db "2-¯à®¢¥à¨âì ¤à㣨¥ (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "訡ª - ¨¤¥®à¥¦¨¬ ¥ ©¤¥.",0 |
;modena db "訡ª - ॡã¥âáï ¯®¤¤¥à¦ª VBE 0x112+.",0 |
not386 db "訡ª - ॡã¥âáï ¯à®æ¥áá®à 386+.",0 |
btns db "訡ª - ¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨ã 梥â .",0 |
fatalsel db "訡ª - ë¡à ë© ¢¨¤¥®à¥¦¨¬ ¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0 |
badsect db 13,10,186," 訡ª - ¨áª¥â ¯®¢à¥¦¤¥ . ®¯à®¡ã©â¥ ¤àã£ãî.",0 |
memmovefailed db 13,10,186," 訡ª - Int 0x15 move failed.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db " £à㧪 ¤¨áª¥âë: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 |
start_msg db " ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥¥¨ï áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥¨ï § £à㧪¨",13,10,0 |
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ " |
time_str db " 5 ᥪ㭤 " |
db " ¤® ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥¨ï",13,10,0 |
current_cfg_msg db "¥ªã騥 áâனª¨:",13,10,0 |
curvideo_msg db " [a] ¨¤¥®à¥¦¨¬: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000 |
modevesa20 db " á LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 梥⮢",0 |
mode10 db "640x480, VGA 16 梥⮢",0 |
probeno_msg db " (áâ ¤ àâë© ¢¨¤¥®à¥¦¨¬)",0 |
probeok_msg db " (¯à®¢¥à¨âì ¥áâ ¤ àâë¥ à¥¦¨¬ë)",0 |
dma_msg db " [b] ᯮ«ì§®¢ ¨¥ DMA ¤«ï § ¯¨á¨ HDD:",0 |
on_msg db " ¢ª«",13,10,0 |
off_msg db " ¢ëª«",13,10,0 |
vrrm_msg db " [c] ᯮ«ì§®¢ ¨¥ VRR:",0 |
preboot_device_msg db " [d] ¡à § ¤¨áª¥âë: ",0 |
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000 |
pdm1 db " áâ®ïé ï ¤¨áª¥â ",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £àã¦¥ë© ®¡à §",13,10,0 |
loading_msg db "¤ñâ § £à㧪 KolibriOS...",0 |
save_quest db " ¯®¬¨âì ⥪ã騥 áâனª¨? [y/n]: ",0 |
loader_block_error db "訡ª ¢ ¤ ëå ç «ì®£® § £àã§ç¨ª , ¯à®¤®«¦¥¨¥ ¥¢®§¬®¦®.",0 |
/kernel/branches/hd_kolibri/kernel/boot/bootstr.inc |
---|
0,0 → 1,52 |
; boot data: common strings (for all languages) |
macro line_full_top { |
db 201 |
times 78 db 205 |
db 187 |
} |
macro line_full_bottom { |
db 200 |
times 78 db 205 |
db 188 |
} |
macro line_half { |
db 186,' ' |
times 76 db 0xc4 |
db ' ',186 |
} |
macro line_space { |
db 186 |
times 78 db 32 |
db 186 |
} |
d80x25_top: |
line_full_top |
cur_line_pos = 75 |
store byte ' ' at d80x25_top+cur_line_pos+1 |
rev_var = __REV__ |
while rev_var > 0 |
store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos |
cur_line_pos = cur_line_pos - 1 |
rev_var = rev_var / 10 |
end while |
store byte ' ' at d80x25_top+cur_line_pos |
store dword ' SVN' at d80x25_top+cur_line_pos-4 |
space_msg: line_space |
verstr: |
; line_space |
; version string |
db 186,32 |
repeat 78 |
load a byte from version+%-1 |
if a = 13 |
break |
end if |
db a |
end repeat |
repeat 78 - ($-verstr) |
db ' ' |
end repeat |
db 32,186 |
line_half |
d80x25_top_num = 4 |
/kernel/branches/hd_kolibri/kernel/boot/et.inc |
---|
0,0 → 1,7 |
$Revision: 425 $ |
; Full ASCII code font |
; only õ and ä added |
; Kaitz |
ET_FNT: |
fontfile file "ETFONT.FNT" |
/kernel/branches/hd_kolibri/kernel/boot/preboot.inc |
---|
0,0 → 1,34 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
display_modechg db 0 ; display mode change for text, yes/no (0 or 2) |
; |
; !! Important note !! |
; |
; Must be set to 2, to avoid two screenmode |
; changes within a very short period of time. |
display_atboot db 0 ; show boot screen messages ( 2-no ) |
preboot_graph db 3 ; graph mode |
preboot_gprobe db 1 ; probe vesa3 videomodes (1-no, 2-yes) |
preboot_vrrm db 1 ; use VRR_M (1-yes, 2- no) |
preboot_dma_write db 2 ; use DMA for writing to HDD (1-yes, 2-no) |
preboot_device db 2 ; boot device |
; (1-floppy 2-harddisk 3-kernel restart) |
;!!!! 0 - autodetect !!!! |
preboot_blogesc db 1 ; start immediately after bootlog |
if $>10200h |
ERROR: prebooting parameters must fit in first sector!!! |
end if |
hdsysimage db 'KOLIBRI IMG' ; load from |
image_save db 'KOLIBRI IMG' ; save to |
preboot_lfb db 0 |
preboot_bootlog db 0 |
/kernel/branches/hd_kolibri/kernel/boot/ru.inc |
---|
0,0 → 1,93 |
$Revision: 425 $ |
; Generated by RUFNT.EXE |
; By BadBugsKiller (C) |
; Modifyed by BadBugsKiller 12.01.2004 17:45 |
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé, |
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà. |
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòàíèöà 866. |
RU_FNT1: |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
RU_FNT2: |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
/kernel/branches/hd_kolibri/kernel/boot/shutdown.inc |
---|
0,0 → 1,545 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Shutdown for Menuet ;; |
;; ;; |
;; Distributed under General Public License ;; |
;; See file COPYING for details. ;; |
;; Copyright 2003 Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
system_shutdown: ; shut down the system |
call stop_all_services |
push 3 ; stop playing cd |
pop eax |
call sys_cd_audio |
cld |
mov al,[0x2f0000+0x9030] |
cmp al,1 |
jl no_shutdown_parameter |
cmp al,4 |
jle yes_shutdown_param |
no_shutdown_parameter: |
; movzx ecx,word [0x2f0000+0x900A] |
; movzx esi,word [0x2f0000+0x900C] |
; imul ecx,esi ;[0xfe04] |
;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen |
; push ecx |
; mov esi,[0xfe80] |
; cmp esi,32*0x100000 |
; jbe no_darken_screen |
; mov edi,16*0x100000 |
; push esi edi |
; sdnewpix: |
; lodsd |
; shr eax,1 |
; and eax,0x7f7f7f7f |
; stosd |
; loop sdnewpix |
; pop ecx |
; pop esi edi |
; rep movsd |
; no_darken_screen: |
; read shutdown code: |
; 1) display shutdown "window" |
mov eax,[0xfe00] |
shr eax,1 |
lea esi,[eax+220] ; x end |
sub eax,220 ; x start |
mov ebx,[ScreenHeight] |
shr ebx,1 |
mov [shutdownpos],ebx |
lea ebp,[ebx+105] ; y end |
sub ebx,120 ; y start |
xor edi,edi |
inc edi ; force putpixel & dtext |
mov ecx,0x0000ff |
; vertical loop begin |
sdnewpix1: |
push eax ; save x start |
; horizontal loop begin |
sdnewpix2: |
call [putpixel] |
inc eax |
cmp eax,esi |
jnz sdnewpix2 |
; horizontal loop end |
dec ecx ; color |
pop eax ; restore x start |
inc ebx ; advance y pos |
cmp ebx,ebp |
jnz sdnewpix1 |
; vertical loop end |
; 2) display text strings |
; a) version |
mov eax,[0xfe00] |
shr eax,1 |
shl eax,16 |
mov ax,word [shutdownpos] |
push eax |
sub eax,(220-27)*10000h + 105 |
mov ebx,0xffff00 |
mov ecx,version |
push 34 |
pop edx |
call dtext |
; b) variants |
add eax,105+33 |
push 6 |
pop esi |
; mov ebx,0xffffff |
mov bl,0xFF |
mov ecx,shutdowntext |
mov dl,40 |
newsdt: |
call dtext |
add eax,10 |
add ecx,edx |
dec esi |
jnz newsdt |
; 3) load & display rose.txt |
mov eax,rosef-std_application_base_address ; load rose.txt |
xor ebx,ebx |
push 2 |
pop ecx |
mov edx,0x90000 |
push edx |
push 12 |
pop esi |
push edi ; may be destroyed |
pushad |
push eax |
call file_system_lfn ; by SPraid fileread |
pop eax |
popad |
pop edi |
pop ecx |
inc ecx ; do not display stars from rose.txt |
pop eax |
add eax,20*10000h - 110 |
mov ebx,0x00ff00 |
push 27 |
pop edx |
nrl: |
call dtext |
; sub ebx,0x050000 |
ror ebx, 16 |
sub bl, 0x05 |
ror ebx, 16 |
add eax,8 |
add ecx,31 |
cmp cx,word 0x0001+25*31 |
jnz nrl |
call checkVga_N13 |
yes_shutdown_param: |
cli |
mov eax,kernel ; load kernel.mnt to 0x8000:0 |
push 12 |
pop esi |
xor ebx,ebx |
or ecx,-1 |
mov edx,0x80000 |
call fileread |
mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0 |
mov edi,0x40000 |
mov ecx,1000 |
rep movsb |
mov eax,0x2F0000 ; restore 0x0 - 0xffff |
xor ebx,ebx |
mov ecx,0x10000 |
call memmove |
call restorefatchain |
mov al, 0xFF |
out 0x21, al |
out 0xA1, al |
mov word [0x467+0],pr_mode_exit-0x10000 |
mov word [0x467+2],0x1000 |
mov al,0x0F |
out 0x70,al |
mov al,0x05 |
out 0x71,al |
mov al,0xFE |
out 0x64,al |
hlt |
use16 |
pr_mode_exit: |
org $-0x10000 |
; setup stack |
mov ax, 3000h |
mov ss, ax |
mov esp, 0EC00h |
; setup ds |
push cs |
pop ds |
lidt [old_ints_h-0x10000] |
;remap IRQs |
mov al,0x11 |
out 0x20,al |
call rdelay |
out 0xA0,al |
call rdelay |
mov al,0x08 |
out 0x21,al |
call rdelay |
mov al,0x70 |
out 0xA1,al |
call rdelay |
mov al,0x04 |
out 0x21,al |
call rdelay |
mov al,0x02 |
out 0xA1,al |
call rdelay |
mov al,0x01 |
out 0x21,al |
call rdelay |
out 0xA1,al |
call rdelay |
mov al,0xB8 |
out 0x21,al |
call rdelay |
mov al,0xBD |
out 0xA1,al |
sti |
temp_3456: |
xor ax,ax |
mov es,ax |
mov al,byte [es:0x9030] |
cmp al,1 |
jl nbw |
cmp al,4 |
jle nbw32 |
nbw: |
in al,0x60 |
call pause_key |
cmp al,6 |
jae nbw |
mov bl,al |
nbw2: |
in al,0x60 |
call pause_key |
cmp al,bl |
je nbw2 |
cmp al,240 ;ax,240 |
jne nbw31 |
mov al,bl |
dec ax |
jmp nbw32 |
nbw31: |
add bl,128 |
cmp al,bl |
jne nbw |
sub al,129 |
nbw32: |
dec ax ; 1 = write floppy |
js nbw |
jnz no_floppy_write |
call floppy_write |
jmp temp_3456 ;nbw |
no_floppy_write: |
dec ax ; 2 = power off |
jnz no_apm_off |
call APM_PowerOff |
jmp $ |
no_apm_off: |
dec ax ; 3 = reboot |
jnz restart_kernel ; 4 = restart kernel |
push 0x40 |
pop ds |
mov word[0x0072],0x1234 |
jmp 0xF000:0xFFF0 |
pause_key: |
mov cx,100 |
pause_key_1: |
loop pause_key_1 |
ret |
rdelay: |
ret |
iglobal |
kernel db 'KERNEL MNT' |
; shutdown_parameter db 0 |
endg |
restart_kernel: |
mov ax,0x0003 ; set text mode for screen |
int 0x10 |
jmp 0x4000:0000 |
restart_kernel_4000: |
cli |
; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0 |
; |
; new_kernel_block_move: |
; |
; mov ebx,0 |
; |
; new_kernel_byte_move: |
; |
; mov ax,di |
; add ax,0x7000 |
; mov es,ax |
; mov dl,[es:bx] |
; mov es,di |
; mov [es:bx],dl |
; |
; inc ebx |
; cmp ebx,65536 |
; jbe new_kernel_byte_move |
; |
; add di,0x1000 |
; cmp di,0x2000 |
; jbe new_kernel_block_move |
push ds |
pop es |
mov cx, 0x8000 |
push cx |
mov ds, cx |
xor si, si |
xor di, di |
rep movsw |
push 0x9000 |
pop ds |
push 0x2000 |
pop es |
pop cx |
rep movsw |
wbinvd ; write and invalidate cache |
; mov ax,0x1000 |
; mov es,ax |
; mov ax,0x3000 |
; mov ss,ax |
; mov sp,0xec00 |
; restore timer |
mov al, 00110100b |
out 43h, al |
jcxz $+2 |
mov al, 0xFF |
out 40h, al |
jcxz $+2 |
out 40h, al |
jcxz $+2 |
sti |
; (hint by Black_mirror) |
; We must read data from keyboard port, |
; because there may be situation when previous keyboard interrupt is lost |
; (due to return to real mode and IRQ reprogramming) |
; and next interrupt will not be generated (as keyboard waits for handling) |
in al, 0x60 |
; bootloader interface |
push 0x1000 |
pop ds |
mov si, kernel_restart_bootblock-0x10000 |
mov ax, 'KL' |
jmp 0x1000:0000 |
APM_PowerOff: |
mov ax, 5304h |
xor bx, bx |
int 15h |
;!!!!!!!!!!!!!!!!!!!!!!!! |
mov ax,0x5300 |
xor bx,bx |
int 0x15 |
push ax |
mov ax,0x5301 |
xor bx,bx |
int 0x15 |
mov ax,0x5308 |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x530E |
xor bx,bx |
pop cx |
int 0x15 |
mov ax,0x530D |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x530F |
mov bx,1 |
mov cx,bx |
int 0x15 |
mov ax,0x5307 |
mov bx,1 |
mov cx,3 |
int 0x15 |
;!!!!!!!!!!!!!!!!!!!!!!!! |
fwwritedone: |
ret |
org $+0x10000 |
flm db 0 |
org $-0x10000 |
floppy_write: ; write diskette image to physical floppy |
cmp [flm-0x10000],byte 1 |
je fwwritedone |
mov [flm-0x10000],byte 1 |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov cx,0x0001 ; startcyl,startsector |
; mov dx,0x0000 ; starthead,drive |
xor dx, dx |
mov ax, 80*2 ; read no of sect |
fwwrites: |
push ax |
; move 1mb+ -> 0:a000 |
pusha |
mov si,fwmovedesc -0x10000 |
mov cx,256*18 |
mov ah,0x87 |
push ds |
pop es |
int 0x15 |
add dword [fwmovedesc-0x10000+0x12], 512*18 |
popa |
xor si,si |
mov es,si |
fwnewwrite: |
mov bx,0xa000 ; es:bx -> data area |
mov ax,0x0300+18 ; read, no of sectors to read |
int 0x13 |
test ah, ah |
jz fwgoodwrite |
inc si |
cmp si,10 |
jnz fwnewwrite |
; can't access diskette - return |
pop ax |
ret |
fwgoodwrite: |
inc dh |
cmp dh,2 |
jnz fwbb2 |
mov dh,0 |
inc ch |
fwbb2: |
pop ax |
dec ax |
jnz fwwrites |
ret |
org $+0x10000 |
fwmovedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
org $-0x10000 |
use32 |
org $+0x10000 |
uglobal |
shutdownpos dd 0x0 |
endg |
iglobal |
if lang eq en |
shutdowntext: |
db "IT'S SAFE TO POWER OFF COMPUTER OR " |
db ' ' |
db '1) SAVE RAMDISK TO FLOPPY ' |
db '2) APM - POWEROFF ' |
db '3) REBOOT ' |
db '4) RESTART KERNEL ' |
else if lang eq ru |
shutdowntext: |
db "¥§®¯ ᮥ ¢ëª«î票¥ ª®¬¯ìîâ¥à ¨«¨ " |
db ' ' |
db '1) ®åà ¨âì à ¬¤¨áª ¤¨áª¥âã ' |
db '2) APM - ¢ëª«î票¥ ¯¨â ¨ï ' |
db '3) ¥à¥§ £à㧪 á¨á⥬ë ' |
db '4) ¥áâ àâ ï¤à ¨§ ' |
else |
shutdowntext: |
db "SIE KOENNEN DEN COMPUTER NUN AUSSCHALTEN" |
db ' ' |
db '1) RAMDISK AUF DISK SPEICHERN ' |
db '2) APM - AUSSCHALTEN ' |
db '3) NEUSTARTEN ' |
db '4) KERNEL NEU STARTEN ' |
end if |
rosef: |
dd 0,0,0,1024,0x90000-std_application_base_address |
db '/rd/1/ROSE.TXT',0 |
endg |
/kernel/branches/hd_kolibri/kernel/bootstrap/bootlog.inc |
---|
0,0 → 1,31 |
boot_log: |
pushad |
mov eax,10*65536 |
mov ax,word [boot_y] |
add [boot_y],dword 10 |
mov ebx,0x80ffffff ; ASCIIZ string with white color |
mov ecx,esi |
mov edi,1 |
call dtext |
mov [novesachecksum],1000 |
call checkVga_N13 |
cmp [preboot_blogesc],byte 1 |
je .bll2 |
cmp esi,boot_tasking |
jne .bll2 |
; begin ealex 04.08.05 |
; in al,0x61 |
; and al,01111111b |
; out 0x61,al |
; end ealex 04.08.05 |
.bll1: in al,0x60 ; wait for ESC key press |
cmp al,129 |
jne .bll1 |
.bll2: popad |
ret |
/kernel/branches/hd_kolibri/kernel/bootstrap/bootmsg.inc |
---|
0,0 → 1,25 |
iglobal |
boot_memdetect db 'Determining amount of memory',0 |
boot_fonts db 'Fonts loaded',0 |
boot_tss db 'Setting TSSs',0 |
boot_cpuid db 'Reading CPUIDs',0 |
boot_devices db 'Detecting devices',0 |
boot_timer db 'Setting timer',0 |
boot_irqs db 'Reprogramming IRQs',0 |
boot_setmouse db 'Setting mouse',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reserving IRQs & ports',0 |
boot_setrports db 'Setting addresses for IRQs',0 |
boot_setostask db 'Setting OS task',0 |
boot_allirqs db 'Unmasking all IRQs',0 |
boot_tsc db 'Reading TSC',0 |
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0 |
boot_pal_vga db 'Setting VGA 640x480 palette',0 |
boot_mtrr db 'Setting MTRR',0 |
boot_tasking db 'All set - press ESC to start',0 |
endg |
iglobal |
boot_y dd 10 |
endg |
/kernel/branches/hd_kolibri/kernel/bootstrap/bootstrap.inc |
---|
0,0 → 1,582 |
align 4 |
B32: |
; CLEAR 0x280000-0xF00000 |
xor eax,eax |
mov edi,0x280000 |
mov ecx,(0x100000*0xF-0x280000) / 4 |
cld |
rep stosd |
; CLEAR 0x80000-0x90000 |
; xor eax,eax |
mov edi,0x80000 |
mov ecx,(0x90000-0x80000)/4 |
; cld |
rep stosd |
; CLEAR KERNEL UNDEFINED GLOBALS |
mov edi, endofcode |
mov ecx, (uglobals_size/4)+4 |
rep stosd |
; SAVE & CLEAR 0-0xffff |
mov esi,0x0000 |
mov edi,0x2F0000 |
mov ecx,0x10000 / 4 |
cld |
rep movsd |
xor eax,eax |
mov edi,0 |
mov ecx,0x10000 / 4 |
cld |
rep stosd |
; SAVE REAL MODE VARIABLES |
mov ax, [0x2f0000 + 0x9031] |
mov [IDEContrRegsBaseAddr], ax |
; --------------- APM --------------------- |
mov eax, [0x2f0000 + 0x9040] ; entry point |
mov dword[apm_entry], eax |
mov word [apm_entry + 4], apm_code_32 - gdts |
mov eax, [0x2f0000 + 0x9044] ; version & flags |
mov [apm_vf], eax |
; ----------------------------------------- |
; movzx eax,byte [0x2f0000+0x9010] ; mouse port |
; mov [0xF604],byte 1 ;al |
mov al, [0x2F0000+0x901F] ; DMA writing |
mov [allow_dma_write], al |
mov al,[0x2f0000+0x9000] ; bpp |
mov [ScreenBPP],al |
movzx eax,word [0x2f0000+0x900A] ; X max |
dec eax |
mov [ScreenWidth],eax |
mov [screen_workarea.right],eax |
movzx eax,word [0x2f0000+0x900C] ; Y max |
dec eax |
mov [ScreenHeight],eax |
mov [screen_workarea.bottom],eax |
movzx eax,word [0x2f0000+0x9008] ; screen mode |
mov [SCR_MODE],eax |
mov eax,[0x2f0000+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 |
mov ax,[0x2f0000+0x9001] ; for other modes |
mov [BytesPerScanLine],ax |
@@: |
; GRAPHICS ADDRESSES |
;mov eax,0x100000*8 ; LFB address |
;cmp [0xfe0c],word 0x13 |
;je no_d_lfb |
;cmp [0xfe0c],word 0x12 |
;je no_d_lfb |
;cmp [0x2f0000+0x901e],byte 1 |
;jne no_d_lfb |
mov byte [0x2f0000+0x901e],0x0 |
mov eax,[0x2f0000+0x9018] |
;no_d_lfb: |
mov [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 [0xe024],dword Vesa12_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz ga24 |
mov [PUTPIXEL],dword Vesa12_putpixel32 |
mov [0xe024],dword Vesa12_getpixel32 |
ga24: |
jmp v20ga24 |
setvesa20: |
mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 |
mov [0xe024],dword Vesa20_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz v20ga24 |
v20ga32: |
mov [PUTPIXEL],dword Vesa20_putpixel32 |
mov [0xe024],dword Vesa20_getpixel32 |
v20ga24: |
cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 |
jne no_mode_0x12 |
mov [PUTPIXEL],dword VGA_putpixel |
mov [0xe024],dword Vesa20_getpixel32 |
no_mode_0x12: |
call test_cpu |
; btr [cpu_caps], CAPS_SSE ;test: dont't use sse code |
; btr [cpu_caps], CAPS_SSE2 ;test: don't use sse2 |
; btr [cpu_caps], CAPS_FXSR ;test: disable sse support |
;all sse commands rise #UD exption |
; btr [cpu_caps], CAPS_PSE ;test: don't use large pages |
; btr [cpu_caps], CAPS_PGE ;test: don't use global pages |
; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR |
bts [cpu_caps], CAPS_TSC ;force use rdtsc |
; -------- Fast System Call init ---------- |
; Intel SYSENTER/SYSEXIT (AMD CPU support it too) |
bt [cpu_caps], CAPS_SEP |
jnc .SEnP ; SysEnter not Present |
xor edx, edx |
mov ecx, MSR_SYSENTER_CS |
mov eax, os_code |
wrmsr |
mov ecx, MSR_SYSENTER_ESP |
; mov eax, sysenter_stack ; Check it |
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 |
; !!!! It`s dirty hack, fix it !!! |
; Bits of EDX : |
; Bit 3116 During the SYSRET instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; Bit 150 During the SYSCALL instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; mov edx, (os_code + 16) * 65536 + os_code |
mov edx, 0x1B0013 |
mov eax, syscall_entry |
mov ecx, MSR_AMD_STAR |
wrmsr |
.noSYSCALL: |
; ----------------------------------------- |
; MEMORY MODEL |
call mem_test |
call init_mtrr |
call init_mem |
call init_page_map |
; ENABLE PAGING |
mov eax, sys_pgdir |
mov cr3, eax |
mov eax,cr0 |
or eax,CR0_PG |
mov cr0,eax |
call init_kernel_heap |
stdcall kernel_alloc, RING0_STACK_SIZE+512 |
mov [os_stack], eax |
call init_LFB |
call init_fpu |
call init_malloc |
stdcall alloc_kernel_space, 0x4F000 |
mov [ipc_tmp], eax |
mov ebx, 0x1000 |
add eax, 0x40000 |
mov [proc_mem_map], eax |
add eax, 0x8000 |
mov [proc_mem_pdir], eax |
add eax, ebx |
mov [proc_mem_tab], eax |
add eax, ebx |
mov [tmp_task_pdir], eax |
add eax, ebx |
mov [tmp_task_ptab], eax |
add eax, ebx |
mov [ipc_pdir], eax |
add eax, ebx |
mov [ipc_ptab], eax |
call init_events |
mov eax, srv.fd-SRV_FD_OFFSET |
mov [srv.fd], eax |
mov [srv.bk], eax |
mov edi, irq_tab |
xor eax, eax |
mov ecx, 16 |
rep stosd |
;Set base of graphic segment to linear address of LFB |
mov eax,[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 |
; BUILD SCHEDULER |
call build_scheduler ; sys32.inc |
; LOAD IDT |
lidt [cs:idtreg] |
cli |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/disks.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
; READ RAMDISK IMAGE FROM HD |
;!!!!!!!!!!!!!!!!!!!!!!! |
;include 'rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
; mov [dma_hdd],1 |
; CALCULATE FAT CHAIN FOR RAMDISK |
call calculatefatchain |
; LOAD VMODE DRIVER |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeld.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
; LOAD FONTS I and II |
mov [CURRENT_TASK],dword 1 |
mov [TASK_COUNT],dword 1 |
mov [TASK_BASE],dword TASK_DATA |
pushad |
push eax |
mov eax,char - std_application_base_address |
call file_system_lfn |
mov eax,char2 - std_application_base_address |
call file_system_lfn |
pop eax |
popad |
; mov esi,char |
; xor ebx,ebx |
; mov ecx,2560;26000 |
; mov edx,FONT_I |
; call fs_RamdiskRead |
; mov esi,char2 |
; xor ebx,ebx |
; mov ecx,2560;26000 |
; mov edx,FONT_II |
; call fs_RamdiskRead |
mov esi,boot_fonts |
call boot_log |
; PRINT AMOUNT OF MEMORY |
mov esi, boot_memdetect |
call boot_log |
movzx ecx, word [boot_y] |
or ecx, (10+29*6) shl 16 ; "Determining amount of memory" |
sub ecx, 10 |
mov edx, 0xFFFFFF |
mov ebx, [MEM_AMOUNT] |
shr ebx, 20 |
mov edi, 1 |
mov eax, 0x00040000 |
call display_number_force |
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f |
mov esi,boot_irqs |
call boot_log |
call rerouteirqs |
mov esi,boot_tss |
call boot_log |
mov esi,boot_devices |
call boot_log |
call detect_devices |
; TIMER SET TO 1/100 S |
mov esi,boot_timer |
call boot_log |
mov al,0x34 ; set to 100Hz |
out 0x43,al |
mov al,0x9b ; lsb 1193180 / 1193 |
out 0x40,al |
mov al,0x2e ; msb |
out 0x40,al |
; SET MOUSE |
mov esi,boot_setmouse |
call boot_log |
call setmouse |
mov [pci_access_enabled],1 |
; SET PRELIMINARY WINDOW STACK AND POSITIONS |
mov esi,boot_windefs |
call boot_log |
call setwindowdefaults |
; SET BACKGROUND DEFAULTS |
mov esi,boot_bgr |
call boot_log |
call calculatebackground |
; RESERVE SYSTEM IRQ'S JA PORT'S |
mov esi,boot_resirqports |
call boot_log |
call reserve_irqs_ports |
; SET PORTS FOR IRQ HANDLERS |
mov esi,boot_setrports |
call boot_log |
call setirqreadports |
; SET UP OS TASK |
mov esi,boot_setostask |
call boot_log |
; mov eax, fpu_data |
; mov dword [SLOT_BASE+APPDATA.fpu_state], eax |
; mov dword [SLOT_BASE+APPDATA.fpu_handler], 0 |
; mov dword [SLOT_BASE+APPDATA.sse_handler], 0 |
; name for OS/IDLE process |
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' |
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' |
mov edi, [os_stack] |
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi |
add edi, RING0_STACK_SIZE |
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi |
mov esi, fpu_data |
mov ecx, 512/4 |
cld |
rep movsd |
mov dword [SLOT_BASE+256+APPDATA.fpu_handler], 0 |
mov dword [SLOT_BASE+256+APPDATA.sse_handler], 0 |
mov ebx, [def_cursor] |
mov dword [SLOT_BASE+256+APPDATA.cursor], ebx |
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET |
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx |
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx |
; task list |
mov [TASK_DATA+TASKDATA.wnd_number], 1 ; on screen number |
mov [TASK_DATA+TASKDATA.pid], 1 ; process id number |
mov [TASK_DATA+TASKDATA.mem_start], 0 ; process base address |
mov edi,tss_data+tss_step |
mov ecx, (tss_step)/4 |
xor eax, eax |
cld |
rep stosd |
mov edi,tss_data+tss_step |
mov [edi+TSS._ss0], os_data |
mov eax,cr3 |
mov [edi+TSS._cr3],eax |
mov [edi+TSS._eip],osloop |
mov [edi+TSS._eflags],dword 0x11202 ; sti and resume |
mov eax, [os_stack] |
add eax, RING0_STACK_SIZE |
mov [edi+TSS._esp], eax |
mov [edi+TSS._cs],os_code |
mov [edi+TSS._ss],os_data |
mov [edi+TSS._ds],os_data |
mov [edi+TSS._es],os_data |
mov [edi+TSS._fs],os_data |
mov [edi+TSS._gs],os_data |
mov ax,tss0 |
ltr ax |
call init_cursors |
; READ TSC / SECOND |
mov esi,boot_tsc |
call boot_log |
call _rdtsc |
mov ecx,eax |
mov esi,250 ; wait 1/4 a second |
call delay_ms |
call _rdtsc |
sub eax,ecx |
shl eax,2 |
mov [CPU_FREQ],eax ; save tsc / sec |
mov ebx, 1000000 |
div ebx |
mov [stall_mcs], eax |
; SET VARIABLES |
call set_variables |
; STACK AND FDC |
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 |
no_pal_vga: |
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 |
mov esi,_skin_file_default |
mov edi,_skin_file |
movsd |
movsd |
movsd |
call load_skin |
; LOAD FIRST APPLICATION |
mov [CURRENT_TASK],dword 1 |
mov [TASK_COUNT],dword 1 |
cli |
cmp byte [0x2f0000+0x9030],1 |
jne no_load_vrr_m |
mov ebp, vrr_m |
xor ebx, ebx |
xor edx, edx |
call fs_execute |
cmp eax,2 ; if vrr_m app found (PID=2) |
je first_app_found |
no_load_vrr_m: |
mov ebp, firstapp |
xor ebx, ebx |
xor edx, edx |
call fs_execute |
cmp eax,2 ; continue if a process has been loaded |
je first_app_found |
mov eax, 0xDEADBEEF ; otherwise halt |
hlt |
first_app_found: |
cli |
;mov [TASK_COUNT],dword 2 |
mov [CURRENT_TASK],dword 1 ; set OS task fisrt |
; SET KEYBOARD PARAMETERS |
mov al, 0xf6 ; reset keyboard, scan enabled |
call kb_write |
; wait until 8042 is ready |
xor ecx,ecx |
@@: |
in al,64h |
and al,00000010b |
loopnz @b |
; mov al, 0xED ; svetodiody - only for testing! |
; call kb_write |
; call kb_read |
; mov al, 111b |
; call kb_write |
; call kb_read |
mov al, 0xF3 ; set repeat rate & delay |
call kb_write |
; call kb_read |
mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500 |
call kb_write |
; call kb_read |
;// mike.dld [ |
call set_lights |
;// mike.dld ] |
; START MULTITASKING |
mov esi,boot_tasking |
call boot_log |
; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled |
; UNMASK ALL IRQ'S |
mov esi,boot_allirqs |
call boot_log |
cli ;guarantee forbidance of interrupts. |
mov al,0 ; unmask all irq's |
out 0xA1,al |
out 0x21,al |
mov ecx,32 |
ready_for_irqs: |
mov al,0x20 ; ready for irqs |
out 0x20,al |
out 0xa0,al |
loop ready_for_irqs ; flush the queue |
stdcall attach_int_handler, dword 1, irq1 |
; mov [dma_hdd],1 |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
sti |
jmp $ ; wait here for timer to take control |
; Fly :) |
/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_fd.inc |
---|
0,0 → 1,28 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;*************************************************** |
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû |
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD |
; àâòîð Mario79 |
;*************************************************** |
xor eax,eax |
mov edi,DRIVE_DATA |
mov ecx,16384 |
cld |
rep stosd |
mov al,0x10 |
out 0x70,al |
mov cx,0xff |
wait_cmos: |
dec cx |
cmp cx,0 |
jne wait_cmos |
in al,0x71 |
mov [DRIVE_DATA],al |
/kernel/branches/hd_kolibri/kernel/bootstrap/detect/dev_hdcd.inc |
---|
0,0 → 1,382 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;****************************************************** |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
;****************************************************** |
;**************************************************** |
;* ÏÎÈÑÊ HDD è CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov ax,[Sector512+176] |
; mov [DRIVE_DATA+6],ax |
; mov ax,[Sector512+126] |
; mov [DRIVE_DATA+8],ax |
; mov ax,[Sector512+128] |
; mov [DRIVE_DATA+8],ax |
mov [DiskNumber],1 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+7],al |
inc [ChannelNumber] |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+8],al |
mov [DiskNumber],1 |
call FindHDD_1 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+9],al |
jmp EndFindHDD |
FindHDD_1: |
call ReadHDD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2 |
cmp [Sector512+6],word 16 |
ja FindHDD_2 |
cmp [Sector512+12],word 255 |
ja FindHDD_2 |
inc byte [DRIVE_DATA+1] |
jmp FindHDD_2_2 |
FindHDD_2: |
call DeviceReset |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
call ReadCD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
inc byte [DRIVE_DATA+1] |
inc byte [DRIVE_DATA+1] |
FindHDD_2_2: |
ret |
FindHDD_3: |
call FindHDD_1 |
shl byte [DRIVE_DATA+1],2 |
ret |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
SectorAddress DD ? |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadHDD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATAHead],0 |
mov [ATACommand],0ECh |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
mov DX,[ATABasePortAddr] |
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíè |
mov ecx,0xffff |
@@WaitCompleet: |
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû |
dec ecx |
cmp ecx,0 |
je @@Error1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw ;ïðèíÿòü áëîê äàííûõ |
jmp @@End |
; Çàïèñàòü êîä îøèáêè |
@@Error1: |
mov [DevErrorCode],1 |
jmp @@End |
@@Error6: |
mov [DevErrorCode],6 |
@@End: ret |
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2 |
StandardATABases DW 1F0h, 170h |
; Íîìåð êàíàëà |
ChannelNumber DW ? |
; Íîìåð äèñêà |
DiskNumber DB ? |
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA |
ATABasePortAddr DW ? |
; Ïàðàìåòðû ATA-êîìàíäû |
ATAFeatures DB ? ;îñîáåííîñòè |
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ |
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà |
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà |
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè |
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA) |
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ |
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé |
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè, |
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà, |
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè |
; êîìàíäû) |
DevErrorCode DB ? |
;**************************************************** |
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1); * |
;* ATAFeatures - "îñîáåííîñòè"; * |
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; * |
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; * |
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; * |
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; * |
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); * |
;* ATACommand - êîä êîìàíäû. * |
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: * |
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; * |
;* â DevErrorCode - íîëü. * |
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò * |
;* âîçâðàùåí êîä îøèáêè. * |
;**************************************************** |
SendCommandToHDD: |
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà |
cmp [ATAAddressMode],1 |
ja @@Err2 |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3 |
cmp BX,2 |
ja @@Err3 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov AX,[ebx+StandardATABases] |
mov [ATABasePortAddr],AX |
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû |
; Âûáðàòü íóæíûé äèñê |
mov DX,[ATABasePortAddr] |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ |
inc DX |
mov ecx,0xfff |
; mov eax,[timer_ticks] |
; mov [TickCounter_1],eax |
@@WaitHDReady: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
cmp ecx,0 |
je @@Err1 |
; mov eax,[timer_ticks] |
; sub eax,[TickCounter_1] |
; cmp eax,300 ;îæèäàòü 300 òèêîâ |
; ja @@Err1 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ |
test AL,08h |
jnz @@WaitHDReady |
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà |
cli |
mov DX,[ATABasePortAddr] |
inc DX ;ðåãèñòð "îñîáåííîñòåé" |
mov AL,[ATAFeatures] |
out DX,AL |
inc DX ;ñ÷åò÷èê ñåêòîðîâ |
mov AL,[ATASectorCount] |
out DX,AL |
inc DX ;ðåãèñòð íîìåðà ñåêòîðà |
mov AL,[ATASectorNumber] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò) |
mov AX,[ATACylinder] |
out DX,AL |
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò) |
mov AL,AH |
out DX,AL |
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà |
mov AL,[DiskNumber] |
shl AL,4 |
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè |
ja @@Err5 |
or AL,[ATAHead] |
or AL,10100000b |
mov AH,[ATAAddressMode] |
shl AH,6 |
or AL,AH |
out DX,AL |
; Ïîñëàòü êîìàíäó |
mov AL,[ATACommand] |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
sti |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
jmp @@End_2 |
; Çàïèñàòü êîä îøèáêè |
@@Err1: mov [DevErrorCode],1 |
jmp @@End_2 |
@@Err2: mov [DevErrorCode],2 |
jmp @@End_2 |
@@Err3: mov [DevErrorCode],3 |
jmp @@End_2 |
@@Err4: mov [DevErrorCode],4 |
jmp @@End_2 |
@@Err5: mov [DevErrorCode],5 |
; Çàâåðøåíèå ðàáîòû ïðîãðàììû |
@@End_2: |
ret |
;************************************************* |
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà; * |
;* DiskNumber - íîìåð äèñêà íà êàíàëå. * |
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ * |
;* â ìàññèâ Sector512. * |
;************************************************* |
ReadCD_ID: |
; Çàäàòü ðåæèì CHS |
mov [ATAAddressMode],0 |
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà |
mov [ATAFeatures],0 |
mov [ATASectorCount],0 |
mov [ATASectorNumber],0 |
mov [ATACylinder],0 |
mov [ATAHead],0 |
mov [ATACommand],0A1h |
call SendCommandToHDD |
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè |
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè |
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD |
mov DX,[ATABasePortAddr] |
add DX,7 ;ïîðò 1õ7h |
mov ecx,0xffff |
@@WaitCompleet_1: |
; Ïðîâåðèòü âðåì |
dec ecx |
cmp ecx,0 |
je @@Error1_1 ;îøèáêà òàéì-àóòà |
; Ïðîâåðèòü ãîòîâíîñòü |
in AL,DX |
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY |
jnz @@WaitCompleet_1 |
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR |
jnz @@Error6_1 |
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ |
jz @@WaitCompleet_1 |
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà |
; mov AX,DS |
; mov ES,AX |
mov EDI,Sector512 ;offset Sector512 |
mov DX,[ATABasePortAddr] ;ïîðò 1x0h |
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ |
rep insw |
jmp @@End_1 |
; Çàïèñàòü êîä îøèáêè |
@@Error1_1: |
mov [DevErrorCode],1 |
jmp @@End_1 |
@@Error6_1: |
mov [DevErrorCode],6 |
@@End_1: |
ret |
;************************************************* |
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ * |
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå * |
;* ïåðåìåííûå: * |
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); * |
;* DiskNumber - íîìåð äèñêà (0 èëè 1). * |
;************************************************* |
DeviceReset: |
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà |
mov BX,[ChannelNumber] |
cmp BX,1 |
jb @@Err3_2 |
cmp BX,2 |
ja @@Err3_2 |
; Óñòàíîâèòü áàçîâûé àäðåñ |
dec BX |
shl BX,1 |
movzx ebx,bx |
mov DX,[ebx+StandardATABases] |
mov [ATABasePortAddr],DX |
; Âûáðàòü íóæíûé äèñê |
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê |
mov AL,[DiskNumber] |
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà |
ja @@Err4_2 |
shl AL,4 |
or AL,10100000b |
out DX,AL |
; Ïîñëàòü êîìàíäó "Ñáðîñ" |
mov AL,08h |
inc DX ;ðåãèñòð êîìàíä |
out DX,AL |
mov ecx,0x80000 |
@@WaitHDReady_1: |
; Ïðîâåðèòü âðåìÿ îæèäàíè |
dec ecx |
cmp ecx,0 |
je @@Err1_2 ;îøèáêà òàéì-àóòà |
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè |
in AL,DX |
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY |
test AL,80h |
jnz @@WaitHDReady_1 |
; Ñáðîñèòü ïðèçíàê îøèáêè |
mov [DevErrorCode],0 |
jmp @@End_3 |
; Îáðàáîòêà îøèáîê |
@@Err1_2: mov [DevErrorCode],1 |
jmp @@End_3 |
@@Err3_2: mov [DevErrorCode],3 |
jmp @@End_3 |
@@Err4_2: mov [DevErrorCode],4 |
; Çàïèñàòü êîä îøèáêè |
@@End_3: |
ret |
EndFindHDD: |
/kernel/branches/hd_kolibri/kernel/bootstrap/detect/disks.inc |
---|
0,0 → 1,5 |
$Revision: 425 $ |
include 'dev_fd.inc' |
include 'dev_hdcd.inc' |
include 'sear_par.inc' |
/kernel/branches/hd_kolibri/kernel/bootstrap/detect/sear_par.inc |
---|
0,0 → 1,125 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;**************************************************** |
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD |
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû |
; àâòîð Mario79 |
;**************************************************** |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
partition_data_transfer: |
mov edi,[transfer_adress] |
mov esi,PARTITION_START |
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 |
; sti |
ret |
end_search_partitions_ide: |
;PARTITION_START dd 0x3f |
;PARTITION_END dd 0 |
;SECTORS_PER_FAT dd 0x1f3a |
;NUMBER_OF_FATS dd 0x2 |
;SECTORS_PER_CLUSTER dd 0x8 |
;BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
;ROOT_CLUSTER dd 2 ; first rootdir cluster |
;FAT_START dd 0 ; start of fat table |
;ROOT_START dd 0 ; start of rootdir (only fat16) |
;ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
;DATA_START dd 0 ; start of data area (=first cluster 2) |
;LAST_CLUSTER dd 0 ; last availabe cluster |
;ADR_FSINFO dd 0 ; used only by fat32 |
; |
;fatRESERVED dd 0x0FFFFFF6 |
;fatBAD dd 0x0FFFFFF7 |
;fatEND dd 0x0FFFFFF8 |
;fatMASK dd 0x0FFFFFFF |
; |
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32 |
/kernel/branches/hd_kolibri/kernel/bootstrap/rdload.inc |
---|
0,0 → 1,102 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; READ RAMDISK IMAGE FROM HD |
cmp [boot_dev],1 |
jne no_sys_on_hd |
test [DRIVE_DATA+1],byte 0x40 |
jz position_2 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],0 |
position_1_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+2] |
cmp [fat32part],eax |
jle position_1_1 |
position_2: |
test [DRIVE_DATA+1],byte 0x10 |
jz position_3 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],0 |
position_2_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+3] |
cmp eax,[fat32part] |
jle position_2_1 |
position_3: |
test [DRIVE_DATA+1],byte 0x4 |
jz position_4 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],0 |
position_3_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+4] |
cmp eax,[fat32part] |
jle position_3_1 |
position_4: |
test [DRIVE_DATA+1],byte 0x1 |
jz no_sys_on_hd |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],0 |
position_4_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+5] |
cmp eax,[fat32part] |
jle position_4_1 |
jmp yes_sys_on_hd |
search_and_read_image: |
call set_FAT32_variables |
mov edx, bootpath |
call read_image |
test eax, eax |
jz image_present |
mov edx, bootpath2 |
call read_image |
test eax, eax |
jz image_present |
ret |
image_present: |
mov [image_retrieved],1 |
ret |
read_image: |
mov eax, hdsysimage |
mov ebx, 1474560/512 |
mov ecx, RAMDISK |
mov esi, 0 |
mov edi, 12 |
call file_read |
ret |
image_retrieved db 0 |
counter_of_partitions db 0 |
no_sys_on_hd: |
yes_sys_on_hd: |
/kernel/branches/hd_kolibri/kernel/bootstrap/switch.inc |
---|
0,0 → 1,65 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SWITCH TO 32 BIT PROTECTED MODE ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
os_data = os_data_l-gdts ; GDTs |
os_code = os_code_l-gdts |
int_code equ int_code_l-gdts |
int_data equ int_data_l-gdts |
tss0sys equ tss0sys_l-gdts |
graph_data equ 3+graph_data_l-gdts |
tss0 equ tss0_l-gdts |
app_code equ 3+app_code_l-gdts |
app_data equ 3+app_data_l-gdts |
; CR0 Flags - Protected mode and Paging |
mov ecx, CR0_PE |
; Enabling 32 bit protected mode |
sidt [cs:old_ints_h-0x10000] |
cli ; disable all irqs |
cld |
mov al,255 ; mask all irqs |
out 0xa1,al |
out 0x21,al |
l.5: in al, 0x64 ; Enable A20 |
test al, 2 |
jnz l.5 |
mov al, 0xD1 |
out 0x64, al |
l.6: in al, 0x64 |
test al, 2 |
jnz l.6 |
mov al, 0xDF |
out 0x60, al |
l.7: in al, 0x64 |
test al, 2 |
jnz l.7 |
mov al, 0xFF |
out 0x64, al |
lgdt [cs:gdts-0x10000] ; Load GDT |
mov eax, cr0 ; Turn on paging // protected mode |
or eax, ecx |
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled |
mov cr0, eax |
jmp $+2 |
org $+0x10000 |
mov ax,os_data ; Selector for os |
mov ds,ax |
mov es,ax |
mov fs,ax |
mov gs,ax |
mov ss,ax |
mov esp,0x3ec00 ; Set stack |
jmp pword os_code:B32 ; jmp to enable 32 bit mode |
if gdte >= $ |
error 'GDT overlaps with used code!' |
end if |
/kernel/branches/hd_kolibri/kernel/bootstrap/vmodeld.inc |
---|
0,0 → 1,38 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; Load of videomode driver in memory |
; |
; (driver is located at 0x760000-0x768000 - 32kb) // if this area not occuped anything |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
; LOAD VIDEOMODE DRIVER |
; If vmode.mdr file not found |
or eax,-1 ; Driver ID = -1 (not present in system) |
mov [OS_BASE+0x760000],eax ; |
mov [OS_BASE+0x760100],byte 0xC3 ; Instruction RETN - driver loop |
pushad |
push eax |
mov eax, vmode - std_application_base_address |
call file_system_lfn |
pop eax |
popad |
; mov esi, vmode |
; xor ebx, ebx |
; mov ecx, 0x8000 ; size of memory area for driver |
; mov edx, OS_BASE+0x760000 ; Memory position of driver |
; call fs_RamdiskRead |
/kernel/branches/hd_kolibri/kernel/build.bat |
---|
0,0 → 1,32 |
@echo off |
set drivers=sound sis infinity ati2d |
mkdir bin |
mkdir bin\drivers |
mkdir bin\skins |
:Target_kernel |
echo building kernel |
echo lang fix en > lang.inc |
fasm -m 65536 kernel.asm bin\kernel.mnt |
:Target_drivers |
echo building drivers ... |
for %%a in (%drivers%) do ( |
fasm -m 65536 drivers\%%a.asm bin\drivers\%%a.obj |
) |
:Target_skins |
echo building skins ... |
cd skin |
fasm -m 65536 default.asm ..\bin\skins\default.skn |
cd .. |
pause |
/kernel/branches/hd_kolibri/kernel/bus/pci/pci16.inc |
---|
0,0 → 1,50 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCI16.INC ;; |
;; ;; |
;; 16 bit PCI driver code ;; |
;; ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
init_pci_16: |
pushad |
xor ax,ax |
mov es,ax |
mov byte [es:0x9020],1 ;default mechanism:1 |
mov ax,0xb101 |
int 0x1a |
or ah,ah |
jnz pci16skip |
mov [es:0x9021],cl ;last PCI bus in system |
mov [es:0x9022],bx |
mov [es:0x9024],edi |
; we have a PCI BIOS, so check which configuration mechanism(s) |
; it supports |
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) |
test al,1 |
jnz pci16skip |
test al,2 |
jz pci16skip |
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 |
pci16skip: |
mov ax,0x1000 |
mov es,ax |
popad |
/kernel/branches/hd_kolibri/kernel/bus/pci/pci32.inc |
---|
0,0 → 1,363 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; PCI32.INC ;; |
;; ;; |
;; 32 bit PCI driver code ;; |
;; ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; Credits: ;; |
;; Ralf Brown ;; |
;; Mike Hibbett, mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;*************************************************************************** |
; Function |
; pci_api: |
; |
; Description |
; entry point for system PCI calls |
;*************************************************************************** |
align 4 |
pci_api: |
cmp [pci_access_enabled],1 |
jne no_pci_access_for_applications |
or al,al |
jnz pci_fn_1 |
; PCI function 0: get pci version (AH.AL) |
movzx eax,word [0x2F0000+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[0x2F0000+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[0x2F0000+0x9020] |
ret |
pci_fn_3: |
cmp al,4 |
jz pci_read_reg ;byte |
cmp al,5 |
jz pci_read_reg ;word |
cmp al,6 |
jz pci_read_reg ;dword |
cmp al,8 |
jz pci_write_reg ;byte |
cmp al,9 |
jz pci_write_reg ;word |
cmp al,10 |
jz pci_write_reg ;dword |
no_pci_access_for_applications: |
mov eax,-1 |
ret |
;*************************************************************************** |
; Function |
; pci_make_config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ah |
; device+func in bh (dddddfff) |
; register in bl |
; |
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 ) |
;*************************************************************************** |
align 4 |
pci_make_config_cmd: |
shl eax,8 ; move bus to bits 16-23 |
mov ax,bx ; combine all |
and eax,0xffffff |
or eax,0x80000000 |
ret |
;*************************************************************************** |
; Function |
; pci_read_reg: |
; |
; Description |
; read a register from the PCI config space into EAX/AX/AL |
; IN: ah=bus,device+func=bh,register address=bl |
; number of bytes to read (1,2,4) coded into AL, bits 0-1 |
;*************************************************************************** |
align 4 |
pci_read_reg: |
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? |
je pci_read_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; get requested DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl ; add to port address first 2 bits of register address |
or esi,esi |
jz pci_read_byte1 |
cmp esi,1 |
jz pci_read_word1 |
cmp esi,2 |
jz pci_read_dword1 |
jmp pci_fin_read1 |
pci_read_byte1: |
in al,dx |
jmp pci_fin_read1 |
pci_read_word1: |
in ax,dx |
jmp pci_fin_read1 |
pci_read_dword1: |
in eax,dx |
jmp pci_fin_read1 |
pci_fin_read1: |
; restore configuration control |
xchg eax,[esp] |
mov dx,0xcf8 |
out dx,eax |
pop eax |
pop esi |
ret |
pci_read_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_read_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
or esi,esi |
jz pci_read_byte2 |
cmp esi,1 |
jz pci_read_word2 |
cmp esi,2 |
jz pci_read_dword2 |
jmp pci_fin_read2 |
pci_read_byte2: |
in al,dx |
jmp pci_fin_read2 |
pci_read_word2: |
in ax,dx |
jmp pci_fin_read2 |
pci_read_dword2: |
in eax,dx |
; jmp pci_fin_read2 |
pci_fin_read2: |
; restore configuration space |
xchg eax,[esp] |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
pop eax |
pop esi |
ret |
pci_read_reg_err: |
xor eax,eax |
dec eax |
ret |
;*************************************************************************** |
; Function |
; pci_write_reg: |
; |
; Description |
; write a register from ECX/CX/CL into the PCI config space |
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, |
; value to write in ecx |
; number of bytes to write (1,2,4) coded into AL, bits 0-1 |
;*************************************************************************** |
align 4 |
pci_write_reg: |
cmp byte [0x2F0000+0x9020],2 ;what mechanism will we use? |
je pci_write_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state into ecx |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; write DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl |
mov eax,ecx |
or esi,esi |
jz pci_write_byte1 |
cmp esi,1 |
jz pci_write_word1 |
cmp esi,2 |
jz pci_write_dword1 |
jmp pci_fin_write1 |
pci_write_byte1: |
out dx,al |
jmp pci_fin_write1 |
pci_write_word1: |
out dx,ax |
jmp pci_fin_write1 |
pci_write_dword1: |
out dx,eax |
jmp pci_fin_write1 |
pci_fin_write1: |
; restore configuration control |
pop eax |
mov dl,0xf8 |
out dx,eax |
xor eax,eax |
pop esi |
ret |
pci_write_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_write_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
; write register |
mov eax,ecx |
or esi,esi |
jz pci_write_byte2 |
cmp esi,1 |
jz pci_write_word2 |
cmp esi,2 |
jz pci_write_dword2 |
jmp pci_fin_write2 |
pci_write_byte2: |
out dx,al |
jmp pci_fin_write2 |
pci_write_word2: |
out dx,ax |
jmp pci_fin_write2 |
pci_write_dword2: |
out dx,eax |
jmp pci_fin_write2 |
pci_fin_write2: |
; restore configuration space |
pop eax |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
xor eax,eax |
pop esi |
ret |
pci_write_reg_err: |
xor eax,eax |
dec eax |
ret |
/kernel/branches/hd_kolibri/kernel/const.inc |
---|
0,0 → 1,576 |
$Revision: 434 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
drw0 equ 10010010b ; data read/write dpl0 |
drw3 equ 11110010b ; data read/write dpl3 |
cpl0 equ 10011010b ; code read dpl0 |
cpl3 equ 11111010b ; code read dpl3 |
D32 equ 01000000b ; 32bit segment |
G32 equ 10000000b ; page gran |
;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; |
CPU_386 equ 3 |
CPU_486 equ 4 |
CPU_PENTIUM equ 5 |
CPU_P6 equ 6 |
CPU_PENTIUM4 equ 0x0F |
CAPS_FPU equ 00 ;on-chip x87 floating point unit |
CAPS_VME equ 01 ;virtual-mode enhancements |
CAPS_DE equ 02 ;debugging extensions |
CAPS_PSE equ 03 ;page-size extensions |
CAPS_TSC equ 04 ;time stamp counter |
CAPS_MSR equ 05 ;model-specific registers |
CAPS_PAE equ 06 ;physical-address extensions |
CAPS_MCE equ 07 ;machine check exception |
CAPS_CX8 equ 08 ;CMPXCHG8B instruction |
CAPS_APIC equ 09 ;on-chip advanced programmable |
; interrupt controller |
; 10 ;unused |
CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions |
CAPS_MTRR equ 12 ;memory-type range registers |
CAPS_PGE equ 13 ;page global extension |
CAPS_MCA equ 14 ;machine check architecture |
CAPS_CMOV equ 15 ;conditional move instructions |
CAPS_PAT equ 16 ;page attribute table |
CAPS_PSE36 equ 17 ;page-size extensions |
CAPS_PSN equ 18 ;processor serial number |
CAPS_CLFLUSH equ 19 ;CLFUSH instruction |
CAPS_DS equ 21 ;debug store |
CAPS_ACPI equ 22 ;thermal monitor and software |
;controlled clock supported |
CAPS_MMX equ 23 ;MMX instructions |
CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions |
CAPS_SSE equ 25 ;SSE instructions |
CAPS_SSE2 equ 26 ;SSE2 instructions |
CAPS_SS equ 27 ;self-snoop |
CAPS_HTT equ 28 ;hyper-threading technology |
CAPS_TM equ 29 ;thermal monitor supported |
CAPS_IA64 equ 30 ;IA64 capabilities |
CAPS_PBE equ 31 ;pending break enable |
;ecx |
CAPS_SSE3 equ 32 ;SSE3 instructions |
; 33 |
; 34 |
CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions |
CAPS_DS_CPL equ 36 ; |
CAPS_VMX equ 37 ;virtual mode extensions |
; 38 ; |
CAPS_EST equ 39 ;enhansed speed step |
CAPS_TM2 equ 40 ;thermal monitor2 supported |
; 41 |
CAPS_CID equ 42 ; |
; 43 |
; 44 |
CAPS_CX16 equ 45 ;CMPXCHG16B instruction |
CAPS_xTPR equ 46 ; |
; |
;reserved |
; |
;ext edx /ecx |
CAPS_SYSCAL equ 64 ; |
CAPS_XD equ 65 ;execution disable |
CAPS_FFXSR equ 66 ; |
CAPS_RDTSCP equ 67 ; |
CAPS_X64 equ 68 ; |
CAPS_3DNOW equ 69 ; |
CAPS_3DNOWEXT equ 70 ; |
CAPS_LAHF equ 71 ; |
CAPS_CMP_LEG equ 72 ; |
CAPS_SVM equ 73 ;secure virual machine |
CAPS_ALTMOVCR8 equ 74 ; |
; CPU MSR names |
MSR_SYSENTER_CS equ 0x174 |
MSR_SYSENTER_ESP equ 0x175 |
MSR_SYSENTER_EIP equ 0x176 |
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register |
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register |
CR0_PE equ 0x00000001 ;protected mode |
CR0_MP equ 0x00000002 ;monitor fpu |
CR0_EM equ 0x00000004 ;fpu emulation |
CR0_TS equ 0x00000008 ;task switch |
CR0_ET equ 0x00000010 ;extension type hardcoded to 1 |
CR0_NE equ 0x00000020 ;numeric error |
CR0_WP equ 0x00010000 ;write protect |
CR0_AM equ 0x00040000 ;alignment check |
CR0_NW equ 0x20000000 ;not write-through |
CR0_CD equ 0x40000000 ;cache disable |
CR0_PG equ 0x80000000 ;paging |
CR4_VME equ 0x0001 |
CR4_PVI equ 0x0002 |
CR4_TSD equ 0x0004 |
CR4_DE equ 0x0008 |
CR4_PSE equ 0x0010 |
CR4_PAE equ 0x0020 |
CR4_MCE equ 0x0040 |
CR4_PGE equ 0x0080 |
CR4_PCE equ 0x0100 |
CR4_OSFXSR equ 0x0200 |
CR4_OSXMMEXPT equ 0x0400 |
SSE_IE equ 0x0001 |
SSE_DE equ 0x0002 |
SSE_ZE equ 0x0004 |
SSE_OE equ 0x0008 |
SSE_UE equ 0x0010 |
SSE_PE equ 0x0020 |
SSE_DAZ equ 0x0040 |
SSE_IM equ 0x0080 |
SSE_DM equ 0x0100 |
SSE_ZM equ 0x0200 |
SSE_OM equ 0x0400 |
SSE_UM equ 0x0800 |
SSE_PM equ 0x1000 |
SSE_FZ equ 0x8000 |
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) |
OS_BASE equ 0 |
window_data equ (OS_BASE+0x0000000) |
CURRENT_TASK equ (OS_BASE+0x0003000) |
TASK_COUNT equ (OS_BASE+0x0003004) |
CURRENT_RING0_ESP equ (OS_BASE+0x0003008) |
TASK_BASE equ (OS_BASE+0x0003010) |
TASK_DATA equ (OS_BASE+0x0003020) |
TASK_EVENT equ (OS_BASE+0x0003020) |
mouseunder equ (OS_BASE+0x0006900) |
FLOPPY_BUFF equ (OS_BASE+0x0008000) |
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused |
idts equ (OS_BASE+0x000B100) |
WIN_STACK equ (OS_BASE+0x000C000) |
WIN_POS equ (OS_BASE+0x000C400) |
FDD_BUFF equ (OS_BASE+0x000D000) |
;unused ? only one reference |
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000) |
PUTPIXEL equ (OS_BASE+0x000E020) |
GETPIXEL equ (OS_BASE+0x000E024) |
;unused ? only one reference |
BANK_SWITCH equ (OS_BASE+0x000E030) |
;unused ? store mousepointer |
MOUSE_PICTURE equ (OS_BASE+0x000F200) |
MOUSE_VISIBLE equ (OS_BASE+0x000F204) |
WIN_TEMP_XY equ (OS_BASE+0x000F300) |
KEY_COUNT equ (OS_BASE+0x000F400) |
KEY_BUFF equ (OS_BASE+0x000F401) |
BTN_COUNT equ (OS_BASE+0x000F500) |
BTN_BUFF equ (OS_BASE+0x000F501) |
CPU_FREQ equ (OS_BASE+0x000F600) |
;unused ? no active references |
MOUSE_PORT equ (OS_BASE+0x000F604) |
;unused |
PS2_CHUNK equ (OS_BASE+0x000FB00) |
MOUSE_X equ (OS_BASE+0x000FB0A) |
MOUSE_Y equ (OS_BASE+0x000FB0C) |
MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10) |
COLOR_TEMP equ (OS_BASE+0x000FB30) |
BTN_DOWN equ (OS_BASE+0x000FB40) |
MOUSE_DOWN equ (OS_BASE+0x000FB44) |
X_UNDER equ (OS_BASE+0x000FB4A) |
Y_UNDER equ (OS_BASE+0x000FB4C) |
ScreenBPP equ (OS_BASE+0x000FBF1) |
;unused ? only one reference |
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) |
LFBAddress equ (OS_BASE+0x000FE80) |
MEM_AMOUNT equ (OS_BASE+0x000FE8C) |
;LFBSize equ (OS_BASE+0x02f9050) |
ScreenWidth equ (OS_BASE+0x000FE00) |
ScreenHeight equ (OS_BASE+0x000FE04) |
BytesPerScanLine equ (OS_BASE+0x000FE08) |
SCR_MODE equ (OS_BASE+0x000FE0C) |
BTN_ADDR equ (OS_BASE+0x000FE88) |
SYS_SHUTDOWN equ (OS_BASE+0x000FF00) |
TASK_ACTIVATE equ (OS_BASE+0x000FF01) |
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0) |
BANK_RW equ (OS_BASE+0x000FFF2) |
MOUSE_BACKGROUND equ (OS_BASE+0x000FFF4) |
DONT_DRAW_MOUSE equ (OS_BASE+0x000FFF5) |
DONT_SWITCH equ (OS_BASE+0x000FFFF) |
TMP_STACK_TOP equ 0x003EC00 |
FONT_II equ (OS_BASE+0x003EC00) |
FONT_I equ (OS_BASE+0x003F600) |
DRIVE_DATA equ (OS_BASE+0x0040000) |
SLOT_BASE equ (OS_BASE+0x0080000) |
;unused |
TMP_BUFF equ (OS_BASE+0x0090000) |
VGABasePtr equ (OS_BASE+0x00A0000) |
RAMDISK equ (OS_BASE+0x0100000) |
RAMDISK_FAT equ (OS_BASE+0x0280000) |
FLOPPY_FAT equ (OS_BASE+0x0282000) |
; unused? |
SB16_Status equ (OS_BASE+0x02B0000) |
BUTTON_INFO equ (OS_BASE+0x02C0000) |
RESERVED_PORTS equ (OS_BASE+0x02D0000) |
IRQ_SAVE equ (OS_BASE+0x02E0000) |
BOOT_VAR equ (OS_BASE+0x02f0000) |
IMG_BACKGROUND equ (OS_BASE+0x0300000) |
WinMapAddress equ (OS_BASE+0x0460000) |
display_data equ (OS_BASE+0x0460000) |
;unused ? |
HD_CACHE equ (OS_BASE+0x0600000) |
stack_data_start equ (OS_BASE+0x0700000) |
eth_data_start equ (OS_BASE+0x0700000) |
stack_data equ (OS_BASE+0x0704000) |
stack_data_end equ (OS_BASE+0x071ffff) |
VMODE_BASE equ (OS_BASE+0x0760000) |
resendQ equ (OS_BASE+0x0770000) |
skin_data equ (OS_BASE+0x0778000) |
tss_data equ (OS_BASE+0x780000) |
draw_data equ (OS_BASE+0x988000) |
HEAP_BASE equ (OS_BASE+0x98B000) |
LFB_BASE equ 0x7DC00000 |
page_tabs equ 0x7FC00000 |
master_tab equ 0x7FDFF000 |
app_page_tabs equ 0x7FE00000 |
sys_pgdir equ OS_BASE+0x00050000 |
sys_master_tab equ OS_BASE+0x00051000 |
sys_pgmap equ OS_BASE+0x00052000 |
new_app_base equ 0x80000000 |
twdw equ (CURRENT_TASK-window_data) |
std_application_base_address equ new_app_base |
RING0_STACK_SIZE equ (0x2000-512) ;512 áàéò äëÿ êîíòåêñòà FPU |
;PAGES_USED equ 4 |
PG_UNMAP equ 0x000 |
PG_MAP equ 0x001 |
PG_WRITE equ 0x002 |
PG_SW equ 0x003 |
PG_USER equ 0x005 |
PG_UW equ 0x007 |
PG_NOCACHE equ 0x018 |
PG_LARGE equ 0x080 |
PG_GLOBAL equ 0x100 |
;;;;;;;;;;;boot time variables |
;BOOT_BPP equ 0x9000 ;byte bits per pixel |
BOOT_SCANLINE equ 0x9001 ;word scanline length |
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode |
;;BOOT_X_RES equ 0x900A ;word X res |
;;BOOT_Y_RES equ 0x900C ;word Y res |
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used |
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch |
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address |
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration |
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) |
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled |
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data |
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no |
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr |
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount |
TMP_FILE_NAME equ 0 |
TMP_CMD_LINE equ 1024 |
TMP_ICON_OFFS equ 1280 |
EVENT_REDRAW equ 0x00000001 |
EVENT_KEY equ 0x00000002 |
EVENT_BUTTON equ 0x00000004 |
EVENT_BACKGROUND equ 0x00000010 |
EVENT_MOUSE equ 0x00000020 |
EVENT_IPC equ 0x00000040 |
EVENT_NETWORK equ 0x00000080 |
EVENT_DEBUG equ 0x00000100 |
EVENT_EXTENDED equ 0x00000200 |
EV_INTR equ 1 |
struc SYS_VARS |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
.cpu_caps dd ? |
dd ? |
dd ? |
dd ? |
} |
struc APPOBJ ;common object header |
{ |
.magic dd ? ; |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
}; |
virtual at 0 |
APPOBJ APPOBJ |
end virtual |
APP_OBJ_OFFSET equ 48 |
APP_EV_OFFSET equ 40 |
struc CURSOR |
{;common object header |
.magic dd ? ;'CURS' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
;cursor data |
.base dd ? ;allocated memory |
.hot_x dd ? ;hotspot coords |
.hot_y dd ? |
} |
virtual at 0 |
CURSOR CURSOR |
end virtual |
CURSOR_SIZE equ 32 |
struc EVENT |
{ |
.magic dd ? ;'EVNT' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.id dd ? ;event uid |
.state dd ? ;internal flags |
.code dd ? |
rd 5 |
} |
EVENT_SIZE equ 52 |
virtual at 0 |
EVENT EVENT |
end virtual |
struc HEAP_DATA |
{ |
.mutex rd 1 |
.refcount rd 1 |
.heap_base rd 1 |
.heap_top rd 1 |
.app_mem rd 1 |
} |
HEAP_DATA_SIZE equ 20 |
virtual at 0 |
HEAP_DATA HEAP_DATA |
end virtual |
struc BOOT_DATA |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
.mouse_port dd ? |
.bank_switch dd ? |
.lfb dd ? |
.vesa_mem dd ? |
.log dd ? |
.direct_lfb dd ? |
.pci_data dd ? |
; dd ? |
.vrr dd ? |
.ide_base dd ? |
.mem_amount dd ? |
.pages_count dd ? |
.pagemap_size dd ? |
.kernel_max dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.cpu_vendor dd ? |
dd ? |
dd ? |
.cpu_sign dd ? |
.cpu_info dd ? |
.cpu_caps dd ? |
dd ? |
dd ? |
} |
virtual at 0 |
BOOT_DATA BOOT_DATA |
end virtual |
struc MEM_STATE |
{ .mutex rd 1 |
.smallmap rd 1 |
.treemap rd 1 |
.topsize rd 1 |
.top rd 1 |
.smallbins rd 4*32 |
.treebins rd 32 |
} |
struc PG_DATA |
{ .mem_amount dd ? |
.vesa_mem dd ? |
.pages_count dd ? |
.pages_free dd ? |
.pages_faults dd ? |
.pagemap_size dd ? |
.kernel_max dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.sys_page_dir dd ? |
.pg_mutex dd ? |
} |
;struc LIB |
;{ .lib_name rb 16 |
; .lib_base dd ? |
; .lib_start dd ? |
; .export dd ? |
; .import dd ? |
;} |
struc SRV |
{ .srv_name rb 16 ;ASCIIZ string |
.magic dd ? ;+0x10 ;'SRV ' |
.size dd ? ;+0x14 ;size of structure SRV |
.fd dd ? ;+0x18 ;next SRV descriptor |
.bk dd ? ;+0x1C ;prev SRV descriptor |
.base dd ? ;+0x20 ;service base address |
.entry dd ? ;+0x24 ;service START function |
.srv_proc dd ? ;+0x28 ;main service handler |
} |
SRV_FD_OFFSET equ 0x18 |
SRV_SIZE equ 44 |
struc COFF_HEADER |
{ .machine dw ? |
.nSections dw ? |
.DataTime dd ? |
.pSymTable dd ? |
.nSymbols dd ? |
.optHeader dw ? |
.flags dw ? |
}; |
struc COFF_SECTION |
{ .Name rb 8 |
.VirtualSize dd ? |
.VirtualAddress dd ? |
.SizeOfRawData dd ? |
.PtrRawData dd ? |
.PtrReloc dd ? |
.PtrLinenumbers dd ? |
.NumReloc dw ? |
.NumLinenum dw ? |
.Characteristics dd ? |
} |
COFF_SECTION_SIZE equ 40 |
struc COFF_RELOC |
{ .VirtualAddress dd ? |
.SymIndex dd ? |
.Type dw ? |
} |
struc COFF_SYM |
{ .Name rb 8 |
.Value dd ? |
.SectionNumber dw ? |
.Type dw ? |
.StorageClass db ? |
.NumAuxSymbols db ? |
} |
CSYM_SIZE equ 18 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
;virtual at 0 |
; LIB LIB |
;end virtual |
virtual at 0 |
SRV SRV |
end virtual |
virtual at 0 |
CFH COFF_HEADER |
end virtual |
virtual at 0 |
CFS COFF_SECTION |
end virtual |
virtual at 0 |
CRELOC COFF_RELOC |
end virtual |
virtual at 0 |
CSYM COFF_SYM |
end virtual |
/kernel/branches/hd_kolibri/kernel/core/debug.inc |
---|
0,0 → 1,507 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; diamond, 2006 |
sys_debug_services: |
cmp eax, 9 |
ja @f |
jmp dword [sys_debug_services_table+eax*4] |
@@: ret |
sys_debug_services_table: |
dd debug_set_event_data |
dd debug_getcontext |
dd debug_setcontext |
dd debug_detach |
dd debug_suspend |
dd debug_resume |
dd debug_read_process_memory |
dd debug_write_process_memory |
dd debug_terminate |
dd debug_set_drx |
debug_set_event_data: |
; in: ebx = pointer |
; destroys eax |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
mov [eax+SLOT_BASE+APPDATA.dbg_event_mem], ebx |
ret |
get_debuggee_slot: |
; in: ebx=PID |
; out: CF=1 if error |
; CF=0 and eax=slot*0x20 if ok |
; out: interrupts disabled |
cli |
mov eax, ebx |
call pid_to_slot |
test eax, eax |
jz .ret_bad |
shl eax, 5 |
push ebx |
mov ebx, [CURRENT_TASK] |
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx |
pop ebx |
jnz .ret_bad |
; clc ; automatically |
ret |
.ret_bad: |
stc |
ret |
debug_detach: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 |
call do_resume |
.ret: |
sti |
ret |
debug_terminate: |
; in: ebx=pid |
call get_debuggee_slot |
jc debug_detach.ret |
mov ebx, eax |
shr ebx, 5 |
push 2 |
pop eax |
jmp sys_system |
debug_suspend: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state |
test bl, bl |
jz .1 |
cmp bl, 5 |
jnz .ret |
mov bl, 2 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
.ret: |
sti |
ret |
.1: |
inc ebx |
jmp .2 |
do_resume: |
mov bl, [CURRENT_TASK+eax+TASKDATA.state] |
cmp bl, 1 |
jz .1 |
cmp bl, 2 |
jnz .ret |
mov bl, 5 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
.ret: ret |
.1: dec ebx |
jmp .2 |
debug_resume: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
call do_resume |
.ret: sti |
ret |
debug_getcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
add edx, std_application_base_address |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .ret |
imul eax, tss_step/32 |
add eax, tss_data |
mov edi, edx |
cmp [eax+TSS._cs], app_code |
jnz .ring0 |
lea esi, [eax+TSS._eip] |
shr ecx, 2 |
rep movsd |
jmp .ret |
.ring0: |
; note that following code assumes that all interrupt/exception handlers |
; saves ring-3 context by push ds es, pushad in this order |
mov esi, [eax+TSS._esp0] |
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad |
sub esi, 8+12+8+20h |
lodsd |
mov [edi+24h], eax |
lodsd |
mov [edi+20h], eax |
lodsd |
mov [edi+1Ch], eax |
lodsd |
lodsd |
mov [edi+14h], eax |
lodsd |
mov [edi+10h], eax |
lodsd |
mov [edi+0Ch], eax |
lodsd |
mov [edi+8], eax |
add esi, 8 |
lodsd |
mov [edi], eax |
lodsd |
lodsd |
mov [edi+4], eax |
lodsd |
mov [edi+18h], eax |
.ret: |
sti |
ret |
debug_setcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
add edx, std_application_base_address |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .stiret |
imul eax, tss_step/32 |
add eax, tss_data |
mov esi, edx |
cmp [eax+TSS._cs], app_code |
jnz .ring0 |
lea edi, [eax+TSS._eip] |
shr ecx, 2 |
rep movsd |
jmp .stiret |
.ring0: |
mov edi, [eax+TSS._esp0] |
sub edi, 8+12+8+20h |
mov eax, [esi+24h] |
stosd |
mov eax, [esi+20h] |
stosd |
mov eax, [esi+1Ch] |
stosd |
scasd |
mov eax, [esi+14h] |
stosd |
mov eax, [esi+10h] |
stosd |
mov eax, [esi+0Ch] |
stosd |
mov eax, [esi+8] |
stosd |
add edi, 8 |
mov eax, [esi] |
stosd |
scasd |
mov eax, [esi+4] |
stosd |
mov eax, [esi+18h] |
stosd |
.stiret: |
sti |
.ret: |
ret |
debug_set_drx: |
call get_debuggee_slot |
jc .errret |
mov ebp, eax |
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] |
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
; [eax+10]=dr7 |
add edx, std_application_base_address |
jc .errret |
cmp cl, 3 |
ja .errret |
mov ebx, dr7 |
shr ebx, cl |
shr ebx, cl |
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable |
jnz .errret2 |
test ch, ch |
jns .new |
; clear breakpoint |
movzx ecx, cl |
add ecx, ecx |
and dword [eax+ecx*2], 0 ; clear DR<i> |
btr dword [eax+10h], ecx ; clear L<i> bit |
test byte [eax+10h], 55h |
jnz .okret |
imul eax, ebp, tss_step/32 |
and byte [eax + tss_data + TSS._trap], not 1 |
.okret: |
and dword [esp+36], 0 |
sti |
ret |
.errret: |
sti |
mov dword [esp+36], 1 |
ret |
.errret2: |
sti |
mov dword [esp+36], 2 |
ret |
.new: |
; add new breakpoint |
; cl=index; ch=flags; edx=address |
test ch, 0xF0 |
jnz .errret |
mov bl, ch |
and bl, 3 |
cmp bl, 2 |
jz .errret |
mov bl, ch |
shr bl, 2 |
cmp bl, 2 |
jz .errret |
test dl, bl |
jnz .errret |
or byte [eax+10h+1], 3 ; set GE and LE flags |
movzx ebx, ch |
movzx ecx, cl |
add ecx, ecx |
bts dword [eax+10h], ecx ; set L<i> flag |
add ecx, ecx |
mov [eax+ecx], edx ; set DR<i> |
shl ebx, cl |
mov edx, 0xF |
shl edx, cl |
not edx |
and [eax+10h+2], dx |
or [eax+10h+2], bx ; set R/W and LEN fields |
imul eax, ebp, tss_step/32 |
or byte [eax + tss_data + TSS._trap], 1 |
jmp .okret |
debug_read_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(read) |
; destroys all |
add esi, std_application_base_address |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz .err |
call get_debuggee_slot |
jc .err |
shr eax, 5 |
mov ebx, esi |
call read_process_memory |
sti |
mov dword [esp+36], eax |
ret |
.err: |
or dword [esp+36], -1 |
ret |
debug_write_process_memory: |
; in: |
; ebx=pid |
; ecx=length |
; esi->buffer in debugger |
; edx=address in debuggee |
; out: [esp+36]=sizeof(write) |
; destroys all |
add esi, std_application_base_address |
push ebx |
mov ebx, esi |
call check_region |
pop ebx |
dec eax |
jnz debug_read_process_memory.err |
call get_debuggee_slot |
jc debug_read_process_memory.err |
shr eax, 5 |
mov ebx, esi |
call write_process_memory |
sti |
mov [esp+36], eax |
ret |
debugger_notify: |
; in: eax=debugger slot |
; ecx=size of debug message |
; [esp+4]..[esp+4+ecx]=message |
; interrupts must be disabled! |
; destroys all general registers |
; interrupts remain disabled |
xchg ebp, eax |
mov edi, [timer_ticks] |
add edi, 500 ; 5 sec timeout |
.1: |
mov eax, ebp |
shl eax, 8 |
mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
test edx, edx |
jz .ret |
; read buffer header |
push ecx |
push eax |
push eax |
mov eax, ebp |
mov ebx, esp |
mov ecx, 8 |
call read_process_memory |
cmp eax, ecx |
jz @f |
add esp, 12 |
jmp .ret |
@@: |
cmp dword [ebx], 0 |
jg @f |
.2: |
pop ecx |
pop ecx |
pop ecx |
cmp dword [CURRENT_TASK], 1 |
jnz .notos |
cmp [timer_ticks], edi |
jae .ret |
.notos: |
sti |
call change_task |
cli |
jmp .1 |
@@: |
mov ecx, [ebx+8] |
add ecx, [ebx+4] |
cmp ecx, [ebx] |
ja .2 |
; advance buffer position |
push ecx |
mov ecx, 4 |
sub ebx, ecx |
mov eax, ebp |
add edx, ecx |
call write_process_memory |
pop eax |
; write message |
mov eax, ebp |
add edx, ecx |
add edx, [ebx+8] |
add ebx, 20 |
pop ecx |
pop ecx |
pop ecx |
call write_process_memory |
; new debug event |
mov eax, ebp |
shl eax, 8 |
or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
.ret: |
ret |
debug_exc: |
; int 1 = #DB |
save_ring3_context |
cld |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov eax, dr6 |
test ax, ax |
jns @f |
; this is exception from task switch |
; set DRx registers for task and continue |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
add eax, SLOT_BASE+APPDATA.dbg_regs |
mov ecx, [eax+0] |
mov dr0, ecx |
mov ecx, [eax+4] |
mov dr1, ecx |
mov ecx, [eax+8] |
mov dr2, ecx |
mov ecx, [eax+0Ch] |
mov dr3, ecx |
xor ecx, ecx |
mov dr6, ecx |
mov ecx, [eax+10h] |
mov dr7, ecx |
restore_ring3_context |
iretd |
@@: |
push eax |
xor eax, eax |
mov dr6, eax |
; test if debugging |
cli |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
mov eax, [SLOT_BASE+eax+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
add esp, 28h+4 |
mov [error_interrupt], 1 |
call show_error_parameters |
mov edx, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 4 |
jmp change_task |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
; eax=debugger PID |
pop edx |
mov ebx, dr7 |
mov cl, not 1 |
.l1: |
test bl, 1 |
jnz @f |
and dl, cl |
@@: |
shr ebx, 2 |
add cl, cl |
inc ecx |
cmp cl, not 10h |
jnz .l1 |
push edx ; DR6 image |
mov ecx, [TASK_BASE] |
push dword [ecx+TASKDATA.pid] ; PID |
push 12 |
pop ecx |
push 3 ; 3 = debug exception |
call debugger_notify |
pop ecx |
pop ecx |
pop ecx |
mov edx, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
restore_ring3_context |
iretd |
/kernel/branches/hd_kolibri/kernel/core/detect/commouse.inc |
---|
0,0 → 1,143 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;************************************************** |
;* ÏÎÈÑÊ ÌÛØÈ ÏÎ ÏÎÑËÅÄÎÂÀÒÅËÜÍÛÌ ÏÎÐÒÀÌ * |
;* Ïðîöåäóðà ïîäãîòàâëèâàåò ãëîáàëüíûå ïåðåìåííûå * |
;* COMPortNum è COMPortBaseAddr äëÿ ïîäïðîãðàììû * |
;* óñòàíîâêè îáðàáîò÷èêà ïðåðûâàíèÿ * |
;************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
Detect_COM_Mouse: |
pusha |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com1_mouse_detected],1 |
pusha |
mov eax,4 |
shl eax,2 |
mov [irq_owner+eax],byte 1 |
inc dword [RESERVED_PORTS] |
mov edi,[RESERVED_PORTS] |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0x3f0 |
mov [RESERVED_PORTS+edi+8],dword 0x3ff |
popa |
mov esi,boot_setmouse_type+22 |
call boot_log |
@@: |
sub [COMPortBaseAddr],100h |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com2_mouse_detected],1 |
pusha |
mov eax,3 |
shl eax,2 |
mov [irq_owner+eax],byte 1 |
inc dword [RESERVED_PORTS] |
mov edi,[RESERVED_PORTS] |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0x2f0 |
mov [RESERVED_PORTS+edi+8],dword 0x2ff |
popa |
mov esi,boot_setmouse_type+44 |
call boot_log |
@@: |
popa |
jmp end_detecting_mouse |
MSMouseSearch: |
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ |
MouseSearch: |
; Óñòàíàâëèâàåì ñêîðîñòü |
; ïðèåìà/ïåðåäà÷è 1200 áîä |
mov DX,[COMPortBaseAddr] |
add DX,3 |
in AL,DX |
or AL,80h ;óñòàíîâèòü áèò DLAB |
out DX,AL |
mov DX,[COMPortBaseAddr] |
mov AL,60h ;1200 áîä |
out DX,AL |
inc DX |
mov AL,0 |
out DX,AL |
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò, |
; ÷åòíîñòü íå êîíòðîëèðîâàòü |
mov DX,[COMPortBaseAddr] |
add DX,3 |
mov AL,00000010b |
out DX,AL |
; Çàïðåòèòü âñå ïðåðûâàíè |
mov DX,[COMPortBaseAddr] |
inc DX |
mov AL,0 |
out DX,AL |
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ |
; ìûøüþ òèïà MSMouse |
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè |
mov DX,[COMPortBaseAddr] |
add DX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì |
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2 |
out DX,AL |
; Îæèäàòü 5 "òèêîâ" (0,2 ñ) |
mov ecx,0xffff |
dT_1: |
dec ecx |
cmp ecx,0 |
jne dT_1 |
mov ecx,0xffff |
; Âêëþ÷èòü ïèòàíèå ìûøè |
mov AL,11b ;óñòàíîâèòü DTR è RTS |
out DX,AL |
; Î÷èñòèòü ðåãèñòð äàííûõ |
mov DX,[COMPortBaseAddr] |
in AL,DX |
; Öèêë îïðîñà ïîðòà |
WaitData: |
; Îæèäàòü åùå 10 "òèêîâ" |
dec ecx |
cmp ecx,0 |
je NoMouse |
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà |
mov DX,[COMPortBaseAddr] |
add DX,5 |
in AL,DX |
test AL,1 ;Äàííûå ãîòîâû? |
jz WaitData |
; Ââåñòè äàííûå |
mov DX,[COMPortBaseAddr] |
in AL,DX |
NoMouse: |
ret |
iglobal |
COMPortBaseAddr dw 3F8h |
;COMPortNum dw 0 |
endg |
iglobal |
boot_setmouse_type db 'Detected - PS2 mouse',0 |
db 'Detected - COM1 mouse',0 |
db 'Detected - COM2 mouse',0 |
endg |
end_detecting_mouse: |
/kernel/branches/hd_kolibri/kernel/core/detect/ps2mouse.inc |
---|
0,0 → 1,139 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MouseSearch_PS2: |
jmp MouseSearch_PS2_begin |
mouse_error equ MouseSearch_PS2_begin.error |
kb_cmd_c: |
call kb_cmd |
jmp check_kbd |
kb_write_c: |
call kb_write |
jmp check_kbd |
kb_read_c: |
call kb_read |
;jmp check_kbd |
check_kbd: |
cmp ah, 1 |
je mouse_error |
ret |
uglobal |
mouse_cmd_byte db 0 |
mouse_nr_tries db 0 |
mouse_nr_resends db 0 |
mouse_error_esp dd 0 |
endg |
mouse_cmd: |
mov [mouse_cmd_byte], al |
mov [mouse_nr_resends], 5 |
.resend: |
mov bl, 0xd4 |
call kb_cmd_c |
mov al, [mouse_cmd_byte] |
call kb_write_c |
call mouse_read |
cmp al, 0xFA ; ack |
jne .noack |
ret |
.noack: |
cmp al, 0xFE ; resend |
jne .noresend |
dec [mouse_nr_resends] |
jnz .resend |
.noresend: |
jmp mouse_error |
mouse_read: |
mov [mouse_nr_tries], 100 |
.repeat: |
call kb_read |
cmp ah, 1 |
jne .fin |
mov esi, 10 |
call delay_ms |
dec [mouse_nr_tries] |
jnz .repeat |
jmp mouse_error |
.fin: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MouseSearch_PS2_begin: |
pushad |
mov [mouse_error_esp], esp |
mov bl, 0xAD ; disable keyboard interface |
call kb_cmd_c |
mov bl, 0xA8 ; enable mouse interface |
call kb_cmd_c |
mov al, 0xFF ; reset |
call mouse_cmd |
; now the mouse is in Reset Mode |
; get the Basic Assurance Test completion code |
call mouse_read |
cmp al, 0xAA |
jne .error ; dead mouse |
; get device ID |
call mouse_read |
cmp al, 0x00 |
jne .error ; unknown device |
; reset completed successfully |
; enable mouse interrupt - IRQ12 |
mov bl, 0x20 ; read command byte |
call kb_cmd_c |
call kb_read_c |
or al, 10b |
push eax |
mov bl, 0x60 ; write command byte |
call kb_cmd_c |
pop eax |
call kb_write_c |
mov al, 0xF4 ; enable data reporting |
call mouse_cmd |
mov [ps2_mouse_detected], 1 |
mov bl, 0xAE ; enable keyboard interface |
call kb_cmd |
mov esi, boot_setmouse_type |
call boot_log |
jmp .finish |
.error: |
mov esp, [mouse_error_esp] ; clear stack frame |
mov [ps2_mouse_detected], 0 |
mov bl, 0xA7 ; disable mouse interface |
call kb_cmd |
mov bl, 0xAE ; enable keyboard interface |
call kb_cmd |
.finish: |
popad |
/kernel/branches/hd_kolibri/kernel/core/dll.inc |
---|
0,0 → 1,1084 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
DRV_COMPAT equ 4 ;minimal required drivers version |
DRV_CURRENT equ 4 ;current drivers model version |
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT |
align 4 |
proc attach_int_handler stdcall, irq:dword, handler:dword |
mov ebx, [irq] ;irq num |
test ebx, ebx |
jz .err |
mov eax, [handler] |
test eax, eax |
jz .err |
mov [irq_tab+ebx*4], eax |
stdcall enable_irq, [irq] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc detach_int_handler |
ret |
endp |
align 4 |
proc enable_irq stdcall, irq_line:dword |
mov ebx, [irq_line] |
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
mov edx, 0xA1 |
sub ebx,8 |
@@: |
in al,dx |
btr eax, ebx |
out dx, al |
ret |
endp |
align 16 |
;; proc irq_serv |
irq_serv: |
.irq_1: |
push eax |
mov eax, 1 |
jmp .main |
align 4 |
.irq_2: |
push eax |
mov eax, 2 |
jmp .main |
align 4 |
.irq_3: |
push eax |
mov eax, 3 |
jmp .main |
align 4 |
.irq_4: |
push eax |
mov eax, 4 |
jmp .main |
align 4 |
.irq_5: |
push eax |
mov eax, 5 |
jmp .main |
align 4 |
.irq_6: |
push eax |
mov eax, 6 |
jmp .main |
align 4 |
.irq_7: |
push eax |
mov eax, 7 |
jmp .main |
align 4 |
.irq_8: |
push eax |
mov eax, 8 |
jmp .main |
align 4 |
.irq_9: |
push eax |
mov eax, 9 |
jmp .main |
align 4 |
.irq_10: |
push eax |
mov eax, 10 |
jmp .main |
align 4 |
.irq_11: |
push eax |
mov eax, 11 |
jmp .main |
align 4 |
.irq_12: |
push eax |
mov eax, 12 |
jmp .main |
align 4 |
.irq_13: |
push eax |
mov eax, 13 |
jmp .main |
align 4 |
.irq_14: |
push eax |
mov eax, 14 |
jmp .main |
align 4 |
.irq_15: |
push eax |
mov eax, 15 |
jmp .main |
align 16 |
.main: |
save_ring3_context |
mov bx, os_data |
mov ds, bx |
mov es, bx |
mov ebx, [irq_tab+eax*4] |
test ebx, ebx |
jz .exit |
call ebx |
.exit: |
restore_ring3_context |
cmp eax, 8 |
mov al, 0x20 |
jb @f |
out 0xa0, al |
@@: |
out 0x20, al |
pop eax |
iret |
align 4 |
proc get_notify stdcall, p_ev:dword |
.wait: |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
test dword [ebx+SLOT_BASE+0xA8],EVENT_NOTIFY |
jz @f |
and dword [ebx+SLOT_BASE+0xA8], not EVENT_NOTIFY |
mov edi, [p_ev] |
mov dword [edi], EV_INTR |
mov eax, [ebx+SLOT_BASE+APPDATA.event] |
mov dword [edi+4], eax |
ret |
@@: |
call change_task |
jmp .wait |
endp |
align 4 |
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 6 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
ret |
endp |
align 4 |
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 4 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
ret |
endp |
align 4 |
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 8 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc srv_handler stdcall, ioctl:dword |
mov esi, [ioctl] |
test esi, esi |
jz .err |
mov edi, [esi+handle] |
cmp [edi+SRV.magic], ' SRV' |
jne .fail |
cmp [edi+SRV.size], SRV_SIZE |
jne .fail |
stdcall [edi+SRV.srv_proc], esi |
ret |
.fail: |
xor eax, eax |
not eax |
mov [esi+output], eax |
mov [esi+out_size], 4 |
ret |
.err: |
xor eax, eax |
not eax |
ret |
endp |
; param |
; ebx= io_control |
; |
; retval |
; eax= error code |
align 4 |
srv_handlerEx: |
test ebx, ebx |
jz .fail |
add ebx, new_app_base |
mov eax, [ebx+handle] |
cmp [eax+SRV.magic], ' SRV' |
jne .fail |
cmp [eax+SRV.size], SRV_SIZE |
jne .fail |
add [ebx+input], new_app_base |
add [ebx+output], new_app_base |
stdcall [eax+SRV.srv_proc], ebx |
ret |
.fail: |
or eax, -1 |
ret |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc get_service stdcall, sz_name:dword |
mov eax, [sz_name] |
test eax, eax |
jnz @F |
ret |
@@: |
mov edx, [srv.fd] |
@@: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .not_load |
stdcall strncmp, edx, [sz_name], 16 |
test eax, eax |
je .ok |
mov edx, [edx+SRV.fd] |
jmp @B |
.not_load: |
pop ebp |
jmp load_driver |
.ok: |
mov eax, edx |
ret |
endp |
align 4 |
reg_service: |
.sz_name equ esp+4 |
.handler equ esp+8 |
mov eax, [.sz_name] |
test eax, eax |
jz .fail |
mov ebx, [.handler] |
test ebx, ebx |
jz .fail |
mov eax, SRV_SIZE |
call malloc ;call alloc_service |
test eax, eax |
jz .fail |
mov edi, eax |
mov esi, [.sz_name] |
mov ecx, 16/4 |
rep movsd |
mov [eax+SRV.magic], ' SRV' |
mov [eax+SRV.size], SRV_SIZE |
mov ebx, srv.fd-SRV_FD_OFFSET |
mov edx, [ebx+SRV.fd] |
mov [eax+SRV.fd], edx |
mov [eax+SRV.bk], ebx |
mov [ebx+SRV.fd], eax |
mov [edx+SRV.bk], eax |
mov ecx, [.handler] |
mov [eax+SRV.srv_proc], ecx |
ret 8 |
.fail: |
xor eax, eax |
ret 8 |
align 4 |
proc get_proc stdcall, exp:dword, sz_name:dword |
mov edx, [exp] |
.next: |
mov eax, [edx] |
test eax, eax |
jz .end |
push edx |
stdcall strncmp, eax, [sz_name], 16 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
align 4 |
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword |
@@: |
stdcall strncmp, [pSym], [sz_sym], 8 |
test eax,eax |
jz .ok |
add [pSym], 18 |
dec [count] |
jnz @b |
xor eax, eax |
ret |
.ok: |
mov ebx, [pSym] |
mov eax, [ebx+8] |
ret |
endp |
align 4 |
proc get_curr_task |
mov eax,[CURRENT_TASK] |
shl eax, 8 |
ret |
endp |
align 4 |
proc get_fileinfo stdcall, file_name:dword, info:dword |
locals |
cmd dd ? |
offset dd ? |
dd ? |
count dd ? |
buff dd ? |
db ? |
name dd ? |
endl |
xor eax, eax |
mov ebx, [file_name] |
sub ebx, new_app_base |
mov ecx, [info] |
sub ecx, new_app_base |
mov [cmd], 5 |
mov [offset], eax |
mov [offset+4], eax |
mov [count], eax |
mov [buff], ecx |
mov byte [buff+4], al |
mov [name], ebx |
mov eax, 70 |
lea ebx, [cmd] |
sub ebx, new_app_base |
int 0x40 |
ret |
endp |
align 4 |
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\ |
bytes:dword |
locals |
cmd dd ? |
offset dd ? |
dd ? |
count dd ? |
buff dd ? |
db ? |
name dd ? |
endl |
xor eax, eax |
mov ebx, [file_name] |
mov ecx, [off] |
mov edx, [bytes] |
mov esi, [buffer] |
sub ebx, new_app_base |
sub esi, new_app_base |
mov [cmd], eax |
mov [offset], ecx |
mov [offset+4], eax |
mov [count], edx |
mov [buff], esi |
mov byte [buff+4], al |
mov [name], ebx |
pushad |
push eax |
lea eax, [cmd] |
sub eax, new_app_base |
call file_system_lfn |
pop eax |
popad |
ret |
endp |
; description |
; allocate kernel memory and loads the specified file |
; |
; param |
; file_name= full path to file |
; |
; retval |
; eax= file image in kernel memory |
; ebx= size of file |
; |
; warging |
; You mast call kernel_free() to delete each file |
; loaded by the load_file() function |
align 4 |
proc load_file stdcall, file_name:dword |
locals |
attr dd ? |
flags dd ? |
cr_time dd ? |
cr_date dd ? |
acc_time dd ? |
acc_date dd ? |
mod_time dd ? |
mod_date dd ? |
file_size dd ? |
file dd ? |
file2 dd ? |
endl |
lea eax, [attr] |
stdcall get_fileinfo, [file_name], eax |
test eax, eax |
jnz .fail |
mov eax, [file_size] |
cmp eax, 1024*1024*16 |
ja .fail |
stdcall kernel_alloc, [file_size] |
mov [file], eax |
stdcall read_file, [file_name], eax, dword 0, [file_size] |
cmp ebx, [file_size] |
jne .cleanup |
mov eax, [file] |
cmp dword [eax], 0x4B43504B |
jne .exit |
mov ebx, [eax+4] |
mov [file_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .cleanup |
mov [file2], eax |
stdcall unpack, [file], eax |
stdcall kernel_free, [file] |
mov eax, [file2] |
mov ebx, [file_size] |
.exit: |
push eax |
lea edi, [eax+ebx] ;cleanup remain space |
mov ecx, 4096 ;from file end |
and ebx, 4095 |
sub ecx, ebx |
xor eax, eax |
cld |
rep stosb |
mov ebx, [file_size] |
pop eax |
ret |
.cleanup: |
stdcall kernel_free, [file] |
.fail: |
xor eax, eax |
xor ebx, ebx |
ret |
endp |
align 4 |
proc get_proc_ex stdcall, proc_name:dword, imports:dword |
.look_up: |
mov edx, [imports] |
test edx, edx |
jz .end |
mov edx, [edx] |
test edx, edx |
jz .end |
.next: |
mov eax, [edx] |
test eax, eax |
jz .next_table |
push edx |
stdcall strncmp, eax, [proc_name], 16 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.next_table: |
add [imports], 4 |
jmp .look_up |
.ok: |
mov eax, [edx+4] |
ret |
.end: |
xor eax, eax |
ret |
endp |
align 4 |
proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\ |
sym_count:dword, strings:dword, imports:dword |
locals |
retval dd ? |
endl |
mov edi, [symbols] |
mov [retval], 1 |
.fix: |
movzx ebx, [edi+CSYM.SectionNumber] |
test ebx, ebx |
jnz .internal |
mov eax, dword [edi+CSYM.Name] |
test eax, eax |
jnz @F |
mov edi, [edi+4] |
add edi, [strings] |
@@: |
push edi |
stdcall get_proc_ex, edi,[imports] |
pop edi |
xor ebx, ebx |
test eax, eax |
jnz @F |
mov esi, msg_unresolved |
call sys_msg_board_str |
mov esi, edi |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov [retval],0 |
@@: |
mov edi, [symbols] |
mov [edi+CSYM.Value], eax |
jmp .next |
.internal: |
dec ebx |
shl ebx, 3 |
lea ebx, [ebx+ebx*4] |
add ebx, [sec] |
mov eax, [ebx+CFS.VirtualAddress] |
add [edi+CSYM.Value], eax |
.next: |
add edi, CSYM_SIZE |
mov [symbols], edi |
dec [sym_count] |
jnz .fix |
mov eax, [retval] |
ret |
endp |
align 4 |
proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword |
locals |
n_sec dd ? |
endl |
mov eax, [coff] |
movzx ebx, [eax+CFH.nSections] |
mov [n_sec], ebx |
.fix_sec: |
mov esi, [sec] |
mov edi, [esi+CFS.PtrReloc] |
add edi, [coff] |
movzx ecx, [esi+CFS.NumReloc] |
test ecx, ecx |
jz .next |
.next_reloc: |
mov ebx, [edi+CRELOC.SymIndex] |
add ebx,ebx |
lea ebx,[ebx+ebx*8] |
add ebx, [sym] |
mov edx, [ebx+CSYM.Value] |
cmp [edi+CRELOC.Type], 6 |
je .dir_32 |
cmp [edi+CRELOC.Type], 20 |
jne .next_reloc |
.rel_32: |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [esi+CFS.VirtualAddress] |
sub edx, eax |
sub edx, 4 |
jmp .fix |
.dir_32: |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [esi+CFS.VirtualAddress] |
.fix: |
add [eax], edx |
add edi, 10 |
dec ecx |
jnz .next_reloc |
.next: |
add [sec], COFF_SECTION_SIZE |
dec [n_sec] |
jnz .fix_sec |
.exit: |
ret |
endp |
align 4 |
proc load_driver stdcall, driver_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
start dd ? |
exports dd ? ;fake exports table |
dd ? |
; file_name rb 14+16+4+1 ; '/rd/1/drivers/<up-to-16-chars>.obj' |
; endl |
;----------------------------------------- |
file_name rb 23+16+4+1 ; '/hd0/1/kolibri/drivers/<up-to-16-chars>.obj' |
endl |
lea edx, [file_name] |
mov dword [edx] , '/hd0' |
mov dword [edx+4] , '/1/k' |
mov dword [edx+8] , 'olib' |
mov dword [edx+12], 'ri/d' |
mov dword [edx+16], 'rive' |
mov word [edx+20], 'rs' |
mov byte [edx+22], '/' |
mov esi, [driver_name] |
lea edi, [edx+23] |
mov ecx, 16 |
;--------------------------------------- |
; lea edx, [file_name] |
; mov dword [edx], '/rd/' |
; mov dword [edx+4], '1/dr' |
; mov dword [edx+8], 'iver' |
; mov word [edx+12], 's/' |
; mov esi, [driver_name] |
; lea edi, [edx+14] |
; mov ecx, 16 |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
loop @b |
@@: |
mov dword [edi], '.obj' |
mov byte [edi+4], 0 |
stdcall load_file, edx |
test eax, eax |
jz .exit |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edi, eax |
xor eax, eax |
mov ecx, [img_size] |
add ecx, 4095 |
and ecx, not 4095 |
shr ecx, 2 |
cld |
rep stosd |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15 |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea ebx, [exports] |
mov dword [ebx], kernel_export |
mov dword [ebx+4], 0 |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], ebx |
test eax, eax |
jz .link_fail |
mov ebx, [coff] |
add ebx, 20 |
stdcall fix_coff_relocs, [coff], ebx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion |
test eax, eax |
jz .link_fail |
mov eax, [eax] |
shr eax, 16 |
cmp eax, DRV_COMPAT |
jb .ver_fail |
cmp eax, DRV_CURRENT |
ja .ver_fail |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART |
mov [start], eax |
stdcall kernel_free, [coff] |
mov ebx, [start] |
stdcall ebx, DRV_ENTRY |
test eax, eax |
jnz .ok |
stdcall kernel_free, [img_base] |
xor eax, eax |
ret |
.ok: |
mov ebx, [img_base] |
mov [eax+SRV.base], ebx |
mov ecx, [start] |
mov [eax+SRV.entry], ecx |
ret |
.ver_fail: |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, msg_version |
call sys_msg_board_str |
mov esi, msg_www |
call sys_msg_board_str |
jmp .cleanup |
.link_fail: |
mov esi, msg_module |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
.cleanup: |
stdcall kernel_free,[img_base] |
.fail: |
stdcall kernel_free, [coff] |
.exit: |
xor eax, eax |
ret |
endp |
align 4 |
proc load_library stdcall, file_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
exports dd ? |
endl |
cli |
stdcall load_file, [file_name] |
test eax, eax |
jz .fail |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
call init_heap |
stdcall user_alloc, [img_size] |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
add edi, new_app_base |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15-new_app_base |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], dword 0 |
test eax, eax |
jnz @F |
@@: |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, new_app_base |
lea eax, [edx+20] |
@@: |
add [eax+CFS.VirtualAddress], edi ;patch user space offset |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
add edx, 20 |
stdcall fix_coff_relocs, [coff], edx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS |
mov [exports], eax |
stdcall kernel_free, [coff] |
mov eax, [exports] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc stop_all_services |
mov edx, [srv.fd] |
.next: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .done |
cmp [edx+SRV.magic], ' SRV' |
jne .next |
cmp [edx+SRV.size], SRV_SIZE |
jne .next |
mov ebx, [edx+SRV.entry] |
mov edx, [edx+SRV.fd] |
push edx |
stdcall ebx, dword -1 |
pop edx |
jmp .next |
.done: |
ret |
endp |
; param |
; eax= size |
; ebx= pid |
align 4 |
create_kernel_object: |
push ebx |
call malloc |
pop ebx |
test eax, eax |
jz .fail |
mov ecx,[CURRENT_TASK] |
shl ecx,8 |
add ecx, SLOT_BASE+APP_OBJ_OFFSET |
pushfd |
cli |
mov edx, [ecx+APPOBJ.fd] |
mov [eax+APPOBJ.fd], edx |
mov [eax+APPOBJ.bk], ecx |
mov [eax+APPOBJ.pid], ebx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
popfd |
.fail: |
ret |
; param |
; eax= object |
align 4 |
destroy_kernel_object: |
pushfd |
cli |
mov ebx, [eax+APPOBJ.fd] |
mov ecx, [eax+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
popfd |
xor edx, edx ;clear common header |
mov [eax], edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax+16], edx |
call free ;release object memory |
ret |
;szSound db 'SOUND',0 |
;szInfinity db 'INFINITY',0 |
szHwMouse db 'ATI2D',0 |
szSTART db 'START',0 |
szEXPORTS db 'EXPORTS',0 |
szIMPORTS db 'IMPORTS',0 |
msg_unresolved db 'unresolved ',0 |
msg_module db 'in module ',0 |
msg_version db 'incompatible driver version',13,10,0 |
msg_www db 'please visit www.kolibrios.org',13,10,0 |
msg_CR db 13,10,0 |
align 4 |
create_cursor dd 0 |
set_hw_cursor dd 0 |
hw_restore dd 0 |
/kernel/branches/hd_kolibri/kernel/core/exports.inc |
---|
0,0 → 1,117 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
szKernel db 'KERNEL', 0 |
szVersion db 'version',0 |
szRegService db 'RegService',0 |
szGetService db 'GetService',0 |
szServiceHandler db 'ServiceHandler',0 |
szAttachIntHandler db 'AttachIntHandler',0 |
szFpuSave db 'FpuSave',0 |
szFpuRestore db 'FpuRestore',0 |
szPciApi db 'PciApi', 0 |
szPciRead32 db 'PciRead32', 0 |
szPciRead8 db 'PciRead8', 0 |
szPciWrite8 db 'PciWrite8',0 |
szAllocPage db 'AllocPage',0 |
szAllocPages db 'AllocPages',0 |
szFreePage db 'FreePage',0 |
szGetPgAddr db 'GetPgAddr',0 |
szMapPage db 'MapPage',0 |
szMapSpace db 'MapSpace',0 |
szCommitPages db 'CommitPages',0 |
szReleasePages db 'ReleasePages',0 |
szAllocKernelSpace db 'AllocKernelSpace',0 |
szFreeKernelSpace db 'FreeKernelSpace',0 |
szKernelAlloc db 'KernelAlloc',0 |
szKernelFree db 'KernelFree',0 |
szUserAlloc db 'UserAlloc',0 |
szUserFree db 'UserFree',0 |
szKmalloc db 'Kmalloc',0 |
szKfree db 'Kfree',0 |
szCreateObject db 'CreateObject',0 |
szDestroyObject db 'DestroyObject',0 |
szCreateEvent db 'CreateEvent',0 |
szRaiseEvent db 'RaiseEvent',0 |
szWaitEvent db 'WaitEvent',0 |
szDestroyEvent db 'DestroyEvent',0 |
szClearEvent db 'ClearEvent',0 |
szLoadCursor db 'LoadCursor',0 |
szSetHwCursor db 'SetHwCursor',0 |
szHwCursorRestore db 'HwCursorRestore', 0 |
szHwCursorCreate db 'HwCursorCreate', 0 |
szSysMsgBoardStr db 'SysMsgBoardStr', 0 |
szGetCurrentTask db 'GetCurrentTask',0 |
szLFBAddress db 'LFBAddress',0 |
szLoadFile db 'LoadFile',0 |
szSendEvent db 'SendEvent',0 |
align 16 |
kernel_export: |
dd szRegService , reg_service |
dd szGetService , get_service |
dd szServiceHandler , srv_handler |
dd szAttachIntHandler, attach_int_handler |
dd szFpuSave , fpu_save |
dd szFpuRestore , fpu_restore |
dd szPciApi , pci_api |
dd szPciRead32 , pci_read32 |
dd szPciRead8 , pci_read8 |
dd szPciWrite8 , pci_write8 |
dd szAllocPage , alloc_page |
dd szAllocPages , alloc_pages |
dd szFreePage , free_page |
dd szMapPage , map_page |
dd szMapSpace , map_space |
dd szGetPgAddr , get_pg_addr |
dd szCommitPages , commit_pages ;not implemented |
dd szReleasePages , release_pages |
dd szAllocKernelSpace, alloc_kernel_space |
dd szFreeKernelSpace , free_kernel_space |
dd szKernelAlloc , kernel_alloc |
dd szKernelFree , kernel_free |
dd szUserAlloc , user_alloc |
dd szUserFree , user_free |
dd szKmalloc , malloc |
dd szKfree , free |
dd szCreateObject , create_kernel_object |
dd szDestroyObject , destroy_kernel_object |
dd szCreateEvent , create_event |
dd szRaiseEvent , raise_event |
dd szWaitEvent , wait_event |
dd szDestroyEvent , destroy_event |
dd szClearEvent , clear_event |
dd szLoadCursor , load_cursor |
dd szSetHwCursor , set_hw_cursor |
dd szHwCursorRestore , hw_restore |
dd szHwCursorCreate , create_cursor |
dd szSysMsgBoardStr , sys_msg_board_str |
dd szGetCurrentTask , get_curr_task |
dd szLoadFile , load_file |
dd szSendEvent , send_event |
exp_lfb: |
dd szLFBAddress , 0 |
dd 0 |
endg |
/kernel/branches/hd_kolibri/kernel/core/fpu.inc |
---|
0,0 → 1,283 |
$Revision: 435 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
init_fpu: |
clts |
fninit |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
mov ebx, cr4 |
mov ecx, cr0 |
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT |
mov cr4, ebx |
and ecx, not (CR0_MP+CR0_EM) |
or ecx, CR0_NE |
mov cr0, ecx |
mov dword [esp-4], SSE_INIT |
ldmxcsr [esp-4] |
xorps xmm0, xmm0 |
xorps xmm1, xmm1 |
xorps xmm2, xmm2 |
xorps xmm3, xmm3 |
xorps xmm4, xmm4 |
xorps xmm5, xmm5 |
xorps xmm6, xmm6 |
xorps xmm7, xmm7 |
fxsave [fpu_data] ;[eax] |
ret |
.no_SSE: |
mov ecx, cr0 |
and ecx, not CR0_EM |
or ecx, CR0_MP+CR0_NE |
mov cr0, ecx |
fnsave [fpu_data] |
ret |
; param |
; eax= 512 bytes memory area |
align 4 |
fpu_save: |
push ecx |
push esi |
push edi |
pushfd |
cli |
clts |
mov edi, eax |
mov ecx, [fpu_owner] |
mov esi, [CURRENT_TASK] |
cmp ecx, esi |
jne .save |
call save_context |
jmp .exit |
.save: |
mov [fpu_owner], esi |
shl ecx, 8 |
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] |
call save_context |
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 |
align 4 |
save_context: |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
ret |
.no_SSE: |
fnsave [eax] |
ret |
align 4 |
fpu_restore: |
push ecx |
push esi |
mov esi, eax |
pushfd |
cli |
mov ecx, [fpu_owner] |
mov eax, [CURRENT_TASK] |
cmp ecx, eax |
jne .copy |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxrstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.no_SSE: |
fnclex ;fix possible problems |
frstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.copy: |
shl eax, 8 |
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] |
mov ecx, 512/4 |
cld |
rep movsd |
popfd |
pop esi |
pop ecx |
ret |
align 4 |
e7: ;#NM exception handler |
save_ring3_context |
clts |
mov ax, os_data |
mov ds, ax |
mov es, ax |
mov ebx, [fpu_owner] |
cmp ebx, [CURRENT_TASK] |
je .exit |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
fxrstor [eax] |
.exit: |
restore_ring3_context |
iret |
.no_SSE: |
fnsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
frstor [eax] |
restore_ring3_context |
iret |
iglobal |
fpu_owner dd 1 |
endg |
reg_eip equ ebp+4 |
reg_cs equ ebp+8 |
reg_eflags equ ebp+12 |
reg_esp equ ebp+16 |
reg_ss equ ebp+20 |
align 4 |
except_16: ;fpu native exceptions handler |
push ebp |
mov ebp, esp |
push eax |
push ebx |
push ecx |
push edx |
mov ebx, [ss:CURRENT_TASK] |
shl ebx, 8 |
mov eax, [ss:ebx+SLOT_BASE+APPDATA.fpu_handler] |
test eax, eax |
jz .default |
mov ecx, [reg_eip] |
mov edx, [reg_esp] |
sub edx, 4 |
mov [ss:edx+new_app_base], ecx |
mov [reg_esp], edx |
mov dword [reg_eip], eax |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
iretd |
.default: |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
save_ring3_context ;debugger support |
mov bl, 16 |
jmp exc_c |
align 4 |
except_19: ;sse exceptions handler |
push ebp |
mov ebp, esp |
push eax |
push ebx |
push ecx |
push edx |
mov ebx, [ss:CURRENT_TASK] |
shl ebx, 8 |
mov eax, [ss:ebx+SLOT_BASE+APPDATA.sse_handler] |
test eax, eax |
jz .default |
mov ecx, [reg_eip] |
mov edx, [reg_esp] |
sub edx, 4 |
mov [ss:edx+new_app_base], ecx |
mov [reg_esp], edx |
mov dword [reg_eip], eax |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
iretd |
.default: |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
save_ring3_context ;debugger support |
mov bl, 19 |
jmp exc_c |
restore reg_eip |
restore reg_cs |
restore reg_eflags |
restore reg_esp |
restore reg_ss |
/kernel/branches/hd_kolibri/kernel/core/heap.inc |
---|
0,0 → 1,1095 |
$Revision: 448 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
struc MEM_BLOCK |
{ .next_block dd ? |
.prev_block dd ? ;+4 |
.list_fd dd ? ;+8 |
.list_bk dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
} |
MEM_LIST_OFFSET equ 8 |
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
virtual at 0 |
MEM_BLOCK MEM_BLOCK |
end virtual |
MEM_BLOCK_SIZE equ 8*4 |
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_fd equ MEM_BLOCK.list_fd |
list_bk equ MEM_BLOCK.list_bk |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
macro remove_from_list op |
{ mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
test edx, edx |
jz @f |
mov [edx+list_bk], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_fd], edx |
@@: |
mov [op+list_fd],0 |
mov [op+list_bk],0 |
} |
macro remove_from_free op |
{ |
remove_from_list op |
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
macro remove_from_used op |
{ |
mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
mov [op+list_fd], 0 |
mov [op+list_bk], 0 |
} |
align 4 |
proc init_kernel_heap |
mov ecx, 64/4 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], HEAP_BASE |
mov eax, mem_used.fd-MEM_LIST_OFFSET |
mov [mem_used.fd], eax |
mov [mem_used.bk], eax |
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
mov edi, HEAP_BASE |
.l1: |
stdcall map_page,edi,edx,PG_SW |
add edi, 0x1000 |
add edx, 0x1000 |
dec ecx |
jnz .l1 |
mov edi, HEAP_BASE |
mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
mov [edi+list_fd], eax |
mov [edi+list_bk], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_fd], eax |
mov [ebx+list_bk], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov ecx, [MEM_AMOUNT] |
sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE |
mov [heap_size], ecx |
mov [heap_free], ecx |
mov [ebx+block_size], ecx |
mov [ebx+block_flags], FREE_BLOCK |
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
and [heap_mutex], 0 |
mov [heap_blocks], 4095 |
mov [free_blocks], 4095 |
ret |
endp |
; param |
; eax= required size |
; |
; retval |
; edi= memory block descriptor |
; ebx= descriptor index |
align 4 |
get_block: |
mov ecx, eax |
shr ecx, 12 |
dec ecx |
cmp ecx, 63 |
jle .get_index |
mov ecx, 63 |
.get_index: |
lea esi, [mem_block_mask] |
xor ebx, ebx |
or edx, -1 |
cmp ecx, 32 |
jb .bit_test |
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
.bit_test: |
shl edx, cl |
and edx, [esi] |
.find: |
bsf edi, edx |
jz .high_mask |
add ebx, edi |
mov edi, [mem_block_list+ebx*4] |
.check_size: |
cmp eax, [edi+block_size] |
ja .next |
ret |
.high_mask: |
add esi, 4 |
cmp esi, mem_block_mask+8 |
jae .err |
add ebx, 32 |
mov edx, [esi] |
jmp .find |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.err: |
xor edi, edi |
ret |
align 4 |
proc alloc_mem_block |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
xor eax,eax |
ret |
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
lea eax,[eax+ebx*8] |
shl eax, 5 |
add eax, [mem_block_arr] |
dec [free_blocks] |
ret |
endp |
proc free_mem_block |
mov dword [eax], 0 |
mov dword [eax+4], 0 |
mov dword [eax+8], 0 |
mov dword [eax+12], 0 |
mov dword [eax+16], 0 |
; mov dword [eax+20], 0 |
mov dword [eax+24], 0 |
mov dword [eax+28], 0 |
sub eax, [mem_block_arr] |
shr eax, 5 |
mov ebx, mem_block_map |
bts [ebx], eax |
inc [free_blocks] |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
ret |
@@: |
mov [mem_block_start], eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095 |
mov [size], eax |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
cmp eax, [heap_free] |
ja .error |
call get_block ; eax |
test edi, edi |
jz .error |
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
mov [block_ind], ebx ;index of allocated block |
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
call alloc_mem_block |
and eax, eax |
jz .error |
mov esi, eax ;esi - splitted block |
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_fd], 0 |
mov [esi+list_bk], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
remove_from_list edi |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], edx |
test edx, edx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [esi+list_fd], edx |
mov [esi+list_bk], ecx |
mov [ecx+list_fd], esi |
mov [edx+list_bk], esi |
mov [esi+block_flags], USED_BLOCK |
mov eax, [esi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
ret |
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ebx*4], edx |
and edx, edx |
jnz @f |
btr [mem_block_mask], ebx |
@@: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [edi+list_fd], edx |
mov [edi+list_bk], ecx |
mov [ecx+list_fd], edi |
mov [edx+list_bk], edi |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
ret |
.error: |
xor eax, eax |
mov [heap_mutex], eax |
ret |
endp |
align 4 |
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
mov eax, [esi+block_size] |
add [heap_free], eax |
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
remove_from_free edi |
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
remove_from_used esi |
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
push ecx |
remove_from_list edi |
pop ecx |
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_fd], esi |
test esi, esi |
jz @f |
mov [esi+list_bk], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
ret |
.insert: |
remove_from_used esi |
mov eax, [esi+block_size] |
calc_index eax |
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_fd], edi |
test edi, edi |
jz @f |
mov [edi+list_bk], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
ret |
.fail: |
xor eax, eax |
mov [heap_mutex], eax |
ret |
endp |
align 4 |
proc kernel_alloc stdcall, size:dword |
locals |
lin_addr dd ? |
pages_count dd ? |
endl |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095; |
mov [size], eax |
and eax, eax |
jz .err |
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .err |
mov [lin_addr], eax |
mov ecx, [pages_count] |
mov edx, eax |
mov ebx, ecx |
shr ecx, 3 |
jz .next |
and ebx, not 7 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx ; yes ecx!!! |
and eax, eax |
jz .err |
mov edi, eax |
mov edx, [lin_addr] |
@@: |
stdcall map_page,edx,edi,dword PG_SW |
add edx, 0x1000 |
add edi, 0x1000 |
dec ecx |
jnz @B |
.next: |
mov ecx, [pages_count] |
and ecx, 7 |
jz .end |
@@: |
push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .err |
stdcall map_page,edx,eax,dword PG_SW |
add edx, 0x1000 |
dec ecx |
jnz @B |
.end: |
mov eax, [lin_addr] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc kernel_free stdcall, base:dword |
push ebx esi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
and [heap_mutex], 0 |
push ecx |
mov ecx, [esi+block_size]; |
shr ecx, 12 |
call release_pages ;eax, ecx |
pop ecx |
stdcall free_kernel_space, [base] |
pop esi ebx |
ret |
.fail: |
and [heap_mutex], 0 |
pop esi ebx |
ret |
endp |
restore block_next |
restore block_prev |
restore block_list |
restore block_base |
restore block_size |
restore block_flags |
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
HEAP_TOP equ 0x5FC00000 |
align 4 |
proc init_heap |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
mov eax, [SLOT_BASE+APPDATA.heap_top+ebx] |
test eax, eax |
jz @F |
sub eax,[SLOT_BASE+APPDATA.heap_base+ebx] |
sub eax, 4096 |
ret |
@@: |
mov esi, [SLOT_BASE+APPDATA.mem_size+ebx] |
add esi, 4095 |
and esi, not 4095 |
mov [SLOT_BASE+APPDATA.mem_size+ebx], esi |
mov eax, HEAP_TOP |
mov [SLOT_BASE+APPDATA.heap_base+ebx], esi |
mov [SLOT_BASE+APPDATA.heap_top+ebx], eax |
sub eax, esi |
add esi, new_app_base |
shr esi, 10 |
mov ecx, eax |
sub eax, 4096 |
or ecx, FREE_BLOCK |
mov [page_tabs+esi], ecx |
ret |
.exit: |
xor eax, eax |
ret |
endp |
align 4 |
proc user_alloc stdcall, alloc_size:dword |
mov ecx, [alloc_size] |
add ecx, (4095+4096) |
and ecx, not 4095 |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov esi, dword [ebx+SLOT_BASE+APPDATA.heap_base]; heap_base |
mov edi, dword [ebx+SLOT_BASE+APPDATA.heap_top]; heap_top |
add esi, new_app_base |
add edi, new_app_base |
l_0: |
cmp esi, edi |
jae m_exit |
mov ebx, esi |
shr ebx, 12 |
mov eax, [page_tabs+ebx*4] |
test eax, FREE_BLOCK |
jz test_used |
and eax, 0xFFFFF000 |
cmp eax, ecx ;alloc_size |
jb m_next |
jz @f |
mov edx, esi |
add edx, ecx |
sub eax, ecx; |
or eax, FREE_BLOCK |
shr edx, 12 |
mov [page_tabs+edx*4], eax |
@@: |
or ecx, USED_BLOCK |
mov [page_tabs+ebx*4], ecx |
shr ecx, 12 |
dec ecx |
inc ebx |
@@: |
mov dword [page_tabs+ebx*4], 2 |
inc ebx |
dec ecx |
jnz @B |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
mov ebx, [alloc_size] |
add ebx, 0xFFF |
and ebx, not 0xFFF |
add ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
call update_mem_size |
mov eax, esi |
add eax, 4096 |
sub eax, new_app_base |
ret |
m_next: |
add esi, eax |
jmp l_0 |
test_used: |
test eax, USED_BLOCK |
jz m_exit |
and eax, 0xFFFFF000 |
add esi, eax |
jmp l_0 |
m_exit: |
xor eax, eax |
ret |
endp |
align 4 |
proc user_free stdcall, base:dword |
mov esi, [base] |
test esi, esi |
jz .exit |
xor ebx, ebx |
sub esi, 4096 |
shr esi, 12 |
mov eax, [page_tabs+esi*4] |
test eax, USED_BLOCK |
jz .not_used |
and eax, not 4095 |
mov ecx, eax |
or eax, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
inc esi |
sub ecx, 4096 |
shr ecx, 12 |
mov ebx, ecx |
.release: |
xor eax, eax |
xchg eax, [page_tabs+esi*4] |
test eax, 1 |
jz @F |
call free_page |
mov eax, esi |
shl eax, 12 |
invlpg [eax] |
@@: |
inc esi |
dec ecx |
jnz .release |
.not_used: |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
mov esi, dword [edx+SLOT_BASE+APPDATA.heap_base]; heap_base |
mov edi, dword [edx+SLOT_BASE+APPDATA.heap_top]; heap_top |
sub ebx, [edx+SLOT_BASE+APPDATA.mem_size] |
neg ebx |
call update_mem_size |
call user_normalize |
ret |
.exit: |
xor eax, eax |
inc eax |
ret |
endp |
user_normalize: |
; in: esi=heap_base, edi=heap_top |
; out: eax=0 <=> OK |
; destroys: ebx,edx,esi,edi |
add esi, new_app_base |
add edi, new_app_base |
shr esi, 12 |
shr edi, 12 |
@@: |
mov eax, [page_tabs+esi*4] |
test eax, USED_BLOCK |
jz .test_free |
shr eax, 12 |
add esi, eax |
jmp @B |
.test_free: |
test eax, FREE_BLOCK |
jz .err |
mov edx, eax |
shr edx, 12 |
add edx, esi |
cmp edx, edi |
jae .exit |
mov ebx, [page_tabs+edx*4] |
test ebx, USED_BLOCK |
jz .next_free |
shr ebx, 12 |
add edx, ebx |
mov esi, edx |
jmp @B |
.next_free: |
test ebx, FREE_BLOCK |
jz .err |
and dword [page_tabs+edx*4], 0 |
add eax, ebx |
and eax, not 4095 |
or eax, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
jmp @B |
.exit: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
user_realloc: |
; in: eax = pointer, ebx = new size |
; out: eax = new pointer or NULL |
test eax, eax |
jnz @f |
; realloc(NULL,sz) - same as malloc(sz) |
push ebx |
call user_alloc |
ret |
@@: |
push ecx edx |
lea ecx, [eax + new_app_base - 0x1000] |
shr ecx, 12 |
mov edx, [page_tabs+ecx*4] |
test edx, USED_BLOCK |
jnz @f |
; attempt to realloc invalid pointer |
.ret0: |
pop edx ecx |
xor eax, eax |
ret |
@@: |
add ebx, 0x1FFF |
shr edx, 12 |
shr ebx, 12 |
; edx = allocated size, ebx = new size |
add edx, ecx |
add ebx, ecx |
cmp edx, ebx |
jb .realloc_add |
; release part of allocated memory |
.loop: |
cmp edx, ebx |
jz .release_done |
dec edx |
xor eax, eax |
xchg eax, [page_tabs+edx*4] |
test al, 1 |
jz .loop |
call free_page |
mov eax, edx |
shl eax, 12 |
invlpg [eax] |
jmp .loop |
.release_done: |
sub ebx, ecx |
cmp ebx, 1 |
jnz .nofreeall |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
mov ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
sub ebx, eax |
add ebx, 0x1000 |
or al, FREE_BLOCK |
mov [page_tabs+ecx*4], eax |
push esi edi |
mov esi, [SLOT_BASE+APPDATA.heap_base+edx] |
mov edi, [SLOT_BASE+APPDATA.heap_top+edx] |
call update_mem_size |
call user_normalize |
pop edi esi |
jmp .ret0 ; all freed |
.nofreeall: |
sub edx, ecx |
shl ebx, 12 |
or ebx, USED_BLOCK |
xchg [page_tabs+ecx*4], ebx |
shr ebx, 12 |
sub ebx, edx |
push ebx ecx edx |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
shl ebx, 12 |
sub ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
neg ebx |
call update_mem_size |
pop edx ecx ebx |
lea eax, [ecx+1-(new_app_base shr 12)] |
shl eax, 12 |
push eax |
add ecx, ebx |
add edx, ecx |
shl ebx, 12 |
jz .ret |
push esi |
mov esi, [CURRENT_TASK] |
shl esi, 8 |
mov esi, [SLOT_BASE+APPDATA.heap_top+esi] |
shr esi, 12 |
@@: |
cmp edx, esi |
jae .merge_done |
mov eax, [page_tabs+edx*4] |
test al, USED_BLOCK |
jz .merge_done |
and dword [page_tabs+edx*4], 0 |
and eax, not 0xFFF |
add ebx, eax |
add edx, eax |
jmp @b |
.merge_done: |
pop esi |
or ebx, FREE_BLOCK |
mov [page_tabs+ecx*4], ebx |
.ret: |
pop eax edx ecx |
ret |
.realloc_add: |
; get some additional memory |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
mov eax, [SLOT_BASE+APPDATA.heap_top+eax] |
add eax, new_app_base |
shr eax, 12 |
cmp edx, eax |
jae .cant_inplace |
mov eax, [page_tabs+edx*4] |
shr eax, 12 |
add eax, edx |
cmp eax, ebx |
jb .cant_inplace |
sub eax, ebx |
jz @f |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+ebx*4], eax |
@@: |
mov eax, ebx |
sub eax, ecx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+ecx*4], eax |
lea eax, [ecx+1-(new_app_base shr 12)] |
shl eax, 12 |
push eax |
push edi |
lea edi, [page_tabs+edx*4] |
mov eax, 2 |
sub ebx, edx |
mov ecx, ebx |
cld |
rep stosd |
pop edi |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
shl ebx, 12 |
add ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
call update_mem_size |
pop eax edx ecx |
ret |
.cant_inplace: |
push esi edi |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
mov esi, [SLOT_BASE+APPDATA.heap_base+eax] |
mov edi, [SLOT_BASE+APPDATA.heap_top+eax] |
add esi, new_app_base |
add edi, new_app_base |
shr esi, 12 |
shr edi, 12 |
sub ebx, ecx |
.find_place: |
cmp esi, edi |
jae .place_not_found |
mov eax, [page_tabs+esi*4] |
test al, FREE_BLOCK |
jz .next_place |
shr eax, 12 |
cmp eax, ebx |
jae .place_found |
add esi, eax |
jmp .find_place |
.next_place: |
shr eax, 12 |
add esi, eax |
jmp .find_place |
.place_not_found: |
pop edi esi |
jmp .ret0 |
.place_found: |
sub eax, ebx |
jz @f |
push esi |
add esi, eax |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
pop esi |
@@: |
mov eax, ebx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+esi*4], eax |
inc esi |
mov eax, esi |
shl eax, 12 |
sub eax, new_app_base |
push eax |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
or al, FREE_BLOCK |
sub edx, ecx |
mov [page_tabs+ecx*4], eax |
inc ecx |
@@: |
xor eax, eax |
xchg eax, [page_tabs+ecx*4] |
mov [page_tabs+esi*4], eax |
mov eax, ecx |
shl eax, 12 |
invlpg [eax] |
inc ecx |
inc esi |
dec ebx |
dec edx |
jnz @b |
push ebx |
mov edx, [CURRENT_TASK] |
shl edx, 8 |
shl ebx, 12 |
add ebx, [SLOT_BASE+APPDATA.mem_size+edx] |
call update_mem_size |
pop ebx |
@@: |
mov dword [page_tabs+esi*4], 2 |
inc esi |
dec ebx |
jnz @b |
pop eax edi esi edx ecx |
ret |
if 0 |
align 4 |
proc alloc_dll |
pushf |
cli |
bsf eax, [dll_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [dll_map], eax |
popf |
shl eax, 5 |
add eax, dll_tab |
ret |
endp |
align 4 |
proc alloc_service |
pushf |
cli |
bsf eax, [srv_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [srv_map], eax |
popf |
shl eax,0x02 |
lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
ret |
endp |
end if |
/kernel/branches/hd_kolibri/kernel/core/idle.inc |
---|
0,0 → 1,57 |
checkidle: |
pushad |
cmp [check_idle_semaphore],0 |
jne no_idle_state |
call change_task |
mov eax,[idlemem] |
mov ebx,[timer_ticks] ;[0xfdf0] |
cmp eax,ebx |
jnz idle_exit |
call _rdtsc |
mov ecx,eax |
idle_loop: |
hlt |
cmp [check_idle_semaphore],0 |
jne idle_loop_exit |
mov eax,[timer_ticks] ;[0xfdf0] |
cmp ebx,eax |
jz idle_loop |
idle_loop_exit: |
mov [idlemem],eax |
call _rdtsc |
sub eax,ecx |
mov ebx,[idleuse] |
add ebx,eax |
mov [idleuse],ebx |
popad |
ret |
idle_exit: |
mov ebx,[timer_ticks] ;[0xfdf0] |
mov [idlemem],ebx |
call change_task |
popad |
ret |
no_idle_state: |
dec [check_idle_semaphore] |
mov ebx,[timer_ticks] ;[0xfdf0] |
mov [idlemem],ebx |
call change_task |
popad |
ret |
uglobal |
idlemem dd 0x0 |
idleuse dd 0x0 |
idleusesec dd 0x0 |
check_idle_semaphore dd 0x0 |
endg |
/kernel/branches/hd_kolibri/kernel/core/mainloop.inc |
---|
0,0 → 1,22 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP START ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
osloop: |
call [draw_pointer] |
call checkbuttons |
call checkwindows |
; call check_window_move_request |
call checkmisc |
call checkVga_N13 |
call stack_handler |
call checkidle |
call check_fdd_motor_status |
jmp osloop |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; MAIN OS LOOP END ; |
; ; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
/kernel/branches/hd_kolibri/kernel/core/malloc.inc |
---|
0,0 → 1,1001 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Small heap based on malloc/free/realloc written by Doug Lea |
; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) |
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c |
; License http://creativecommons.org/licenses/publicdomain. |
; eax= size |
; temp |
; esi= nb |
; ebx= idx |
; |
malloc: |
push esi |
; nb = ((size+7)&~7)+8; |
mov esi, eax ;size |
add esi, 7 |
and esi, -8 |
add esi, 8 |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
cmp esi, 256 |
jae .large |
mov ecx, esi |
shr ecx, 3 |
or eax, -1 |
shl eax, cl |
and eax, [mst.smallmap] |
jz .small |
push ebp |
push edi |
bsf eax, eax |
mov ebx, eax |
; psize= idx<<3; |
; B = &ms.smallbins[idx]; |
; p = B->fd; |
; F = p->fd; |
; rsize= psize-nb; |
lea ebp, [eax*8] ;ebp= psize |
shl eax, 4 |
lea edi, [mst.smallbins+eax] ;edi= B |
mov edx, [edi+8] ;edx= p |
mov eax, [edx+8] ;eax= F |
mov ecx, ebp |
sub ecx, esi ;ecx= rsize |
; if (B == F) |
cmp edi, eax |
jne @F |
btr [mst.smallmap], ebx |
@@: |
; B->fd = F; |
; F->bk = B; |
; if(rsize<16) |
cmp ecx, 16 |
mov [edi+8], eax |
mov [eax+12], edi |
jae .split |
; p->head = psize|PINUSE_BIT|CINUSE_BIT; |
; (p + psize)->head |= PINUSE_BIT; |
lea eax, [edx+8] |
or dword [edx+ebp+4], 1 |
or ebp, 3 |
mov [edx+4], ebp |
pop edi |
pop ebp |
.done: |
pop esi |
mov [mst.mutex], 0 |
ret |
.split: |
lea ebx, [edx+8] ;ebx=mem |
; r = chunk_plus_offset(p, nb); |
; p->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
lea eax, [edx+esi] ;eax= r |
or esi, 3 |
mov [edx+4], esi |
mov edx, ecx |
or edx, 1 |
mov [eax+4], edx |
; (r + rsize)->prev_foot = rsize; |
mov [eax+ecx], ecx |
; I = rsize>>3; |
shr ecx, 3 |
; ms.smallmap |= 1<< I; |
bts [mst.smallmap], ecx |
; B = &ms.smallbins[I]; |
shl ecx, 4 |
pop edi |
pop ebp |
add ecx, mst.smallbins ;ecx= B |
mov edx, [ecx+8] ; F = B->fd; |
mov [ecx+8], eax ; B->fd = r; |
mov [edx+12], eax ; F->bk = r; |
mov [eax+8], edx ; r->fd = F; |
mov [eax+12], ecx ; r->bk = B; |
mov eax, ebx |
pop esi |
ret |
.small: |
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) |
cmp [mst.treemap], 0 |
je .from_top |
mov eax, esi |
call malloc_small |
test eax, eax |
jz .from_top |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) |
cmp [mst.treemap], 0 |
je .from_top |
call malloc_large ;esi= nb |
test eax, eax |
jne .done |
.from_top: |
; if (nb < ms.topsize) |
mov eax, [mst.topsize] |
cmp esi, eax |
jae .fail |
; rsize = ms.topsize -= nb; |
; p = ms.top; |
mov ecx, [mst.top] |
sub eax, esi |
mov [mst.topsize], eax |
; r = ms.top = chunk_plus_offset(p, nb); |
; r->head = rsize | PINUSE_BIT; |
; p->head = nb |PINUSE_BIT|CINUSE_BIT; |
lea edx, [ecx+esi] |
or eax, 1 |
mov [mst.top], edx |
or esi, 3 |
mov [edx+4], eax |
mov [ecx+4], esi |
lea eax, [ecx+8] |
pop esi |
and [mst.mutex], 0 |
ret |
.fail: |
xor eax, eax |
pop esi |
and [mst.mutex], 0 |
ret |
; param |
; eax= mem |
align 4 |
free: |
push edi |
mov edi, eax |
add edi, -8 |
; if(p->head & CINUSE_BIT) |
test byte [edi+4], 2 |
je .fail |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
; psize = p->head & (~3); |
mov eax, [edi+4] |
push esi |
mov esi, eax |
and esi, -4 |
; next = chunk_plus_offset(p, psize); |
; if(!(p->head & PINUSE_BIT)) |
test al, 1 |
lea ebx, [esi+edi] |
jne .next |
; prevsize = p->prev_foot; |
; prev=p - prevsize; |
; psize += prevsize; |
; p = prev; |
mov ecx, [edi] ;ecx= prevsize |
add esi, ecx ;esi= psize |
sub edi, ecx ;edi= p |
; if (prevsize < 256) |
cmp ecx, 256 |
jae .unlink_large |
mov eax, [edi+8] ;F = p->fd; |
mov edx, [edi+12] ;B = p->bk; |
; if (F == B) |
; ms.smallmap &= ~(1<< I); |
shr ecx, 3 |
cmp eax, edx |
jne @F |
and [mst.smallmap], ecx |
@@: |
mov [eax+12], edx ;F->bk = B; |
mov [edx+8], eax ;B->fd = F |
jmp .next |
.unlink_large: |
mov edx, edi |
call unlink_large_chunk |
.next: |
; if(next->head & PINUSE_BIT) |
mov eax, [ebx+4] |
test al, 1 |
jz .fail2 |
; if (! (next->head & CINUSE_BIT)) |
test al, 2 |
jnz .fix_next |
; if (next == ms.top) |
cmp ebx, [mst.top] |
jne @F |
; tsize = ms.topsize += psize; |
mov eax, [mst.topsize] |
add eax, esi |
mov [mst.topsize], eax |
; ms.top = p; |
; p->head = tsize | PINUSE_BIT; |
or eax, 1 |
mov [mst.top], edi |
mov [edi+4], eax |
.fail2: |
and [mst.mutex], 0 |
pop esi |
.fail: |
pop edi |
ret |
@@: |
; nsize = next->head & ~INUSE_BITS; |
and eax, -4 |
add esi, eax ;psize += nsize; |
; if (nsize < 256) |
cmp eax, 256 |
jae .unl_large |
mov edx, [ebx+8] ;F = next->fd |
mov ebx, [ebx+12] ;B = next->bk |
; if (F == B) |
cmp edx, ebx |
jne @F |
mov ecx, eax |
shr ecx, 3 |
btr [mst.smallmap], ecx |
@@: |
mov [edx+12], ebx ;F->bk = B |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
mov [ebx+8], edx |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.unl_large: |
; unlink_large_chunk((tchunkptr)next); |
mov edx, ebx |
call unlink_large_chunk |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.fix_next: |
; (p+psize)->prev_foot = psize; |
; next->head &= ~PINUSE_BIT; |
; p->head = psize|PINUSE_BIT; |
and eax, -2 |
mov edx, esi |
mov [ebx+4], eax |
or edx, 1 |
mov [edi+4], edx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
; param |
; ecx = chunk |
; eax = size |
align 4 |
insert_chunk: |
cmp eax, 256 |
push esi |
mov esi, ecx |
jae .large |
; I = S>>3; |
; ms.smallmap |= 1<< I; |
shr eax, 3 |
bts [mst.smallmap], eax |
; B = &ms.smallbins[I]; |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] ;F = B->fd |
mov [eax+8], esi ;B->fd = P |
mov [edx+12], esi ;F->bk = P |
mov [esi+8], edx ;P->fd = F |
mov [esi+12], eax ;P->bk = B |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
mov ebx, eax |
call insert_large_chunk |
pop esi |
and [mst.mutex], 0 |
ret |
align 4 |
; param |
; esi= chunk |
; ebx= size |
align 4 |
insert_large_chunk: |
; I = compute_tree_index(S); |
mov edx, ebx |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
mov edx, ebx |
shr edx, cl |
and edx, 1 |
lea ecx, [edx+eax*2] |
; X->index = I; |
mov dword [esi+28], ecx |
; X->child[0] = X->child[1] = 0; |
and dword [esi+20], 0 |
and dword [esi+16], 0 |
; H = &ms.treebins[I]; |
mov eax, ecx |
lea edx, [mst.treebins+eax*4] |
; if (!(ms.treemap & 1<<I)) |
bt [mst.treemap], ecx |
jc .tree |
; ms.treemap |= 1<<I; |
bts [mst.treemap], ecx |
; *H = X; |
mov dword [edx], esi |
jmp .done |
.tree: |
; T = *H; |
mov edx, [edx] |
; K = S << leftshift_for_tree_index(I); |
mov eax, ecx |
shr eax, 1 |
sub ecx, 31 |
mov edi, 37 |
sub edi, eax |
neg ecx |
sbb ecx, ecx |
and ecx, edi |
mov eax, ebx |
shl eax, cl ;eax= K |
jmp .loop |
.not_eq_size: |
; C = &(T->child[(K >> 31) & 1]); |
mov ecx, eax |
shr ecx, 31 |
lea ecx, [edx+ecx*4+16] |
; K <<= 1; |
; if (*C != 0) |
mov edi, [ecx] |
add eax, eax |
test edi, edi |
jz .insert_child |
; T = *C; |
mov edx, edi |
.loop: |
; for (;;) |
; if ((T->head & ~INUSE_BITS) != S) |
mov ecx, [edx+4] |
and ecx, not 3 |
cmp ecx, ebx |
jne .not_eq_size |
; F = T->fd; |
mov eax, [edx+8] |
; T->fd = F->bk = X; |
mov [eax+12], esi |
mov [edx+8], esi |
; X->fd = F; |
; X->bk = T; |
; X->parent = 0; |
and dword [esi+24], 0 |
mov [esi+8], eax |
mov [esi+12], edx |
ret |
.insert_child: |
; *C = X; |
mov [ecx], esi |
.done: |
; X->parent = T; |
mov [esi+24], edx |
; X->fd = X->bk = X; |
mov [esi+12], esi |
mov [esi+8], esi |
ret |
; param |
; edx= chunk |
align 4 |
unlink_large_chunk: |
mov eax, [edx+12] |
cmp eax, edx |
push edi |
mov edi, [edx+24] |
je @F |
mov ecx, [edx+8] ;F = X->fd |
mov [ecx+12], eax ;F->bk = R; |
mov [eax+8], ecx ;R->fd = F |
jmp .parent |
@@: |
mov eax, [edx+20] |
test eax, eax |
push esi |
lea esi, [edx+20] |
jne .loop |
mov eax, [edx+16] |
test eax, eax |
lea esi, [edx+16] |
je .l2 |
.loop: |
cmp dword [eax+20], 0 |
lea ecx, [eax+20] |
jne @F |
cmp dword [eax+16], 0 |
lea ecx, [eax+16] |
je .l1 |
@@: |
mov eax, [ecx] |
mov esi, ecx |
jmp .loop |
.l1: |
mov dword [esi], 0 |
.l2: |
pop esi |
.parent: |
test edi, edi |
je .done |
mov ecx, [edx+28] |
cmp edx, [mst.treebins+ecx*4] |
lea ecx, [mst.treebins+ecx*4] |
jne .l3 |
test eax, eax |
mov [ecx], eax |
jne .l5 |
mov ecx, [edx+28] |
btr [mst.treemap], ecx |
pop edi |
ret |
.l3: |
cmp [edi+16], edx |
jne @F |
mov [edi+16], eax |
jmp .l4 |
@@: |
mov [edi+20], eax |
.l4: |
test eax, eax |
je .done |
.l5: |
mov [eax+24], edi |
mov ecx, [edx+16] |
test ecx, ecx |
je .l6 |
mov [eax+16], ecx |
mov [ecx+24], eax |
.l6: |
mov edx, [edx+20] |
test edx, edx |
je .done |
mov [eax+20], edx |
mov [edx+24], eax |
.done: |
pop edi |
ret |
; param |
; esi= nb |
align 4 |
malloc_small: |
push ebp |
mov ebp, esi |
push edi |
bsf eax,[mst.treemap] |
mov ecx, [mst.treebins+eax*4] |
; rsize = (t->head & ~INUSE_BITS) - nb; |
mov edi, [ecx+4] |
and edi, -4 |
sub edi, esi |
.loop: |
mov ebx, ecx |
.loop_1: |
; while ((t = leftmost_child(t)) != 0) |
mov eax, [ecx+16] |
test eax, eax |
jz @F |
mov ecx, eax |
jmp .l1 |
@@: |
mov ecx, [ecx+20] |
.l1: |
test ecx, ecx |
jz .unlink |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov eax, [ecx+4] |
and eax, -4 |
sub eax, ebp |
; if (trem < rsize) |
cmp eax, edi |
jae .loop_1 |
; rsize = trem; |
mov edi, eax |
jmp .loop |
.unlink: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebx |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .split |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebp] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebx |
lea eax, [edi+ebp+4] |
pop edi |
or ecx, 3 |
mov [ebx+4], ecx |
or dword [eax], 1 |
pop ebp |
lea eax, [ebx+8] |
ret |
.split: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
; (r+rsize)->prev_foot = rsize; |
or ebp, 3 |
mov edx, edi |
or edx, 1 |
cmp edi, 256 |
mov [ebx+4], ebp |
mov [esi+4], edx |
mov [esi+edi], edi |
jae .large |
shr edi, 3 |
bts [mst.smallmap], edi |
mov eax, edi |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] |
mov [eax+8], esi |
mov [edx+12], esi |
pop edi |
mov [esi+12], eax |
mov [esi+8], edx |
pop ebp |
lea eax, [ebx+8] |
ret |
.large: |
lea eax, [ebx+8] |
push eax |
mov ebx, edi |
call insert_large_chunk |
pop eax |
pop edi |
pop ebp |
ret |
; param |
; esi= nb |
align 4 |
malloc_large: |
.idx equ esp+4 |
.rst equ esp |
push ebp |
push edi |
sub esp, 8 |
; v = 0; |
; rsize = -nb; |
mov edi, esi |
mov ebx, esi |
xor ebp, ebp |
neg edi |
; idx = compute_tree_index(nb); |
mov edx, esi |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
shr esi, cl |
and esi, 1 |
lea ecx, [esi+eax*2] |
mov [.idx], ecx |
; if ((t = ms.treebins[idx]) != 0) |
mov eax, [mst.treebins+ecx*4] |
test eax, eax |
jz .l3 |
; sizebits = nb << leftshift_for_tree_index(idx); |
cmp ecx, 31 |
jne @F |
xor ecx, ecx |
jmp .l1 |
@@: |
mov edx, ecx |
shr edx, 1 |
mov ecx, 37 |
sub ecx, edx |
.l1: |
mov edx, ebx |
shl edx, cl |
; rst = 0; |
mov [.rst], ebp |
.loop: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; v = t; |
; if ((rsize = trem) == 0) |
test ecx, ecx |
mov ebp, eax |
mov edi, ecx |
je .l2 |
@@: |
; rt = t->child[1]; |
mov ecx, [eax+20] |
; t = t->child[(sizebits >> 31) & 1]; |
mov esi, edx |
shr esi, 31 |
; if (rt != 0 && rt != t) |
test ecx, ecx |
mov eax, [eax+esi*4+16] |
jz @F |
cmp ecx, eax |
jz @F |
; rst = rt; |
mov [.rst], ecx |
@@: |
; if (t == 0) |
test eax, eax |
jz @F |
; sizebits <<= 1; |
add edx, edx |
jmp .loop |
@@: |
; t = rst; |
mov eax, [.rst] |
.l2: |
; if (t == 0 && v == 0) |
test eax, eax |
jne .l4 |
test ebp, ebp |
jne .l7 |
mov ecx, [.idx] |
.l3: |
; leftbits = (-1<<idx) & ms.treemap; |
; if (leftbits != 0) |
or edx, -1 |
shl edx, cl |
and edx, [mst.treemap] |
jz @F |
bsf eax, edx |
; t = ms.treebins[i]; |
mov eax, [mst.treebins+eax*4] |
@@: |
; while (t != 0) |
test eax, eax |
jz .l5 |
.l4: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; rsize = trem; |
mov edi, ecx |
; v = t; |
mov ebp, eax |
@@: |
; t = leftmost_child(t); |
mov ecx, [eax+16] |
test ecx, ecx |
je @F |
mov eax, ecx |
jmp .l6 |
@@: |
mov eax, [eax+20] |
.l6: |
; while (t != 0) |
test eax, eax |
jne .l4 |
.l5: |
; if (v != 0) |
test ebp, ebp |
jz .done |
.l7: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebp |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .large |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebx] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebp |
lea eax, [edi+ebx+4] |
or ecx, 3 |
mov [ebp+4], ecx |
or dword [eax], 1 |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.large: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
mov edx, edi |
or ebx, 3 |
mov [ebp+4], ebx |
or edx, 1 |
mov [esi+4], edx |
; (r+rsize)->prev_foot = rsize; |
; insert_large_chunk((tchunkptr)r, rsize); |
mov [esi+edi], edi |
mov eax, edi |
mov ecx, esi |
call insert_chunk |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.done: |
add esp, 8 |
pop edi |
pop ebp |
xor eax, eax |
ret |
align 4 |
init_malloc: |
stdcall kernel_alloc, 0x20000 |
mov [mst.top], eax |
mov [mst.topsize], 128*1024 |
mov dword [eax+4], (128*1024) or 1 |
mov eax, mst.smallbins |
@@: |
mov [eax+8], eax |
mov [eax+12], eax |
add eax, 16 |
cmp eax, mst.smallbins+512 |
jl @B |
ret |
/kernel/branches/hd_kolibri/kernel/core/memory.inc |
---|
0,0 → 1,1662 |
$Revision: 448 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
tmp_page_tab equ HEAP_BASE |
align 4 |
proc mem_test |
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' |
@@: |
add edi, 0x400000 |
xchg ebx, dword [edi] |
cmp dword [edi], 'TEST' |
xchg ebx, dword [edi] |
je @b |
mov [MEM_AMOUNT], edi |
and eax, not (CR0_CD+CR0_NW) ;enable caching |
mov cr0, eax |
mov eax, edi |
mov [LFBSize], 0x00800000 |
ret |
endp |
align 4 |
proc init_mem |
mov eax, [MEM_AMOUNT] |
mov [pg_data.mem_amount], eax |
mov [pg_data.kernel_max], eax |
shr eax, 12 |
mov edx, eax |
mov [pg_data.pages_count], eax |
mov [pg_data.kernel_pages], eax |
shr eax, 3 |
mov [pg_data.pagemap_size], eax |
shr edx, 10 |
cmp edx, 3 |
ja @f |
inc edx ;at least 4Mb for kernel heap |
@@: |
mov [pg_data.kernel_tables], edx |
xor eax, eax |
mov edi, sys_pgdir |
mov ecx, 2048 |
cld |
rep stosd |
mov edx, sys_pgdir |
bt [cpu_caps], CAPS_PSE |
jnc .no_PSE |
mov ebx, cr4 |
or ebx, CR4_PSE |
mov eax, PG_LARGE+PG_SW |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or eax, PG_GLOBAL |
or ebx, CR4_PGE |
@@: |
mov cr4, ebx |
sub [pg_data.kernel_tables], 2 |
mov [edx], eax |
add eax, 0x00400000 |
mov [edx+4], eax |
add edx, 8 |
mov eax, 0x800000+PG_SW |
mov ecx, (HEAP_BASE-0x800000)/4096 |
jmp .map_low |
.no_PSE: |
mov eax, PG_SW |
mov ecx, HEAP_BASE/4096 |
.map_low: |
mov edi, tmp_page_tab |
@@: ; |
stosd |
add eax, 0x1000 |
dec ecx |
jnz @B |
mov ecx, [pg_data.kernel_tables] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov ecx, [pg_data.kernel_tables] |
mov eax, tmp_page_tab+PG_SW |
mov edi, edx |
.map_kernel_tabs: |
stosd |
add eax, 0x1000 |
dec ecx |
jnz .map_kernel_tabs |
mov dword [sys_pgdir+(page_tabs shr 20)], sys_pgdir+PG_SW |
ret |
endp |
align 4 |
proc init_page_map |
mov edi, sys_pgmap |
mov ecx, (HEAP_BASE/4096)/32 ;384/4 |
mov ebx, ecx |
xor eax,eax |
cld |
rep stosd |
not eax |
mov ecx, [pg_data.pagemap_size] |
sub ecx, ebx |
shr ecx, 2 |
rep stosd |
lea edi, [sys_pgmap+ebx*4] ;+384 |
mov edx, [pg_data.pages_count] |
mov ecx, [pg_data.kernel_tables] |
add ecx, (HEAP_BASE/4096) and 31 |
sub edx, HEAP_BASE/4096 |
sub edx, ecx |
mov [pg_data.pages_free], edx |
xor eax, eax |
mov ebx, ecx |
shr ecx, 5 |
rep stosd |
not eax |
mov ecx, ebx |
and ecx, 31 |
shl eax, cl |
mov [page_start], edi; sys_pgmap+384 |
stosd |
mov ebx, sys_pgmap |
add ebx, [pg_data.pagemap_size] |
mov [page_end], ebx |
mov [pg_data.pg_mutex], 0 |
ret |
endp |
align 4 |
proc alloc_page |
pushfd |
cli |
mov ebx, [page_start] |
mov ecx, [page_end] |
.l1: |
bsf eax,[ebx]; |
jnz .found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
.found: |
btr [ebx], eax |
mov [page_start],ebx |
sub ebx, sys_pgmap |
lea eax, [eax+ebx*8] |
shl eax, 12 |
dec [pg_data.pages_free] |
popfd |
ret |
endp |
align 4 |
proc alloc_pages stdcall, count:dword |
pushfd |
cli |
mov eax, [count] |
add eax, 7 |
shr eax, 3 |
mov [count], eax |
cmp eax, [pg_data.pages_free] |
ja .fail |
mov ecx, [page_start] |
mov ebx, [page_end] |
.find: |
mov edx, [count] |
mov edi, ecx |
.match: |
cmp byte [ecx], 0xFF |
jne .next |
dec edx |
jz .ok |
inc ecx |
cmp ecx,ebx |
jb .match |
.fail: xor eax, eax |
popfd |
ret |
.next: |
inc ecx |
cmp ecx, ebx |
jb .find |
popfd |
xor eax, eax |
ret |
.ok: |
sub ecx, edi |
inc ecx |
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 |
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 |
endp |
align 4 |
map_space: ;not implemented |
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 |
@@: |
mov [page_start], eax |
popfd |
ret |
endp |
; param |
; eax= page base + page flags |
; ebx= liear address |
; ecx= count |
align 4 |
commit_pages: |
test ecx, ecx |
jz .fail |
mov edi, ebx |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edx, 0x1000 |
mov ebx, edi |
shr ebx, 12 |
@@: |
mov [page_tabs+ebx*4], eax |
invlpg [edi] |
add edi, edx |
add eax, edx |
inc ebx |
dec ecx |
jnz @B |
mov [pg_data.pg_mutex],ecx |
.fail: |
ret |
; param |
; eax= base |
; ecx= count |
align 4 |
release_pages: |
pushad |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov esi, eax |
mov edi, eax |
shr esi, 10 |
add esi, page_tabs |
mov ebp, [pg_data.pages_free] |
mov ebx, [page_start] |
mov edx, sys_pgmap |
@@: |
xor eax, eax |
xchg eax, [esi] |
invlpg [edi] |
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 |
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 |
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 |
endp |
align 4 |
proc init_LFB |
locals |
pg_count dd ? |
endl |
cmp dword [LFBAddress], -1 |
jne @f |
mov [BOOT_VAR+0x901c],byte 2 |
stdcall kernel_alloc, 0x280000 |
mov [LFBAddress], eax |
ret |
@@: |
test [SCR_MODE],word 0100000000000000b |
jnz @f |
mov [BOOT_VAR+0x901c],byte 2 |
ret |
@@: |
mov edx, LFB_BASE |
mov esi, [LFBAddress] |
mov edi, [LFBSize] |
mov dword [exp_lfb+4], edx |
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 |
shr edx, 20 |
mov ecx, edx |
@@: |
mov [sys_pgdir+edx], esi |
add edx, 4 |
add esi, 0x00400000 |
dec edi |
jnz @B |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or dword [sys_pgdir+ecx], PG_GLOBAL |
@@: |
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 .map_page_tables |
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 |
mov dword [LFBAddress], LFB_BASE |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
endp |
align 4 |
proc new_mem_resize stdcall, new_size:dword |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edi, [new_size] |
add edi,4095 |
and edi,not 4095 |
mov [new_size], edi |
mov edx,[CURRENT_TASK] |
shl edx,8 |
cmp [SLOT_BASE+APPDATA.heap_base+edx],0 |
jne .exit |
mov esi, [SLOT_BASE+APPDATA.mem_size+edx] |
add esi, 4095 |
and esi, not 4095 |
cmp edi, esi |
jae .expand |
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 |
invlpg [ebx+std_application_base_address] |
call free_page |
.next: add edi, 1 |
cmp edi, esi |
jb @B |
.update_size: |
mov ebx, [new_size] |
call update_mem_size |
xor eax, eax |
dec [pg_data.pg_mutex] |
ret |
.expand: |
add edi, new_app_base |
add esi, new_app_base |
push esi |
push edi |
add edi, 0x3FFFFF |
and edi, not(0x3FFFFF) |
add esi, 0x3FFFFF |
and esi, not(0x3FFFFF) |
cmp esi, edi |
jae .grow |
xchg esi, edi |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
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 |
add edi, 0x00400000 |
cmp edi, esi |
jb @B |
.grow: |
pop edi |